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

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

/*	vpsf.c	4.1	83/03/07	*/
/*
 * Versatec printer filter
 * 	make wide listings by placing pages side by side
 */

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

#define	LINELN 440
#define	PAGELN	86
#define	LMARG	10

int	pltmode[] = {VPLOT, 0, 0};
int	prtmode[] = {VPRINT, 0, 0};

char	screen[PAGELN][LINELN];
char	ul[PAGELN][LINELN];
char	anyul[PAGELN];
int	origin;
int	outline;
int	outcol;
int	npages;
int	width = 106;	/* page width */
int	length = 86;	/* page length */

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;

	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':
				if ((i = atoi(&argv[0][2])) > 0 && i <= PAGELN)
					length = i;
				break;

			case 'c':	/* Print input without throwing away
					   control chars and without putting
					   in page breaks. */
				literal++;
				break;
			}
		} else
			acctfile = *argv;
	}

	/*
	 * input file is open on file descriptor 0.
	 * vp should be open on file descriptor 1.
	 * The error log file is open on file descriptor 2.
	 */
	ioctl(1, VSETSTATE, prtmode);
	process();

	/*
	 * Put out an extra null to ensure versatec will get an even
	 * number of good characters.
	 */
	putchar('\0');

	if (ferror(stdout))
		exit(1);
	if (name && acctfile && access(acctfile, 02) >= 0 &&
	    freopen(acctfile, "a", stdout) != NULL) {
		if (host)
			printf("%7.2f\t%s:%s\n", (float)npages, host, name);
		else
			printf("%7.2f\t%s\n", (float)npages, name);
	}
	exit(0);
}

process()
{
	register int c;

	clear(screen, sizeof(screen));
	origin = LMARG;
	outcol = LMARG;
	cutmark(LMARG);

	while ((c = getchar()) != EOF)
		switch (c) {
		case ' ':
			outcol++;
			break;

		case '\t':
			outcol = ((outcol - origin) | 07) + origin + 1;
			break;

		case '\b':
			if (outcol > origin)
				outcol--;
			break;

		case '\r':
			outcol = origin; 
			break;

		case '\f':
			outline = length;
			/* fall into ... */

		case '\n':
			if (++outline >= length) {
				origin += width;
				if (origin + width > LINELN) {
					cutmark(origin);
					oflush();
					break;
				}
				outline = 0;
				cutmark(origin);
			}
			outcol = origin;
			break;

		default:
			outchar(c);
			break;
		}

	if (outline || origin != LMARG) {
		cutmark(origin + width);
		oflush();
	}
	printf("\n\n\n\n\n");
}

outchar(c)
	register int c;
{
	register char *cp;
	register int d;

	if (!literal && (c < 040 || c >= 0177))
		return;
	if (outcol >= LINELN) {
		outcol++;
		return;
	}
	cp = &screen[outline][outcol];
	d = *cp;
	if (d != ' ') {
		if (d == '_' || c == '_') {
			if (c == d) {
				outcol++;
				return;
			}
			if (anyul[outline] == 0)
				clear(ul[outline], LINELN);
			anyul[outline] = 1;
			ul[outline][outcol] = 0377;
			if (c == '_')
				c = d;
		}
	}
	*cp = c;
	outcol++;
}

oflush()
{
	register char *cp, *dp;
	register int i, j, oc, dc, c;

	npages++;
	putchar('\n');
	for (i = 0; i < length; i++)
		putline(i);
	for (i = 0; i < LINELN; i++)
		putchar('_');
	putchar('\n');
	clear(screen, sizeof(screen));
	outline = 0;
	outcol = LMARG;
	origin = LMARG;
	cutmark(LMARG);
}

clear(cp, i)
	register char *cp;
	register int i;
{
	if (i > 0)
		do
			*cp++ = ' ';
		while (--i);
}

cutmark(o)
	register int o;
{
	register int i;

	screen[0][o - LMARG] = '|';
	screen[1][o - LMARG] = '|';
	screen[length - 1][o - LMARG] = '|';
	screen[length - 2][o - LMARG] = '|';
}

putline(n)
	register int n;
{
	register char *cp;
	register int j;

	fwrite(screen[n], sizeof(char), sizeof(screen[0]), stdout);
	if (anyul[n]) {
		putchar('\n');
		putchar('\0');
		fflush(stdout);
		ioctl(1, VSETSTATE, pltmode);
		cp = ul[n];
		j = LINELN;
		do {
			putchar(*cp & 0377);
			putchar(*cp++ & 0377);
		} while (--j);
		fflush(stdout);
		ioctl(1, VSETSTATE, prtmode);
	} else
		putchar('\n');
	if (ferror(stdout))
		exit(1);
}