120200Sdist /*
2*61841Sbostic * Copyright (c) 1983, 1993
3*61841Sbostic * The Regents of the University of California. All rights reserved.
433680Sbostic *
542801Sbostic * %sccs.include.redist.c%
620200Sdist */
720200Sdist
813951Ssam #ifndef lint
956263Selan static char copyright[] =
10*61841Sbostic "@(#) Copyright (c) 1983, 1993\n\
11*61841Sbostic The Regents of the University of California. All rights reserved.\n";
1233680Sbostic #endif /* not lint */
1313951Ssam
1433680Sbostic #ifndef lint
15*61841Sbostic static char sccsid[] = "@(#)lpf.c 8.1 (Berkeley) 06/06/93";
1633680Sbostic #endif /* not lint */
1733680Sbostic
1813951Ssam /*
1910861Sralph * filter which reads the output of nroff and converts lines
2010861Sralph * with ^H's to overwritten lines. Thus this works like 'ul'
2110861Sralph * but is much better: it can handle more than 2 overwrites
2210861Sralph * and it is written with some style.
2310861Sralph * modified by kls to use register references instead of arrays
2410861Sralph * to try to gain a little speed.
253682Sroot */
2612174Sralph
2755471Sbostic #include <signal.h>
2855471Sbostic #include <unistd.h>
2955471Sbostic #include <stdlib.h>
303682Sroot #include <stdio.h>
313682Sroot
3210861Sralph #define MAXWIDTH 132
3310861Sralph #define MAXREP 10
343682Sroot
3510861Sralph char buf[MAXREP][MAXWIDTH];
3610861Sralph int maxcol[MAXREP] = {-1};
3711429Sralph int lineno;
3811429Sralph int width = 132; /* default line length */
3911429Sralph int length = 66; /* page length */
4012582Sralph int indent; /* indentation length */
4111429Sralph int npages = 1;
4211429Sralph int literal; /* print control characters */
4311429Sralph char *name; /* user's login name */
4411429Sralph char *host; /* user's machine name */
4511429Sralph char *acctfile; /* accounting information file */
463682Sroot
4755471Sbostic int
main(argc,argv)4811583Sralph main(argc, argv)
4911583Sralph int argc;
5011583Sralph char *argv[];
5111583Sralph {
5210861Sralph register FILE *p = stdin, *o = stdout;
5310861Sralph register int i, col;
5410861Sralph register char *cp;
5510861Sralph int done, linedone, maxrep;
5610861Sralph char ch, *limit;
573682Sroot
5811429Sralph while (--argc) {
5911429Sralph if (*(cp = *++argv) == '-') {
6011429Sralph switch (cp[1]) {
6111429Sralph case 'n':
6211429Sralph argc--;
6311429Sralph name = *++argv;
6411429Sralph break;
6511429Sralph
6611429Sralph case 'h':
6711429Sralph argc--;
6811429Sralph host = *++argv;
6911429Sralph break;
7011429Sralph
7111429Sralph case 'w':
7211429Sralph if ((i = atoi(&cp[2])) > 0 && i <= MAXWIDTH)
7311429Sralph width = i;
7411429Sralph break;
7511429Sralph
7611429Sralph case 'l':
7711429Sralph length = atoi(&cp[2]);
7811429Sralph break;
7911429Sralph
8012582Sralph case 'i':
8112582Sralph indent = atoi(&cp[2]);
8212582Sralph break;
8312582Sralph
8411429Sralph case 'c': /* Print control chars */
8511429Sralph literal++;
8611429Sralph break;
8711429Sralph }
8811429Sralph } else
8911429Sralph acctfile = cp;
9011429Sralph }
9111429Sralph
9210861Sralph for (cp = buf[0], limit = buf[MAXREP]; cp < limit; *cp++ = ' ');
9310861Sralph done = 0;
9410861Sralph
9510861Sralph while (!done) {
9612582Sralph col = indent;
9711903Sralph maxrep = -1;
9810861Sralph linedone = 0;
9910861Sralph while (!linedone) {
10010861Sralph switch (ch = getc(p)) {
10110861Sralph case EOF:
10210861Sralph linedone = done = 1;
10310861Sralph ch = '\n';
10410861Sralph break;
1053682Sroot
10610861Sralph case '\f':
10711429Sralph lineno = length;
10810861Sralph case '\n':
10911903Sralph if (maxrep < 0)
11011903Sralph maxrep = 0;
11110861Sralph linedone = 1;
11210861Sralph break;
1133682Sroot
11410861Sralph case '\b':
11512582Sralph if (--col < indent)
11612582Sralph col = indent;
11710861Sralph break;
1183682Sroot
11910861Sralph case '\r':
12012582Sralph col = indent;
12110861Sralph break;
12210861Sralph
12310861Sralph case '\t':
12412582Sralph col = ((col - indent) | 07) + indent + 1;
12510861Sralph break;
12610861Sralph
12711354Sralph case '\031':
12811354Sralph /*
12911354Sralph * lpd needs to use a different filter to
13011354Sralph * print data so stop what we are doing and
13111354Sralph * wait for lpd to restart us.
13211354Sralph */
13311354Sralph if ((ch = getchar()) == '\1') {
13411354Sralph fflush(stdout);
13511354Sralph kill(getpid(), SIGSTOP);
13611354Sralph break;
13711354Sralph } else {
13811354Sralph ungetc(ch, stdin);
13911354Sralph ch = '\031';
14011354Sralph }
14111354Sralph
14210861Sralph default:
14312582Sralph if (col >= width || !literal && ch < ' ') {
14412582Sralph col++;
14510861Sralph break;
14612582Sralph }
14710861Sralph cp = &buf[0][col];
14810861Sralph for (i = 0; i < MAXREP; i++) {
14910861Sralph if (i > maxrep)
15010861Sralph maxrep = i;
15110861Sralph if (*cp == ' ') {
15210861Sralph *cp = ch;
15310861Sralph if (col > maxcol[i])
15410861Sralph maxcol[i] = col;
15510861Sralph break;
15610861Sralph }
15710861Sralph cp += MAXWIDTH;
15810861Sralph }
15910861Sralph col++;
16010861Sralph break;
1613682Sroot }
1623682Sroot }
1633682Sroot
16410861Sralph /* print out lines */
16510861Sralph for (i = 0; i <= maxrep; i++) {
16610861Sralph for (cp = buf[i], limit = cp+maxcol[i]; cp <= limit;) {
16710861Sralph putc(*cp, o);
16810861Sralph *cp++ = ' ';
16910861Sralph }
17010861Sralph if (i < maxrep)
17110861Sralph putc('\r', o);
17210861Sralph else
17310861Sralph putc(ch, o);
17411903Sralph if (++lineno >= length) {
17518584Sralph fflush(o);
17611903Sralph npages++;
17711903Sralph lineno = 0;
17811903Sralph }
17910861Sralph maxcol[i] = -1;
18010150Sroot }
1813682Sroot }
18211429Sralph if (lineno) { /* be sure to end on a page boundary */
18311429Sralph putchar('\f');
18411429Sralph npages++;
18511429Sralph }
18611429Sralph if (name && acctfile && access(acctfile, 02) >= 0 &&
18711429Sralph freopen(acctfile, "a", stdout) != NULL) {
18811429Sralph printf("%7.2f\t%s:%s\n", (float)npages, host, name);
18911429Sralph }
19011429Sralph exit(0);
1913682Sroot }
192