home *** CD-ROM | disk | FTP | other *** search
/ Unix System Administration Handbook 1997 October / usah_oct97.iso / news / nn.tar / nn-6.5.1 / unshar.c < prev    next >
C/C++ Source or Header  |  1995-04-29  |  6KB  |  192 lines

  1. /****************************************************************
  2.  * unshar.c: Unpackage one or more shell archive files
  3.  *
  4.  * Description:    unshar is a filter which removes the front part
  5.  *        of a file and passes the rest to the 'sh' command.
  6.  *        It understands phrases like "cut here", and also
  7.  *        knows about shell comment characters and the Unix
  8.  *        commands "echo", "cat", and "sed".
  9.  *
  10.  * HISTORY
  11.  *  27-July-88  Kim F. Storm (storm@texas.dk) Texas Instruments, Denmark
  12.  *    Adapted to :unshar command in nn
  13.  *    Added static to function declarations
  14.  *    Removed all unused functions, i.e. not useful as stand-alone pgm.
  15.  * 29-Jan-85  Michael Mauldin (mlm) at Carnegie-Mellon University
  16.  *    Created.
  17.  ****************************************************************/
  18.  
  19. #include "config.h"
  20.  
  21. /* unshar.c */
  22.  
  23. static int stlmatch __APROTO((char *big, char *small));
  24. static int smatch __APROTO((register char *dat, register char *pat, register char **res));
  25.  
  26. extern long ftell ();
  27.  
  28.  
  29. /*****************************************************************
  30.  * stlmatch  --  match leftmost part of string
  31.  *
  32.  * Usage:  i = stlmatch (big,small)
  33.  *    int i;
  34.  *    char *small, *big;
  35.  *
  36.  * Returns 1 iff initial characters of big match small exactly;
  37.  * else 0.
  38.  *
  39.  * HISTORY
  40.  * 18-May-82 Michael Mauldin (mlm) at Carnegie-Mellon University
  41.  *      Ripped out of CMU lib for Rog-O-Matic portability
  42.  * 20-Nov-79  Steven Shafer (sas) at Carnegie-Mellon University
  43.  *    Rewritten for VAX from Ken Greer's routine.
  44.  *
  45.  *  Originally from klg (Ken Greer) on IUS/SUS UNIX
  46.  *****************************************************************/
  47.  
  48. static int   stlmatch (big, small)
  49. char *small, *big;
  50. { register char *s, *b;
  51.   s = small;
  52.   b = big;
  53.   do
  54.   { if (*s == '\0')
  55.       return (1);
  56.   }
  57.   while (*s++ == *b++);
  58.   return (0);
  59. }
  60.  
  61. /*****************************************************************
  62.  * smatch: Given a data string and a pattern containing one or
  63.  * more embedded stars (*) (which match any number of characters)
  64.  * return true if the match succeeds, and set res[i] to the
  65.  * characters matched by the 'i'th *.
  66.  *****************************************************************/
  67.  
  68. static int
  69. smatch (dat, pat, res)
  70. register char *dat, *pat, **res;
  71. {
  72.   register char *star = 0, *starend = 0, *resp = 0;
  73.   int nres = 0;
  74.  
  75.   while (1)
  76.   { if (*pat == '*')
  77.     { star = ++pat;                  /* Pattern after * */
  78.       starend = dat;                  /* Data after * match */
  79.       resp = res[nres++];              /* Result string */
  80.       *resp = '\0';                  /* Initially null */
  81.     }
  82.     else if (*dat == *pat)              /* Characters match */
  83.     { if (*pat == '\0')              /* Pattern matches */
  84.     return (1);
  85.       pat++;                      /* Try next position */
  86.       dat++;
  87.     }
  88.     else
  89.     { if (*dat == '\0')              /* Pattern fails - no more */
  90.     return (0);                  /* data */
  91.       if (star == 0)                  /* Pattern fails - no * to */
  92.     return (0);                  /* adjust */
  93.       pat = star;                  /* Restart pattern after * */
  94.       *resp++ = *starend;              /* Copy character to result */
  95.       *resp = '\0';                  /* null terminate */
  96.       dat = ++starend;                  /* Rescan after copied char */
  97.     }
  98.   }
  99. }
  100.  
  101. /****************************************************************
  102.  * position: position 'fil' at the start of the shell command
  103.  * portion of a shell archive file.
  104.  * Kim Storm: removed static variables
  105.  ****************************************************************/
  106.  
  107. int
  108. unshar_position (fil)
  109. FILE *fil;
  110. {
  111.     char buf[BUFSIZ];
  112.     long pos;
  113.  
  114.     /* Results from star matcher */
  115.     char res1[BUFSIZ], res2[BUFSIZ], res3[BUFSIZ], res4[BUFSIZ];
  116.     char *result[4];
  117.  
  118.     result[0] = res1, result[1] = res2, result[2] = res3, result[3] = res4 ;
  119.  
  120.     /*  rewind (fil);  */
  121.  
  122.     while (1) {
  123.     /* Record position of the start of this line */
  124.     pos = ftell (fil);
  125.  
  126.     /* Read next line, fail if no more */
  127.     if (fgets (buf, BUFSIZ, fil) == NULL) {
  128.         msg("no shell commands in file");
  129.         return (0);
  130.     }
  131.  
  132.     /* Bail out if we see C preprocessor commands or C comments */
  133.     if (stlmatch (buf, "#include")    || stlmatch (buf, "# include") ||
  134.         stlmatch (buf, "#define")    || stlmatch (buf, "# define") ||
  135.         stlmatch (buf, "#ifdef")    || stlmatch (buf, "# ifdef") ||
  136.         stlmatch (buf, "#ifndef")    || stlmatch (buf, "# ifndef") ||
  137.         stlmatch (buf, "/*"))
  138.         {
  139.         msg("file looks like raw C code, not a shar file");
  140.         return (0);
  141.         }
  142.  
  143.     /* Does this line start with a shell command or comment */
  144.     if (stlmatch (buf, "#")    ||
  145.         stlmatch (buf, ":") ||
  146.         stlmatch (buf, "echo ") ||
  147.         stlmatch (buf, "sed ") ||
  148.         stlmatch (buf, "cat "))
  149.     {
  150.         fseek (fil, pos, 0);
  151.         return (1);
  152.     }
  153.  
  154.     /* Does this line say "Cut here" */
  155.     if (smatch (buf, "*CUT*HERE*", result) ||
  156.         smatch (buf, "*cut*here*", result) ||
  157.         smatch (buf, "*TEAR*HERE*", result) ||
  158.         smatch (buf, "*tear*here*", result) ||
  159.         smatch (buf, "*CUT*CUT*", result) ||
  160.         smatch (buf, "*cut*cut*", result))
  161.     {
  162.         /* Read next line after "cut here", skipping blank lines */
  163.         while (1) {
  164.         pos = ftell (fil);
  165.  
  166.         if (fgets (buf, BUFSIZ, fil) == NULL) {
  167.             msg("no shell commands after 'cut'");
  168.             return (0);
  169.         }
  170.  
  171.         if (*buf != '\n') break;
  172.         }
  173.  
  174.         /*
  175.          * Win if line starts with a comment character of
  176.          * lower case letter
  177.          */
  178.         if (*buf == '#' ||
  179.         *buf == ':' ||
  180.         (('a' <= *buf) && ('z' >= *buf))) {
  181.         fseek (fil, pos, 0);
  182.         return (1);
  183.         }
  184.  
  185.         /* Cut here message lied to us */
  186.         msg("invalid data after CUT line");
  187.         return (0);
  188.     }
  189.     }
  190. }
  191.  
  192.