home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / uucp / Uucp.framework / unix.subproj / spool.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-09  |  14.1 KB  |  428 lines

  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[] = "$Id: spool.c,v 1.11 1995/06/30 21:22:54 ian Rel $";
  30. #endif
  31.  
  32. #include "uudefs.h"
  33. #include "sysdep.h"
  34. #include "system.h"
  35.  
  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.  
  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. }
  428.