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