shar 3.11

Warren Tucker wht at n4hgf.uucp
Sat Apr 7 05:25:03 AEST 1990


Submitted by: wht at n4hgf
Archive-name: shar311/part01

#!/bin/sh
# This is shar311, a shell archive (shar 3.11)
# made 04/06/1990 19:13 UTC by wht at n4hgf
# Source directory /u1/src/shar
#
# existing files WILL be overwritten
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#   5093 -rw-r--r-- README
#    333 -rw-r--r-- Makefile
#  24654 -rw-r--r-- shar.c
#   8440 -rw-r--r-- unshar.c
#   1169 -rw-r--r-- uushar.c
#   2784 -rw-r--r-- who at where.c
#
touch 2>&1 | fgrep '[-amc]' > /tmp/s3_touch$$
if [ -s /tmp/s3_touch$$ ]
then
	TOUCH=can
else
	TOUCH=cannot
fi
rm -f /tmp/s3_touch$$
# ============= README ==============
echo "x - extracting README (Text)"
sed 's/^X//' << 'SHAR_EOF' > README &&
XSubmitted by: wht%n4hgf at gatech.edu
XArchive-name: shar311/part01
X
XHere is shar311, an updated version of shar 3.10, derived from 'shar2'
X
XI apologize as appropriate to davidsen at sixhub for his not receiving 
Xmy mail of Wed, 28 Mar 90 17:31:25 EST sending him an advance copy
Xof shar310.  The mail header for this transmission to him is:
X
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 at n4hgf (Warren Tucker)
X    To: davidsen at sixhub
X    Subject: shar 3.11
X    X-Bang-Reply-to: gatech!n4hgf!wht -or- emory!tridom!n4hgf!wht
X    Reply-to: wht%n4hgf at gatech.edu
X    Message-Id: <9004061514.AA01781 at n4hgf.UUCP>
X
X  C.gatechN26ac UUCP uux file
X    U wht n4hgf
X    # return status on failure
X    Z
X    # return address for status or input return
X    R wht
X    F D.n4hgf54ef6e7
X    I D.n4hgf54ef6e7
X    C rmail mailrus!uunet!crdgw1!sixhub!davidsen 
#
XChanges from 3.10:
X
X1) A much simplified who_am_i() is used.  The function in 3.10
X   was derived from code where it was important to obtain the user
X   name of the login user despite su'ing, setuid, etc.  This
X   is difficult to do in a portable fashion and not necessary
X   for the 'shar' application.  This version of shar uses the
X   username assosciated with the 'real uid'; use -s to override
X   the automagically determined submitter name if necessary.
X
X2) The -X switch generates shell sequences in the generated shar
X   code necessary to interactively query the disposition of files
X   which would be overwritten if unshared.  NOTE: _PLEASE_ DO NOT,
X   OH PLEASE, DO NOT use this option for shars submitted to public
X   networks. 
X
X   When -X shars are extracted, the first time a file which would be
X   overwritten is encountered, the user is given the option of
X
X     overwrite 'name' -- [No], [Y]es, [A]ll, [Q]uit?
X     N  means no for this file, continue extraction, skipping 'file'
X     Y  means yes for this file, continue extraction, including 'file'
X     A  means yes for this file, continue extraction, automatically
X        overwriting any additional files encountered
X     Q  means quit extraction
X
X   Credit for this idea is given to Bill Silvert <silvert at cs.dal.ca>,
X   Habitat Ecology Division, Bedford Inst. of Oceanography, Dartmouth,
X   Nova Scotia, Canada
X
X   I repeat: NOTE _PLEASE_: DO NOT, OH PLEASE, DO NOT use this option
X   for shars submitted to public networks.  The overhead for -X is high and
X   its use will SCREW UP a lot of automated unshar mechanisms in use
X   throughout the world when the script tries to read from standard
X   input (which may not be open).  Specifically, the unshar program
X   in this distrivbution is not compatible with shars created by the
X   -X option.  it will die horribly with complaints about shell syntax
X   errors.
X
X3) A bug in the sun version which caused a bogus read from standard
X   input when shar was run has been fixed.  It was botched who_am_i()
X   that was doing it.
X
X4) bugs reported and fixed (thanks!) pat at rwing (Pat Myrto):
X>  One was the M option - it was defined as M in the usage
X>  message, and in the switch construct, but as m in the
X>  getopt() call.  I also changed the defaults for wc checking
X>  and verbose extraction to be ON - the cmd line options
X>  turning these OFF (since usually these are desired to be
X>  on).  In who at where, in the utsname structure, looking at
X>  sysname returns 'UNIX' - I think nodename is what you want
X>  to get the [system's] name. ...  Also declared a
X>  function that gave a compiler warning (getpwuid()).
X
XThis version
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 at 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
X7) other chrome-plated junque
X
X------------------------ usage -----------------------------------
X
Xshar 3.11
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-p  allow positional parameter options. The options "-b"
X    and "-t" 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-D  output date, user, and directory comments to the archive
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
X
XThe 'o' option is required if the '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`
SHAR_EOF
chmod 0644 README || echo "restore of README fails"
if [ $TOUCH = can ]
then
    touch -am 0406151290 README
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 at n4hgf-for 3.10, add who at where.c
X
XCFLAGS	= -O 
X
XSRC	= shar.c uushar.c unshar.sh
XOBJ	= shar.o uushar.o who at 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
chmod 0644 Makefile || echo "restore of Makefile fails"
if [ $TOUCH = can ]
then
    touch -am 0328165590 Makefile
fi
# ============= shar.c ==============
echo "x - extracting shar.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > shar.c &&
X/* CHK=0xE923 */
Xchar *revision = "3.11";
X/*
X** shar.c
X
X  Defined functions:
X	Rname(file)
X	exit_incompat()
X	gen_mkdir(path)
X	gen_mkdir_script(path)
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-03-1990-20:09-wht at n4hgf-3.11 */
X/*:04-01-1990-13:20-pat at rwing-correct case on M option in getopt() call */
X/*:04-01-1990-13:50-pat at rwing-change defaults on -v, -w to be on */
X/*:03-29-1990-18:23-wht at n4hgf-add automatic sequent support */
X/*:03-28-1990-15:56-wht at n4hgf-add mode and length net.bandwidth chrome */
X/*:03-28-1990-14:23-wht at 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 at 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 at 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 at gatech.edu) Warren Tucker
X *
X *  3.11 - Fri Apr  6 14:21:51 EDT 1990
X *  With due deference to davidsen at 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 at n4hgf (Warren Tucker)
X *  To: davidsen at sixhub
X *  Subject: shar 3.11
X *  X-Bang-Reply-to: gatech!n4hgf!wht -or- emory!tridom!n4hgf!wht
X *  Reply-to: wht%n4hgf at gatech.edu
X *  Message-Id: <9004061514.AA01781 at n4hgf.UUCP>
X *
X *  1. changes suggested by pat at rwing (Pat Myrto) and silvert at cs.dal.ca
X *  (Bill Silvert)
X *  2. fixes to who_am_i code in who at where.c
X *  ...!gatech!n4hgf!wht (wht%n4hgf at 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 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;
Xlong ftell();
Xlong TypePos;			/* position for archive type message */
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:btxXcfmpas:n: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			break;
X		case 't': /* text mode */
X			Binary = 0;
X			break;
X		case 'x': /* does the file exist */
X			eXists = 1;
X			if(InterOW || limit)
X				exit_incompat();
X			break;
X		case 'X': /* does the file exist */
X			InterOW = 1;
X			if(limit || eXists)
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 'l': /* size limit in k */
X			if(eXists)
X				exit_incompat();
X			limit = atoi(optarg) - 1;
X			DeBug("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	while(optind < argc)
X	{ /* process positional parameters and files */
X		if(PosParam)
X		{		/* allow -b and -t inline */
X			if(strcmp(argv[optind],"-b") == 0)
X			{ /* set binary */
X				Binary = 1;
X				optind++;
X				continue;
X			}
X			if(strcmp(argv[optind],"-t") == 0)
X			{ /* set mode text */
X				Binary = 0;
X				optind++;
X				continue;
X			}
X		}
X		status += shar(argv[optind++]);
X	}
X
X	/* delete the sequence file, if any */
X	if(limit && filenum > 1)
X	{
X		fputs("rm -f s3_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
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 option without -o\n");
X		helpuser();
X	}
X
X	for(i = 0; i < argc; i++)
X	{ /* skip positional parameters */
X		if(PosParam && (strcmp(argv[i],"-b") == 0 ||
X		    strcmp(argv[i],"-t") == 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/part%02d\n\n",
X			sharname,(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(limit)
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 && (strcmp(argv[i],"-b") == 0 ||
X		    strcmp(argv[i],"-t") == 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	fputs("touch 2>&1 | fgrep '[-amc]' > /tmp/s3_touch$$\n",fpout);
X	fputs("if [ -s /tmp/s3_touch$$ ]\n",fpout);
X	fputs("then\n",fpout);
X	fputs("	TOUCH=can\n",fpout);
X	fputs("else\n",fpout);
X	fputs("	TOUCH=cannot\n",fpout);
X	fputs("fi\n",fpout);
X	fputs("rm -f /tmp/s3_touch$$\n",fpout);
X
X	if(limit)
X	{ /* now check the sequence */
X		fprintf(fpout,"%s%s%s%s",
X		    "if test -r s3_seq_.tmp\n",
X		    "then echo \"Must unpack archives in sequence!\"\n",
X		    "     next=`cat s3_seq_.tmp`; echo \"Please unpack part $next next\"\n",
X		    "     exit 1; fi\n");
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	/* 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
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		}
X		else
X		{ /* start writing the pipe with encodes */
X			FILE *outptr;
X
X			fpsource = fopen(file,"rb");
X			outptr = fdopen(pipex[1],"w");
X			fprintf(outptr,"begin 600 %s\n",RstrName);
X			encode(fpsource,outptr);
X			fprintf(outptr,"end\n");
X			exit(0);
X		}
X		filetype = "Binary";
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			if(InterOW)
X			{
X			fprintf(fpout,"if test -f '%s'\n",RstrName);
X			fprintf(fpout,"then\n");
X			fprintf(fpout,"\tcase $wish in\n");
X			fprintf(fpout,"\tA*|a*) echo x - overwriting '%s';;\n",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\n");
X			fprintf(fpout,"then\n");
X			fprintf(fpout,"\techo x - skipping '%s'\n",RstrName);
X			fprintf(fpout,"else\n");
X			}
X			else
X			{
X				fprintf(fpout,
X			    "if test -f '%s'; then echo \"File %s exists\"; else\n",
X			    RstrName,RstrName);
X			}
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 */
X			fprintf(fpout,"sed 's/^%c//' << '%s' > s3_temp_.tmp &&\n",
X			    PREFIX,Delim);
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(limit && (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\" > s3_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/part%2d\n\n",
X						sharname,(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				fputs("touch 2>&1 | fgrep '[-amc]' > /tmp/s3_touch$$\n",fpout);
X				fputs("if [ -s /tmp/s3_touch$$ ]\n",fpout);
X				fputs("then\n",fpout);
X				fputs("    TOUCH=can\n",fpout);
X				fputs("else\n",fpout);
X				fputs("    TOUCH=cannot\n",fpout);
X				fputs("fi\n",fpout);
X				fputs("rm -f /tmp/s3_touch$$\n",fpout);
X
X				fprintf(fpout,"CurArch=%d\n",filenum);
X				fprintf(fpout,"%s%s%s%s%s%s%s%s%s",
X				    "if test ! -r s3_seq_.tmp\n",
X				    "then echo \"Please unpack part 1 first!\"\n",
X				    "     exit 1; fi\n",
X				    "( read Scheck\n",
X				    "  if test \"$Scheck\" != $CurArch\n",
X				    "  then echo \"Please unpack part $Scheck next!\"\n",
X				    "       exit 1;\n",
X				    "  else exit 0; fi\n",
X				    ") < s3_seq_.tmp || exit 1\n");
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,(Binary ? "s3_temp_.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, decode it and drop the temp */
X		if(Binary)
X		{
X			if(Verbose)
X				fprintf(fpout,"echo \"uudecoding file %s\"\n",RstrName);
X			fprintf(fpout,
X			    "uudecode < s3_temp_.tmp && rm -f s3_temp_.tmp &&\n");
X		}
X
X		/* set the permissions as they were */
X		stat(file,&fst);
X		fprintf(fpout,"chmod %04o %s || echo \"restore of %s fails\"\n",
X		    fst.st_mode & 00777,RstrName,RstrName);
X		lt = localtime(&fst.st_mtime);
X		fputs("if [ $TOUCH = can ]\nthen\n",fpout);
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		fputs("fi\n",fpout);
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\"\n",wc);
X				fprintf(fpout,
X				    "then echo original size %s, current size $Wc_c;fi\n",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		"-p  allow positional parameter options. The options \"-b\"",
X		"    and \"-t\" 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		"-D  output date, user, and directory comments to the archive",
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",
X		"\nThe 'o' option is required if the '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
chmod 0644 shar.c || echo "restore of shar.c fails"
if [ $TOUCH = can ]
then
    touch -am 0406143490 shar.c
fi
# ============= unshar.c ==============
echo "x - extracting unshar.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > unshar.c &&
X/* CHK=0x4D8D */
X/****************************************************************
X * unshar.c: Unpackage one or more shell archive files
X *
X * Usage:	unshar [ -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 * HISTORY
X *  1-Feb-85  Guido van Rossum (guido at 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
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#endif
X
Xchar *strchr();
X
Xextern char *optarg;
Xextern int optind;
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{ 
X	int i,ch;
X	FILE *in;
X
X	setbuf(stdout,NULL);
X	setbuf(stderr,NULL);
X
X	/* Process options */
X
X	while((ch = getopt(argc,argv,"d:")) != 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		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			if(!(in = fopen(argv[i],"r")))
X			{ 
X				fprintf(stderr,"unshar: file '%s' not found\n",argv[i]);
X				exit(1);
X			}
X			process(argv[i],in);
X			fclose(in);
X		}
X	}
X	else
X		process("standard input",stdin);
X
X	exit(0);
X}
X
X
Xprocess(name,in)
Xchar *name;
XFILE *in;
X{ 
X	char ch;
X	FILE *shpr,*popen();
X
X	if(position(name,in))
X	{ 
X		printf("%s:\n",name);
X		if(!(shpr = popen("sh","w")))
X			quit(1,"unshar: cannot open 'sh' process\n");
X
X		while((ch = fgetc(in)) != EOF)
X			fputc(ch,shpr);
X
X		pclose(shpr);
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)
Xchar *fn;
XFILE *fil;
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	rewind(fil);
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 */
X		if(!fgets(buf,BUFSIZ,fil))
X		{ 
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 "))
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
chmod 0644 unshar.c || echo "restore of unshar.c fails"
if [ $TOUCH = can ]
then
    touch -am 0403210990 unshar.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
chmod 0644 uushar.c || echo "restore of uushar.c fails"
if [ $TOUCH = can ]
then
    touch -am 0330002690 uushar.c
fi
# ============= who at where.c ==============
echo "x - extracting who at where.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > who at where.c &&
X/* CHK=0xBAD4 */
X/*+-------------------------------------------------------------------------
X	who at where.c - find out who i am & where i am
X	...!gatech!kd4nc!n4hgf!wht (wht%n4hgf at gatech.edu)
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:04-03-1990-19:55-wht at n4hgf-get rid of complicated who_am_i */
X/*:04-01-1990-13:30-pat at rwing-use utsname.nodename instead of sysname */
X/*:04-02-1990-12:12-wht at n4hgf-sigh... some pwd.h dont declare functions */
X/*:03-29-1990-18:23-wht at n4hgf-add automatic sequent support */
X/*:03-28-1990-15:24-wht at 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 at where.c */
SHAR_EOF
chmod 0644 who at where.c || echo "restore of who at where.c fails"
if [ $TOUCH = can ]
then
    touch -am 0406145790 who at where.c
fi
exit 0
 
-------------------------------------------------------------------
Warren Tucker, TuckerWare  gatech!n4hgf!wht or wht%n4hgf at gatech.edu
Sforzando (It., sfohr-tsahn'-doh).  A direction to perform the tone
or chord with special stress, or marked and sudden emphasis.



More information about the Alt.sources mailing list