⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 printjob.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	register int key;	register char *p;	int c;{	register scnwidth;	for (scnwidth = WIDTH; --scnwidth;) {		key <<= 1;		*p++ = key & 0200 ? c : BACKGND;	}	return (p);}#define TRC(q)	(((q)-' ')&0177)static voidscan_out(scfd, scsp, dlm)	int scfd, dlm;	char *scsp;{	register char *strp;	register nchrs, j;	char outbuf[LINELEN+1], *sp, c, cc;	int d, scnhgt;	extern char scnkey[][HEIGHT];	/* in lpdchar.c */	for (scnhgt = 0; scnhgt++ < HEIGHT+DROP; ) {		strp = &outbuf[0];		sp = scsp;		for (nchrs = 0; ; ) {			d = dropit(c = TRC(cc = *sp++));			if ((!d && scnhgt > HEIGHT) || (scnhgt <= DROP && d))				for (j = WIDTH; --j;)					*strp++ = BACKGND;			else				strp = scnline(scnkey[c][scnhgt-1-d], strp, cc);			if (*sp == dlm || *sp == '\0' || nchrs++ >= PW/(WIDTH+1)-1)				break;			*strp++ = BACKGND;			*strp++ = BACKGND;		}		while (*--strp == BACKGND && strp >= outbuf)			;		strp++;		*strp++ = '\n';			(void) write(scfd, outbuf, strp-outbuf);	}}static intdropit(c)	int c;{	switch(c) {	case TRC('_'):	case TRC(';'):	case TRC(','):	case TRC('g'):	case TRC('j'):	case TRC('p'):	case TRC('q'):	case TRC('y'):		return (DROP);	default:		return (0);	}}/* * sendmail --- *   tell people about job completion */static voidsendmail(user, bombed)	char *user;	int bombed;{	register int i;	int p[2], s;	register char *cp;	char buf[100];	struct stat stb;	FILE *fp;	pipe(p);	if ((s = dofork(DORETURN)) == 0) {		/* child */		dup2(p[0], 0);		for (i = 3; i < NOFILE; i++)			(void) close(i);		if ((cp = rindex(_PATH_SENDMAIL, '/')) != NULL)			cp++;	else			cp = _PATH_SENDMAIL;		sprintf(buf, "%s@%s", user, fromhost);		execl(_PATH_SENDMAIL, cp, buf, 0);		exit(0);	} else if (s > 0) {				/* parent */		dup2(p[1], 1);		printf("To: %s@%s\n", user, fromhost);		printf("Subject: printer job\n\n");		printf("Your printer job ");		if (*jobname)			printf("(%s) ", jobname);		switch (bombed) {		case OK:			printf("\ncompleted successfully\n");			break;		default:		case FATALERR:			printf("\ncould not be printed\n");			break;		case NOACCT:			printf("\ncould not be printed without an account on %s\n", host);			break;		case FILTERERR:			if (stat(tempfile, &stb) < 0 || stb.st_size == 0 ||			    (fp = fopen(tempfile, "r")) == NULL) {				printf("\nwas printed but had some errors\n");				break;			}			printf("\nwas printed but had the following errors:\n");			while ((i = getc(fp)) != EOF)				putchar(i);			(void) fclose(fp);			break;		case ACCESS:			printf("\nwas not printed because it was not linked to the original file\n");		}		fflush(stdout);		(void) close(1);	}	(void) close(p[0]);	(void) close(p[1]);	wait(&s);}/* * dofork - fork with retries on failure */static intdofork(action)	int action;{	register int i, pid;	for (i = 0; i < 20; i++) {		if ((pid = fork()) < 0) {			sleep((unsigned)(i*i));			continue;		}		/*		 * Child should run as daemon instead of root		 */		if (pid == 0)			setuid(DU);		return(pid);	}	syslog(LOG_ERR, "can't fork");	switch (action) {	case DORETURN:		return (-1);	default:		syslog(LOG_ERR, "bad action (%d) to dofork", action);		/*FALL THRU*/	case DOABORT:		exit(1);	}	/*NOTREACHED*/}/* * Kill child processes to abort current job. */static voidabortpr(signo)	int signo;{	(void) unlink(tempfile);	kill(0, SIGINT);	if (ofilter > 0)		kill(ofilter, SIGCONT);	while (wait(NULL) > 0)		;	exit(0);}static voidinit(){	int status;	char *s;	if ((status = cgetent(&bp, printcapdb, printer)) == -2) {		syslog(LOG_ERR, "can't open printer description file");		exit(1);	} else if (status == -1) {		syslog(LOG_ERR, "unknown printer: %s", printer);		exit(1);	} else if (status == -3)		fatal("potential reference loop detected in printcap file");	if (cgetstr(bp, "lp", &LP) == -1)		LP = _PATH_DEFDEVLP;	if (cgetstr(bp, "rp", &RP) == -1)		RP = DEFLP;	if (cgetstr(bp, "lo", &LO) == -1)		LO = DEFLOCK;	if (cgetstr(bp, "st", &ST) == -1)		ST = DEFSTAT;	if (cgetstr(bp, "lf", &LF) == -1)		LF = _PATH_CONSOLE;	if (cgetstr(bp, "sd", &SD) == -1)		SD = _PATH_DEFSPOOL;	if (cgetnum(bp, "du", &DU) < 0)		DU = DEFUID;	if (cgetstr(bp,"ff", &FF) == -1)		FF = DEFFF;	if (cgetnum(bp, "pw", &PW) < 0)		PW = DEFWIDTH;	sprintf(&width[2], "%d", PW);	if (cgetnum(bp, "pl", &PL) < 0)		PL = DEFLENGTH;	sprintf(&length[2], "%d", PL);	if (cgetnum(bp,"px", &PX) < 0)		PX = 0;	sprintf(&pxwidth[2], "%d", PX);	if (cgetnum(bp, "py", &PY) < 0)		PY = 0;	sprintf(&pxlength[2], "%d", PY);	cgetstr(bp, "rm", &RM);	if (s = checkremote())		syslog(LOG_WARNING, s);	cgetstr(bp, "af", &AF);	cgetstr(bp, "of", &OF);	cgetstr(bp, "if", &IF);	cgetstr(bp, "rf", &RF);	cgetstr(bp, "tf", &TF);	cgetstr(bp, "nf", &NF);	cgetstr(bp, "df", &DF);	cgetstr(bp, "gf", &GF);	cgetstr(bp, "vf", &VF);	cgetstr(bp, "cf", &CF);	cgetstr(bp, "tr", &TR);	RS = (cgetcap(bp, "rs", ':') != NULL);	SF = (cgetcap(bp, "sf", ':') != NULL);	SH = (cgetcap(bp, "sh", ':') != NULL);	SB = (cgetcap(bp, "sb", ':') != NULL);	HL = (cgetcap(bp, "hl", ':') != NULL);	RW = (cgetcap(bp, "rw", ':') != NULL);	cgetnum(bp, "br", &BR);	if (cgetnum(bp, "fc", &FC) < 0)		FC = 0;	if (cgetnum(bp, "fs", &FS) < 0)		FS = 0;	if (cgetnum(bp, "xc", &XC) < 0)		XC = 0;	if (cgetnum(bp, "xs", &XS) < 0)		XS = 0;	tof = (cgetcap(bp, "fo", ':') == NULL);}/* * Acquire line printer or remote connection. */static voidopenpr(){	register int i, n;	int resp;	if (!sendtorem && *LP) {		for (i = 1; ; i = i < 32 ? i << 1 : i) {			pfd = open(LP, RW ? O_RDWR : O_WRONLY);			if (pfd >= 0)				break;			if (errno == ENOENT) {				syslog(LOG_ERR, "%s: %m", LP);				exit(1);			}			if (i == 1)				pstatus("waiting for %s to become ready (offline ?)", printer);			sleep(i);		}		if (isatty(pfd))			setty();		pstatus("%s is ready and printing", printer);	} else if (RM != NULL) {		for (i = 1; ; i = i < 256 ? i << 1 : i) {			resp = -1;			pfd = getport(RM);			if (pfd >= 0) {				(void) sprintf(line, "\2%s\n", RP);				n = strlen(line);				if (write(pfd, line, n) == n &&				    (resp = response()) == '\0')					break;				(void) close(pfd);			}			if (i == 1) {				if (resp < 0)					pstatus("waiting for %s to come up", RM);				else {					pstatus("waiting for queue to be enabled on %s", RM);					i = 256;				}			}			sleep(i);		}		pstatus("sending to %s", RM);		remote = 1;	} else {		syslog(LOG_ERR, "%s: no line printer device or host name",			printer);		exit(1);	}	/*	 * Start up an output filter, if needed.	 */	if (!remote && OF) {		int p[2];		char *cp;		pipe(p);		if ((ofilter = dofork(DOABORT)) == 0) {	/* child */			dup2(p[0], 0);		/* pipe is std in */			dup2(pfd, 1);		/* printer is std out */			for (i = 3; i < NOFILE; i++)				(void) close(i);			if ((cp = rindex(OF, '/')) == NULL)				cp = OF;			else				cp++;			execl(OF, cp, width, length, 0);			syslog(LOG_ERR, "%s: %s: %m", printer, OF);			exit(1);		}		(void) close(p[0]);		/* close input side */		ofd = p[1];			/* use pipe for output */	} else {		ofd = pfd;		ofilter = 0;	}}struct bauds {	int	baud;	int	speed;} bauds[] = {	50,	B50,	75,	B75,	110,	B110,	134,	B134,	150,	B150,	200,	B200,	300,	B300,	600,	B600,	1200,	B1200,	1800,	B1800,	2400,	B2400,	4800,	B4800,	9600,	B9600,	19200,	EXTA,	38400,	EXTB,	0,	0};/* * setup tty lines. */static voidsetty(){	struct sgttyb ttybuf;	register struct bauds *bp;	if (ioctl(pfd, TIOCEXCL, (char *)0) < 0) {		syslog(LOG_ERR, "%s: ioctl(TIOCEXCL): %m", printer);		exit(1);	}	if (ioctl(pfd, TIOCGETP, (char *)&ttybuf) < 0) {		syslog(LOG_ERR, "%s: ioctl(TIOCGETP): %m", printer);		exit(1);	}	if (BR > 0) {		for (bp = bauds; bp->baud; bp++)			if (BR == bp->baud)				break;		if (!bp->baud) {			syslog(LOG_ERR, "%s: illegal baud rate %d", printer, BR);			exit(1);		}		ttybuf.sg_ispeed = ttybuf.sg_ospeed = bp->speed;	}	ttybuf.sg_flags &= ~FC;	ttybuf.sg_flags |= FS;	if (ioctl(pfd, TIOCSETP, (char *)&ttybuf) < 0) {		syslog(LOG_ERR, "%s: ioctl(TIOCSETP): %m", printer);		exit(1);	}	if (XC) {		if (ioctl(pfd, TIOCLBIC, &XC) < 0) {			syslog(LOG_ERR, "%s: ioctl(TIOCLBIC): %m", printer);			exit(1);		}	}	if (XS) {		if (ioctl(pfd, TIOCLBIS, &XS) < 0) {			syslog(LOG_ERR, "%s: ioctl(TIOCLBIS): %m", printer);			exit(1);		}	}}#if __STDC__#include <stdarg.h>#else#include <varargs.h>#endifvoid#if __STDC__pstatus(const char *msg, ...)#elsepstatus(msg, va_alist)	char *msg;        va_dcl#endif{	register int fd;	char buf[BUFSIZ];	va_list ap;#if __STDC__	va_start(ap, msg);#else	va_start(ap);#endif	umask(0);	fd = open(ST, O_WRONLY|O_CREAT, 0664);	if (fd < 0 || flock(fd, LOCK_EX) < 0) {		syslog(LOG_ERR, "%s: %s: %m", printer, ST);		exit(1);	}	ftruncate(fd, 0);	(void)vsnprintf(buf, sizeof(buf), msg, ap);	va_end(ap);	strcat(buf, "\n");	(void) write(fd, buf, strlen(buf));	(void) close(fd);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -