📄 printjob.c
字号:
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 + -