home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************
- * unshar.c: Unpackage one or more shell archive files
- *
- * Description: unshar is a filter which removes the front part
- * of a file and passes the rest to the 'sh' command.
- * It understands phrases like "cut here", and also
- * knows about shell comment characters and the Unix
- * commands "echo", "cat", and "sed".
- *
- * HISTORY
- * 27-July-88 Kim F. Storm (storm@texas.dk) Texas Instruments, Denmark
- * Adapted to :unshar command in nn
- * Added static to function declarations
- * Removed all unused functions, i.e. not useful as stand-alone pgm.
- * 29-Jan-85 Michael Mauldin (mlm) at Carnegie-Mellon University
- * Created.
- ****************************************************************/
-
- #include "config.h"
-
-
- /*****************************************************************
- * stlmatch -- match leftmost part of string
- *
- * Usage: i = stlmatch (big,small)
- * int i;
- * char *small, *big;
- *
- * Returns 1 iff initial characters of big match small exactly;
- * else 0.
- *
- * HISTORY
- * 18-May-82 Michael Mauldin (mlm) at Carnegie-Mellon University
- * Ripped out of CMU lib for Rog-O-Matic portability
- * 20-Nov-79 Steven Shafer (sas) at Carnegie-Mellon University
- * Rewritten for VAX from Ken Greer's routine.
- *
- * Originally from klg (Ken Greer) on IUS/SUS UNIX
- *****************************************************************/
-
- static int stlmatch (big, small)
- char *small, *big;
- { register char *s, *b;
- s = small;
- b = big;
- do
- { if (*s == '\0')
- return (1);
- }
- while (*s++ == *b++);
- return (0);
- }
-
- /*****************************************************************
- * smatch: Given a data string and a pattern containing one or
- * more embedded stars (*) (which match any number of characters)
- * return true if the match succeeds, and set res[i] to the
- * characters matched by the 'i'th *.
- *****************************************************************/
-
- static smatch (dat, pat, res)
- register char *dat, *pat, **res;
- { register char *star = 0, *starend, *resp;
- int nres = 0;
-
- while (1)
- { if (*pat == '*')
- { star = ++pat; /* Pattern after * */
- starend = dat; /* Data after * match */
- resp = res[nres++]; /* Result string */
- *resp = '\0'; /* Initially null */
- }
- else if (*dat == *pat) /* Characters match */
- { if (*pat == '\0') /* Pattern matches */
- return (1);
- pat++; /* Try next position */
- dat++;
- }
- else
- { if (*dat == '\0') /* Pattern fails - no more */
- return (0); /* data */
- if (star == 0) /* Pattern fails - no * to */
- return (0); /* adjust */
- pat = star; /* Restart pattern after * */
- *resp++ = *starend; /* Copy character to result */
- *resp = '\0'; /* null terminate */
- dat = ++starend; /* Rescan after copied char */
- }
- }
- }
-
- /****************************************************************
- * position: position 'fil' at the start of the shell command
- * portion of a shell archive file.
- * Kim Storm: removed static variables
- ****************************************************************/
-
- unshar_position (fil)
- FILE *fil;
- {
- char buf[BUFSIZ];
- long pos, ftell ();
-
- /* Results from star matcher */
- char res1[BUFSIZ], res2[BUFSIZ], res3[BUFSIZ], res4[BUFSIZ];
- char *result[4];
-
- result[0] = res1, result[1] = res2, result[2] = res3, result[3] = res4 ;
-
- /* rewind (fil); */
-
- while (1) {
- /* Record position of the start of this line */
- pos = ftell (fil);
-
- /* Read next line, fail if no more */
- if (fgets (buf, BUFSIZ, fil) == NULL) {
- msg("no shell commands in file");
- return (0);
- }
-
- /* Bail out if we see C preprocessor commands or C comments */
- if (stlmatch (buf, "#include") || stlmatch (buf, "# include") ||
- stlmatch (buf, "#define") || stlmatch (buf, "# define") ||
- stlmatch (buf, "#ifdef") || stlmatch (buf, "# ifdef") ||
- stlmatch (buf, "#ifndef") || stlmatch (buf, "# ifndef") ||
- stlmatch (buf, "/*"))
- {
- msg("file looks like raw C code, not a shar file");
- return (0);
- }
-
- /* Does this line start with a shell command or comment */
- if (stlmatch (buf, "#") ||
- stlmatch (buf, ":") ||
- stlmatch (buf, "echo ") ||
- stlmatch (buf, "sed ") ||
- stlmatch (buf, "cat "))
- {
- fseek (fil, pos, 0);
- return (1);
- }
-
- /* Does this line say "Cut here" */
- if (smatch (buf, "*CUT*HERE*", result) ||
- smatch (buf, "*cut*here*", result) ||
- smatch (buf, "*TEAR*HERE*", result) ||
- smatch (buf, "*tear*here*", result) ||
- smatch (buf, "*CUT*CUT*", result) ||
- smatch (buf, "*cut*cut*", result))
- {
- /* Read next line after "cut here", skipping blank lines */
- while (1) {
- pos = ftell (fil);
-
- if (fgets (buf, BUFSIZ, fil) == NULL) {
- msg("no shell commands after 'cut'");
- return (0);
- }
-
- if (*buf != '\n') break;
- }
-
- /*
- * Win if line starts with a comment character of
- * lower case letter
- */
- if (*buf == '#' ||
- *buf == ':' ||
- (('a' <= *buf) && ('z' >= *buf))) {
- fseek (fil, pos, 0);
- return (1);
- }
-
- /* Cut here message lied to us */
- msg("invalid data after CUT line");
- return (0);
- }
- }
- }
-
-