fixes q order problems and temporary file names when inchar > 'z'.
[unix-history] / usr / src / usr.sbin / lpr / filters / lpf.c
index 0a02387..0149fd1 100644 (file)
-/*     lpf.c   4.4     83/01/05        */
-/*
- * lpf -- Line printer filter: handles underlines for those printers/
- *       device drivers that won't
+/*             lpf.c   4.7     83/03/07
+ *     filter which reads the output of nroff and converts lines
+ *     with ^H's to overwritten lines.  Thus this works like 'ul'
+ *     but is much better: it can handle more than 2 overwrites
+ *     and it is written with some style.
+ *     modified by kls to use register references instead of arrays
+ *     to try to gain a little speed.
  */
  */
-
 #include <stdio.h>
 #include <signal.h>
 
 #include <stdio.h>
 #include <signal.h>
 
-#define        LINELN  132
-
-char   linebuf[LINELN+2];
-int    ov;
-int    ff;
-char   ovbuf[LINELN];
-
-main()
-{
-       extern char _sobuf[BUFSIZ];
-
-       setbuf(stdout, _sobuf);
-       while (getline())
-               putline();
-       fflush(stdout);
-       if (ferror(stdout))
-               exit(1);
-       exit(0);
-}
-
-getline()
+#define MAXWIDTH  132
+#define MAXREP    10
+
+char   buf[MAXREP][MAXWIDTH];
+int    maxcol[MAXREP] = {-1};
+int    lineno;
+int    width = 132;    /* default line length */
+int    length = 66;    /* page length */
+int    npages = 1;
+int    literal;        /* print control characters */
+char   *name;          /* user's login name */
+char   *host;          /* user's machine name */
+char   *acctfile;      /* accounting information file */
+
+main(argc, argv)
+int argc;
+char *argv[];
 {
 {
-       register int col, maxcol, c;
-
-       ov = 0;
-       for (col = 0; col < LINELN; col++) {
-               linebuf[col] = ' ';
-               ovbuf[col] = 0;
-       }
-       col = 0;
-       maxcol = 0;
-       for (;;) switch (c = getchar()) {
-
-       case EOF:
-               return(0);
-
-       default:
-               if (c >= ' ') {
-                       if (col < LINELN) {
-                               if (linebuf[col] != ' ') {
-                                       ov++;
-                                       ovbuf[col] = c;
-                               } else
-                                       linebuf[col] = c;
-                               if (++col > maxcol)
-                                       maxcol = col;
+       register FILE *p = stdin, *o = stdout;
+       register int i, col;
+       register char *cp;
+       int done, linedone, maxrep;
+       char ch, *limit;
+
+       while (--argc) {
+               if (*(cp = *++argv) == '-') {
+                       switch (cp[1]) {
+                       case 'n':
+                               argc--;
+                               name = *++argv;
+                               break;
+
+                       case 'h':
+                               argc--;
+                               host = *++argv;
+                               break;
+
+                       case 'w':
+                               if ((i = atoi(&cp[2])) > 0 && i <= MAXWIDTH)
+                                       width = i;
+                               break;
+
+                       case 'l':
+                               length = atoi(&cp[2]);
+                               break;
+
+                       case 'c':       /* Print control chars */
+                               literal++;
+                               break;
                        }
                        }
-               }
-               continue;
-
-       case ' ':
-               col++;
-               continue;
-
-       case '\t':
-               col = (col|07) + 1;
-               if (col > maxcol)
-                       maxcol = col;
-               continue;
+               } else
+                       acctfile = cp;
+       }
 
 
-       case '\r':
+       for (cp = buf[0], limit = buf[MAXREP]; cp < limit; *cp++ = ' ');
+       done = 0;
+       
+       while (!done) {
                col = 0;
                col = 0;
-               continue;
-
-       case '\f':
-               ff = 1;         /* force form feed */
-       case '\n':
-               if (maxcol >= LINELN)
-                       maxcol = LINELN;
-               linebuf[maxcol] = 0;
-               return(1);
-
-       case '\b':
-               if (col > 0)
-                       col--;
-               continue;
-       }
-}
+               maxrep = 0;
+               linedone = 0;
+               while (!linedone) {
+                       switch (ch = getc(p)) {
+                       case EOF:
+                               linedone = done = 1;
+                               ch = '\n';
+                               break;
+
+                       case '\f':
+                               lineno = length;
+                       case '\n':
+                               if (++lineno >= length) {
+                                       npages++;
+                                       lineno = 0;
+                               }
+                               linedone = 1;
+                               break;
+
+                       case '\b':
+                               if (col-- < 0)
+                                       col = 0;
+                               break;
+
+                       case '\r':
+                               col = 0;
+                               break;
+
+                       case '\t':
+                               col = (col | 07) + 1;
+                               break;
+
+                       case '\031':
+                               /*
+                                * lpd needs to use a different filter to
+                                * print data so stop what we are doing and
+                                * wait for lpd to restart us.
+                                */
+                               if ((ch = getchar()) == '\1') {
+                                       fflush(stdout);
+                                       kill(getpid(), SIGSTOP);
+                                       break;
+                               } else {
+                                       ungetc(ch, stdin);
+                                       ch = '\031';
+                               }
+
+                       default:
+                               if (col >= width || !literal && ch < ' ')
+                                       break;
+                               cp = &buf[0][col];
+                               for (i = 0; i < MAXREP; i++) {
+                                       if (i > maxrep)
+                                               maxrep = i;
+                                       if (*cp == ' ') {
+                                               *cp = ch;
+                                               if (col > maxcol[i])
+                                                       maxcol[i] = col;
+                                               break;
+                                       }
+                                       cp += MAXWIDTH;
+                               }
+                               col++;
+                               break;
+                       }
+               }
 
 
-putline()
-{
-       register char c, *lp;
-
-       lp = linebuf;
-       while (c = *lp++)
-               output(c);
-       if (ov) {
-               putchar('\r');
-               lp = ovbuf;
-               while (ov) {
-                       if (c = *lp++) {
-                               output(c);
-                               ov--;
-                       } else
-                               output(' ');
+               /* print out lines */
+               for (i = 0; i <= maxrep; i++) {
+                       for (cp = buf[i], limit = cp+maxcol[i]; cp <= limit;) {
+                               putc(*cp, o);
+                               *cp++ = ' ';
+                       }
+                       if (i < maxrep)
+                               putc('\r', o);
+                       else
+                               putc(ch, o);
+                       maxcol[i] = -1;
                }
        }
                }
        }
-       putchar('\n');
-       if (ff) {
-               ff = 0;
+       if (lineno) {           /* be sure to end on a page boundary */
                putchar('\f');
                putchar('\f');
+               npages++;
        }
        }
-       if (ferror(stdout))
-               exit(1);
-}
-
-output(c)
-register char c;
-{
-
-       if (c == -1)
-               return;
-       c &= 0177;
-       if (c == 0177)
-               putchar('^'), c = '?';
-       if (c == 033)
-               c = '$';
-       if (c < ' ') switch (c) {
-
-       case '\n':
-               break;
-
-       case '\f':
-       case '\b':
-       case '\t':
-       case '\r':
-               break;
-
-       default:
-               putchar('^');
-               c |= 0100;
+       if (name && acctfile && access(acctfile, 02) >= 0 &&
+           freopen(acctfile, "a", stdout) != NULL) {
+               printf("%7.2f\t%s:%s\n", (float)npages, host, name);
        }
        }
-       putchar(c);
+       exit(0);
 }
 }