/* Paginator. * * The -d flag prints debugging info. */ #include "/lib/h/stat.h" #include "/lib/h/sgtty.h" #include "/lib/h/sig.h" /* Unix stuff */ #define INTCH 3 /* Interrupt chat - can't get this from /* the kernel, grrr. */ #define IFILE 0 #define OFILE 1 extern int errno; extern char *sys_errlist[]; struct sgargs sargs; struct inode iino; /* Command stuff */ int dflg; /* Debugging */ int pgsiz 22; /* Tuned for VT100 */ int ifile, tfile; /* Data */ #define BLKSIZ 512 #define MAXLIN 100 #define PAD 2 /* In case last char is a ^ */ char ibuf[BLKSIZ]; char *ibp; char *lst; int bfil; char obuf[MAXLIN + PAD]; char pipestr[] "--stdin--More?--"; char filestr[] "--%s--%d%%--More?--"; char eraser[] "\r "; /* */ main(argc, argv) char **argv; { char *arg, *ifnm; int cleanup(); argv++; for (argc--; (argc > 0); argc--) { arg = *argv; if (*arg++ != '-') break; argv++; switch (*arg) { case '?': printf("more {-d} \n"); exit(1); case 'd': dflg++; break; case 'p': pgsiz = atoi(*argv++); argc--; break; default: printf("Bad flag: %c", *arg); exit(1); } } signal(SIGINT, &cleanup); signal(SIGQIT, &cleanup); ttyset(argc); if (argc == 0) { ifnm = "stdin"; ifile = IFILE; bufinit(IFILE); prfile(ifnm, 0); } else { ifnm = *argv++; while (argc > 0) { dofile(ifnm); if (--argc > 0) printf("----------------%s----------------\n", (ifnm = *argv++)); } } ttyunset(); exit(0); } dofile(fnm) char *fnm; { ifile = open(fnm, 0); if (ifile < 0) serror("Cannot open input file"); bufinit(ifile); if (dflg) printf("input file %d\n", ifile); if (stat(fnm, &iino) < 0) serror("Can't stat input file"); prfile(fnm, iino.i_size1); close(ifile); } /* Print file, doing more processing as we go. * * For now, assumes file size can be contained in a short. */ prfile(fnm, len) char *fnm; int len; { register char *obp, c; int fnml, erlen, ermax, wval; int csiz, cline, nctl, i; int pos, perc; int hpc, lpc; char ic; fnml = strlen(fnm); erlen = (strlen(&filestr[0]) + fnml); ermax = strlen(&eraser[0]); if (erlen >= ermax) { printf("File name too long to erase\n"); erlen = ermax; } csiz = pgsiz; cline = 0; pos = 0; for (;;) { obp = &obuf[0]; nctl = 0; for (i = 0; (i < MAXLIN); i++) { c = rdch(); if (c == -1) break; if (c == '\n') { *obp++ = c; i++; break; } if ((c == '\t') || ((c >= 040) && (c != 0177))) { *obp++ = c; continue; } obp = prchar(c, obp); nctl++; i++; } wval = write(OFILE, &obuf[0], i); if (wval < 0) serror("Output file write failed"); if (dflg > 1) printf("write %d %d\n", i, wval); pos =+ (i - nctl); if ((++cline < csiz) && (c != -1)) continue; cline = 0; if (ifile == IFILE) printf(&pipestr[0]); else { lpc = (pos * 100); hpc = hmul (pos, 100); perc = ldiv(hpc, lpc, len); printf(&filestr[0], fnm, perc); } read(tfile, &obuf[0], MAXLIN); write(OFILE, &eraser[0], erlen); write(OFILE, "\r", 1); ic = obuf[0]; if (dflg) printf("prrd '%c' %d\n", ic, ic); if (ic == INTCH) cleanup(); if (c == -1) return; if (ic == ' ') { csiz = pgsiz; continue; } if ((ic == '\n') || (ic == '\r')) { csiz = 1; continue; } return; } } /* If the input is a pipe, open /dev/tty to be able to read from the * terminal. Otherwise, just use stdin. Do gtty/stty on stdout, since * it's 'always' attached to the terminal. */ ttyset(argc) { int sval; if (argc == 0) { tfile = open("/dev/tty", 0); if (tfile < 0) serror("Cannot open terminal"); } else tfile = IFILE; if (dflg) printf("terminal file %d\n", tfile); sval = gtty(OFILE, &sargs); if (sval < 0) serror("Cannot get terminal mode"); if (dflg) printf("tty %d %d %o\n", sargs.ispeed, sargs.ospeed, sargs.mode); sargs.mode =& ~SG_ECHO; sargs.mode =| SG_RAW; sval = stty(OFILE, &sargs); if (sval < 0) serror("Cannot set terminal mode"); } ttyunset() { int sval; sargs.mode =| SG_ECHO; sargs.mode =& ~SG_RAW; sval = stty(OFILE, &sargs); if (sval < 0) serror("Cannot reset terminal mode"); if (tfile != IFILE) close(tfile); } bufinit(f) { bfil = f; ibp = &ibuf[BLKSIZ]; lst = ibp; } rdch() { register char *cp; int len; char c; cp = ibp; if (ibp < lst) { c = *cp++; ibp = cp; return(c); } len = read(bfil, &ibuf[0], BLKSIZ); if (len < 0) serror("File read error"); if (dflg) printf("read %d\n", len); if (len == 0) return(-1); ibp = &ibuf[0]; lst = &ibuf[len]; return(rdch()); } prchar(c, aobp) char c, *aobp; { register char *obp; obp = aobp; if (c < 040) { *obp++ = '^'; *obp++ = (c + 0100); return(obp); } if (c == 0177) { *obp++ = '^'; *obp++ = '~'; return(obp); } printf("Bad char in prchar() - '%c' %o", c, c); cleanup(); } cleanup() { ttyunset(); printf("\n"); exit(1); } serror(errstr) char *errstr; { char *s; if (errstr != 0) printf("%s: ", errstr); s = sys_errlist[errno]; printf("%s", s); cleanup(); }