BSD 4_3_Net_1 release
[unix-history] / lpr / filters / lpf.c
/*
* Copyright (c) 1983 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
char copyright[] =
"@(#) Copyright (c) 1983 Regents of the University of California.\n\
All rights reserved.\n";
#endif /* not lint */
#ifndef lint
static char sccsid[] = "@(#)lpf.c 5.3 (Berkeley) 6/30/88";
#endif /* not lint */
/*
* 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>
#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 indent; /* indentation 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 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 'i':
indent = atoi(&cp[2]);
break;
case 'c': /* Print control chars */
literal++;
break;
}
} else
acctfile = cp;
}
for (cp = buf[0], limit = buf[MAXREP]; cp < limit; *cp++ = ' ');
done = 0;
while (!done) {
col = indent;
maxrep = -1;
linedone = 0;
while (!linedone) {
switch (ch = getc(p)) {
case EOF:
linedone = done = 1;
ch = '\n';
break;
case '\f':
lineno = length;
case '\n':
if (maxrep < 0)
maxrep = 0;
linedone = 1;
break;
case '\b':
if (--col < indent)
col = indent;
break;
case '\r':
col = indent;
break;
case '\t':
col = ((col - indent) | 07) + indent + 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 < ' ') {
col++;
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;
}
}
/* 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);
if (++lineno >= length) {
fflush(o);
npages++;
lineno = 0;
}
maxcol[i] = -1;
}
}
if (lineno) { /* be sure to end on a page boundary */
putchar('\f');
npages++;
}
if (name && acctfile && access(acctfile, 02) >= 0 &&
freopen(acctfile, "a", stdout) != NULL) {
printf("%7.2f\t%s:%s\n", (float)npages, host, name);
}
exit(0);
}