[comp.os.minix] V1.4a #4

ast@cs.vu.nl (Andy Tanenbaum) (01/23/89)

: This is a shar archive.  Extract with sh, not csh.
: This archive ends with exit, so do not worry about trailing junk.
: --------------------------- cut here --------------------------
PATH=/bin:/usr/bin:/usr/ucb
echo Extracting 'cgrep.c'
sed 's/^X//' > 'cgrep.c' << '+ END-OF-FILE ''cgrep.c'
X/* cgrep - grep and display context	Author: Mark Mallet */
X
X/*
X        Nov 19 1984     Mark Mallett   (mem@zinn.MV.COM)
X
Xmem	860224	Modified to do r/e (regular expression) parsing on unix
Xmem	860324	Added -f, -n; added code to number lines correctly on
X		output.
Xmem	870325	Added support for regcmp()/regex() style regular expression
X		library; redid some conditionals to provide better mix'n'match.
Xmem	870326	Don't try to print the filename if reading from stdin.
X		Add -w option.  Fix a small problem which occasionally allowed
X		the separator to come out between adjacent lines of the file.
Xmem	871119	Fix semantics of call to regcmp(): the NULL terminating the
X		argument list was missing.  It worked, but probably only
X		due to some bizarre coincidence.
Xdro 890109  Minor mods to compile under Minix
X
X*/
X
X#define  OS_UNIX   /* Define this for unix systems */
X/* #define	REGEX */	/* Define this for re_comp/re_exec library */
X#define  REGCMP    /* Define this to use regcmp/regex */
X/* #define	OS_CPM */	/* Define this for CP/M-80 */
X
X
X/* Don't touch these */
X#define	NOREGEXP		/* Set this for no regular expression */
X#ifdef	REGEX
X#undef	NOREGEXP
X#endif	REGEX
X
X#ifdef	REGCMP
X#undef	NOREGEXP
X#endif	REGCMP
X
X
X#ifdef OS_CPM
X#include "stdio.h"
X#include "ctype.h"
X#endif OS_CPM
X
X#ifdef OS_UNIX
X#include <stdio.h>
X#include <ctype.h>
X
X#include <sys/types.h>
X#include <sys/dir.h>        /* Either here or in sys directory - dro */
X#include <regexp.h>         /* should have this                - dro */
X#endif OS_UNIX
X
X
X/* Local definitions */
X
X#ifndef	NULL
X#define	NULL	((char *)0)
X#endif	NULL
X
X#ifndef NUL
X#define NUL     '\000'
X#endif
X
X#ifndef TRUE
X#define TRUE    1
X#define FALSE   0
X#endif
X
X
X/* Internal data declared global */
X
X
X/* Internal routines */
X
X
X/* External data */
X
X
X/* Local data */
X
Xstatic  int     Debug={FALSE};          /* Debug enabled flag */
Xstatic  int     Lcur = {0};             /* Current line (in Lines array) */
Xstatic  char    **Lines = {(char **)NULL};       /* Lines pointer array */
Xstatic  int     Linlen = {100};         /* Line length */
Xstatic  int     Lone = {0};             /* Line one (in Lines array) */
Xstatic	int	Nmr = {0};		/* Number of matched regions */
Xstatic  char    *Pat = {NULL};          /* Pattern */
Xstatic	char	Shwfile = {TRUE};	/* Show file name... */
Xstatic	char	Shwline = {TRUE};	/* Show line number */
Xstatic  int     Waft = {0};             /* Window after */
Xstatic  int     Wbef = {0};             /* Window before */
Xstatic  int     Wsiz = {0};             /* Window size */
X
Xstruct regexp        *Re;        /* Result from reg compilation */
X
Xmain (argc, argv)
X
Xint             argc;           /* Argument count */
Xchar            **argv;         /* Argument values */
X
X{
Xint             i;              /* Scratch */
Xint             n;              /* Scratch again */
Xint             c;              /* A character */
Xchar            *aptr;          /* Argument pointer */
Xint             nf;             /* number of files on command line */
X
Xnf = 0;                         /* No files on line */
X
Xfor (i = 1; i < argc; i++)      /* Look at args */
X    {
X    if (argv[i][0] != '-')      /* If option */
X        {
X        if (Pat == NULL)        /* If no pattern yet given */
X	    {
X            Pat = argv[i];      /*  point here */
X#ifdef	REGEX
X	    if ((Re = re_comp(Pat)) != NULL)
X            {
X		fprintf(stderr, "cgrep: %s\n", re);
X		exit(1);
X		}
X#endif	REGEX
X
X#ifdef	REGCMP
X        if ((Re = regcomp(Pat)) == NULL)
X	        {
X		fprintf(stderr, "cgrep: error in regular expression.\n");
X		exit(1);
X		}
X#endif	REGCMP
X
X	    }
X        else                    /* This must be a file to search */
X            {
X            nf++;               /* Count it */
X            dosrch (argv[i]);   /* Search */
X            }
X        }
X
X    else                        /* Option char */
X        {
X        c = argv[i][1];         /* Get option char */
X        if (isupper(c))         /* Trap idiot definition of tolower */
X            c = tolower(c);     /* Don't care about case */
X        n = i;
X        aptr = NULL;            /* Find arg, if any */
X        if (argv[i][2] != NUL)
X            {
X            aptr = &argv[i][2];
X            n = i;              /* Where to set i if we use this arg */
X            }
X        else if (i < argc-1)    /* use next.. */
X            {
X            n = i+1;
X            aptr = argv[n];
X            }
X
X        switch (c)              /* Process the option */
X            {
X            case 'a':           /* Lines after */
X                Waft = atoi (aptr);
X                Lines = NULL;
X                i = n;
X                break;
X
X            case 'b':           /* Lines before */
X                Wbef = atoi (aptr);
X                Lines = (char **)NULL;
X                i = n;
X                break;
X
X/* Disable debug output
X            case 'd':
X                Debug = TRUE;
X                break;
X*/
X
X	    case 'f':		/* Suppress filename on output */
X	        Shwfile = FALSE;
X		break;
X
X            case 'l':           /* Line length */
X                Linlen = atoi (aptr);
X                Lines = NULL;
X                i = n;
X                break;
X
X	    case 'n':		/* Suppress line number on output */
X	        Shwline = FALSE;
X		break;
X
X            case 'w':           /* Window: lines before and after */
X                Waft = Wbef = atoi (aptr);
X                Lines = NULL;
X                i = n;
X                break;
X
X            default:
X                fprintf (stderr, "Invalid option %s\n",argv[i]);
X                exit();
X            }
X        }
X    }
X
Xif ( Pat == NULL )		/* If no pattern given */
X    {
X    fprintf(stderr, 
X"Usage: cgrep [-a n] [-b n] [-f] [-l n] [-n] [-w n] pattern [filename... ]\n");
X    exit(1);
X    }
X
Xif (nf == 0)                    /* No files processed ? */
X    dosrch (NULL);              /* Do standard input */
X}
X/*
X
X*//* dosrch (ifnm)
X
X        Perform the search
X
XAccepts :
X
X        ifn             Input file name
X
X
XReturns :
X
X
X*/
X
Xdosrch (ifnm)
X
Xchar            *ifnm;          /* Input filelname */
X
X{
XFILE            *ifp;           /* Input fp */
Xchar            *lptr;          /* Line pointer */
Xint             i;              /* Scratch */
Xint             prtaft;         /* Print-after count */
Xint             linnum;         /* Line number */
Xint		nlb;		/* Number of lines buffered */
X
Xif (ifnm != NULL)               /* If file name given */
X    {
X    ifp = fopen (ifnm, "r");    /* Open it for read access */
X    if (ifp == NULL)
X        {
X        fprintf (stderr, "Can not open file %s\n", ifnm);
X        return;
X        }
X    }
Xelse
X    ifp = stdin;
X
Xif (Lines == NULL)              /* If no line table allocated.. */
X    {
X    Wsiz = Wbef+2;              /* Determine total window size */
X    Lines = (char **) calloc (Wsiz, sizeof (char *));
X                                /* Allocate pointer table */
X    for (i = 0; i < Wsiz; i++)  /* Allocate line buffers */
X        Lines[i] = (char *) calloc (Linlen, sizeof(char));
X    }
X
XLcur = Lone = 0;                /* Setup line pointers */
Xnlb = 0;			/* No lines buffered */
Xlinnum = 0;                     /* Line number is zero */
Xprtaft = -(Wbef+1);		/* Make sure separator given first time */
X
Xfor (;;)                        /* Loop through the file */
X    {
X    lptr = Lines[Lcur];         /* Get pointer to current line */
X    if (++Lcur == Wsiz)         /* Bump curr pointer and wrap */
X        Lcur = 0;               /*  if hit end */
X    if (Lone == Lcur)           /* If wrapped to beginning of window */
X        if (++Lone == Wsiz)     /*  Bump beginning */
X            Lone = 0;           /*   and wrap if hit end */
X
X    if (fgets (lptr, Linlen, ifp) != lptr)
X        break;                  /*  if end of file */
X
X    linnum++;                   /* Count line number */
X    if (matlin (lptr))          /* If matching line */
X        {
X        if (prtaft < (-Wbef) )  /* Check for separator needed */
X            if ( (Nmr++ > 0 ) && ((Wbef > 0) || (Waft > 0)) )
X                printf ("----------------------------------------------------------------------------\n");
X        while (Lone != Lcur)    /* Until we close the window */
X            {
X            shwlin (ifnm, linnum-nlb, Lines[Lone]);
X                                /* Show the line */
X            if (++Lone == Wsiz)
X                Lone = 0;
X	    nlb--;
X            }
X	nlb = 0;		/* No lines buffered */
X        prtaft = Waft;          /* Print n lines after */
X        }
X
X    else                        /* Didn't match */
X        {
X        if (prtaft-- > 0)       /* If must print lines after */
X            {
X            shwlin (ifnm, linnum, lptr);
X                                /* Show the line */
X            Lone = Lcur;        /* Match pointers */
X            }
X	else if (nlb < Wbef)	/* Count lines buffered */
X	    nlb++;
X        }
X    }
X
Xif (ifnm != NULL)
X    fclose (ifp);
X}
X/*
X
X*//* shwlin (fnm, linnum, line)
X
X        Show a matching line
X
X
XAccepts :
X
X        fnm             File name
X
X        linnum          Line number
X
X        line            Line to show
X
X
XReturns :
X
X
X*/
X
Xshwlin (fnm, linnum, line)
X
Xchar            *fnm;           /* File name */
Xint             linnum;         /* Line number */
Xchar            *line;          /* Line (with newline at end) to print */
X
X{
Xif (Shwfile && ( fnm != NULL) )
X    printf("%s%s", fnm, Shwline?" ":":");
Xif (Shwline)
X    printf("@%05d%:", linnum);
Xprintf ("%s", line);
X}
X/*
X
X*//* matlin (line)
X
X        Perform match against pattern and line
X
X
XAccepts :
X
X        line            Address of line to match
X
X
XReturns :
X
X        <value>         TRUE if match
X                        FALSE if not
X
X
X*/
X
X
Xint matlin (line)
X
Xchar            *line;          /* Line to match */
X
X{
Xint		rtncode;		/* Return value from this routine */
X
X
X#ifdef	NOREGEXP
Xchar            *pptr, *lptr, *tlptr;
Xint             c1,c2;
X#endif	NOREGEXP
X
Xif (Debug)
X    printf ("Matching %s against %s", Pat, line);
X
X#ifdef	REGEX
Xrtncode = re_exec(line);	/* Hand off to r/e evaluator */
X#endif	REGEX
X
X#ifdef	REGCMP
Xrtncode = (regexec(Re, line) != NULL );
X#endif	REGCMP
X
X#ifdef	NOREGEX		/* Have to do menial comparison.. */
Xlptr = line;                    /* Init line pointer */
X
Xfor ( rtncode = -1; rtncode < 0; )
X    {
X    tlptr = lptr++;             /* Get temp ptr to line */
X    pptr = Pat;                 /* Get ptr to pattern */
X    while (TRUE)
X        {
X        if ((c1 = *pptr++) == NUL)
X            {
X	    rtncode = 1;	/* GOOD return value */
X	    break;
X            }
X        if ((c2 = *tlptr++) == NUL)
X            {
X	    rtncode = 0;	/* BAD return value */
X	    break;
X            }
X        if (isupper(c1))
X            c1 = tolower(c1);
X        if (isupper(c2))
X            c2 = tolower(c2);
X        if (c1 != c2)
X            break;
X        }
X    }
X#endif	NOREGEX
X
X
Xif (Debug)
X    printf("matlin returned %s\n", rtncode?"TRUE":"FALSE");
Xreturn(rtncode);
X}
X
X
X
Xregerror(s)
X{
X  printf("%s\n", s);
X  exit(1);
X}
+ END-OF-FILE cgrep.c
chmod 'u=rw,g=r,o=r' 'cgrep.c'
set `wc -c 'cgrep.c'`
count=$1
case $count in
10963)	:;;
*)	echo 'Bad character count in ''cgrep.c' >&2
		echo 'Count should be 10963' >&2
esac
echo Extracting 'crc.c'
sed 's/^X//' > 'crc.c' << '+ END-OF-FILE ''crc.c'
X/* crc - list length and checksum		Author: Johan W. Stevenson */
X
X#include <stdio.h>
X#include <string.h>
X
Xint	errs;
Xchar line[256];
X
Xmain(argc,argv)
Xchar **argv;
X{
X
X	if (argc <= 1)
X		while (fgets(line, sizeof line, stdin) != NULL)
X		{
X			if (index(line, '\n') != NULL)
X				*index(line, '\n') = 0;
X			crc(line);
X		}
X	else
X		do {
X			crc(argv[1]);
X			argv++;
X			argc--;
X		} while (argc > 1);
X	exit(errs != 0);
X}
X
X/* crctab calculated by Mark G. Mendel, Network Systems Corporation */
Xstatic unsigned short crctab[256] = {
X	0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
X	0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
X	0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
X	0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
X	0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
X	0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
X	0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
X	0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
X	0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
X	0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
X	0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
X	0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
X	0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
X	0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
X	0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
X	0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
X	0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
X	0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
X	0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
X	0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
X	0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
X	0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
X	0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
X	0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
X	0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
X	0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
X	0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
X	0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
X	0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
X	0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
X	0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
X	0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
X};
X
X/*
X * updcrc macro derived from article Copyright (C) 1986 Stephen Satchell. 
X *  NOTE: First argument must be in range 0 to 255.
X *        Second argument is referenced twice.
X * 
X * Programmers may incorporate any or all code into their programs, 
X * giving proper credit within the source. Publication of the 
X * source routines is permitted so long as proper credit is given 
X * to Stephen Satchell, Satchell Evaluations and Chuck Forsberg, 
X * Omen Technology.
X */
X
X#define updcrc(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp)
X
Xcrc(fname)
Xchar *fname;
X{
X	register FILE		*fp;
X	register int		c;
X	register long		len = 0;
X	register unsigned short	crc = 0;
X
X	if ((fp = fopen(fname, "r")) == NULL) {
X		fprintf(stderr, "crc: cannot open %s\n", fname);
X		errs++;
X	}
X	while ((c = getc(fp)) != EOF) {
X		len++;
X		crc = updcrc(c, crc);
X	}
X	fclose(fp);
X	printf("%05u %6ld %s\n", crc, len, fname);
X}
+ END-OF-FILE crc.c
chmod 'u=rw,g=r,o=r' 'crc.c'
set `wc -c 'crc.c'`
count=$1
case $count in
3504)	:;;
*)	echo 'Bad character count in ''crc.c' >&2
		echo 'Count should be 3504' >&2
esac
echo Extracting 'fortune.c'
sed 's/^X//' > 'fortune.c' << '+ END-OF-FILE ''fortune.c'
X/*
X *  fortune  -  hand out Chinese fortune cookies
X */
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <stdio.h>
X#include <time.h>
X
X#define COOKIEJAR "/usr/lib/fortune.dat"
X
Xstatic char *Copyright = "\0fortune v1.1 Copyright (c) 1988 Bert Reuling";
X
Xlong seed;
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X   int c1, c2, c3;
X   long magic();
X   struct stat cookie_stat;
X   FILE *cookie, *out, *fopen(), *popen();
X
X   if ((cookie = fopen(COOKIEJAR, "r")) == NULL) {
X      fprintf(stderr, "%s:\nCan't open %s\n", argv[0], COOKIEJAR);
X      exit(-1);
X   }
X
X   /*
X    *  create seed from : date, time, user-id and process-id
X    *  we can't get the position of the moon, unfortunately.
X    *  Note that super cookies are not affected by chance...
X    */
X   seed = time(0L) * (long) getuid() * (long) getpid();
X
X   if (stat(COOKIEJAR, &cookie_stat) != 0) {
X      fprintf(stderr, "%s:\nCannot stat cookie jar\n", argv[0]);
X      exit(-1);
X   }
X
X   fseek(cookie, magic((long) cookie_stat.st_size), 0); /* move by magic... */
X
X   c2 = c3 = '\n';
X   while (((c1 = getc(cookie)) != EOF) && ((c1 != '%') || (c2 != '%') || (c3 != '\n'))) {
X      c3 = c2;
X      c2 = c1;
X   }
X
X   if (c1 == EOF) {
X      fprintf(stderr, "%s:\n", argv[0]);
X      fprintf(stderr, "The cookie jar does not have a bottom!\n");
X      fprintf(stderr, "All cookies have fallen out...\n");
X      exit(-1);
X   }
X
X#ifdef FORMATTER
X   if ((out = popen(FORMATTER, "w")) == NULL) {
X      fprintf(stderr, "%s:\nIt furthers one to see a plumber!\n", argv[0]);
X      exit(-1);
X   }
X#else
X   out = stdout;
X#endif
X
X   c2 = c3 = '\n';
X   while (((c1 = getc(cookie)) != '%') || (c2 != '%') || (c3 != '\n')) {
X      if (c1 == EOF) {
X         rewind(cookie);
X         continue;
X      }
X      putc(c2, out);
X      c3 = c2;
X      c2 = c1;
X   }
X   putc('\n', out);
X   fclose(cookie);
X#ifdef FORMATTER
X   pclose(out);
X#endif
X   exit(0);
X}
X
X/*
X *  magic  -  please study carefull: there is more than meets the eye
X */
Xlong magic(range)
Xlong range;
X{
X   int i;
X
X   for (i = 0; i < 1234; i++)
X      seed = 883L * (seed % 881L) - 2 * (seed / 883L) + 1L;
X   return ((long)((int)(seed & 0x7fffL) * range / 0x7fffL));
X}
X
+ END-OF-FILE fortune.c
chmod 'u=rw,g=r,o=r' 'fortune.c'
set `wc -c 'fortune.c'`
count=$1
case $count in
2163)	:;;
*)	echo 'Bad character count in ''fortune.c' >&2
		echo 'Count should be 2163' >&2
esac
echo Extracting 'id.c'
sed 's/^X//' > 'id.c' << '+ END-OF-FILE ''id.c'
X/* id - return uid and gid		Author: John J. Marco */
X
X
X/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
X/* 		----- id.c -----					*/
X/* id - get real and effective user id and group id			*/
X/* Author: John J. Marco						*/
X/*	   pa1343@sdcc15.ucsd.edu					*/
X/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
X#include "stdio.h"
X#include "pwd.h"
X#include "grp.h"
Xmain ()
X{
X	struct passwd *pwd;
X	struct passwd *getpwuid ();
X	struct group *grp;
X	struct group *getgrgid ();
X	int uid, gid, euid, egid;
X	uid = getuid();
X	gid = getgid();
X	euid = geteuid();
X	egid = getegid();
X	if ((pwd = getpwuid(uid)) == 0) 
X		printf("%s%d%s","uid=",uid," ");
X	else printf("%s%d%s%s%s","uid=",uid,"(",pwd->pw_name,") ");
X	if ((grp = getgrgid(gid)) == 0)
X		printf("%s%d%s","gid=",gid," ");
X	else printf("%s%d%s%s%s","gid=",gid,"(",grp->gr_name,") ");
X	if (((pwd = getpwuid(euid)) != 0) && (uid != euid))
X		printf("%s%d%s%s%s","euid=",euid,"(",pwd->pw_name,") ");
X	else if (uid != euid) printf("%s%d%s","euid=",euid," ");
X	if (((grp = getgrgid(egid)) != 0) && (gid != egid))
X		printf("%s%d%s%s%s","egid=",egid,"(",grp->gr_name,") ");
X	else if (gid != egid) printf("%s%d%s","egid=",egid," ");
X	printf("\n");
X}
+ END-OF-FILE id.c
chmod 'u=rw,g=r,o=r' 'id.c'
set `wc -c 'id.c'`
count=$1
case $count in
1236)	:;;
*)	echo 'Bad character count in ''id.c' >&2
		echo 'Count should be 1236' >&2
esac
echo Extracting 'inodes.c'
sed 's/^X//' > 'inodes.c' << '+ END-OF-FILE ''inodes.c'
X/* inodes - print inode characteristics		Author: Johan W. Stevenson */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X
X#define	NAMSIZ	256
X
Xstruct linkbuf {
X	struct linkbuf	*l_nxt;
X	ino_t	l_ino;
X	dev_t	l_dev;
X	char	l_nam[NAMSIZ];
X};
X
Xchar		line[NAMSIZ];
Xstruct stat	statbuf;
Xstruct linkbuf	*lhead;
X
Xmain() {
X	while (gets(line)) {
X#ifdef S_IFLNK
X		if (lstat(line, &statbuf) < 0) {
X#else
X		if (stat(line, &statbuf) < 0) {
X#endif
X			fprintf(stderr, "cannot stat %s\n", line);
X			continue;
X		}
X		switch (statbuf.st_mode & S_IFMT) {
X		case S_IFDIR:	dir(); break;
X		case S_IFCHR:	dev('c'); break;
X		case S_IFBLK:	dev('b'); break;
X		case S_IFREG:	reg(); break;
X#ifdef S_IFLNK
X		case S_IFLNK:	lnk(); break;
X#endif
X#ifdef S_IFSOCK
X		case S_IFSOCK:	sock(); break;
X#endif
X		default:
X			fprintf(stderr, "%s: bad mode 0%o\n", line, statbuf.st_mode);
X			continue;
X		}
X	}
X	exit(0);
X}
X
Xdir() {
X	register struct stat *p = &statbuf;
X
X	printf(
X		"d %04o %2d %2d     X      X %s\n",
X		p->st_mode & 07777,
X		p->st_uid,
X		p->st_gid,
X		line
X	);
X}
X
Xdev(c) {
X	register struct stat *p = &statbuf;
X
X	printf(
X		"%c %04o %2d %2d %5d %6d %s\n",
X		c,
X		p->st_mode & 07777,
X		p->st_uid,
X		p->st_gid,
X		major(p->st_rdev),
X		minor(p->st_rdev),
X		line
X	);
X}
X
Xreg() {
X	register struct stat *p = &statbuf;
X
X	if (p->st_nlink > 1) {
X		register struct linkbuf *lp;
X
X		for (lp = lhead; lp != NULL; lp = lp->l_nxt)
X			if (lp->l_ino == p->st_ino && lp->l_dev == p->st_dev) {
X				printf(
X					"i XXXX  X  X     X      X %s -> %s\n",
X					line,
X					lp->l_nam
X				);
X				return;
X			}
X		lp = (struct linkbuf *) malloc(sizeof(*lp));
X		if (lp == NULL) {
X			fprintf(stderr, "inodes: out of memory, link information lost\n");
X		} else {
X			lp->l_nxt = lhead;
X			lhead = lp;
X			lp->l_ino = p->st_ino;
X			lp->l_dev = p->st_dev;
X			strcpy(lp->l_nam, line);
X		}
X	}
X	printf(
X		"f %04o %2d %2d %05u %6ld %s\n",
X		p->st_mode & 07777,
X		p->st_uid,
X		p->st_gid,
X		crc(),
X		p->st_size,
X		line
X	);
X}
X
X#ifdef S_IFLNK
Xlnk() {
X	register struct stat *p = &statbuf;
X	char buf[NAMSIZ];
X	register i;
X
X	i = readlink(line, buf, sizeof(buf));
X	if (i < 0) {
X		fprintf(stderr, "cannot readlink %s\n", line);
X		return;
X	}
X	buf[i] = 0;
X	printf(
X		"l %04o %2d %2d     X      X %s -> %s\n",
X		p->st_mode & 07777,
X		p->st_uid,
X		p->st_gid,
X		line,
X		buf
X	);
X}
X#endif
X
X#ifdef S_IFSOCK
Xsock() {
X	register struct stat *p = &statbuf;
X
X	printf(
X		"s %04o %2d %2d     X      X %s\n",
X		p->st_mode & 07777,
X		p->st_uid,
X		p->st_gid,
X		line
X	);
X}
X#endif
X
X/* crctab calculated by Mark G. Mendel, Network Systems Corporation */
Xstatic unsigned short crctab[256] = {
X	0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
X	0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
X	0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
X	0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
X	0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
X	0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
X	0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
X	0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
X	0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
X	0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
X	0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
X	0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
X	0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
X	0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
X	0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
X	0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
X	0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
X	0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
X	0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
X	0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
X	0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
X	0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
X	0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
X	0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
X	0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
X	0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
X	0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
X	0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
X	0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
X	0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
X	0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
X	0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
X};
X
X/*
X * updcrc macro derived from article Copyright (C) 1986 Stephen Satchell. 
X *  NOTE: First argument must be in range 0 to 255.
X *        Second argument is referenced twice.
X * 
X * Programmers may incorporate any or all code into their programs, 
X * giving proper credit within the source. Publication of the 
X * source routines is permitted so long as proper credit is given 
X * to Stephen Satchell, Satchell Evaluations and Chuck Forsberg, 
X * Omen Technology.
X */
X
X#define updcrc(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp)
X
Xcrc()
X{
X	register unsigned short crc;
X	register i, c;
X	register FILE *f;
X
X	if ((f = fopen(line, "r")) == NULL) {
X		fprintf(stderr, "can't open %s\n", line);
X		return(0);
X	}
X	crc = 0;
X	while ((c = getc(f)) != EOF) {
X		crc = updcrc(c, crc);
X	}
X	if (ferror(f))
X		fprintf(stderr, "read error on %s\n", line);
X	fclose(f);
X	return(crc);
X}
+ END-OF-FILE inodes.c
chmod 'u=rw,g=r,o=r' 'inodes.c'
set `wc -c 'inodes.c'`
count=$1
case $count in
5555)	:;;
*)	echo 'Bad character count in ''inodes.c' >&2
		echo 'Count should be 5555' >&2
esac
echo Extracting 'leave.c'
sed 's/^X//' > 'leave.c' << '+ END-OF-FILE ''leave.c'
X/*  leave - tell the user when to go home	Author: Terrence W. Holm */
X
X
X/*  Usage:  leave  [ [+] hhmm ] */
X
X
X#include <signal.h>
X#include <stdio.h>
X#include <utmp.h>
X
X#define  Min(a,b)  ((a<b) ? a : b)
X
X#ifndef  WTMP
X#define  WTMP   "/usr/adm/wtmp"
X#endif
X
X#define  BUFFER_SIZE     1024	  /*  Room for wtmp records  */
X#define  MAX_WTMP_COUNT  ( BUFFER_SIZE / sizeof(struct utmp) )
X
Xstruct utmp  wtmp_buffer[ MAX_WTMP_COUNT ];
X
X#define  STRING	   80		/*  Lots of room for an argument  */
X#define  MIN	   60L		/*  Seconds per minute		  */
X#define  HOUR      (60L*60L)	/*  Seconds per hour		  */
X#define  HALF_DAY  (12L*HOUR)	/*  Seconds per half day	  */
X#define  DAY	   (24L*HOUR)	/*  Seconds per day		  */
X
X/*  Set the following to your personal preferences for the	  */
X/*  time and contents of warnings.				  */
X
X#define  INTERVALS 13		/*  Size of intervals[]		  */
X#define  WARNINGS  4		/*  Size of warnings[]		  */
X
Xint intervals[ INTERVALS ] = { -5*MIN, -1*MIN, 0, MIN, 2*MIN, 3*MIN,
X	4*MIN, 5*MIN, 6*MIN, 7*MIN, 8*MIN, 9*MIN, 10*MIN };
X
Xchar *warnings[ WARNINGS ] = {
X	"You have to leave within 5 minutes",
X	"Just one more minute!",
X	"Time to leave!",
X	"You're going to be late!"   /*  For all subsequent warnings */
X	 };
X
X
X#ifdef V7
Xextern long timezone;
X#else
X#ifdef BSD
X#include <time.h>
Xlong timezone;
X#else
Xlong timezone = 0 * HOUR;	/*  Should be in ctime(3)	  */
X#endif
X#endif
X
X
Xlong  time();
Xchar *ttyname();
Xchar *cuserid();
Xchar *ctime();
X
X
Xmain( argc, argv )
X  int   argc;
X  char *argv[];
X
X  {
X  char when[ STRING ];
X  long now = time( 0 );
X  long leave;
X  int  hour, min;
X  int  pid;
X
X
X  /*  Get the argument string "when" either from stdin, or argv  */
X
X  if ( argc <= 1 )
X    {
X    printf( "When do you have to leave? " );
X
X    if ( fgets( when, STRING, stdin ) == NULL  ||  when[0] == '\n' )
X      exit( 0 );
X    }
X  else
X    {
X    strcpy( when, argv[1] );
X
X    if ( argc > 2 )
X      strcat( when, argv[2] );
X    }
X
X
X  /*  Determine the leave time from the current time and "when"  */
X
X
X  if ( when[0] == '+' )
X    {
X    Get_Hour_Min( &when[1], &hour, &min );
X
X    leave = now + hour * HOUR + min * MIN;
X    }
X  else
X    {
X    /*  User entered an absolute time.  */
X
X#ifdef BSD
X    timezone = - localtime(&now)->tm_gmtoff;
X#endif
X
X    Get_Hour_Min( &when[0], &hour, &min );
X
X    if ( hour >= 1  &&  hour <= 12 )
X	{
X	/*  12-hour format: relative to previous midnight or noon.  */
X
X	leave = now - (now - timezone) % HALF_DAY + hour % 12 * HOUR + min * MIN;
X
X	if ( leave < now - HOUR )
X	  leave = leave + HALF_DAY;
X	else if ( leave < now )
X	  {
X	  printf( "That time has already passed!\n" );
X	  exit( 1 );
X	  }
X	}
X    else if ( hour <= 24 )
X	{
X	/*  24-hour format: relative to previous midnight.  */
X
X	leave = now - (now - timezone) % DAY + hour * HOUR + min * MIN;
X
X	if ( leave < now - HOUR )
X	  leave = leave + DAY;
X	else if ( leave < now )
X	  {
X	  printf( "That time has already passed!\n" );
X	  exit( 1 );
X	  }
X	}
X    else
X	Usage();
X    }
X
X
X  printf( "Alarm set for %s", ctime( &leave ) );
X
X  if ( (pid = fork()) == -1 )
X    {
X    fprintf( stderr, "leave: can not fork\n" );
X    exit( 1 );
X    }
X
X  if ( pid != 0 )
X    exit( 0 );
X
X
X  /*  Only the child continues on  */
X
X  {
X  char *user = cuserid( NULL );
X  char *tty  = ttyname( 0 ) + 5;
X  long delta;
X  int  i;
X
X  if ( user == NULL  ||  tty == NULL )
X    {
X    fprintf( stderr, "leave: Can not determine user and terminal name\n" );
X    exit( 1 );
X    }
X
X
X  signal( SIGINT,  SIG_IGN );
X  signal( SIGQUIT, SIG_IGN );
X  signal( SIGTERM, SIG_IGN );
X
X
X  for(;;)
X    {
X    if( ! Still_Logged_On( user, tty ) )
X      exit( 0 );
X
X    /*  How much longer until the leave time?  */
X
X    delta = leave - time( 0 );
X
X    /*  Which interval are we currently in?  */
X
X    for ( i = 0;  i < INTERVALS;  ++i )
X      if ( delta + intervals[i] > 0 )
X	break;
X
X    /*  If we are within intervals[0] then print a warning.  */
X    /*  If there are more intervals than messages, then use  */
X    /*  warnings[WARNINGS-1] for all subsequent messages.    */
X
X    if ( i > 0 )
X      printf( "\007%s\n", warnings[ i > WARNINGS ? WARNINGS-1 : i-1 ] );
X
X    if ( i == INTERVALS )
X      {
X      printf( "That was the last time I'll tell you. Bye.\n" );
X      exit( 0 );
X      }
X
X    /*  Sleep until the next interval. For long periods, wake	*/
X    /*  up every hour to check if the user is still on (also	*/
X    /*  required because 16 bit ints don't allow long waits).	*/
X
X    sleep( (int) Min( delta + intervals[i], HOUR ) );
X    }
X  }
X  }
X
X
X
XGet_Hour_Min( when, hour, min )
X  char *when;
X  int  *hour;
X  int  *min;
X
X  {
X  int hour_min;
X  int just_min = 0;
X
X  switch ( sscanf( when, "%d:%d", &hour_min, &just_min ) )
X    {
X    case 1 :  *hour = hour_min / 100;
X	      *min  = hour_min % 100;
X	      break;
X
X    case 2 :  *hour = hour_min;
X	      *min  = just_min;
X	      break;
X
X    default:  Usage();
X    }
X
X
X  if ( hour_min < 0  ||  just_min < 0  ||  *min > 59 )
X	Usage();
X  }
X
X
X
XStill_Logged_On( user, tty )
X  char *user;
X  char *tty;
X
X  {
X  FILE  *f;
X  long   size;		/*  Number of wtmp records in the file	*/
X  int    wtmp_count;	/*  How many to read into wtmp_buffer	*/
X
X
X  if( (f = fopen( WTMP, "r" )) == NULL )
X    /*  No login/logout records kept  */
X    return( 1 );
X
X  if ( fseek( f, 0L, 2 ) != 0  ||  (size = ftell(f)) % sizeof(struct utmp) != 0  )
X    {
X    fprintf( stderr, "leave: invalid wtmp file\n" );
X    exit( 1 );
X    }
X
X
X  size /= sizeof(struct utmp);	/*  Number of records in wtmp	*/
X
X
X  while( size > 0 )
X    {
X    wtmp_count = (int) Min( size, MAX_WTMP_COUNT );
X
X    size -= (long) wtmp_count;
X
X    fseek( f, size * sizeof(struct utmp), 0 );
X
X    if ( fread( &wtmp_buffer[ 0 ], sizeof(struct utmp), wtmp_count, f ) != wtmp_count )
X	{
X    	fprintf( stderr, "leave: read error on wtmp file\n" );
X    	exit( 1 );
X    	}
X
X
X    while ( --wtmp_count >= 0 )
X	{
X	if ( strcmp( wtmp_buffer[ wtmp_count ].ut_line, "~" ) == 0 )
X	  return( 0 );
X
X	if ( strncmp( wtmp_buffer[ wtmp_count ].ut_line, tty, 8 ) == 0 )
X          if ( strncmp( wtmp_buffer[ wtmp_count ].ut_name, user, 8 ) == 0 )
X	    return( 1 );
X	  else
X	    return( 0 );
X	}
X
X    }  /* end while( size > 0 ) */
X
X  return( 0 );
X  }
X
X
X
XUsage()
X  {
X  fprintf( stderr, "Usage: leave [[+]hhmm]\n" );
X  exit( 1 );
X  }
+ END-OF-FILE leave.c
chmod 'u=rw,g=r,o=r' 'leave.c'
set `wc -c 'leave.c'`
count=$1
case $count in
6232)	:;;
*)	echo 'Bad character count in ''leave.c' >&2
		echo 'Count should be 6232' >&2
esac
echo Extracting 'look.c'
sed 's/^X//' > 'look.c' << '+ END-OF-FILE ''look.c'
X/*  look - look up words in the dictionary	Author: Terrence W. Holm */
X
X
X/*  look  [ -f ]  prefix[/suffix]  [ dictionary ]
X *
X *  Looks for all words in the on-line dictionary
X *  beginning with the specified <prefix> and ending
X *  with <suffix>.
X *
X *  Fold to lower case if "-f" given. Use the file
X *  "dictionary" or /usr/lib/dictionary.
X *
X ******************************************************
X *
X *  This command was written for MINIX, and is slightly
X *  different than the UNIX look(1). First of all, the
X *  list of words is in a different place. Second, these
X *  words are not sorted by -df. And finally, the
X *  ``suffix'' option was added to limit the output of
X *  the multiple variations of each word as contained
X *  in the MINIX dictionary.
X */
X
X#include <ctype.h>
X#include <stdio.h>
X#include <string.h>
X#include <unistd.h>
X
X#ifdef UNIX
X#define  WORDS   "/usr/dict/words"
X#else
X#define  WORDS   "/usr/lib/dictionary"
X#endif
X
X#define  MAX_WORD_LENGTH   80	  /*  including '\0'  */
X
X
Xmain( argc, argv )
X  int   argc;
X  char *argv[];
X
X  {
X  int   fold = 0;
X  char *prefix;
X  char *suffix;
X  char *word_file = WORDS;
X
X  FILE *words;
X  long  head = 0;
X  long  tail;
X  long  mid_point;
X  char  word[ MAX_WORD_LENGTH ];
X  char  unfolded_word[ MAX_WORD_LENGTH ];
X  int   cmp;
X
X
X  /*  Check the arguments: fold, prefix, suffix and word_file.  */
X
X  if ( argc > 1  &&  strcmp( argv[1], "-f" ) == 0 )
X    {
X    fold = 1;
X    --argc;
X    ++argv;
X    }
X
X  if ( argc < 2  ||  argc > 3 )
X    {
X    fprintf( stderr, "Usage: %s [-f] prefix[/suffix] [dictionary]\n", argv[0] );
X    exit( 1 );
X    }
X
X  prefix = argv[1];
X
X  if ( (suffix = strchr( prefix, '/' )) == NULL )
X    suffix = "";
X  else
X    *suffix++ = '\0';
X
X  if ( fold )
X    {
X    Fold( prefix );
X    Fold( suffix );
X    }
X
X  if ( argc == 3 )
X    word_file = argv[2];
X
X
X  /*  Open the word file, and find how big it is.  */
X
X  if ( (words = fopen( word_file, "r" )) == NULL )
X	File_Error( word_file );
X
X  if ( fseek( words, 0L, SEEK_END ) != 0 )
X	File_Error( word_file );
X
X  tail = ftell( words );
X
X
X  /*  Use a binary search on the word file to find a 512 byte	*/
X  /*  window containing the first word starting with "prefix".	*/
X
X  while ( head + 512 < tail )
X    {
X    mid_point = ( head + tail ) / 2;
X
X    if ( fseek( words, mid_point, SEEK_SET ) != 0 )
X	File_Error( word_file );
X
X    /*  Skip the partial word we seeked into.  */
X
X    fgets( word, MAX_WORD_LENGTH, words );
X
X    if ( fgets( word, MAX_WORD_LENGTH, words ) == NULL )
X	File_Error( word_file );
X
X    word[ strlen(word) - 1 ] = '\0';	/* remove \n  */
X
X    strcpy( unfolded_word, word );
X
X    if ( fold )
X	Fold( word );
X
X    cmp = strcmp( prefix, word );
X
X    if ( cmp == 0 )
X	{
X	printf( "%s\n", unfolded_word );
X	head = ftell( words );
X	break;
X	}
X
X    if ( cmp < 0 )
X	tail = mid_point;
X    else
X	head = ftell( words );
X    }
X
X  fseek( words, head, SEEK_SET );
X
X
X
X  {
X  /*  Print out all the words starting with "prefix".  */
X
X  int   prefix_length = strlen( prefix );
X  int   suffix_length = strlen( suffix );
X  int   word_length;
X
X
X  while( fgets( word, MAX_WORD_LENGTH, words ) != NULL )
X    {
X    word_length = strlen( word ) - 1;
X
X    word[ word_length ] = '\0';		/* remove \n  */
X
X    strcpy( unfolded_word, word );
X
X    if ( fold )
X	Fold( word );
X
X    cmp = strncmp( prefix, word, prefix_length );
X
X    if ( cmp < 0 )
X 	break;
X
X    if ( cmp == 0 )
X	if ( suffix_length == 0  ||  word_length >= suffix_length
X	   &&  strcmp( suffix, word+word_length-suffix_length ) == 0 )
X		printf( "%s\n", unfolded_word );
X    }
X  }
X
X  fclose( words );
X
X  exit( 0 );
X  }
X
X
X
XFold( str )
X  char *str;
X
X  {
X  while( *str ) {
X    if ( isupper( *str ) ) *str = *str - 'A' + 'a';
X    str++;
X  }
X  }
X
X
X
XFile_Error( word_file )
X  char *word_file;
X
X  {
X  perror( word_file );
X  exit( 1 );
X  }
+ END-OF-FILE look.c
chmod 'u=rw,g=r,o=r' 'look.c'
set `wc -c 'look.c'`
count=$1
case $count in
3803)	:;;
*)	echo 'Bad character count in ''look.c' >&2
		echo 'Count should be 3803' >&2
esac
exit 0