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