4.1cBSD/usr/src/usr.lib/lpr/vpf.c

Compare this file to the similar file:
Show the results in this format:

/*	vpf.c	4.1	83/03/07	*/
/*
 * Varian/Versatec printer filter
 */

#include <signal.h>
#include <stdio.h>
#include <sgtty.h>
#include <sys/vcmd.h>

#define LINELN 440

int	pltmode[] = {VPLOT, 0, 0};
int	prtmode[] = {VPRINT, 0, 0};
char	linebuf[LINELN+1];
char	ovbuf[LINELN];
int	ov;
int	lineno;
int	varian = 1;	/* default is the varian */
int	width = 132;	/* default line length */
int	length = 58;	/* 80 for 11" long paper */
int	npages = 1;
int	literal;
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 i;

	if (argv[0][strlen(argv[0])-1] == 'W') { /* Wide: the versatec. */
		varian = 0;
		width = 440;
		length = 66;
	}

	while (--argc) {
		if (*(*++argv) == '-') {
			switch (argv[0][1]) {
			case 'n':
				argc--;
				name = *++argv;
				break;

			case 'h':
				argc--;
				host = *++argv;
				break;

			case 'w':
				if ((i = atoi(&argv[0][2])) > 0 && i < LINELN)
					width = i;
				break;

			case 'l':
				length = atoi(&argv[0][2]);
				break;

			case 'c':	/* Print input without throwing away
					   control chars and without putting
					   in page breaks. */
				literal++;
				break;
			}
		} else
			acctfile = *argv;
	}
	/*
	 * device should be open on file descriptor 1.
	 */
	ioctl(1, VSETSTATE, prtmode);
	send();
	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);
}

send()
{
	register nskipped;

	lineno = 0;
	nskipped = 0;
	while (getline()) {
		if (!literal && varian && lineno==0 && linebuf[0]==0 && nskipped<3) {
			nskipped++;
			continue;
		}
		if (varian && lineno >= length) {
			nskipped = 0;
			putline(1);
			lineno = 0;
		} else {
			putline(0);
			if (literal)	/* Don't make page breaks if -l. */
				lineno = 1;
			else
				lineno++;
		}
	}
	if (varian && lineno)
		putchar('\f');	/* be sure to end on a page boundary */
	/*
	 * Put out an extra null to ensure varian will get an even
	 * number of good characters.
	 */
	putchar('\0');
	npages += (lineno + length - 1) / length;
}

getline()
{
	register col, maxcol, c;

	ov = 0;
	for (col = 0; col < width; col++) {
		linebuf[col] = ' ';
		ovbuf[col] = 0;
	}
	col = 0;
	maxcol = 0;
	for (;;) switch (c = getchar()) {

	case EOF:
		return(0);

	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 ((c = getchar()) == '\1') {
			putchar('\0');		/* make sure even # sent */
			fflush(stdout);
			kill(getpid(), SIGSTOP);
			ioctl(1, VSETSTATE, prtmode);
			continue;
		}
		ungetc(c, stdin);
		c = '\031';
		/* fall through if not stop sequence */
	default:
		if (c >= ' ' || literal) {
			if (col < width) {
				if (linebuf[col] == '_') {
					ovbuf[col] = 0377;
					ov++;
				}
				linebuf[col++] = c;
				if (col > maxcol)
					maxcol = col;
			} else
				col++;
		}
		continue;

	case ' ':
		col++;
		continue;

	case '\t':
		col = (col|07) + 1;
		continue;

	case '\r':
		col = 0;
		continue;

	case '_':
		if (col < width) {
			if (linebuf[col] != ' ') {
				ovbuf[col] = 0377;
				ov++;
			} else
				linebuf[col] = c;
			col++;
			if (col > maxcol)
				maxcol = col;
		} else
			col++;
		continue;

	case '\f':
		/* Fall through, treating a ff as a line break, too... */
		lineno = length;
	case '\n':
		if (maxcol > width)
			maxcol = width;
		linebuf[maxcol] = '\0';
		return(1);

	case '\b':
		if (col > 0)
			col--;
		continue;
	}
}

putline(ff)
int ff;
{
	register char *lp;
	register c, i;

	lp = linebuf;
	while (c = *lp++)
		putchar(c);
	if (ov) {
		putchar('\n');
		putchar('\0');
		fflush(stdout);
		ioctl(1, VSETSTATE, pltmode);
		for (lp = ovbuf, i = ov; ov--; ) {
			putchar(*lp & 0377);
			putchar(*lp++ & 0377);
		}
		if (ov & 1)
			putchar('\0');
		fflush(stdout);
		ioctl(1, VSETSTATE, prtmode);
	}
	if (ff) {
		putchar('\f');
		npages++;
	} else if (ov == 0)
		putchar('\n');
	if (ferror(stdout))
		exit(1);
}