home *** CD-ROM | disk | FTP | other *** search
- From: wht@n4hgf.uucp (Warren Tucker)
- Newsgroups: alt.sources
- Subject: shar 3.21
- Message-ID: <674@n4hgf.uucp>
- Date: 19 Apr 90 20:51:37 GMT
- X-Checksum-Snefru: cb786230 9313e18f 020da0e0 47abd985
-
- Submitted-by: wht%n4hgf@gatech.edu
- Archive-name: shar321/part01
-
- Here is shar 3.21, an updated version of shar 3.11, derived from 'shar2'.
- This offering is the work of many people. Lately, rhg@CPS.COM (Richard H.
- Gumpertz) made significant changes to 3.11. colas@avahi.inria.fr (Colas
- Nahaboo) and I made enhancements to unshar. The details appear in
- the README file.
-
- ---- Cut Here and unpack ----
- #!/bin/sh
- # This is shar321, a shell archive (shar 3.21)
- # made 04/19/1990 20:17 UTC by wht%n4hgf@gatech.edu
- # Source directory /u1/src/shar
- #
- # existing files WILL be overwritten
- #
- # This shar contains:
- # length mode name
- # ------ ---------- ------------------------------------------
- # 5941 -rw-r--r-- README
- # 333 -rw-r--r-- Makefile
- # 28774 -rw-r--r-- shar.c
- # 10737 -rw-r--r-- unshar.c
- # 1169 -rw-r--r-- uushar.c
- # 2784 -rw-r--r-- who@where.c
- #
- if touch 2>&1 | fgrep '[-amc]' > /dev/null
- then TOUCH=touch
- else TOUCH=true
- fi
- # ============= README ==============
- echo "x - extracting README (Text)"
- sed 's/^X//' << 'SHAR_EOF' > README &&
- XSubmitted-by: wht%n4hgf@gatech.edu
- XArchive-name: shar321/part01
- X
- XHere is shar 3.21, an updated version of shar 3.11, derived from 'shar2'.
- XThis offering is the work of many people. Lately, rhg@CPS.COM (Richard H.
- XGumpertz) made significant changes to 3.11. colas@avahi.inria.fr (Colas
- XNahaboo) and I made enhancements to unshar. The change history appears
- Xat the bottom of this file.
- X
- XThis version's shar:
- X1) generates shell code which attempts to create missing directories
- X2) handle deviants sun, vax, pyramid, sequent, and SCO XENIX/UNIX
- X automatically; for system V systems I did not catch, add -DSYS5
- X to CFLAGS; for other BSD-like systems, add -DBSD42
- X3) if unsharing system's touch is Sys V compatible (allows touch -m),
- X the unshar process restores file dates
- X4) An archive name may be specified for includion in the header
- X of the shar files( -n switch)
- X5) allows automatic generation of "Submitted-by: who@where" &
- X "Archive-name: <name>/part##" headers
- X6) uses getopt; no good system library should be without a copy
- X but it is readily available (like look in unshar.c)
- X7) other chrome-plated junque
- X
- XThis version's unshar:
- X1) can change directory before unsharing
- X2) can unshar from standard in, from a collection of shars,
- X from a file containing multiple concatenated shars,
- X or a mixture of shar files and concatenated-shar files.
- X3) does not have an Social Security number.
- X
- X------------------------ shar usage -----------------------------------
- X
- Xshar 3.21
- Xusage: shar [ options ] file [ file1 ... ] ]
- X-v verbose messages OFF while executing
- X-w don't check with 'wc -c' after unpack
- X-n Name of archive (documentation)
- X-a Generate Submitted-by: & Archive-name: headers
- X-s override automatically determined submitter name
- X-x don't overwrite existing files
- X-X interactively overwrite existing files (NOT FOR NET SHARS)
- X-b treat all files as binary, use uuencode
- X-t treat all files as text (default)
- X-C compress and uuencode all files
- X-p allow positional parameter options. The options "-b" and "-t"
- X and "-C" may be embedded, and files to the right of the
- X option will be processed in the specified mode
- X-M mixed mode. Determine if the files are text or
- X binary and archive correctly.
- X-P use temp files instead of pipes in the shar file
- X-c start the shar with a cut line
- X-f restore by filename only, rather than path
- X-dXXX use XXX to delimit the files in the shar
- X-oXXX (or -o XXX) output to file XXX.01 thru XXX.nn
- X-lXX limit output file size to XXk bytes (but don't split files)
- X-LXX limit output file size to XXk bytes (may split files)
- X
- XThe 'o' option is required if the 'l' or 'L' option is used
- XThe 'n' option is required if the 'a' option is used
- XThe 'x' and 'L' options are incompatible
- X
- X-a generates sharname/part## headers. If you are producing patches
- Xyou'll need to edit -a headers (or please improve shar :-))
- XThe automatic submitter name is trivial: essentially `whoami`@`uname`
- X
- X------------------------ unshar usage -----------------------------------
- XUnshar has no usage built in. It has default actions when invoked
- Xwith no arguments (read from stdin).
- X
- XUsage: unshar [-c] [-C exit_line] [ -d directory ] [ file ] ...
- X
- X The -d flag tells unshar to change directory before unsharing
- X
- X It can unshar shar files concatenated in one file, with the
- X the "-c" command, which separates files by recognizing the
- X "exit 0" string at the beginning of a line
- X
- X (The -C string option allows you to specify this string, thus
- X -c is equivalent to -C "exit 0")
- X
- X
- X--------------------- history -----------------------------------------
- XChanges since 3.11: kudos to rhg@CPS.COM (Richard H. Gumpertz)
- X
- X1. The -l switch still specifies a maximum size for the generated
- X shar files, but now it prevents files from spanning shar parts.
- X Shars generated using this method may be unpacked in any order.
- X
- X2. The old -l switch functionality is precisely emulated by using the
- X the -L switch. That is, archived files may be split across parts.
- X Shars generated using this method must still be unpacked in order.
- X
- X3. The -C switch causes files to be compressed, then uuencoded.
- X Unpacking reverses the process.
- X
- X4. The -P causes the shar to use temp files instead of pipes in
- X the unshar process.
- X
- X5. The -f causes files to be resotred by name only (i.e., strip
- X directory portion of input filenames before placing the name
- X into the shar.
- X
- X
- XChanges since 3.20: kudos to colas@avahi.inria.fr (Colas Nahaboo)
- X
- X1. The Archived-name: header no longer uses "/part" if there is
- X a "/" in the -n name. Thus
- X -n xyzzy procduces:
- X xyzzy/part01
- X xyzzy/part02
- X
- X -n xyzzy/patch procduces:
- X xyzzy/patch01
- X xyzzy/patch02
- X
- X -n xyzzy/patch01. procduces:
- X xyzzy/patch01.01
- X xyzzy/patch01.02
- X2. The Archive-name part number other than part01 had no leading zero
- X in the number.
- X
- X3. The "Submitted-by:" header was missing the hyphen (minus for olde
- X UNIX hackres).
- X
- X4. The unshar program may now unshar a whole mailbox or concatenation
- X of shar files.
- X
- X -C "string" looks for "string" at the beginning of the line to
- X break the file into individual shar files
- X -c is equivalent to -C "exit 0"
- X
- X This of course will only work if there is something in the shar
- X file recognizable to terminate the shar. Some shars dont have
- X "exit 0" at the end. However, a clue: most/many .signatures have
- X "--" on a line right before them.
- X
- X5. Unshar -d (change directory) no longer makes argv files unreachable.
- X I had never used the feature until the other day. I guess the
- X author has used in only for unsharing from stdin.
- X
- SHAR_EOF
- $TOUCH -am 0419161790 README &&
- chmod 0644 README ||
- echo "restore of README failed"
- set `wc -c README`;Wc_c=$1
- if test "$Wc_c" != "5941"; then
- echo original size 5941, current size $Wc_c
- fi
- # ============= Makefile ==============
- echo "x - extracting Makefile (Text)"
- sed 's/^X//' << 'SHAR_EOF' > Makefile &&
- X# CHK=0xDDF8
- X#
- X# makefile for shar
- X#
- X#+:EDITS:
- X#:03-28-1990-14:54-wht@n4hgf-for 3.10, add who@where.c
- X
- XCFLAGS = -O
- X
- XSRC = shar.c uushar.c unshar.sh
- XOBJ = shar.o uushar.o who@where.o
- XDOC = shar.1 unshar.1 shar.readme
- X
- Xall: shar unshar
- X
- Xshar: $(OBJ)
- X cc $(CFLAGS) $(OBJ) -o shar
- X
- Xunshar : unshar.c
- X cc $(CFLAGS) unshar.c -o unshar;
- SHAR_EOF
- $TOUCH -am 0328165590 Makefile &&
- chmod 0644 Makefile ||
- echo "restore of Makefile failed"
- set `wc -c Makefile`;Wc_c=$1
- if test "$Wc_c" != "333"; then
- echo original size 333, current size $Wc_c
- fi
- # ============= shar.c ==============
- echo "x - extracting shar.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > shar.c &&
- X/* CHK=0x688E */
- Xchar *revision = "3.21";
- X/*
- X** shar.c
- X
- X Defined functions:
- X Rname(file)
- X exit_incompat()
- X gen_mkdir(path)
- X gen_mkdir_script(path)
- X setTOUCH()
- X header(argc,argv)
- X helpuser()
- X main(argc,argv)
- X mode_map(mode,mode_str)
- X shar(file)
- X
- X*/
- X/*+:EDITS:*/
- X/*:04-18-1990-02:01-wht@n4hgf-3.20 rhg@cps.com did all the NICE work */
- X/*:04-17-1990-14:30-rhg@cps.com-pretty up if-then-else-fi in shar file */
- X/*:04-17-1990-12:13-rhg@cps.com-add Split and renamed old -l to -L */
- X/*:04-17-1990-12:13-rhg@cps.com-add -c option to shar file execution */
- X/*:04-17-1990-11:20-rhg@cps.com-simplify TOUCH logic in shar file */
- X/*:04-17-1990-10:27-rhg@cps.com-create setTOUCH to avoid duplicate code */
- X/*:04-17-1990-04:43-rhg@cps.com-add missing && to commands in shar file(s) */
- X/*:04-17-1990-02:03-rhg@cps.com-add Compress */
- X/*:04-16-1990-17:08-rhg@cps.com-add AvoidPipes as well as code to use pipes */
- X/*:04-03-1990-20:09-wht@n4hgf-3.11 */
- X/*:04-01-1990-13:20-pat@rwing-correct case on M option in getopt() call */
- X/*:04-01-1990-13:50-pat@rwing-change defaults on -v, -w to be on */
- X/*:03-29-1990-18:23-wht@n4hgf-add automatic sequent support */
- X/*:03-28-1990-15:56-wht@n4hgf-add mode and length net.bandwidth chrome */
- X/*:03-28-1990-14:23-wht@n4hgf-correct some runtime diagnostics */
- X/*:11-14-1989-02:21-wht-SHAR_EOF was botched if last file char not newline */
- X/*:11-02-1989-14:11-wht-add touch -am */
- X
- X/*
- X Shar puts readable text files together in a package
- X from which they are easy to extract.
- X earlier attribution wht@n4hgf has: decvax!microsof!uw-beave!jim
- X (James Gosling at CMU)
- X*/
- X/*
- X * I have made several mods to this program:
- X *
- X * 1) the -----Cut Here-----... now preceds the script.
- X * 2) the cat has been changed to a sed which removes a prefix
- X * character from the beginning of each line of the extracted
- X * file, this prefix character is added to each line of the archived
- X * files and is not the same as the first character of the
- X * file delimeter.
- X * 3) added several options:
- X * -c - add the -----Cut Here-----... line.
- X * -d'del' - change the file delimeter to del.
- X * -s - cause the resulting script to print the wc of
- X * the orignal file and the wc of the extracted
- X * file.
- X *
- X * Michael A. Thompson
- X * Dalhousie University
- X * Halifax, N.S., Canada.
- X */
- X
- X/*
- X * I, too, have been hacking this code. This is the version on sixhub
- X * bill davidsen (davidsen@sixhub.uucp)
- X *
- X * - added support for binary files
- X * - automatic creation of limited size multiple file archives,
- X * each of which may be unpacked separately, and with sequence
- X * checking.
- X * - support for mixed text and binary files
- X * - preserve file permissions
- X * - restore to filename rather than pathname
- X *
- X */
- X/*
- X * One good hack deserves another ... this version generates shell
- X * code which attempts to create missing directories
- X * handle deviants sun, vax, pyr (pyramid), SCO XENIX/UNIX automatically
- X * for sequent, add -DBSD42
- X * force Verbose on
- X * if unsharing system's touch Sys V compatible (allows touch -m),
- X * restore file dates
- X * -n switch puts an alpha "name" in header
- X * -a (if also -n) puts "Submitted-by:" & "Archive-name: <name>/part##
- X * use getopt
- X * as well as some other chrome-plated junque
- X * ...!gatech!emory!tridom!wht (wht%n4hgf@gatech.edu) Warren Tucker
- X *
- X * 3.11 - Fri Apr 6 14:21:51 EDT 1990
- X * With due deference to davidsen@sixhub, more changes..... copies
- X * of this, like 3.10, were mailed to him:
- X * From wht Fri Apr 6 15:14:30 1990 remote from n4hgf
- X * Received: by n4hgf.UUCP (smail2.5-UNIX/386 5.3.2)
- X * id AA01781; 6 Apr 90 15:14:30 EDT (Fri)
- X * Date: Fri, 6 Apr 90 15:14:30 EDT
- X * X-Mailer: Mail User's Shell (6.5 4/17/89)
- X * From: wht@n4hgf (Warren Tucker)
- X * To: davidsen@sixhub
- X * Subject: shar 3.11
- X * X-Bang-Reply-to: gatech!n4hgf!wht -or- emory!tridom!n4hgf!wht
- X * Reply-to: wht%n4hgf@gatech.edu
- X * Message-Id: <9004061514.AA01781@n4hgf.UUCP>
- X *
- X * 1. changes suggested by pat@rwing (Pat Myrto) and silvert@cs.dal.ca
- X * (Bill Silvert)
- X * 2. fixes to who_am_i code in who@where.c
- X *
- X * 3.20 - Wed Apr 18 01:58:32 EDT 1990
- X * changes were made per edit notes by
- XFrom: gatech!mailrus!uunet!cpsolv.CPS.COM!rhg (Richard H. Gumpertz)
- X * ...!gatech!n4hgf!wht (wht%n4hgf@gatech.edu) Warren Tucker
- X *
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <time.h>
- X#include <sys/stat.h>
- X
- X/* assume system v unless otherwise fixed */
- X#if (defined(pyr) || defined(vax) || defined(sequent)) && !defined(BSD42)
- X#define BSD42
- X#endif
- X#if defined(sun) /* this miscreant doesn't exactly fit BSD or SYSV */
- X#undef BSD42
- X#undef SYS5
- X#endif
- X#if !defined(BSD42) && !defined(sun)
- X#define SYS5
- X#endif
- X
- X#if defined(sun) || defined(BSD42)
- X#define strchr index
- X#define strrchr rindex
- X#endif
- X
- Xchar *strchr();
- Xchar *strrchr();
- X#ifdef __STDC__ /* my concession to ANSI-pansiness */
- Xvoid *malloc();
- X#else
- Xchar *malloc();
- X#endif
- XFILE *fdopen();
- XFILE *popen();
- X
- X#define DELIM "SHAR_EOF"/* put after each file */
- X#define PREFIX1 'X' /* goes in front of each line */
- X#define PREFIX2 'Y' /* goes in front of each line if Delim
- X * starts with PREFIX1 */
- X#define PREFIX (Delim[0] == PREFIX1 ? PREFIX2 : PREFIX1)
- X#define WC "wc -c"
- X
- Xint Archive_name = 0; /* option to generate "Archive-name:" headers */
- Xint Verbose = 1; /* option to provide append/extract feedback */
- Xint Wc_c = 1; /* option to provide wc checking */
- Xchar *Delim = DELIM; /* pointer to delimiter string */
- Xint Cut = 0; /* option to provide cut mark */
- Xint Binary = 0; /* flag for binary files */
- Xint AvoidPipes = 0; /* use temp file instead of pipe to feed uudecode, etc.
- X (better error detection at expense of disk space) */
- Xint Compress = 0; /* run input files through compress (requires Binary) */
- Xint Mixed = 0; /* mixed text and binary files */
- Xint eXists = 0; /* check if file exists */
- Xint InterOW = 0; /* interactive overwrite */
- Xint PosParam = 0; /* allow positional parameters */
- Xint FileStrip; /* strip directories from filenames */
- X#ifdef DEBUG
- Xint de_bug = 0; /* switch for debugging on */
- X#define DeBug(f,v) if (de_bug) printf(f, v)
- X#else /* normal compile */
- X#define DeBug(f,v) /* do nothing */
- X#endif
- X
- XFILE *fpout = stdout;
- Xchar *Rname(); /* file restore name */
- Xunsigned limit = 0;
- Xint Split = 0; /* Split files in the middle */
- Xlong ftell();
- Xlong TypePos; /* position for archive type message */
- Xlong EndHeadPos; /* position for first file in the shar file */
- Xchar outname[50]; /* base for output filename */
- Xchar filename[50]; /* actual output filename */
- Xchar *sharname = (char *)0;
- Xchar *submitter = (char *)0;
- Xint filenum = 0; /* output file # */
- Xstruct stat fst; /* check file type, access */
- X
- Xmain(argc,argv)
- Xchar **argv;
- X{
- Xint status = 0;
- Xchar *oname;
- Xint c;
- Xextern int optind;
- Xextern char *optarg;
- X
- X while((c = getopt(argc,argv,"vwd:btCxXcfMpPas:n:l:L:o:h")) != -1)
- X {
- X switch(c)
- X {
- X case 'v':
- X Verbose = 0;
- X break;
- X case 'w':
- X Wc_c = 0;
- X break;
- X case 'd':
- X Delim = optarg;
- X break;
- X case 'b': /* binary files */
- X Binary = 1;
- X Compress = 0;
- X break;
- X case 't': /* text mode */
- X Binary = 0;
- X Compress = 0;
- X break;
- X case 'C': /* Compress */
- X Binary = 1;
- X Compress = 1;
- X break;
- X case 'x': /* does the file exist */
- X eXists = 1;
- X if(InterOW || Split)
- X exit_incompat();
- X break;
- X case 'X': /* does the file exist */
- X InterOW = 1;
- X if(eXists || Split)
- X exit_incompat();
- X eXists = 1;
- X break;
- X case 'c':
- X Cut = 1;
- X break;
- X case 'f': /* filenames only */
- X FileStrip = 1;
- X break;
- X case 'M': /* mixed text and binary */
- X Mixed = 1;
- X break;
- X case 'p': /* allow positional parameters */
- X PosParam = 1;
- X break;
- X case 'P': /* use temp files instead of pipes in the shar file */
- X AvoidPipes = 1;
- X break;
- X case 'l': /* soft size limit in k */
- X if((limit = atoi(optarg)) > 1)
- X --limit;
- X Split = 0;
- X DeBug("Soft limit %dk\n",limit);
- X break;
- X case 'L': /* hard size limit in k */
- X if(eXists)
- X exit_incompat();
- X if((limit = atoi(optarg)) > 1)
- X --limit;
- X Split = (limit != 0);
- X AvoidPipes = 1;
- X DeBug("Hard limit %dk\n",limit);
- X break;
- X case 'n': /* name of archive */
- X sharname = optarg;
- X break;
- X case 's': /* submitter */
- X submitter = optarg;
- X break;
- X case 'a': /* generate Archive-name: headers */
- X Archive_name = 1;
- X break;
- X case 'o': /* specify output file */
- X oname = optarg;
- X strcpy(outname,oname);
- X strcat(outname,".");
- X filenum = 1;
- X strcpy(filename,outname);
- X strcat(filename,"01");
- X fpout = fopen(filename,"w");
- X if(!fpout)
- X { /* creation error */
- X perror("can't create output file");
- X exit(1);
- X }
- X break;
- X#ifdef DEBUG
- X case '$': /* totally undocumented $ option, debug on */
- X de_bug = 1;
- X break;
- X#endif
- X default: /* invalid option */
- X case 'h': /* help */
- X helpuser();
- X break;
- X }
- X }
- X
- X if(optind >= argc)
- X {
- X fprintf(stderr,"shar: No input files\n");
- X helpuser();
- X exit(1);
- X }
- X
- X if(Archive_name && !sharname)
- X {
- X fprintf(stderr,"shar: -n must accompany -a\n");
- X helpuser();
- X exit(1);
- X }
- X
- X if(!submitter)
- X {
- X submitter = malloc(128);
- X who_where(submitter);
- X }
- X
- X if(header(argc-optind,&argv[optind]))
- X exit(2);
- X
- X if(InterOW)
- X {
- X Verbose = 1;
- X fprintf(fpout,"wish=\n");
- X if(Archive_name)
- X {
- X printf("PLEASE do not submit -X shars to the usenet or other\n");
- X printf("public networks. They will cause problems.\n");
- X }
- X }
- X
- X EndHeadPos = ftell(fpout);
- X
- X while(optind < argc)
- X { /* process positional parameters and files */
- X if(PosParam)
- X { /* allow -b and -t and -C inline */
- X if(strcmp(argv[optind],"-b") == 0)
- X { /* set binary */
- X Binary = 1;
- X Compress = 0;
- X optind++;
- X continue;
- X }
- X if(strcmp(argv[optind],"-t") == 0)
- X { /* set mode text */
- X Binary = 0;
- X Compress = 0;
- X optind++;
- X continue;
- X }
- X if(strcmp(argv[optind],"-C") == 0)
- X { /* set compress */
- X Binary = 1;
- X Compress = 1;
- X optind++;
- X continue;
- X }
- X }
- X status += shar(argv[optind++]);
- X }
- X
- X /* delete the sequence file, if any */
- X if(Split && filenum > 1)
- X {
- X fputs("rm -f @shar_seq_.tmp\n",fpout);
- X fputs("echo \"You have unpacked the last part\"\n",fpout);
- X if(!Verbose)
- X fprintf(stderr,"Created %d files\n",filenum);
- X }
- X fputs("exit 0\n",fpout);
- X exit(status);
- X}
- X
- X/*+-----------------------------------------------------------------------
- X mode_map(mode,mode_str) build drwxrwxrwx string
- X------------------------------------------------------------------------*/
- Xchar *
- Xmode_map(mode,mode_str)
- Xunsigned short mode;
- Xchar *mode_str;
- X{
- Xregister unsigned ftype = mode & S_IFMT;
- Xregister char *rtn;
- Xstatic char result[12];
- X
- X rtn = (mode_str == (char *)0) ? result : mode_str;
- X
- X /* drwxrwxrwx */
- X /* 0123456789 */
- X strcpy(rtn,"----------");
- X
- X#ifdef THIS_IS_NOT_NEEDED_FOR_SHAR
- X switch(ftype)
- X {
- X case S_IFIFO: *rtn = 'p'; break; /* FIFO (named pipe) */
- X case S_IFDIR: *rtn = 'd'; break; /* directory */
- X case S_IFCHR: *rtn = 'c'; break; /* character special */
- X case S_IFBLK: *rtn = 'b'; break; /* block special */
- X case S_IFREG: *rtn = '-'; break; /* regular */
- X
- X#if defined(sun) | defined(BSD42)
- X case S_IFLNK: *rtn = 'l'; break; /* symbolic link */
- X case S_IFSOCK: *rtn = 's'; break; /* socket */
- X#endif
- X
- X#if defined (SYS5)
- X case S_IFNAM: /* name space entry */
- X if(mode & S_INSEM) /* semaphore */
- X {
- X *rtn = 's';
- X break;
- X }
- X if(mode & S_INSHD) /* shared memory */
- X {
- X *rtn = 'm';
- X break;
- X }
- X#endif
- X
- X default: *rtn = '?'; break; /* ??? */
- X }
- X#endif /* THIS_IS_NOT_NEEDED_FOR_SHAR */
- X
- X if(mode & 000400) *(rtn + 1) = 'r';
- X if(mode & 000200) *(rtn + 2) = 'w';
- X if(mode & 000100) *(rtn + 3) = 'x';
- X if(mode & 004000) *(rtn + 3) = 's';
- X if(mode & 000040) *(rtn + 4) = 'r';
- X if(mode & 000020) *(rtn + 5) = 'w';
- X if(mode & 000010) *(rtn + 6) = 'x';
- X if(mode & 002000) *(rtn + 6) = 's';
- X if(mode & 000004) *(rtn + 7) = 'r';
- X if(mode & 000002) *(rtn + 8) = 'w';
- X if(mode & 000001) *(rtn + 9) = 'x';
- X if(mode & 001000) *(rtn + 9) = 't';
- X
- X return(rtn);
- X
- X} /* end of mode_map */
- X
- Xvoid
- XsetTOUCH()
- X{
- X fputs("if touch 2>&1 | fgrep '[-amc]' > /dev/null\n",fpout);
- X fputs(" then TOUCH=touch\n",fpout);
- X fputs(" else TOUCH=true\n",fpout);
- X fputs("fi\n",fpout);
- X} /* end of setTOUCH */
- X
- Xheader(argc,argv)
- Xchar **argv;
- X{
- Xint i;
- Xint status;
- XFILE *fpsource; /* pipe temp */
- Xchar s128[128];
- Xlong now;
- Xstruct tm *utc;
- Xstruct tm *gmtime();
- X
- X /* see if any conflicting options */
- X if(limit && !filenum)
- X { /* can't rename what you don't have */
- X fprintf(stderr,"Can't use -l or -L option without -o\n");
- X helpuser();
- X }
- X
- X for(i = 0; i < argc; i++)
- X { /* skip positional parameters */
- X if(PosParam &&
- X (strcmp(argv[i],"-b") == 0 ||
- X strcmp(argv[i],"-t") == 0 ||
- X strcmp(argv[i],"-C") == 0))
- X continue;
- X
- X /* see if access and correct type */
- X if(access(argv[i],4))
- X {
- X fprintf(stderr,"shar: Can't access %s\n",argv[i]);
- X return(1);
- X }
- X
- X /* get file type */
- X stat(argv[i],&fst);
- X status = fst.st_mode & S_IFMT;
- X
- X /* at this point I check to see that this is a regular file */
- X if(status != S_IFREG)
- X { /* this is not a regular file */
- X fprintf(stderr,"shar: %s is not a regular file\n",argv[i]);
- X return(1);
- X }
- X }
- X
- X if(Archive_name)
- X {
- X fprintf(fpout,"Submitted-by: %s\n",submitter);
- X fprintf(fpout,"Archive-name: %s%s%02d\n\n",
- X sharname,(strchr(sharname,'/')) ? "" : "/part",
- X (filenum) ? filenum : 1);
- X }
- X
- X if(Cut)
- X fputs("---- Cut Here and unpack ----\n",fpout);
- X fputs("#!/bin/sh\n",fpout);
- X if(sharname)
- X fprintf(fpout,"# This is %s, a shell archive (shar %s)\n",
- X sharname,revision);
- X else
- X fprintf(fpout,"# This is a shell archive (shar %s)\n",revision);
- X
- X time(&now);
- X utc = gmtime(&now);
- X fprintf(fpout,"# made %02d/%02d/%04d %02d:%02d UTC ",
- X utc->tm_mon + 1,utc->tm_mday,utc->tm_year + 1900,
- X utc->tm_hour,utc->tm_min);
- X
- X fputs("by ",fpout);
- X fputs(submitter,fpout);
- X fputs("\n",fpout);
- X
- X#if defined(SYS5)
- X if(!(fpsource = popen("/bin/pwd","r")))
- X return(-1);
- X fgets(s128,sizeof(s128),fpsource);
- X s128[strlen(s128) - 1] = 0;
- X fclose(fpsource);
- X#else
- X#if defined(BSD42) || defined(sun)
- X getwd(s128);
- X#else
- X#include "Need_conditional_compile_fix"
- X#endif
- X#endif
- X fprintf(fpout,"# Source directory %s\n",s128);
- X
- X fprintf(fpout,"#\n# existing files %s be overwritten\n",
- X (eXists) ? "will NOT"
- X : ((InterOW) ? "MAY" : "WILL"));
- X if(InterOW)
- X fprintf(fpout,"# The unsharer will be INTERACTIVELY queried.\n");
- X
- X if(Split)
- X { /* may be split, explain */
- X fputs("#\n",fpout);
- X TypePos = ftell(fpout);
- X fprintf(fpout,"%-75s\n%-75s\n","#","#");
- X }
- X
- X fputs("#\n# This shar contains:\n",fpout);
- X fputs("# length mode name\n",fpout);
- X fputs("# ------ ---------- ------------------------------------------\n",
- X fpout);
- X for(i = 0; i < argc; i++)
- X { /* output names of files but not parameters */
- X if(PosParam &&
- X (strcmp(argv[i],"-b") == 0 ||
- X strcmp(argv[i],"-t") == 0 ||
- X strcmp(argv[i],"-C") == 0))
- X continue;
- X stat(argv[i],&fst);
- X fst.st_mode &= ~(07000); /* turn off setuid, setgid and sticky bits */
- X fprintf(fpout,"# %6ld %s %s\n",fst.st_size,
- X mode_map(fst.st_mode,(char *)0),Rname(argv[i]));
- X }
- X fputs("#\n",fpout);
- X
- X setTOUCH();
- X
- X if(Split)
- X { /* now check the sequence */
- X fputs("if test -r @shar_seq_.tmp; then\n",fpout);
- X fputs("\techo \"Must unpack archives in sequence!\"\n",fpout);
- X fputs("\tnext=`cat @shar_seq_.tmp`; ",fpout);
- X fputs("echo \"Please unpack part $next next\"\n\texit 1\nfi\n",fpout);
- X }
- X return(0);
- X}
- X
- X#define MAX_MKDIR_ALREADY 128 /* ridiculously enough */
- Xchar *mkdir_already[MAX_MKDIR_ALREADY];
- Xint mkdir_already_count = 0;
- X
- Xvoid
- Xgen_mkdir(path)
- Xchar *path;
- X{
- Xregister int ialready;
- Xchar *cptr;
- X
- X/* if already generated code for this dir creation, dont do again */
- X for(ialready = 0; ialready < mkdir_already_count; ialready++)
- X {
- X if(!strcmp(path,mkdir_already[ialready]))
- X return;
- X }
- X
- X/* haven't done this one */
- X if(mkdir_already_count == MAX_MKDIR_ALREADY)
- X {
- X fprintf(stderr,"too many directories for mkdir generation\n");
- X exit(255);
- X }
- X if(!(cptr = mkdir_already[mkdir_already_count++] = malloc(strlen(path)+1)))
- X {
- X fprintf(stderr,"out of memory for mkdir generation\n");
- X exit(255);
- X }
- X strcpy(cptr,path);
- X
- X/* generate the text */
- X fprintf(fpout,"if test ! -d '%s'; then\n",path);
- X if(Verbose)
- X fprintf(fpout," echo \"x - creating directory %s\"\n",path);
- X fprintf(fpout," mkdir '%s'\n",path);
- X fprintf(fpout,"fi\n");
- X
- X} /* end of gen_mkdir */
- X
- Xvoid
- Xgen_mkdir_script(path)
- Xregister char *path;
- X{
- Xregister char *cptr;
- X
- X for(cptr = strchr(path,'/'); cptr; cptr = strchr(cptr + 1,'/'))
- X {
- X /* avoid empty string if leading or double '/' */
- X if(cptr == path || *(cptr - 1) == '/')
- X continue;
- X /* omit '.' */
- X if((*(cptr - 1) == '.') && ((cptr == path + 1) || (*(cptr - 2) == '/')))
- X continue;
- X *cptr = 0; /* temporarily terminate string */
- X gen_mkdir(path);
- X *cptr = '/';
- X }
- X} /* end of gen_mkdir_script */
- X
- Xshar(file)
- Xchar *file;
- X{
- Xchar line[BUFSIZ];
- XFILE *fpsource;
- Xlong cursize,remaining,ftell();
- Xint split = 0; /* file split flag */
- Xchar *filetype; /* text or binary */
- Xchar *RstrName; /* name for restore */
- Xstruct tm *lt;
- Xchar *filename_base;
- X
- X /* get file size, dates, and mode for later */
- X stat(file,&fst);
- X
- X /* if limit set, get the current output length */
- X if(limit)
- X {
- X cursize = ftell(fpout);
- X remaining = (limit * 1024L) - cursize;
- X DeBug("In shar: remaining size %ld\n",remaining);
- X
- X if(!Split && cursize > EndHeadPos &&
- X (Binary ? fst.st_size + fst.st_size/3 : fst.st_size) > remaining)
- X { /* change to another file */
- X DeBug("Newfile, remaining %ld, ",remaining);
- X DeBug("limit still %d\n",limit);
- X
- X fprintf(fpout,
- X "echo \"End of part %d, continue with part %d\"\n",
- X filenum,filenum + 1);
- X fprintf(fpout,"exit 0\n");
- X
- X fclose(fpout);
- X
- X /* form the next filename */
- X sprintf(filename,"%s%02d",outname,++filenum);
- X fpout = fopen(filename,"w");
- X
- X if(Archive_name)
- X {
- X fprintf(fpout,"Submitted-by: %s\n",submitter);
- X fprintf(fpout,"Archive-name: %s%s%02d\n\n",
- X sharname,(strchr(sharname,'/')) ? "." : "/part",
- X (filenum) ? filenum : 1);
- X }
- X
- X if(Cut)
- X fputs("---- Cut Here and unpack ----\n",fpout);
- X if(!(filename_base = strrchr(filename,'/')))
- X filename_base = filename;
- X else
- X filename_base++;
- X
- X fprintf(fpout,"#!/bin/sh\n");
- X fprintf(fpout,"# This is part %02d of %s\n",
- X filenum,(sharname) ? sharname : "a multipart archive");
- X
- X setTOUCH();
- X
- X EndHeadPos = ftell(fpout);
- X }
- X }
- X
- X /* determine the name to use for restore */
- X RstrName = Rname(file);
- X
- X fputs("# ============= ",fpout);
- X fputs(RstrName,fpout);
- X fputs(" ==============\n",fpout);
- X
- X gen_mkdir_script(RstrName);
- X
- X /* if mixed, determine the file type */
- X if(Mixed)
- X {
- X int count;
- X sprintf(line,"file %s | egrep -c \"text|shell\"",file);
- X fpsource = popen(line,"r");
- X fscanf(fpsource,"%d",&count);
- X pclose(fpsource);
- X Binary = (count != 1);
- X }
- X
- X if(Binary)
- X { /* fork a uuencode process */
- X static int pid,pipex[2];
- X
- X pipe(pipex);
- X fflush(fpout);
- X
- X if(pid = fork())
- X { /* parent, create a file to read */
- X close(pipex[1]);
- X fpsource = fdopen(pipex[0],"r");
- X filetype = (Compress ? "Compressed" : "Binary");
- X }
- X else
- X { /* start writing the pipe with encodes */
- X FILE *outptr;
- X
- X if(Compress)
- X {
- X sprintf(line, "compress < %s", file);
- X fpsource = popen(line, "r");
- X }
- X else
- X fpsource = fopen(file, "rb");
- X outptr = fdopen(pipex[1],"w");
- X fprintf(outptr,"begin 600 %s\n",
- X (Compress ? "@shar_cmp_.tmp" : RstrName));
- X encode(fpsource,outptr);
- X fprintf(outptr,"end\n");
- X if(Compress)
- X pclose(fpsource);
- X else
- X fclose(fpsource);
- X exit(0);
- X }
- X }
- X else
- X {
- X fpsource = fopen(file,"r");
- X filetype = "Text";
- X }
- X
- X if(fpsource)
- X {
- X /* protect existing files */
- X if(eXists)
- X {
- X fprintf(fpout,"if test X\"$1\" != X\"-c\" -a -f '%s'; then\n",
- X RstrName);
- X if(InterOW)
- X {
- X fprintf(fpout,"\tcase $wish in\n");
- X fprintf(fpout,"\tA*|a*) echo x - overwriting '%s';;\n",
- X RstrName);
- X fprintf(fpout,
- X "\t*) echo \"? - overwrite '%s' -- [No], [Y]es, [A]ll, [Q]uit? \"\n",
- X RstrName);
- X fprintf(fpout,"\t\tread wish;;\n");
- X fprintf(fpout,"\tesac\n");
- X fprintf(fpout,"\tcase $wish in\n");
- X fprintf(fpout,"\tQ*|q*) echo aborted; exit 86;;\n");
- X fprintf(fpout,"\tA*|a*|Y*|y*) x=Y;;\n");
- X fprintf(fpout,"\t*) x=N;;\n");
- X fprintf(fpout,"\tesac\n");
- X fprintf(fpout,"else\n");
- X fprintf(fpout,"\tx=Y\n");
- X fprintf(fpout,"fi\n");
- X fprintf(fpout,"if test $x != Y; then\n");
- X fprintf(fpout,"\techo x - skipping '%s'\n",RstrName);
- X }
- X else
- X fprintf(fpout,"\techo \"File already exists: skipping '%s'\"\n",
- X RstrName);
- X fprintf(fpout,"else\n");
- X }
- X
- X fprintf(stderr,"shar: saving %s (%s)\n",file,filetype);
- X if(Verbose)
- X { /* info on archive and unpack */
- X fprintf(fpout,"echo \"x - extracting %s (%s)\"\n",
- X RstrName,filetype);
- X }
- X if(Binary)
- X { /* run sed through uudecode (via temp file if might get split) */
- X fprintf(fpout, "sed 's/^%c//' << '%s' %s &&\n",
- X PREFIX,Delim,
- X (AvoidPipes ? "> @shar_tmp_.tmp" : "| uudecode"));
- X }
- X else
- X { /* just run it into the file */
- X fprintf(fpout,"sed 's/^%c//' << '%s' > %s &&\n",
- X PREFIX,Delim,RstrName);
- X }
- X while(fgets(line,BUFSIZ,fpsource))
- X { /* output a line and test the length */
- X fprintf(fpout,"%c%s",PREFIX,line);
- X if(Split && (remaining -= strlen(line) + 2) < 0)
- X { /* change to another file */
- X DeBug("Newfile, remaining %ld, ",remaining);
- X DeBug("limit still %d\n",limit);
- X
- X if(line[strlen(line) - 1] != '\n')
- X fputc('\n',fpout);
- X
- X fprintf(fpout,"%s\n",Delim);
- X if(Verbose)
- X { /* output some reassurance */
- X fprintf(fpout,
- X "echo \"End of %s part %d\"\n",
- X (sharname) ? sharname : "",filenum);
- X fprintf(fpout,
- X "echo \"File %s is continued in part %d\"\n",
- X RstrName,filenum + 1);
- X }
- X else
- X fprintf(fpout,
- X "echo \"End of part %d, continue with part %d\"\n",
- X filenum,filenum + 1);
- X fprintf(fpout,"echo \"%d\" > @shar_seq_.tmp\n",filenum + 1);
- X fprintf(fpout,"exit 0\n");
- X
- X if(filenum == 1)
- X { /* rewrite the info lines on the firstheader */
- X fseek(fpout,TypePos,0);
- X fprintf(fpout,"%-75s\n%-75s\n",
- X "# This is part 1 of a multipart archive",
- X "# do not concatenate these parts, unpack them in order with /bin/sh");
- X }
- X fclose(fpout);
- X
- X /* form the next filename */
- X sprintf(filename,"%s%02d",outname,++filenum);
- X fpout = fopen(filename,"w");
- X
- X if(Archive_name)
- X {
- X fprintf(fpout,"Submitted-by: %s\n",submitter);
- X fprintf(fpout,"Archive-name: %s%s%02d\n\n",
- X sharname,(strchr(sharname,'/')) ? "." : "/part",
- X (filenum) ? filenum : 1);
- X }
- X
- X if(Cut)
- X fputs("---- Cut Here and unpack ----\n",fpout);
- X if(!(filename_base = strrchr(filename,'/')))
- X filename_base = filename;
- X else
- X filename_base++;
- X
- X fprintf(fpout,"#!/bin/sh\n");
- X fprintf(fpout,
- X "# this is %s (part %d of %s)\n",
- X filename_base,
- X filenum,
- X (sharname) ? sharname : "a multipart archive");
- X fputs("# do not concatenate these parts, ",fpout);
- X fputs("unpack them in order with /bin/sh\n",fpout);
- X fprintf(fpout,"# file %s continued\n#\n",RstrName);
- X
- X setTOUCH();
- X
- X fputs("if test ! -r @shar_seq_.tmp; then\n",fpout);
- X fputs("\techo \"Please unpack part 1 first!\"\n",fpout);
- X fputs("\texit 1\nfi\n",fpout);
- X fputs("(read Scheck\n",fpout);
- X fprintf(fpout,
- X " if test \"$Scheck\" != %d; then\n",filenum);
- X fputs("\techo \"Please unpack part $Scheck next!\"\n",
- X fpout);
- X fputs("\texit 1\n",fpout);
- X fputs(" else\n\texit 0\n fi\n",fpout);
- X fputs(") < @shar_seq_.tmp || exit 1\n",fpout);
- X
- X if(Verbose)
- X { /* keep everybody informed */
- X fprintf(stderr,"Starting file %s\n",filename);
- X fprintf(fpout,
- X "echo \"x - Continuing file %s\"\n",RstrName);
- X }
- X fprintf(fpout,
- X "sed 's/^%c//' << '%s' >> %s &&\n",
- X PREFIX,Delim,
- X (Binary ? "@shar_tmp_.tmp" : RstrName));
- X remaining = limit * 1024L;
- X split = 1;
- X }
- X }
- X
- X (void) fclose(fpsource);
- X
- X if(line[strlen(line) - 1] != '\n')
- X fputc('\n',fpout);
- X
- X fprintf(fpout,"%s\n",Delim);
- X if(split && Verbose)
- X fprintf(fpout,
- X "echo \"File %s is complete\" &&\n",RstrName);
- X
- X /* if this file was uuencoded w/Split, decode it and drop the temp */
- X if(Binary && AvoidPipes)
- X {
- X if(Verbose)
- X fprintf(fpout,"echo \"uudecoding file %s\" &&\n",RstrName);
- X fprintf(fpout,
- X "uudecode < @shar_tmp_.tmp && rm -f @shar_tmp_.tmp &&\n");
- X }
- X
- X /* if this file was compressed, uncompress it and drop the temp */
- X if(Compress)
- X {
- X if(Verbose)
- X fprintf(fpout,"echo \"uncompressing file %s\" &&\n",RstrName);
- X fprintf(fpout,
- X "compress -d < @shar_cmp_.tmp > %s && rm -f @shar_cmp_.tmp &&\n",
- X RstrName);
- X }
- X
- X /* set the dates as they were */
- X lt = localtime(&fst.st_mtime);
- X fprintf(fpout,"$TOUCH -am %02d%02d%02d%02d%02d %s &&\n",
- X lt->tm_mon + 1,lt->tm_mday,lt->tm_hour,lt->tm_min,lt->tm_year,
- X RstrName);
- X
- X /* set the permissions as they were */
- X fprintf(fpout,"chmod %04o %s ||\n",
- X fst.st_mode & 00777,RstrName);
- X
- X /* report an error if any of the above failed */
- X fprintf(fpout,"echo \"restore of %s failed\"\n",RstrName);
- X
- X if(Wc_c)
- X { /* validate the transferred file */
- X FILE *pfp;
- X char command[BUFSIZ];
- X
- X sprintf(command,"%s %s",WC,file);
- X if((pfp = popen(command,"r")))
- X {
- X char wc[BUFSIZ];
- X
- X fscanf(pfp,"%s",wc);
- X fprintf(fpout,"set `%s %s`;Wc_c=$1\n",
- X WC,RstrName);
- X fprintf(fpout,
- X "if test \"$Wc_c\" != \"%s\"; then\n",wc);
- X fprintf(fpout,
- X "\techo original size %s, current size $Wc_c\nfi\n",
- X wc);
- X pclose(pfp);
- X }
- X }
- X
- X /* if the exists option is in place close the if */
- X if(eXists)
- X fprintf(fpout,"fi\n");
- X
- X return(0);
- X }
- X else
- X {
- X fprintf(stderr,"shar: Can't open %s (%s): ",file,filetype);
- X perror("");
- X return(1);
- X }
- X}
- X
- Xchar *
- XRname(file)
- Xregister char *file;
- X{
- X register char *RstrName;
- X
- X if(FileStrip)
- X { /* use just the filename */
- X RstrName = file+strlen(file);
- X while(RstrName > file && *RstrName != '/')
- X RstrName--;
- X if(*RstrName == '/') RstrName++;
- X }
- X else
- X RstrName = file;
- X if(!strncmp(RstrName,"./",2))
- X RstrName += 2;
- X return(RstrName);
- X}
- X
- X/*****************************************************************
- X | exit_incompat - incompatible options
- X ****************************************************************/
- X
- Xexit_incompat()
- X{
- X fputs("You may only specify one of -L, -X or -x\n",stderr);
- X exit(1);
- X}
- X
- Xhelpuser()
- X{ /* output a command format message */
- X register char **ptr;
- X static char *helpinfo[] =
- X {
- X "-v verbose messages OFF while executing",
- X "-w don't check with 'wc -c' after unpack",
- X "-n Name of archive (documentation)",
- X "-a Generate Submitted-by: & Archive-name: headers",
- X "-s override automatically determined submitter name",
- X "-x don't overwrite existing files",
- X "-X interactively overwrite existing files (NOT FOR NET SHARS)",
- X "-b treat all files as binary, use uuencode",
- X "-t treat all files as text (default)",
- X "-C compress and uuencode all files",
- X "-p allow positional parameter options. The options \"-b\" and \"-t\"",
- X " and \"-C\" may be embedded, and files to the right of the",
- X " option will be processed in the specified mode",
- X "-M mixed mode. Determine if the files are text or",
- X " binary and archive correctly.",
- X "-P use temp files instead of pipes in the shar file",
- X#ifdef THIS_APPEARS_TO_BE_OBSOLETE
- X "-D output date, user, and directory comments to the archive",
- X#endif /* THIS_APPEARS_TO_BE_OBSOLETE */
- X "-c start the shar with a cut line",
- X "-f restore by filename only, rather than path",
- X "-dXXX use XXX to delimit the files in the shar",
- X "-oXXX (or -o XXX) output to file XXX.01 thru XXX.nn",
- X "-lXX limit output file size to XXk bytes (but don't split files)",
- X "-LXX limit output file size to XXk bytes (may split files)",
- X "\nThe 'o' option is required if the 'l' or 'L' option is used",
- X "The 'n' option is required if the 'a' option is used",
- X "The 'x' and 'L' options are incompatible",
- X "\n-a generates sharname/part## headers. If you are producing patches",
- X "you'll need to edit -a headers (or please improve shar :-))",
- X "The automatic submitter name is trivial: essentially `whoami`@`uname`",
- X (char *)0
- X };
- X fprintf(stderr,
- X "shar %s\nusage: shar [ options ] file [ file1 ... ] ]\n",revision);
- X for(ptr = helpinfo; *ptr; ptr++)
- X fprintf(stderr,"%s\n",*ptr);
- X
- X exit(1);
- X}
- X/* vi: set tabstop=4 shiftwidth=4: */
- SHAR_EOF
- $TOUCH -am 0419135590 shar.c &&
- chmod 0644 shar.c ||
- echo "restore of shar.c failed"
- set `wc -c shar.c`;Wc_c=$1
- if test "$Wc_c" != "28774"; then
- echo original size 28774, current size $Wc_c
- fi
- # ============= unshar.c ==============
- echo "x - extracting unshar.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > unshar.c &&
- X/* CHK=0x2B39 */
- Xchar *revision = "3.22";
- X/****************************************************************
- X * unshar.c: Unpackage one or more shell archive files
- X *
- X * Usage: unshar [-c] [-C exit_line] [ -d directory ] [ file ] ...
- X *
- X * Description: unshar is a filter which removes the front part
- X * of a file and passes the rest to the 'sh' command.
- X * It understands phrases like "cut here", and also
- X * knows about shell comment characters and the Unix
- X * commands "echo", "cat", and "sed".
- X *
- X * It can unshar shar files concatenated in one file, with the
- X * the "-c" command, which separates files by recognizing the
- X * "exit 0" string at the beginning of a line
- X *
- X * (The -C string option allows you to specify this string, thus
- X * -c is equivalent to -C "exit 0")
- X *
- X * The -d flag tells unshar to change directory before unsharing
- X *
- X * HISTORY
- X * 19-Apr-90 Colas Nahaboo (colas@mirsa.inria.fr)
- X * added -c and -C flags to read from concatenated archives
- X * 1-Feb-85 Guido van Rossum (guido@mcvax) at CWI, Amsterdam
- X * Added missing 'quit' routine;
- X * added -d flag to change to directory first;
- X * added filter mode (read stdin when no arguments);
- X * added 'getopt' to get flags (makes it self-contained).
- X * 29-Jan-85 Michael Mauldin (mlm) at Carnegie-Mellon University
- X * Created.
- X ****************************************************************/
- X/*+:EDITS:*/
- X/*:04-19-1990-15:20-wht@n4hgf-fix so -d doesnt make argv files unreachable */
- X/*:04-19-1990-15:06-wht@n4hgf-colas@mirsa patches had expanded tabs */
- X/*:04-10-1990-22:02-wht@n4hgf-stdin failed sometimes-can not seek on pipe */
- X
- X#include <stdio.h>
- X#define EOL '\n'
- X
- X#if defined(pyr) || defined(sun) || defined(BSD42) || \
- X defined(vax) || defined(sequent)
- X#define strchr index
- X#undef USE_GETCWD
- Xchar *getwd();
- X#else
- X#define USE_GETCWD
- Xchar *getcwd();
- X#endif
- X
- Xchar *strchr();
- X
- Xextern char *optarg;
- Xextern int optind;
- X
- Xint continue_reading = 0;
- Xchar *exit_string = "exit 0";
- Xint exit_string_length;
- Xchar argvdir[1024];
- X
- Xmain(argc,argv)
- Xint argc;
- Xchar *argv[];
- X{
- X int i,ch;
- X FILE *in;
- X char s1024[1024];
- X
- X setbuf(stdout,NULL);
- X setbuf(stderr,NULL);
- X
- X#ifdef USE_GETCWD
- X if(!getcwd(argvdir,sizeof(argvdir)))
- X {
- X perror("cannot get current directory name");
- X exit(1);
- X }
- X#else
- X argvdir[0] = 0;
- X if(!getwd(argvdir))
- X {
- X if(argvdir[0])
- X fprintf(stderr,"%s\n",argvdir);
- X else
- X printf(stderr,"cannot get current directory name\n");
- X exit(1);
- X }
- X#endif
- X
- X
- X /* Process options */
- X
- X while((ch = getopt(argc,argv,"d:cC:")) != EOF)
- X {
- X switch(ch)
- X {
- X case 'd':
- X if(chdir(optarg) == -1)
- X {
- X fprintf(stderr,"unshar: cannot chdir to '%s'\n",optarg);
- X exit(2);
- X }
- X break;
- X case 'C':
- X exit_string = optarg;
- X case 'c':
- X continue_reading = 1;
- X exit_string_length = strlen(exit_string);
- X break;
- X default:
- X quit(2,"Usage: unshar [-d directory] [file] ...\n");
- X }
- X }
- X
- X if(optind < argc)
- X {
- X for(i= optind; i < argc; ++i)
- X {
- X strcpy(s1024,argvdir);
- X strcat(s1024,"/");
- X strcat(s1024,argv[i]);
- X if(!(in = fopen(s1024,"r")))
- X {
- X perror(s1024);
- X exit(1);
- X }
- X process(s1024,in);
- X fclose(in);
- X }
- X }
- X else
- X {
- X sprintf(s1024,"/tmp/unsh.%05d",getpid());
- X unlink(s1024);
- X if(!(in = fopen(s1024,"w+")))
- X {
- X fprintf(stderr,"cannot open temp file '%s'\n",s1024);
- X exit(1);
- X }
- X unlink(s1024); /* don't try this with MSDOS, sports fans */
- X while(i = fread(s1024,1,sizeof(s1024),stdin))
- X fwrite(s1024,i,1,in);
- X rewind(in);
- X process("standard input",in);
- X fclose(in);
- X }
- X
- X exit(0);
- X}
- X
- X
- Xprocess(name,in)
- Xchar *name;
- XFILE *in;
- X{
- X char buffer[8196];
- X char ch;
- X FILE *shpr,*popen();
- X long current_position = 0;
- X char *more_to_read = 0;
- X
- X while(position(name,in,current_position))
- X {
- X printf("%s:\n",name);
- X if(!(shpr = popen("sh","w")))
- X quit(1,"unshar: cannot open 'sh' process\n");
- X
- X if (!continue_reading) {
- X while((ch = fgetc(in)) != EOF)
- X fputc(ch,shpr);
- X pclose(shpr);
- X break;
- X } else {
- X while (more_to_read = fgets(buffer, 8196, in)) {
- X fputs(buffer, shpr);
- X if (!strncmp(exit_string, buffer, exit_string_length)) {
- X break;
- X }
- X }
- X pclose(shpr);
- X if (more_to_read)
- X current_position = ftell(in);
- X else {
- X break;
- X }
- X }
- X }
- X}
- X
- X/****************************************************************
- X * position: position 'fil' at the start of the shell command
- X * portion of a shell archive file.
- X ****************************************************************/
- X
- Xposition(fn,fil,start)
- Xchar *fn;
- XFILE *fil;
- Xlong start; /* scan file from position */
- X{
- X char buf[BUFSIZ];
- X long pos,ftell();
- X
- X /* Results from star matcher */
- X static char res1[BUFSIZ],res2[BUFSIZ],res3[BUFSIZ],res4[BUFSIZ];
- X static char *result[] =
- X {
- X res1,res2,res3,res4 };
- X
- X fseek(fil, start, 0);
- X
- X while(1)
- X { /* Record position of the start of this line */
- X pos = ftell(fil);
- X
- X /* Read next line, fail if no more and no previous process */
- X if(!fgets(buf,BUFSIZ,fil))
- X {
- X if(!start)
- X fprintf(stderr,"unshar: found no shell commands in %s\n",fn);
- X return(0);
- X }
- X
- X /* Bail out if we see C preprocessor commands or C comments */
- X if(stlmatch(buf,"#include") || stlmatch(buf,"# include") ||
- X stlmatch(buf,"#define") || stlmatch(buf,"# define") ||
- X stlmatch(buf,"#ifdef") || stlmatch(buf,"# ifdef") ||
- X stlmatch(buf,"#ifndef") || stlmatch(buf,"# ifndef") ||
- X stlmatch(buf,"/*"))
- X {
- X fprintf(stderr,
- X "unshar: %s looks like raw C code, not a shell archive\n",fn);
- X return(0);
- X }
- X
- X /* Does this line start with a shell command or comment */
- X if(stlmatch(buf,"#") || stlmatch(buf,":") ||
- X stlmatch(buf,"echo ") || stlmatch(buf,"sed ") ||
- X stlmatch(buf,"cat ") || stlmatch(buf,"if "))
- X {
- X fseek(fil,pos,0);
- X return(1);
- X }
- X
- X /* Does this line say "Cut here" */
- X if(smatch(buf,"*CUT*HERE*",result) ||
- X smatch(buf,"*cut*here*",result) ||
- X smatch(buf,"*TEAR*HERE*",result) ||
- X smatch(buf,"*tear*here*",result) ||
- X smatch(buf,"*CUT*CUT*",result) ||
- X smatch(buf,"*cut*cut*",result))
- X {
- X /* Read next line after "cut here", skipping blank lines */
- X while(1)
- X {
- X pos = ftell(fil);
- X
- X if(!fgets(buf,BUFSIZ,fil))
- X {
- X fprintf(stderr,
- X "unshar: found no shell commands after 'cut' in %s\n",fn);
- X return(0);
- X }
- X
- X if(*buf != '\n') break;
- X }
- X
- X /* Win if line starts with a comment character of lower case letter */
- X if(*buf == '#' || *buf == ':' || (('a' <= *buf) && ('z' >= *buf)))
- X {
- X fseek(fil,pos,0);
- X return(1);
- X }
- X
- X /* Cut here message lied to us */
- X fprintf(stderr,"unshar: %s is probably not a shell archive,\n",fn);
- X fprintf(stderr," the 'cut' line was followed by: %s",buf);
- X return(0);
- X }
- X }
- X}
- X
- X/*****************************************************************
- X * stlmatch -- match leftmost part of string
- X *
- X * Usage: i = stlmatch (big,small)
- X * int i;
- X * char *small, *big;
- X *
- X * Returns 1 iff initial characters of big match small exactly;
- X * else 0.
- X *
- X * HISTORY
- X * 18-May-82 Michael Mauldin (mlm) at Carnegie-Mellon University
- X * Ripped out of CMU lib for Rog-O-Matic portability
- X * 20-Nov-79 Steven Shafer (sas) at Carnegie-Mellon University
- X * Rewritten for VAX from Ken Greer's routine.
- X *
- X * Originally from klg (Ken Greer) on IUS/SUS UNIX
- X *****************************************************************/
- X
- Xint stlmatch(big,small)
- Xchar *small,*big;
- X{
- X register char *s,*b;
- X s = small;
- X b = big;
- X do
- X {
- X if(*s == '\0')
- X return(1);
- X } while(*s++ == *b++);
- X return(0);
- X}
- X
- X/*****************************************************************
- X * smatch: Given a data string and a pattern containing one or
- X * more embedded stars (*) (which match any number of characters)
- X * return true if the match succeeds, and set res[i] to the
- X * characters matched by the 'i'th *.
- X *****************************************************************/
- X
- Xsmatch(dat,pat,res)
- Xregister char *dat,*pat,**res;
- X{
- X register char *star = 0,*starend,*resp;
- X int nres = 0;
- X
- X while(1)
- X {
- X if(*pat == '*')
- X {
- X star = ++pat; /* Pattern after * */
- X starend = dat; /* Data after * match */
- X resp = res[nres++]; /* Result string */
- X *resp = '\0'; /* Initially null */
- X }
- X else if(*dat == *pat) /* Characters match */
- X {
- X if(*pat == '\0') /* Pattern matches */
- X return(1);
- X pat++; /* Try next position */
- X dat++;
- X }
- X else
- X {
- X if(*dat == '\0') /* Pattern fails - no more */
- X return(0); /* data */
- X if(star == 0) /* Pattern fails - no * to */
- X return(0); /* adjust */
- X pat = star; /* Restart pattern after * */
- X *resp++ = *starend; /* Copy character to result */
- X *resp = '\0'; /* null terminate */
- X dat = ++starend; /* Rescan after copied char */
- X }
- X }
- X}
- X
- X/*****************************************************************
- X * Addendum: quit subroutine (print a message and exit)
- X *****************************************************************/
- X
- Xquit(status,message)
- Xint status;
- Xchar *message;
- X{
- X fprintf(stderr,message);
- X exit(status);
- X}
- X
- X/*****************************************************************
- X * Public Domain getopt routine
- X *****************************************************************/
- X
- X/*
- X * get option letter from argument vector
- X */
- Xint opterr = 1; /* useless, never set or used */
- Xint optind = 1; /* index into parent argv vector */
- Xint optopt; /* character checked for validity */
- Xchar *optarg; /* argument associated with option */
- X
- X#define BADCH (int)'?'
- X#define EMSG ""
- X#define tell(s) fputs(*nargv,stderr);fputs(s,stderr); \
- X fputc(optopt,stderr);fputc('\n',stderr);return(BADCH);
- X
- Xgetopt(nargc,nargv,ostr)
- Xint nargc;
- Xchar **nargv,*ostr;
- X{
- X static char *place = EMSG; /* option letter processing */
- X register char *oli; /* option letter list index */
- X char *strchr();
- X
- X if(!*place)
- X { /* update scanning pointer */
- X if(optind >= nargc || *(place = nargv[optind]) != '-' || !*++place)
- X return(EOF);
- X if(*place == '-')
- X { /* found "--" */
- X ++optind;
- X return(EOF);
- X }
- X } /* option letter okay? */
- X if((optopt = (int)*place++) == (int)':' || !(oli = strchr(ostr,optopt)))
- X {
- X if(!*place) ++optind;
- X tell(": illegal option -- ");
- X }
- X if(*++oli != ':')
- X { /* don't need argument */
- X optarg = (char *)0;
- X if(!*place) ++optind;
- X }
- X else
- X { /* need an argument */
- X if(*place) optarg = place; /* no white space */
- X else if(nargc <= ++optind)
- X { /* no arg */
- X place = EMSG;
- X tell(": option requires an argument -- ");
- X }
- X else optarg = nargv[optind]; /* white space */
- X place = EMSG;
- X ++optind;
- X }
- X return(optopt); /* dump back option letter */
- X}
- X/* vi: set tabstop=4 shiftwidth=4: */
- SHAR_EOF
- $TOUCH -am 0419161290 unshar.c &&
- chmod 0644 unshar.c ||
- echo "restore of unshar.c failed"
- set `wc -c unshar.c`;Wc_c=$1
- if test "$Wc_c" != "10737"; then
- echo original size 10737, current size $Wc_c
- fi
- # ============= uushar.c ==============
- echo "x - extracting uushar.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > uushar.c &&
- X/* CHK=0x46B4 */
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X
- X/* ENC is the basic 1 character encoding function to make a char printing */
- X#define ENC(c) ((((c) & 077) + ' ') | ((c & 077) == 0 ? 0100 : 0))
- X
- Xencode (in, out)
- X FILE *in;
- X FILE *out;
- X{
- X char buf[80];
- X int i, n;
- X
- X for (;;)
- X {
- X /* 1 (up to) 45 character line */
- X n = fr (in, buf, 45);
- X putc (ENC (n), out);
- X
- X for (i = 0; i < n; i += 3)
- X outdec (&buf[i], out);
- X
- X putc ('\n', out);
- X if (n <= 0)
- X break;
- X }
- X}
- X
- X/*
- X * output one group of 3 bytes, pointed at by p, on file f.
- X */
- Xoutdec (p, f)
- X char *p;
- X FILE *f;
- X{
- X int c1, c2, c3, c4;
- X
- X c1 = *p >> 2;
- X c2 = (*p << 4) & 060 | (p[1] >> 4) & 017;
- X c3 = (p[1] << 2) & 074 | (p[2] >> 6) & 03;
- X c4 = p[2] & 077;
- X putc (ENC (c1), f);
- X putc (ENC (c2), f);
- X putc (ENC (c3), f);
- X putc (ENC (c4), f);
- X}
- X
- X/* fr: like read but stdio */
- Xint
- X fr (fp, buf, cnt)
- X FILE *fp;
- X char *buf;
- X int cnt;
- X{
- X int c, i;
- X
- X for (i = 0; i < cnt; i++)
- X {
- X c = getc (fp);
- X if (c == EOF)
- X return (i);
- X buf[i] = c;
- X }
- X return (cnt);
- X}
- X/* vi: set tabstop=4 shiftwidth=4: */
- SHAR_EOF
- $TOUCH -am 0330002690 uushar.c &&
- chmod 0644 uushar.c ||
- echo "restore of uushar.c failed"
- set `wc -c uushar.c`;Wc_c=$1
- if test "$Wc_c" != "1169"; then
- echo original size 1169, current size $Wc_c
- fi
- # ============= who@where.c ==============
- echo "x - extracting who@where.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > who@where.c &&
- X/* CHK=0xCB66 */
- X/*+-------------------------------------------------------------------------
- X who@where.c - find out who i am & where i am
- X ...!gatech!kd4nc!n4hgf!wht (wht%n4hgf@gatech.edu)
- X--------------------------------------------------------------------------*/
- X/*+:EDITS:*/
- X/*:04-03-1990-19:55-wht@n4hgf-get rid of complicated who_am_i */
- X/*:04-01-1990-13:30-pat@rwing-use utsname.nodename instead of sysname */
- X/*:04-02-1990-12:12-wht@n4hgf-sigh... some pwd.h dont declare functions */
- X/*:03-29-1990-18:23-wht@n4hgf-add automatic sequent support */
- X/*:03-28-1990-15:24-wht@n4hgf-creation */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <pwd.h>
- X
- X/* assume system v unless otherwise fixed */
- X#if (defined(pyr) || defined(vax) || defined(sequent)) && !defined(BSD42)
- X#define BSD42
- X#endif
- X#if defined(sun) /* this miscreant doesn't exactly fit BSD or SYSV */
- X#undef BSD42
- X#undef SYS5
- X#endif
- X#if !defined(BSD42) && !defined(sun)
- X#define SYS5
- X#endif
- X
- X#if defined(sun) || defined(BSD42)
- X#define strchr index
- X#define strrchr rindex
- X#endif
- X
- X#if !defined(SYS5) || defined(sun)
- X#include <sys/time.h>
- Xextern int errno;
- X#else
- X#include <sys/utsname.h>
- X#include <time.h>
- X#endif /* system dependencies */
- X
- X/*+-------------------------------------------------------------------------
- X who_am_i() - get user name
- X--------------------------------------------------------------------------*/
- Xchar *
- Xwho_am_i()
- X{
- X struct passwd *getpwuid();
- X struct passwd *passwd;
- X passwd = getpwuid(getuid());
- X (void)endpwent();
- X if(passwd == (struct passwd *)0)
- X return("???");
- X return(passwd->pw_name);
- X
- X} /* end of who_am_i */
- X
- X/*+-------------------------------------------------------------------------
- X where_am_i() - do uname, gethostname, or read file (/etc/systemid)
- X--------------------------------------------------------------------------*/
- Xchar *
- Xwhere_am_i()
- X{
- X#if defined(M_SYS5) /* SCO UNIX or XENIX */
- XFILE *fpsid = fopen("/etc/systemid","r");
- Xstatic char s20[20];
- X if(!fpsid)
- X return("???");
- X fgets(s20,sizeof(s20),fpsid);
- X fclose(fpsid);
- X s20[strlen(s20) - 1] = 0;
- X return(s20);
- X#else /* M_SYS5 */
- X#if defined(SYS5)
- Xstatic struct utsname where_i_am;
- X uname(&where_i_am);
- X return(where_i_am.nodename);
- X#else /* SYS5 */
- Xstatic char where_i_am[64];
- X gethostname(where_i_am,sizeof(where_i_am));
- X return(where_i_am);
- X#endif /* SYS5 */
- X#endif /* M_SYS5 */
- X} /* end of where_am_i */
- X
- X/*+-------------------------------------------------------------------------
- X who_where(buf)
- X--------------------------------------------------------------------------*/
- Xchar *
- Xwho_where(buf)
- Xchar *buf;
- X{
- Xstatic char ww[64];
- X
- X if(!buf)
- X buf = ww;
- X strcpy(buf,who_am_i());
- X strcat(buf,"@");
- X strcat(buf,where_am_i());
- X} /* end of who_where */
- X
- X/* vi: set tabstop=4 shiftwidth=4: */
- X/* end of who@where.c */
- SHAR_EOF
- $TOUCH -am 0419135590 who@where.c &&
- chmod 0644 who@where.c ||
- echo "restore of who@where.c failed"
- set `wc -c who@where.c`;Wc_c=$1
- if test "$Wc_c" != "2784"; then
- echo original size 2784, current size $Wc_c
- fi
- exit 0
-
- ------------------------------------------------------------------
- Warren Tucker, TuckerWare gatech!n4hgf!wht or wht%n4hgf@gatech.edu
- McCarthyism did to cinema what ANSI did to C, cast a great number
- of characters into the void.
-