home *** CD-ROM | disk | FTP | other *** search
- /* spool.c
- Find a file in the spool directory.
-
- Copyright (C) 1991, 1992, 1993 Ian Lance Taylor
-
- This file is part of the Taylor UUCP package.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The author of the program may be contacted at ian@airs.com or
- c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
- */
-
- #include "uucp.h"
-
- #if USE_RCS_ID
- const char spool_rcsid[] = "$Id: spool.c,v 1.11 1995/06/30 21:22:54 ian Rel $";
- #endif
-
- #include "uudefs.h"
- #include "sysdep.h"
- #include "system.h"
-
- /* There are several types of files that go in the spool directory,
- and they go into various different subdirectories. Whenever the
- system name LOCAL appears below, it means whatever the local system
- name is.
-
- Command files
- These contain instructions for uucico indicating what files to transfer
- to and from what systems. Each line of a work file is a command
- beginning with S, R, X, or E.
- #if ! SPOOLDIR_TAYLOR
- They are named C.ssssssgqqqq, where ssssss is the system name to
- transfer to or from, g is the grade and qqqq is the sequence number.
- #if SPOOLDIR_V2
- They are put in the spool directory.
- #elif SPOOLDIR_BSD42 || SPOOLDIR_BSD43
- They are put in the directory "C.".
- #elif SPOOLDIR_HDB
- They are put in a directory named for the system for which they were
- created.
- #elif SPOOLDIR_ULTRIX
- If the directory sys/ssssss exists, they are put in the directory
- sys/ssssss/C; otherwise, they are put in the directory sys/DEFAULT/C.
- #elif SPOOLDIR_SVR4
- They are put in the directory sys/g, where sys is the system name
- and g is the grade.
- #endif
- #else SPOOLDIR_TAYLOR
- They are named C.gqqqq, where g is the grade and qqqq is the
- sequence number, and are placed in the directory ssssss/C. where
- ssssss is the system name to transfer to or from. The sequence
- number for a C. file is actually a long string; it is not based on
- the sequence number file, but is generated via a process which
- attempts to produce a unique string each time it is run.
- #endif
-
- Data files
- There are files to be transferred to other systems. Some files to
- be transferred may not be in the spool directory, depending on how
- uucp was invoked. Data files are named in work files, so it is
- never necessary to look at them directly (except to remove old ones);
- it is only necessary to create them. These means that the many
- variations in naming are inconsequential.
- #if ! SPOOLDIR_TAYLOR
- They are named D.ssssssgqqqq where ssssss is a system name (which
- may be LOCAL for locally initiated transfers or a remote system for
- remotely initiated transfers, except that HDB appears to use the
- system the file is being transferred to), g is the grade and qqqq
- is the sequence number. Some systems use a trailing subjob ID
- number, but we currently do not. The grade is not important, and
- some systems do not use it. If the data file is to become an
- execution file on another system the grade (if present) will be
- 'X'. Otherwise Ultrix appears to use 'b'; the uux included with
- gnuucp 1.0 appears to use 'S'; SCO does not appear to use a grade,
- although it does use a subjob ID number.
- #if SPOOLDIR_V2
- They are put in the spool directory.
- #elif SPOOLDIR_BSD42
- If the name begins with D.LOCAL, the file is put in the directory
- D.LOCAL. Otherwise the file is put in the directory D..
- #elif SPOOLDIR_BSD43
- If the name begins with D.LOCALX, the file is put in the directory
- D.LOCALX. Otherwise if the name begins with D.LOCAL, the file is
- put in the directory D.LOCAL Otherwise the file is put in the
- directory "D.".
- #elif SPOOLDIR_HDB
- They are put in a directory named for the system for which they
- were created.
- #elif SPOOLDIR_ULTRIX
- Say the file is being transferred to system REMOTE. If the
- directory sys/REMOTE exists, then if the file begins with D.LOCALX
- it is put in sys/REMOTE/D.LOCALX, if the file begins with D.LOCAL
- it is put in sys/REMOTE/D.LOCAL, and otherwise it is put in
- "sys/REMOTE/D.". If the directory sys/REMOTE does not exist, the
- same applies except that DEFAULT is used instead of REMOTE.
- #elif SPOOLDIR_SVR4
- They are put in the directory sys/g, where sys is the system name
- and g is the grade.
- #endif
- #else SPOOLDIR_TAYLOR
- If the file is to become an executable file on another system it is
- named D.Xqqqq, otherwise it is named D.qqqq where in both cases
- qqqq is a sequence number. If the corresponding C. file is in
- directory ssssss/C., a D.X file is placed in ssssss/D.X and a D.
- file is placed in "ssssss/D.".
- #endif
-
- Execute files
- These are files that specify programs to be executed. They are
- created by uux, perhaps as run on another system. These names are
- important, because a file transfer done to an execute file name
- causes an execution to occur. The name is X.ssssssgqqqq, where
- ssssss is the requesting system, g is the grade, and qqqq is a
- sequence number.
- #if SPOOLDIR_V2 || SPOOLDIR_BSD42
- These files are placed in the spool directory.
- #elif SPOOLDIR_BSD43
- These files are placed in the directory X..
- #elif SPOOLDIR_HDB || SPOOLDIR_SVR4
- These files are put in a directory named for the system for which
- the files were created.
- #elif SPOOLDIR_ULTRIX
- If there is a spool directory (sys/ssssss) for the requesting
- system, the files are placed in sys/ssssss/X.; otherwise, the files
- are placed in "sys/DEFAULT/X.".
- #elif SPOOLDIR_TAYLOR
- The system name is automatically truncated to seven characters when
- a file is created. The files are placed in the subdirectory X. of
- a directory named for the system for which the files were created.
- #endif
-
- Temporary receive files
- These are used when receiving files from another system. They are
- later renamed to the final name. The actual name is unimportant,
- although it generally begins with TM..
- #if SPOOLDIR_V2 || SPOOLDIR_BSD42
- These files are placed in the spool directory.
- #elif SPOOLDIR_BSD43 || SPOOLDIR_ULTRIX || SPOOLDIR_TAYLOR
- These files are placed in the directory .Temp.
- #elif SPOOLDIR_HDB || SPOOLDIR_SVR4
- These files are placed in a directory named for the system for
- which they were created.
- #endif
-
- System status files
- These are used to record when the last call was made to the system
- and what the status is. They are used to prevent frequent recalls
- to a system which is not responding. I will not attempt to
- recreate the format of these exactly, since they are not all that
- important. They will be put in the directory .Status, as in HDB,
- and they use the system name as the name of the file.
-
- Sequence file
- This is used to generate a unique sequence number. It contains an
- ASCII number.
- #if SPOOLDIR_V2 || SPOOLDIR_BSD42 || SPOOLDIR_BSD43
- The file is named SEQF and is kept in the spool directory.
- #elif SPOOLDIR_HDB || SPOOLDIR_SVR4
- A separate sequence file is kept for each system in the directory
- .Sequence with the name of the system.
- #elif SPOOLDIR_ULTRIX
- Each system with a file sys/ssssss has a sequence file in
- sys/ssssss/.SEQF. Other systems use sys/DEFAULT/.SEQF.
- #else SPOOLDIR_TAYLOR
- A sequence file named SEQF is kept in the directory ssssss for each
- system.
- #endif
- */
-
- /* Given the name of a file as specified in a UUCP command, and the
- system for which this file has been created, return where to find
- it in the spool directory. The file will begin with C. (a command
- file), D. (a data file) or X. (an execution file). Under
- SPOOLDIR_SVR4 we need to know the grade of the file created by the
- local system; this is the bgrade argument, which is -1 for a file
- from a remote system. */
-
- /*ARGSUSED*/
- char *
- zsfind_file (zsimple, zsystem, bgrade)
- const char *zsimple;
- const char *zsystem;
- int bgrade;
- {
- /* zsysdep_spool_commands calls this with TMPXXX which we must treat
- as a C. file. */
- if ((zsimple[0] != 'T'
- || zsimple[1] != 'M'
- || zsimple[2] != 'P')
- && ! fspool_file (zsimple))
- {
- ulog (LOG_ERROR, "Unrecognized file name %s", zsimple);
- return NULL;
- }
-
- #if ! SPOOLDIR_HDB && ! SPOOLDIR_SVR4 && ! SPOOLDIR_TAYLOR
- if (*zsimple == 'X')
- {
- static char *zbuf;
- static size_t cbuf;
- size_t clen, cwant;
-
- /* Files beginning with X. are execute files. It is important
- for security reasons that we know the system which created
- the X. file. This is easy under SPOOLDIR_HDB or
- SPOOLDIR_SVR4 SPOOLDIR_TAYLOR, because the file will be in a
- directory named for the system. Under other schemes, we must
- get the system name from the X. file name. To prevent
- security violations, we set the system name directly here;
- this will cause problems if the maximum file name length is
- too short, but hopefully no problem will occur since any
- System V systems will be using HDB or SVR4 or TAYLOR. */
- clen = strlen (zsimple);
- if (clen < 5)
- {
- ulog (LOG_ERROR, "Bad file name (too short) %s", zsimple);
- return NULL;
- }
- cwant = strlen (zsystem) + 8;
- if (cwant > cbuf)
- {
- zbuf = (char *) xrealloc ((pointer) zbuf, cwant);
- cbuf = cwant;
- }
- sprintf (zbuf, "X.%s%s", zsystem, zsimple + clen - 5);
- zsimple = zbuf;
- }
- #endif /* ! SPOOLDIR_HDB && ! SPOOLDIR_SVR4 && ! SPOOLDIR_TAYLOR */
-
- #if SPOOLDIR_V2
- /* V2 never uses subdirectories. */
- return zbufcpy (zsimple);
- #endif /* SPOOLDIR_V2 */
-
- #if SPOOLDIR_HDB
- /* HDB always uses the system name as a directory. */
- return zsysdep_in_dir (zsystem, zsimple);
- #endif /* SPOOLDIR_HDB */
-
- #if SPOOLDIR_SVR4
- /* SVR4 uses grade directories within the system directory for local
- command and data files. */
- if (bgrade < 0 || *zsimple == 'X')
- return zsysdep_in_dir (zsystem, zsimple);
- else
- {
- char abgrade[2];
-
- abgrade[0] = bgrade;
- abgrade[1] = '\0';
- return zsappend3 (zsystem, abgrade, zsimple);
- }
- #endif /* SPOOLDIR_SVR4 */
-
- #if ! SPOOLDIR_V2 && ! SPOOLDIR_HDB && ! SPOOLDIR_SVR4
- switch (*zsimple)
- {
- case 'C':
- case 'T':
- #if SPOOLDIR_BSD42 || SPOOLDIR_BSD43
- return zsysdep_in_dir ("C.", zsimple);
- #endif /* SPOOLDIR_BSD42 || SPOOLDIR_BSD43 */
- #if SPOOLDIR_ULTRIX
- if (fsultrix_has_spool (zsystem))
- return zsappend4 ("sys", zsystem, "C.", zsimple);
- else
- return zsappend4 ("sys", "DEFAULT", "C.", zsimple);
- #endif /* SPOOLDIR_ULTRIX */
- #if SPOOLDIR_TAYLOR
- return zsappend3 (zsystem, "C.", zsimple);
- #endif /* SPOOLDIR_TAYLOR */
-
- case 'D':
- #if SPOOLDIR_BSD42 || SPOOLDIR_BSD43
- {
- size_t c;
- boolean ftruncated;
-
- /* D.LOCAL in D.LOCAL/, others in D./. If BSD43, D.LOCALX in
- D.LOCALX/. */
- ftruncated = TRUE;
- if (strncmp (zsimple + 2, zSlocalname, strlen (zSlocalname)) == 0)
- {
- c = strlen (zSlocalname);
- ftruncated = FALSE;
- }
- else if (strncmp (zsimple + 2, zSlocalname, 7) == 0)
- c = 7;
- else if (strncmp (zsimple + 2, zSlocalname, 6) == 0)
- c = 6;
- else
- c = 0;
- #if SPOOLDIR_BSD43
- if (c > 0 && zsimple[c + 2] == 'X')
- c++;
- #endif /* SPOOLDIR_BSD43 */
- if (c > 0)
- {
- char *zalloc;
-
- zalloc = zbufalc (c + 3);
- memcpy (zalloc, zsimple, c + 2);
- zalloc[c + 2] = '\0';
-
- /* If we truncated the system name, and there is no existing
- directory with the truncated name, then just use D.. */
- if (! ftruncated || fsysdep_directory (zalloc))
- {
- char *zret;
-
- zret = zsysdep_in_dir (zalloc, zsimple);
- ubuffree (zalloc);
- return zret;
- }
- ubuffree (zalloc);
- }
- return zsysdep_in_dir ("D.", zsimple);
- }
- #endif /* SPOOLDIR_BSD42 || SPOOLDIR_BSD43 */
- #if SPOOLDIR_ULTRIX
- {
- size_t c;
- boolean ftruncated;
- char *zfree;
- const char *zdir;
- char *zret;
-
- /* D.LOCALX in D.LOCALX/, D.LOCAL in D.LOCAL/, others in D./. */
- ftruncated = TRUE;
- if (strncmp (zsimple + 2, zSlocalname, strlen (zSlocalname)) == 0)
- {
- c = strlen (zSlocalname);
- ftruncated = FALSE;
- }
- else if (strncmp (zsimple + 2, zSlocalname, 7) == 0)
- c = 7;
- else if (strncmp (zsimple + 2, zSlocalname, 6) == 0)
- c = 6;
- else
- c = 0;
- if (c > 0 && zsimple[c + 2] == 'X')
- ++c;
- if (c > 0)
- {
- zfree = zbufalc (c + 3);
- memcpy (zfree, zsimple, c + 2);
- zfree[c + 2] = '\0';
- zdir = zfree;
-
- /* If we truncated the name, and there is no directory for
- the truncated name, then don't use it. */
- if (ftruncated)
- {
- char *zlook;
-
- zlook = zsappend3 ("sys",
- (fsultrix_has_spool (zsystem)
- ? zsystem
- : "DEFAULT"),
- zdir);
- if (! fsysdep_directory (zlook))
- zdir = "D.";
- ubuffree (zlook);
- }
- }
- else
- {
- zfree = NULL;
- zdir = "D.";
- }
-
- zret = zsappend4 ("sys",
- (fsultrix_has_spool (zsystem)
- ? zsystem
- : "DEFAULT"),
- zdir,
- zsimple);
- ubuffree (zfree);
- return zret;
- }
- #endif /* SPOOLDIR_ULTRIX */
- #if SPOOLDIR_TAYLOR
- if (zsimple[2] == 'X')
- return zsappend3 (zsystem, "D.X", zsimple);
- else
- return zsappend3 (zsystem, "D.", zsimple);
- #endif /* SPOOLDIR_TAYLOR */
-
-
- case 'X':
- #if SPOOLDIR_BSD42
- return zbufcpy (zsimple);
- #endif
- #if SPOOLDIR_BSD43
- return zsysdep_in_dir ("X.", zsimple);
- #endif
- #if SPOOLDIR_ULTRIX
- return zsappend4 ("sys",
- (fsultrix_has_spool (zsystem)
- ? zsystem
- : "DEFAULT"),
- "X.",
- zsimple);
- #endif
- #if SPOOLDIR_TAYLOR
- return zsappend3 (zsystem, "X.", zsimple);
- #endif
- }
-
- /* This is just to avoid warnings; it will never be executed. */
- return NULL;
- #endif /* ! SPOOLDIR_V2 && ! SPOOLDIR_HDB && ! SPOOLDIR_SVR4 */
- }
-