xref: /csrg-svn/usr.sbin/lpr/filters/lpf.c (revision 61841)
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