Ultrix-3.1/src/cmd/olx/lpx.c

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


/**********************************************************************
 *   Copyright (c) Digital Equipment Corporation 1984, 1985, 1986.    *
 *   All Rights Reserved. 					      *
 *   Reference "/usr/src/COPYRIGHT" for applicable restrictions.      *
 **********************************************************************/

static char Sccsid[] = "@(#)lpx.c	3.0	4/22/86";
/*
 * ULTRIX-11 line printer exerciser program (lpx).
 * Fred Canter 10/31/82
 * Bill Burns 4/84
 *	added event flag code
 *
 ************************************************
 *                                              *
 * The line printer driver must be set up for   *
 * NO indent, so that all columns will be used. *
 *                                              *
 ************************************************
 *
 * This program exercises the lp11 line printer
 * and interface via the unix character
 * I/O mechanism. It prints test patterns that
 * must be visually verified by user.
 * If an error occurs a message is printed and the
 * print operation is retried at one minute intervals.
 * In order to save paper the program prints 12 pages
 * (11 pages if 80 column) and then "pauses" for a time,
 * specified by -p option. Durring the pause, non printing
 * characters are sent to the printer to simulate
 * constant use of the line printer and controller.
 * This program is a system level exerciser, it is NOT
 * intended to be a device diagnostic.
 *
 * USAGE:
 *
 *	lpx	-h	Print the help message.
 *
 *	lpx	-p#	Specify the paper saving "pause"
 *			time as (#) minutes.
 *			The default pause time is 15 minutes.
 *
 *	lpx	-p0	Specify continuous printing (no pause).
 *
 *	lpx	-p	Specify continuous pause (no printing).
 *
 */

#include <sys/param.h>	/* Don't matter which one */
#include <stdio.h>
#include <signal.h>

/*
 * Help message text
 */

char	*help[] =
{
	"\n\n\nUSAGE:",
	"\n\n\tlpx [-h] [-p#]",
	"\n\n\t-h\tPrint the help message.",
	"\n\n\t-p#\tSpecify the paper saving \"pause\"",
	"\n\t\tas (#) minutes, default is 15 minutes.",
	"\n\t\tSet pause time to zero for continuous printing.",
	"\n\t\tUse -p without (#) for continuous pause (no print).",
	"\n\n\n\n",
	0
};

time_t	timbuf;
time_t	stbuf;
char	lptpat;
char	lptsv;
char	lpform = 014;
char	lpbuf[134];
int	ptime = 15;
char	*lock = "/usr/spool/lpd/lock";

#ifdef EFLG
#include <sys/eflg.h>
char	*efpis;
char	*efids;
int	efbit;
int	efid;
long	evntflg();
int	zflag;
#else
char	*killfn = "lpx.kill";	/* name of kill file */
#endif

#define	NPASS	66 * 100	/* pass count - 100 pages @ 66 lines each */

int	lc;			/* line count */
int	termsig;
int	stopsig;

main(argc, argv)
char *argv[];
int argc;
{
	int	stop(), intr();
	FILE	*argf;
	char	*p;
	int	i, j;
	int	first, fd;

	signal(SIGTTOU, SIG_IGN);
	signal(SIGINT, SIG_IGN);
	signal(SIGTERM, intr);
	signal(SIGQUIT, stop);
	for(i=1; i<argc; i++) {	/* decode option arg's */
		p = argv[i];
		if(*p++ != '-') {
		argerr:
			fprintf(stderr,"\nlpx: bad arg\n");
			exit(1);
			}
		switch(*p) {
		case 'h':	/* print help message */
			for(j=0; help[j]; j++)
				printf("%s", help[j]);
			exit(0);
		case 'p':	/* pause time */
			p++;
			if(*p == 0) {
				ptime = -1;
				break;
			}
			ptime = atoi(p);
			ptime &= 077777; /* make it positive */
			if(ptime > 480)	/* 8 hours max */
				ptime = 480;
			break;
#ifdef EFLG
		case 'z':
			zflag++;
			i++;
			efpis = argv[i++];
			efids = argv[i];
			break;
#else
		case 'r':	/* kill file name */
			i++;
			killfn = argv[i];
			break;
#endif
		default:
			goto argerr;
		}
	}
	if(!zflag) {
		if(isatty(2)) {
		    fprintf(stderr, "lpx: detaching... type \"sysxstop\" to stop\n");
		    fflush(stderr);
		}
		if((i = fork()) == -1) {
			printf("lpx: Can't fork new copy !\n");
			exit(1);
		}
		if(i != 0)
			exit(0);
	}
	setpgrp(0, 31111);
/*
 * TEST DESCRIPTION
 *
 *  1.	Open the line printer (/dev/lp) and,
 *	do a form feed on the first open only.
 *
 *  2.	Print 5 pages of alternating ones and zeroes
 *	(U*U*) pattern. (4 pages if 80 column)
 *
 *  3.	Do a form feed.
 *
 *  4.	Print 3/4 page of the test pattern, then a form feed.
 *
 *  5.	Print 1/2 page of the test pattern, then a form feed.
 *
 *  6.	Print 1/4 page of the test pattern, then a form feed.
 *
 *  7.	Print 3 full pages of the test pattern.
 *
 *  8.	Print 5 lines short of a full page
 *	of the test pattern. The form feed on close
 *	should align the paper to the top of the next page.
 *
 *  9.	"pause", print non printing characters, for the
 *	specified time.
 *
 * 10	Close the line printer, should cause a form feed.
 *
 * 11.	Repeat steps 1 thru 10, until the cows come home.
 *
 */

	if(access(lock, 0) == 0) {
		fprintf(stderr, "\07\07\07");
		fprintf(stderr, "\nlpx: Printer in use by spooler,");
		fprintf(stderr, "\n     waiting for print job to finish !\n");
	}
	while(access(lock, 0) == 0)
		sleep(1);
	time(&timbuf);
	printf("\n\nLine printer exerciser started - %s", ctime(&timbuf));
	fflush(stdout);
#ifdef EFLG
	if(zflag) {
		efbit = atoi(efpis);
		efid = atoi(efids);
		evntflg(EFCLR, efid, (long)efbit);
	}
#else
	unlink(killfn);		/* tell SYSX lpx started */
#endif
lploop:
	fd = open("/dev/lp", 1);
	if(fd < 0) {
		fprintf(stderr, "\07\07\07");
		fprintf(stderr,"\nlpx: Can't open LP, check for LP off-line.");
		fprintf(stderr,"\n     Will retry at one minute intervals.\n");
		}
	while(fd < 0) {
		sleep(60);
		fd = open("/dev/lp", 1);
		}
	if(ptime == -1)
		goto noprnt;
	if(first == 0) {
/*
 * A dummy line must be printed in order to
 * make the first and only the first form feed
 * work. Not sure why !!!
 */
		lpbuf[0] = 040;
		lpbuf[1] = '\n';
		lpwrt(fd, 0);
		lpwrt(fd, 1);	/* form fead */
		first++;
		}
	for(i=1; i<133; i++) {
		p = &lpbuf;
		for(j=0; j<132; j++) {
			if(j < (132-i))
				*p++ = ' ';
			else {
				if(j & 1)
					*p++ = 'U';
				else
					*p++ = '*';
				}
			}
		*p++ = '\n';
		lpwrt(fd, 0);	/* print from lp buffer */
		}
	for(i=1; i<133; i++) {
		p = &lpbuf;
		for(j=0; j<132; j++) {
			if(j < (133-i)) {
				if(j & 1)
					*p++ = '*';
				else
					*p++ = 'U';
			} else
				*p++ = ' ';
			}
		*p++ = '\n';
		lpwrt(fd, 0);
		}
	lpwrt(fd, 1);	/* form feed */
	lptp(fd, 45);	/* 45 lines of test pat */
	lpwrt(fd, 1);
	lptp(fd, 30);
	lpwrt(fd, 1);
	lptp(fd, 15);
	lpwrt(fd, 1);
	lptp(fd, 235);
	if(ptime == 0) {	/* continuous printing */
		close(fd);
		if(lc >= NPASS)
			goto lp_eop;	/* end of pass */
		else
			goto lploop;
		}
noprnt:
	time(&stbuf);	/* time of pause start */
	p = &lpbuf;
	for(j=0; j<132; j++)
		*p++ = 0;
/*		*p++= ' ' + (i & 077);	 ascii char set */
/*
 * NULL is the only non printing character that works on all LP
 */
	*p++ = '\r';			/* NO PRINT */
ploop:
	if(lc >= NPASS)
		goto lp_eop;	/* end of pass */
	for(j=0; j<5; j++)
		lpwrt(fd, 0);
	sleep(1);
	time(&timbuf);	/* current time */
	if(ptime == -1) {	/* no print */
		if((timbuf - stbuf) < (15 * 60))
			goto ploop;
		else {
			close(fd);
			goto lploop;
		}
	}
	if((timbuf - stbuf) < (ptime * 60))
		goto ploop;
	close(fd);
	goto lploop;
lp_eop:				/* LPX end of pass */
	lc = 0;
	time(&timbuf);
	printf("\nLP exerciser end of pass - %s", ctime(&timbuf));
	fflush(stdout);
	if((i = fork()) == 0)
	lp_eop1:
		if(ptime == 0)
			goto lploop;
		else
			goto ploop;
	if(i == -1) {
		fprintf(stderr, "\nlpx: Can't fork new copy of lpx !\n");
		goto lp_eop1;	/* continue running this copy */
	}
	exit(0);
}

/*
 * Write to the line printer and  delay
 * and retry on error.
 * flag = 1 for form feed
 * flag = 0 for write from lp buffer.
 */

lpwrt(fd, flag)
{
	int err;

	lc++;		/* increment line count */
retry:
	termsig = 0;
	if(flag) {
		lptpat = 040;
		err = write(fd, &lpform, 1);
	} else
		err = write(fd, &lpbuf, 133);
#ifdef EFLG
	if(zflag) {			
		if(stopsig || checkflg())
			stop();
	} else {
		if(stopsig)
			stop();
	}
#else
	if(stopsig || (access(killfn, 0) == 0))
		stop();
#endif
	if(!termsig && (err < 0)) {
		printf("\nlpx: LP error, will retry at one minute intervals");
		fflush(stdout);
		sleep(60);
		goto retry;
			}
}

/*
 * Print the specified number (lc) of lines of
 * the test pattern.
 */

lptp(fd, lc)
{
	int	i,j;
	char	*p;

	for(i=0; i<lc; i++) {
		lptsv = lptpat;
		p = &lpbuf;
		for(j=0; j<132; j++) {
			*p++ = lptpat++;
			if(lptpat >= 0177)
				lptpat = 040;
			}
		*p++ = '\n';
		lpwrt(fd, 0);
		lptpat = lptsv + 1;
		if(lptpat >= 0177)
			lptpat = 040;
		}
}

intr()
{
	termsig++;
	signal(SIGTERM, intr);
#ifdef EFLG
	if(zflag) {
		if(!checkflg())
			return;
	} else
		return;
#else
	if(access(killfn, 0) != 0)
		return;
#endif
	stop();
}

stop()
{
	if(stopsig++)
		exit(0);
	signal(SIGQUIT, SIG_IGN);
	signal(SIGTERM, SIG_IGN);
	time(&timbuf);
	printf("\n\nLine printer exerciser stopped - %s", ctime(&timbuf));
	fflush(stdout);
#ifdef EFLG
	if(zflag)
		evntflg(EFCLR, efid, (long)efbit);
#else
	unlink(killfn);
#endif
	exit(0);
}

/*
 * Check eventflags to stop
 * return 0 for continuation
 * return 1 to stop
 */
extern int errno;
checkflg()
{
	union efrt {
		long	efret;
		struct {
			int	a;
			int	b;
		} retval
	} ef;
	errno = 0;
	ef.efret = evntflg(EFRD, efid, (long)0);
	if(errno && ef.retval.a == -1) {
		zflag = 0;
		return(0);
	}
	if(ef.efret & (1L << efbit))
		return(1);
	return(0);
}