]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - gnu/libexec/uucp/libunix/spool.c
This commit was generated by cvs2svn to compensate for changes in r56545,
[FreeBSD/FreeBSD.git] / gnu / libexec / uucp / libunix / spool.c
1 /* spool.c
2    Find a file in the spool directory.
3
4    Copyright (C) 1991, 1992, 1993 Ian Lance Taylor
5
6    This file is part of the Taylor UUCP package.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2 of the
11    License, or (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21
22    The author of the program may be contacted at ian@airs.com or
23    c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
24    */
25
26 #include "uucp.h"
27
28 #if USE_RCS_ID
29 const char spool_rcsid[] = "$FreeBSD$";
30 #endif
31
32 #include "uudefs.h"
33 #include "sysdep.h"
34 #include "system.h"
35 \f
36 /* There are several types of files that go in the spool directory,
37    and they go into various different subdirectories.  Whenever the
38    system name LOCAL appears below, it means whatever the local system
39    name is.
40
41    Command files
42    These contain instructions for uucico indicating what files to transfer
43    to and from what systems.  Each line of a work file is a command
44    beginning with S, R, X, or E.
45    #if ! SPOOLDIR_TAYLOR
46    They are named C.ssssssgqqqq, where ssssss is the system name to
47    transfer to or from, g is the grade and qqqq is the sequence number.
48    #if SPOOLDIR_V2
49    They are put in the spool directory.
50    #elif SPOOLDIR_BSD42 || SPOOLDIR_BSD43
51    They are put in the directory "C.".
52    #elif SPOOLDIR_HDB
53    They are put in a directory named for the system for which they were
54    created.
55    #elif SPOOLDIR_ULTRIX
56    If the directory sys/ssssss exists, they are put in the directory
57    sys/ssssss/C; otherwise, they are put in the directory sys/DEFAULT/C.
58    #elif SPOOLDIR_SVR4
59    They are put in the directory sys/g, where sys is the system name
60    and g is the grade.
61    #endif
62    #else SPOOLDIR_TAYLOR
63    They are named C.gqqqq, where g is the grade and qqqq is the
64    sequence number, and are placed in the directory ssssss/C. where
65    ssssss is the system name to transfer to or from.  The sequence
66    number for a C. file is actually a long string; it is not based on
67    the sequence number file, but is generated via a process which
68    attempts to produce a unique string each time it is run.
69    #endif
70
71    Data files
72    There are files to be transferred to other systems.  Some files to
73    be transferred may not be in the spool directory, depending on how
74    uucp was invoked.  Data files are named in work files, so it is
75    never necessary to look at them directly (except to remove old ones);
76    it is only necessary to create them.  These means that the many
77    variations in naming are inconsequential.
78    #if ! SPOOLDIR_TAYLOR
79    They are named D.ssssssgqqqq where ssssss is a system name (which
80    may be LOCAL for locally initiated transfers or a remote system for
81    remotely initiated transfers, except that HDB appears to use the
82    system the file is being transferred to), g is the grade and qqqq
83    is the sequence number.  Some systems use a trailing subjob ID
84    number, but we currently do not.  The grade is not important, and
85    some systems do not use it.  If the data file is to become an
86    execution file on another system the grade (if present) will be
87    'X'.  Otherwise Ultrix appears to use 'b'; the uux included with
88    gnuucp 1.0 appears to use 'S'; SCO does not appear to use a grade,
89    although it does use a subjob ID number.
90    #if SPOOLDIR_V2
91    They are put in the spool directory.
92    #elif SPOOLDIR_BSD42
93    If the name begins with D.LOCAL, the file is put in the directory
94    D.LOCAL.  Otherwise the file is put in the directory D..
95    #elif SPOOLDIR_BSD43
96    If the name begins with D.LOCALX, the file is put in the directory
97    D.LOCALX.  Otherwise if the name begins with D.LOCAL, the file is
98    put in the directory D.LOCAL Otherwise the file is put in the
99    directory "D.".
100    #elif SPOOLDIR_HDB
101    They are put in a directory named for the system for which they
102    were created.
103    #elif SPOOLDIR_ULTRIX
104    Say the file is being transferred to system REMOTE.  If the
105    directory sys/REMOTE exists, then if the file begins with D.LOCALX
106    it is put in sys/REMOTE/D.LOCALX, if the file begins with D.LOCAL
107    it is put in sys/REMOTE/D.LOCAL, and otherwise it is put in
108    "sys/REMOTE/D.".  If the directory sys/REMOTE does not exist, the
109    same applies except that DEFAULT is used instead of REMOTE.
110    #elif SPOOLDIR_SVR4
111    They are put in the directory sys/g, where sys is the system name
112    and g is the grade.
113    #endif
114    #else SPOOLDIR_TAYLOR
115    If the file is to become an executable file on another system it is
116    named D.Xqqqq, otherwise it is named D.qqqq where in both cases
117    qqqq is a sequence number.  If the corresponding C. file is in
118    directory ssssss/C., a D.X file is placed in ssssss/D.X and a D.
119    file is placed in "ssssss/D.".
120    #endif
121
122    Execute files
123    These are files that specify programs to be executed.  They are
124    created by uux, perhaps as run on another system.  These names are
125    important, because a file transfer done to an execute file name
126    causes an execution to occur.  The name is X.ssssssgqqqq, where
127    ssssss is the requesting system, g is the grade, and qqqq is a
128    sequence number.
129    #if SPOOLDIR_V2 || SPOOLDIR_BSD42
130    These files are placed in the spool directory.
131    #elif SPOOLDIR_BSD43
132    These files are placed in the directory X..
133    #elif SPOOLDIR_HDB || SPOOLDIR_SVR4
134    These files are put in a directory named for the system for which
135    the files were created.
136    #elif SPOOLDIR_ULTRIX
137    If there is a spool directory (sys/ssssss) for the requesting
138    system, the files are placed in sys/ssssss/X.; otherwise, the files
139    are placed in "sys/DEFAULT/X.".
140    #elif SPOOLDIR_TAYLOR
141    The system name is automatically truncated to seven characters when
142    a file is created.  The files are placed in the subdirectory X. of
143    a directory named for the system for which the files were created.
144    #endif
145
146    Temporary receive files
147    These are used when receiving files from another system.  They are
148    later renamed to the final name.  The actual name is unimportant,
149    although it generally begins with TM..
150    #if SPOOLDIR_V2 || SPOOLDIR_BSD42
151    These files are placed in the spool directory.
152    #elif SPOOLDIR_BSD43 || SPOOLDIR_ULTRIX || SPOOLDIR_TAYLOR
153    These files are placed in the directory .Temp.
154    #elif SPOOLDIR_HDB || SPOOLDIR_SVR4
155    These files are placed in a directory named for the system for
156    which they were created.
157    #endif
158
159    System status files
160    These are used to record when the last call was made to the system
161    and what the status is.  They are used to prevent frequent recalls
162    to a system which is not responding.  I will not attempt to
163    recreate the format of these exactly, since they are not all that
164    important.  They will be put in the directory .Status, as in HDB,
165    and they use the system name as the name of the file.
166
167    Sequence file
168    This is used to generate a unique sequence number.  It contains an
169    ASCII number.
170    #if SPOOLDIR_V2 || SPOOLDIR_BSD42 || SPOOLDIR_BSD43
171    The file is named SEQF and is kept in the spool directory.
172    #elif SPOOLDIR_HDB || SPOOLDIR_SVR4
173    A separate sequence file is kept for each system in the directory
174    .Sequence with the name of the system.
175    #elif SPOOLDIR_ULTRIX
176    Each system with a file sys/ssssss has a sequence file in
177    sys/ssssss/.SEQF.  Other systems use sys/DEFAULT/.SEQF.
178    #else SPOOLDIR_TAYLOR
179    A sequence file named SEQF is kept in the directory ssssss for each
180    system.
181    #endif
182    */
183 \f
184 /* Given the name of a file as specified in a UUCP command, and the
185    system for which this file has been created, return where to find
186    it in the spool directory.  The file will begin with C. (a command
187    file), D. (a data file) or X. (an execution file).  Under
188    SPOOLDIR_SVR4 we need to know the grade of the file created by the
189    local system; this is the bgrade argument, which is -1 for a file
190    from a remote system.  */
191
192 /*ARGSUSED*/
193 char *
194 zsfind_file (zsimple, zsystem, bgrade)
195      const char *zsimple;
196      const char *zsystem;
197      int bgrade;
198 {
199   /* zsysdep_spool_commands calls this with TMPXXX which we must treat
200      as a C. file.  */
201   if ((zsimple[0] != 'T'
202        || zsimple[1] != 'M'
203        || zsimple[2] != 'P')
204       && ! fspool_file (zsimple))
205     {
206       ulog (LOG_ERROR, "Unrecognized file name %s", zsimple);
207       return NULL;
208     }
209
210 #if ! SPOOLDIR_HDB && ! SPOOLDIR_SVR4 && ! SPOOLDIR_TAYLOR
211   if (*zsimple == 'X')
212     {
213       static char *zbuf;
214       static size_t cbuf;
215       size_t clen, cwant;
216
217       /* Files beginning with X. are execute files.  It is important
218          for security reasons that we know the system which created
219          the X. file.  This is easy under SPOOLDIR_HDB or
220          SPOOLDIR_SVR4 SPOOLDIR_TAYLOR, because the file will be in a
221          directory named for the system.  Under other schemes, we must
222          get the system name from the X. file name.  To prevent
223          security violations, we set the system name directly here;
224          this will cause problems if the maximum file name length is
225          too short, but hopefully no problem will occur since any
226          System V systems will be using HDB or SVR4 or TAYLOR.  */
227       clen = strlen (zsimple);
228       if (clen < 5)
229         {
230           ulog (LOG_ERROR, "Bad file name (too short) %s", zsimple);
231           return NULL;
232         }
233       cwant = strlen (zsystem) + 8;
234       if (cwant > cbuf)
235         {
236           zbuf = (char *) xrealloc ((pointer) zbuf, cwant);
237           cbuf = cwant;
238         }
239       sprintf (zbuf, "X.%s%s", zsystem, zsimple + clen - 5);
240       zsimple = zbuf;
241     }
242 #endif /* ! SPOOLDIR_HDB && ! SPOOLDIR_SVR4 && ! SPOOLDIR_TAYLOR */
243
244 #if SPOOLDIR_V2
245   /* V2 never uses subdirectories.  */
246   return zbufcpy (zsimple);
247 #endif /* SPOOLDIR_V2 */
248
249 #if SPOOLDIR_HDB
250   /* HDB always uses the system name as a directory.  */
251   return zsysdep_in_dir (zsystem, zsimple);
252 #endif /* SPOOLDIR_HDB */
253
254 #if SPOOLDIR_SVR4
255   /* SVR4 uses grade directories within the system directory for local
256      command and data files.  */
257   if (bgrade < 0 || *zsimple == 'X')
258     return zsysdep_in_dir (zsystem, zsimple);
259   else
260     {
261       char abgrade[2];
262
263       abgrade[0] = bgrade;
264       abgrade[1] = '\0';
265       return zsappend3 (zsystem, abgrade, zsimple);
266     }
267 #endif /* SPOOLDIR_SVR4 */
268
269 #if ! SPOOLDIR_V2 && ! SPOOLDIR_HDB && ! SPOOLDIR_SVR4
270   switch (*zsimple)
271     {
272     case 'C':
273     case 'T':
274 #if SPOOLDIR_BSD42 || SPOOLDIR_BSD43
275       return zsysdep_in_dir ("C.", zsimple);
276 #endif /* SPOOLDIR_BSD42 || SPOOLDIR_BSD43 */
277 #if SPOOLDIR_ULTRIX
278       if (fsultrix_has_spool (zsystem))
279         return zsappend4 ("sys", zsystem, "C.", zsimple);
280       else
281         return zsappend4 ("sys", "DEFAULT", "C.", zsimple);
282 #endif /* SPOOLDIR_ULTRIX */
283 #if SPOOLDIR_TAYLOR
284       return zsappend3 (zsystem, "C.", zsimple);
285 #endif /* SPOOLDIR_TAYLOR */
286
287     case 'D':
288 #if SPOOLDIR_BSD42 || SPOOLDIR_BSD43
289       {
290         size_t c;
291         boolean ftruncated;
292       
293         /* D.LOCAL in D.LOCAL/, others in D./.  If BSD43, D.LOCALX in
294            D.LOCALX/.  */
295         ftruncated = TRUE;
296         if (strncmp (zsimple + 2, zSlocalname, strlen (zSlocalname)) == 0)
297           {
298             c = strlen (zSlocalname);
299             ftruncated = FALSE;
300           }
301         else if (strncmp (zsimple + 2, zSlocalname, 7) == 0)
302           c = 7;
303         else if (strncmp (zsimple + 2, zSlocalname, 6) == 0)
304           c = 6;
305         else
306           c = 0;
307 #if SPOOLDIR_BSD43
308         if (c > 0 && zsimple[c + 2] == 'X')
309           c++;
310 #endif /* SPOOLDIR_BSD43 */
311         if (c > 0)
312           {
313             char *zalloc;
314
315             zalloc = zbufalc (c + 3);
316             memcpy (zalloc, zsimple, c + 2);
317             zalloc[c + 2] = '\0';
318
319             /* If we truncated the system name, and there is no existing
320                directory with the truncated name, then just use D..  */
321             if (! ftruncated || fsysdep_directory (zalloc))
322               {
323                 char *zret;
324
325                 zret = zsysdep_in_dir (zalloc, zsimple);
326                 ubuffree (zalloc);
327                 return zret;
328               }
329             ubuffree (zalloc);
330           }
331         return zsysdep_in_dir ("D.", zsimple);
332       }
333 #endif /* SPOOLDIR_BSD42 || SPOOLDIR_BSD43 */
334 #if SPOOLDIR_ULTRIX
335       {
336         size_t c;
337         boolean ftruncated;
338         char *zfree;
339         const char *zdir;
340         char *zret;
341       
342         /* D.LOCALX in D.LOCALX/, D.LOCAL in D.LOCAL/, others in D./.  */
343         ftruncated = TRUE;
344         if (strncmp (zsimple + 2, zSlocalname, strlen (zSlocalname)) == 0)
345           {
346             c = strlen (zSlocalname);
347             ftruncated = FALSE;
348           }
349         else if (strncmp (zsimple + 2, zSlocalname, 7) == 0)
350           c = 7;
351         else if (strncmp (zsimple + 2, zSlocalname, 6) == 0)
352           c = 6;
353         else
354           c = 0;
355         if (c > 0 && zsimple[c + 2] == 'X')
356           ++c;
357         if (c > 0)
358           {
359             zfree = zbufalc (c + 3);
360             memcpy (zfree, zsimple, c + 2);
361             zfree[c + 2] = '\0';
362             zdir = zfree;
363
364             /* If we truncated the name, and there is no directory for
365                the truncated name, then don't use it.  */
366             if (ftruncated)
367               {
368                 char *zlook;
369
370                 zlook = zsappend3 ("sys",
371                                    (fsultrix_has_spool (zsystem)
372                                     ? zsystem
373                                     : "DEFAULT"),
374                                    zdir);
375                 if (! fsysdep_directory (zlook))
376                   zdir = "D.";
377                 ubuffree (zlook);
378               }
379           }
380         else
381           {
382             zfree = NULL;
383             zdir = "D.";
384           }
385       
386         zret = zsappend4 ("sys",
387                           (fsultrix_has_spool (zsystem)
388                            ? zsystem
389                            : "DEFAULT"),
390                           zdir,
391                           zsimple);
392         ubuffree (zfree);
393         return zret;
394       }
395 #endif /* SPOOLDIR_ULTRIX */
396 #if SPOOLDIR_TAYLOR
397       if (zsimple[2] == 'X')
398         return zsappend3 (zsystem, "D.X", zsimple);
399       else
400         return zsappend3 (zsystem, "D.", zsimple);
401 #endif /* SPOOLDIR_TAYLOR */
402
403
404     case 'X':
405 #if SPOOLDIR_BSD42
406       return zbufcpy (zsimple);
407 #endif
408 #if SPOOLDIR_BSD43
409       return zsysdep_in_dir ("X.", zsimple);
410 #endif
411 #if SPOOLDIR_ULTRIX
412       return zsappend4 ("sys",
413                         (fsultrix_has_spool (zsystem)
414                          ? zsystem
415                          : "DEFAULT"),
416                         "X.",
417                         zsimple);
418 #endif
419 #if SPOOLDIR_TAYLOR
420       return zsappend3 (zsystem, "X.", zsimple);
421 #endif
422     }
423
424   /* This is just to avoid warnings; it will never be executed.  */
425   return NULL;
426 #endif /* ! SPOOLDIR_V2 && ! SPOOLDIR_HDB && ! SPOOLDIR_SVR4 */
427 }