# /* * print file with headings * precl[2]+head+2+page[56]+endl[5] */ /* * NOTE: Defaults are set in the routine dflts() * and not in these declares. */ int errno; char *sys_errlst[]; int ncol 1; /* number of columns */ char *header; /* header text */ int col; int icol; int file; char *bufp; #define BUFS 5120 char buffer[BUFS]; #define FF 014 int line; /* current line on page */ int linum; /* current text line */ int ftext; /* first text line on page */ char *colp[72]; int nofile; /* number of current file */ char isclosed[10]; int peekc; int swval; /* value for next switch */ int fpage; /* first page to print */ int page; /* current page number */ int oheadr; /* use old header format */ int colw; /* column width */ int nspace; int width 65; /* line width */ int pwidth 65; /* width of physical line */ int length 66; /* length of physical page */ int plength 61; /* last print line */ int margin 10; int prone 1; /* print header on page one */ int ntflg; /* no header or trailer */ int nuflg; /* not header line */ int mflg; int tabc; /* print this as column separator */ char *tty; int mode; int precl 2; /* # blank lines preceding hdr */ int endl 5; /* min # blank lines end of page */ int indent; /* spaces preceding each line */ int ff; /* use ff, not blank lines */ int wasff; /* page break caused by ff */ int blankl; /* # blank lines between lines */ int count; /* whether to count linums */ int tab2sp; /* change tabs => spaces */ int queeze; /* squeeze blank lines from top */ /* of each page */ int jnamflg; /* print just file and not path */ int rapflg; /* wrap-around line overflow */ int spaftfil 0; /* space between files */ struct inode { int dev; int inum; int flags; char nlink; char uid; char gid; char siz0; int size; int ptr[8]; int atime[2]; int mtime[2]; }; main (argc, argv) char **argv; { int nfdone; int onintr (); extern fout; tty = "/dev/ttyx"; fout = dup (1); close (1); if ((signal (2, 1) & 01) == 0) signal (2, onintr); fixtty (); dflts (0); for (nfdone = 0; argc > 1; argc--) { argv++; if (**argv == '-') { swval = 1; /* default to on */ setsw: switch (*++*argv) { case 'b': blankl = getn (++*argv); continue; case 'c': count = swval; continue; case 'd': dflts (*++*argv); continue; case 'e': endl = getn (++*argv); continue; case 'f': ff = swval; continue; case 'h': if (argc >= 2) { header = *++argv; argc--; } continue; case 'i': indent = getn (++*argv); continue; case 'j': jnamflg = swval; continue; case 'l': length = getn (++*argv); continue; case 'm': mflg = swval; continue; case 'n': prone = (swval ^ 1); /* Yes => no */ continue; case 'o': oheadr = swval; continue; case 'p': precl = getn (++*argv); continue; case 'q': queeze = swval; continue; case 'r': rapflg = swval; continue; case 's': spaftfil = getn( ++*argv); continue; case 't': ntflg = swval; continue; case 'u': nuflg = swval; continue; case 'w': width = getn (++*argv); continue; case 'x': tab2sp = swval; continue; case '-': swval = 0; goto setsw; default: ncol = getn (*argv); continue; } } else if (**argv == '+') { fpage = getn (++*argv); } else { col = 0; icol = 0; line = 0; nspace = 0; print (*argv, argv); nfdone++; if (mflg) break; } } if (nfdone == 0) print (0); flush (); onintr (); } onintr () { chmod (tty, mode); exit (0); } fixtty () { struct inode sbuf; extern fout; tty[8] = ttyn (fout); fstat (fout, &sbuf); mode = sbuf.flags & 0777; chmod (tty, 0600); } dflts (dfltpkg) { switch (dfltpkg) { case 'd': ncol = 1; /* number of columns */ width = 65; /* line width */ length = 60; /* length of physical page */ plength = 61; /* last print line */ margin = 10; precl = 1; /* # blank lines preceding hdr */ endl = 5; /* min # blank lines end of page */ indent = 5; /* spaces preceding each line */ ff = 1; /* use ff, not blank lines */ blankl = 0; /* # blank lines between lines */ count = 0; /* whether to count linums */ prone = 0; /* print header on page one */ tab2sp = 0; /* change tabs into spaces */ queeze = 1; /* squeeze beginning of pages */ jnamflg = 0; /* print full pathname */ rapflg = 1; /* wrap around long lines */ oheadr = 0; /* nothin' but the best... */ break; case 'l': ncol = 1; /* number of columns */ width = 77; /* line width */ length = 60; /* length of physical page */ plength = 61; /* last print line */ margin = 10; precl = 2; /* # blank lines preceding hdr */ endl = 5; /* min # blank lines end of page */ indent = 5; /* spaces preceding each line */ ff = 1; /* use ff, not blank lines */ blankl = 0; /* # blank lines between lines */ count = 0; /* whether to count linums */ prone = 1; /* print header on page one */ tab2sp = 0; /* change tabs into spaces */ queeze = 0; /* preserve start of each page */ jnamflg = 0; /* print full pathname */ rapflg = 1; /* wrap around long lines */ oheadr = 0; /* nothin' but the best... */ break; case 'n': ncol = 1; /* number of columns */ width = 80; /* line width */ length = 60; /* length of physical page */ plength = 61; /* last print line */ margin = 10; precl = 2; /* # blank lines preceding hdr */ endl = 5; /* min # blank lines end of page */ indent = 5; /* spaces preceding each line */ ff = 1; /* use ff, not blank lines */ blankl = 0; /* # blank lines between lines */ count = 1; /* whether to count linums */ prone = 1; /* print header on page one */ tab2sp = 0; /* don't change tabs into spaces */ queeze = 0; /* preserve start of each page */ jnamflg = 0; /* print full pathname */ rapflg = 1; /* wrap around long lines */ oheadr = 0; /* nothin' but the best... */ break; case 0: default: ncol = 0; /* number of columns */ width = 72; /* line width */ length = 66; /* length of physical page */ plength = 61; /* last print line */ margin = 10; precl = 2; /* # blank lines preceding hdr */ endl = 5; /* min # blank lines end of page */ indent = 0; /* spaces preceding each line */ ff = 0; /* use ff, not blank lines */ blankl = 0; /* # blank lines between lines */ count = 0; /* whether to count linums */ prone = 1; /* print header on page one */ tab2sp = 0; /* don't change tabs into spaces */ queeze = 0; /* preserve start of each page */ jnamflg = 1; /* don't print full pathname */ rapflg = 0; /* don't wrap around long lines */ oheadr = 1; /* nothin' but the worst... */ break; } } print (fp, argp) char *fp; char **argp; { struct inode sbuf; int tmp1; register int sncol, sheader; register char *cbuf; extern fout; linum = 1; if (ntflg) margin = 0; else margin = precl + endl + (nuflg ? 0 : 3); if (length <= margin) length = 66; if (width <= 0) width = 65; if (ncol > 72 || ncol > width) { write (2, "Very funny.\n", 12); exit (); } if (mflg) { mopen (argp); ncol = nofile; } if (ncol > 1) rapflg = 0; colw = width / ncol; sncol = ncol; sheader = header; plength = length - endl; pwidth = width + indent; if (ntflg) plength = length; if (--ncol < 0) ncol = 0; if (mflg) fp = 0; if (fp) { file = open (fp, 0); if (file < 0) { errrpt (fp, sys_errlst[errno]); return; } fstat (file, &sbuf); } else { file = 0; time (sbuf.mtime); } if ((header == 0) && (file != 0)) header = jnamflg ? fp : getpath (fp); cbuf = ctime (sbuf.mtime); cbuf[16] = '\0'; cbuf[24] = '\0'; page = 1; icol = 0; colp[ncol] = bufp = buffer; if (mflg == 0) nexbuf (); while (mflg && nofile || (!mflg) && tpgetc (ncol) > 0) { if (mflg == 0) { colp[ncol]--; if (colp[ncol] < buffer) colp[ncol] = &buffer[BUFS]; } line = 0; if (ntflg == 0) { for (tmp1 = precl; tmp1--;) put ('\n'); if ((nuflg == 0) && (prone || (page > 1))) { for (tmp1 = indent; tmp1--;) put (' '); if (!oheadr && header) { puts (header); puts (" "); } puts (cbuf + 4); put (' '); puts (cbuf + 20); if (oheadr) { puts (" "); if (header) { puts (header); put (' '); } } else do put (' '); while (col < (pwidth - 9)); puts ("Page "); if (oheadr) putd (page); else putrd (page); puts ("\n\n\n"); } } ftext = line; /* # of first text line */ putpage (); if (ff) put ('\014'); else if (ntflg == 0) while (line < length) put ('\n'); page++; } if ( (ntflg != 0) && (spaftfil > 0)) for (tmp1 = spaftfil; tmp1--;) put('\n'); if (file) close (file); ncol = sncol; header = sheader; } mopen (ap) char **ap; { register char **p, *p1; p = ap; while ((p1 = *p++) && p1 != -1) { isclosed[nofile] = fopen (p1, &buffer[2 * 259 * nofile]); if (++nofile >= 10) { write (2, "Too many args.\n", 15); exit (); } } } putpage () { register int lastcol, i, c; int j; if (ncol == 0) { i = 1; /* always starting on new line */ while (c = pgetc (0)) { if (i) /* new line */ { if ((queeze) && (c == '\n') && (line == ftext) && (!wasff) && (page > 1) ) { linum++; continue; } for (i = indent; i--;) put (' '); if (count) { putrd (linum); puts (" "); }; i = 0; }; switch (c) { case FF: wasff = 1; return; case '\n': linum++; for ((i = (blankl + 1)); i--;) { put ('\n'); if (line >= plength) { wasff = 0; return; } } i = 1; /* signal new line */ break; default: put (c); } } return; } colp[0] = colp[ncol]; if (mflg == 0) for (i = 1; i <= ncol; i++) { colp[i] = colp[i - 1]; for (j = margin; j < length; j++) while ((c = tpgetc (i)) != '\n') if (c == 0) break; } while (line < plength) { for (i = indent; i--;) put (' '); lastcol = colw + indent; for (i = 0; i < ncol; i++) { while ((c = pgetc (i)) && c != '\n') if (col < lastcol || tabc != 0) put (c); if (c == 0 && ntflg) return; if (tabc) put (tabc); else while (col < lastcol) put (' '); lastcol =+ colw; } while ((c = pgetc (ncol)) && c != '\n') put (c); put ('\n'); } } nexbuf () { register int n; register char *rbufp; rbufp = bufp; n = &buffer[BUFS] - rbufp; if (n > 512) n = 512; if ((n = read (file, rbufp, n)) <= 0) *rbufp = 0376; else { rbufp =+ n; if (rbufp >= &buffer[BUFS]) rbufp = buffer; *rbufp = 0375; } bufp = rbufp; } tpgetc (ai) { register char **p; register int c, i; i = ai; if (mflg) { if ((c = getc (&buffer[2 * 259 * i])) < 0) { if (isclosed[i] == 0) { isclosed[i] = 1; if (--nofile <= 0) return (0); } return ('\n'); } if (c == FF && ncol > 0) c = '\n'; return (c); } loop: c = **(p = &colp[i]) & 0377; if (c == 0375) { nexbuf (); c = **p & 0377; } if (c == 0376) return (0); (*p)++; if (*p >= &buffer[BUFS]) *p = buffer; if (c == 0) goto loop; return (c); } pgetc (i) { register int c; if (peekc) { c = peekc; peekc = 0; } else c = tpgetc (i); if (tabc) return (c); switch (c) { case '\t': icol++; if ((icol & 07) != 0) peekc = '\t'; return (' '); case '\n': icol = 0; break; } if (c >= ' ') icol++; return (c); } puts (as) char *as; { register int c; register char *s; if ((s = as) == 0) return; while (c = *s++) put (c); } putrd (an) { register int mag; for (mag = 1000; ((mag > 1) && (mag > an)); mag =/ 10) put (' '); putd (an); } putd (an) { register int a, n; n = an; if (a = n / 10) putd (a); put (n % 10 + '0'); } put (ac) { register c; int tspace; c = ac; if (tabc) { putcp (c); if (c == '\n') line++; return; } switch (c) { case ' ': nspace++; col++; return; /* case '\t': */ /* c = '~'; */ /* break; */ /* nspace =& 0177770; */ /* nspace =+ 010; */ /* col =& 0177770; */ /* col =+ 010; */ /* return; */ case '\n': nspace = 0; line++; col = 0; break; case 010: case 033: if (--col < 0) col = 0; if (--nspace < 0) nspace = 0; } if (rapflg && (col >= 84)) /* overflow */ { putcp ('\n'); line++; tspace = col - 84; col = nspace = 62; /* 84 - 22 */ sppr (); putcp ('*'); putcp ('*'); col =+ (2 + (nspace = tspace)); }; sppr (); if (c >= ' ') col++; putcp (c); } sppr () { register int c, ns; if ((c != '\n') && (c != FF)) while (nspace) { if ( (!tab2sp) && (nspace > 2) && (col > (ns = ((col - nspace) | 07))) ) { nspace = col - ns - 1; putcp ('\t'); } else { nspace--; putcp (' '); } } } getn (ap) char *ap; { register int n, c; register char *p; p = ap; n = 0; if ((*p < '0') || (*p > '9')) errrpt (p, "in parameter is supposed to be a number"); while ((c = *p++) >= '0' && c <= '9') n = n * 10 + c - '0'; return (n); } putcp (c) { if (page >= fpage) putchar (c); } int fout; errrpt (str1, str2) char *str1, *str2; { int ofout; flush (); ofout = fout; fout = 2; printf ("pr: \"%s\" %s.\n", str1, str2); flush (); fout = ofout; }; #define DOT "." #define DOTDOT ".." #define ROOT "/" #define DEBUG getpath (filestr) char *filestr; { int n; int gpfile; char *fulpath; struct statb { int devn, inum, i[18]; } x; struct entry { int jnum; char name[16]; } y; if (*filestr == '/') { fulpath = filestr; /* already a full name */ return (fulpath); } fulpath = alloc (1); /* got to start somewhere */ *fulpath = 0; setexit (); if (*fulpath) /* been here before ? */ { chdir (fulpath); /* get back to original dir */ rplstr (&fulpath, dircat ("", fulpath)); rplstr (&fulpath, dircat (fulpath, filestr)); return (fulpath); } while (1) { stat (DOT, &x); if ((gpfile = open (DOTDOT, 0)) < 0) reset (); do { if ((n = read (gpfile, &y, 16)) < 16) reset (); /* printf("y.name = %s\n",y.name); */ } while (y.jnum != x.inum); close (gpfile); /* printf("y.jnum = %d\n",y.jnum); */ if (y.jnum == 1) ckroot (y.name, &fulpath); rplstr (&fulpath, dircat (y.name, fulpath)); /* printf("fulpath = %s\n",fulpath); */ chdir (DOTDOT); } } ckroot (name, fulpath) char *name, **fulpath; { int i, n; int gpfile; struct statb { int devn, inum, i[18]; } x; struct entry { int jnum; char name[16]; } y; if ((n = stat (name, &x)) < 0) reset (); i = x.devn; if (((n = chdir (ROOT)) < 0) || ((gpfile = open (ROOT, 0)) < 0)) reset (); /* printf("fulpath = %s\n",*fulpath); */ while (1) { if ((n = read (gpfile, &y, 16)) < 16) reset (); if (y.jnum == 0) continue; if ((n = stat (y.name, &x)) < 0) reset (); if (x.devn != i) continue; x.i[0] =& 060000; if (x.i[0] != 040000) continue; if ((strequ (y.name, ".")) || (strequ (y.name, ".."))) break; /* printf("y.name = %s\n",y.name); */ rplstr (fulpath, dircat (y.name, *fulpath)); /* printf("fulpath = %s\n",*fulpath); */ } reset (); } /* */ /* Return the length of the given string. This length */ /* does not include the terminating null character. */ pstrlen (string) char *string; { register char *rstring; register int rlength; /* length of string */ rstring = string; for (rlength = 0; *rstring++ != 0; ++rlength); return (rlength); } /* */ /* Copy the given string to the given location. */ /* */ strcpy (from, to) char *from, *to; { register char *rfrom, *rto; rfrom = from; rto = to; while (*rto++ = *rfrom++); } /* */ /* Concatenate the first given string the the second */ /* given string. */ dircat (prefix, suffix) char *prefix, *suffix; { register char *rprefix, *rsuffix, *ptr; char *newstr; if ((ptr = newstr = alloc (pstrlen (rprefix = prefix) + pstrlen (rsuffix = suffix) + 2)) == -1) { write (1, "No more string storage!\n", 24); exit (); } while (*ptr++ = *rprefix++); ptr--; if (ptr[-1] != '/') *ptr++ = '/'; while (*ptr++ = *rsuffix++); return (newstr); } /* */ /* Determine if the two given strings are equivalent. */ /* */ strequ (str1, str2) char *str1, *str2; { register char *rstr1, *rstr2; rstr1 = str1; rstr2 = str2; while (*rstr1 == *rstr2++) if (*rstr1++ == 0) return (1); return (0); } rplstr (oldstr, newstr) char **oldstr, *newstr; { /* printf("oldstr = %s\nnewstr = %s\n",*oldstr,newstr); */ free (*oldstr); *oldstr = newstr; }