X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/3a02162b5e25c68daafdaef92318d90fe17e3849..731697c1e362a933620b285d1697bd59b5ee9098:/usr/src/usr.sbin/lpr/lpd/printjob.c diff --git a/usr/src/usr.sbin/lpr/lpd/printjob.c b/usr/src/usr.sbin/lpr/lpd/printjob.c index c1aaa8018f..314e36dc42 100644 --- a/usr/src/usr.sbin/lpr/lpd/printjob.c +++ b/usr/src/usr.sbin/lpr/lpd/printjob.c @@ -1,4 +1,7 @@ -/* printjob.c 4.4 83/05/19 */ +#ifndef lint +static char sccsid[] = "@(#)printjob.c 4.15 (Berkeley) %G%"; +#endif + /* * printjob -- print jobs in the queue. * @@ -8,29 +11,31 @@ #include "lp.h" -#define DORETURN 0 /* absorb fork error */ -#define DOABORT 1 /* abort if dofork fails */ +#define DORETURN 0 /* absorb fork error */ +#define DOABORT 1 /* abort if dofork fails */ -char title[80]; /* ``pr'' title */ -FILE *cfp; /* control file */ -int pfd; /* printer file descriptor */ -int ofd; /* output filter file descriptor */ -int lfd; /* lock file descriptor */ -int pid; /* pid of lpd process */ -int prchild; /* id of pr process */ -int child; /* id of any filters */ -int ofilter; /* id of output filter, if any */ -int tof = 1; /* top of form; init true if open does ff */ -int remote; /* non zero if sending files to remote */ +static char title[80]; /* ``pr'' title */ +static FILE *cfp; /* control file */ +static int pfd; /* printer file descriptor */ +static int ofd; /* output filter file descriptor */ +static int lfd; /* lock file descriptor */ +static int pid; /* pid of lpd process */ +static int prchild; /* id of pr process */ +static int child; /* id of any filters */ +static int ofilter; /* id of output filter, if any */ +static int tof; /* true if at top of form */ +static int count; /* Number of files actually printed */ +static int remote; /* true if sending files to remote */ -extern banner(); /* big character printer */ -char logname[32]; /* user's login name */ -char jobname[32]; /* job or file name */ -char class[32]; /* classification field */ -char width[10] = "-w"; /* page width in characters */ -char length[10] = "-l"; /* page length in lines */ -char pxwidth[10] = "-x"; /* page width in pixels */ -char pxlength[10] = "-y"; /* page length in pixels */ +static char fromhost[32]; /* user's host machine */ +static char logname[32]; /* user's login name */ +static char jobname[100]; /* job or file name */ +static char class[32]; /* classification field */ +static char width[10] = "-w"; /* page width in characters */ +static char length[10] = "-l"; /* page length in lines */ +static char pxwidth[10] = "-x"; /* page width in pixels */ +static char pxlength[10] = "-y"; /* page length in pixels */ +static char indent[10] = "-i0"; /* indentation size in characters */ printjob() { @@ -42,12 +47,18 @@ printjob() extern int onintr(); init(); /* set up capabilities */ - (void) close(2); /* set up log file */ - (void) open(LF, FWRONLY|FAPPEND, 0); - dup2(2, 1); /* closes original connection */ + (void) write(1, "", 1); /* ack that daemon is started */ + (void) close(1); /* set up log file */ + (void) close(2); + if (open(LF, O_WRONLY|O_APPEND) < 0) + (void) open("/dev/null", O_WRONLY); + dup(1); pid = getpid(); /* for use with lprm */ setpgrp(0, pid); - sigset(SIGINT, onintr); + signal(SIGHUP, onintr); + signal(SIGINT, onintr); + signal(SIGQUIT, onintr); + signal(SIGTERM, onintr); /* * uses short form file names @@ -58,12 +69,18 @@ printjob() } if (stat(LO, &stb) == 0 && (stb.st_mode & 0100)) exit(0); /* printing disabled */ - if ((lfd = open(LO, FWRONLY|FCREATE|FTRUNCATE|FEXLOCK|FNBLOCK, 0664)) < 0) { + lfd = open(LO, O_WRONLY|O_CREAT, 0644); + if (lfd < 0) { + log("cannot create %s", LO); + exit(1); + } + if (flock(lfd, LOCK_EX|LOCK_NB) < 0) { if (errno == EWOULDBLOCK) /* active deamon present */ exit(0); - log("cannot create %s", LO); + log("cannot lock %s", LO); exit(1); } + ftruncate(lfd, 0); /* * write process id for others to know */ @@ -82,6 +99,10 @@ printjob() } if (nitems == 0) /* no work to do */ exit(0); + if (stb.st_mode & 01) { /* reset queue flag */ + if (fchmod(lfd, stb.st_mode & 0776) < 0) + log("cannot chmod %s", LO); + } openpr(); /* open printer or remote */ again: /* @@ -104,14 +125,23 @@ again: else i = sendit(q->q_name); /* - * Check to see if we are supposed to stop printing. - */ - if (stat(LO, &stb) == 0 && (stb.st_mode & 0100)) - goto done; - /* - * Check to see if we should try reprinting the job. + * Check to see if we are supposed to stop printing or + * if we are to rebuild the queue. */ - if (i > 0) { + if (fstat(lfd, &stb) == 0) { + if (stb.st_mode & 0100) + goto done; + if (stb.st_mode & 01) { + for (free((char *) q); nitems--; free((char *) q)) + q = *qp++; + if (fchmod(lfd, stb.st_mode & 0776) < 0) + log("cannot chmod %s", LO); + break; + } + } + if (i == 0) /* file ok and printed */ + count++; + else if (i > 0) { /* try reprinting the job */ log("restarting"); if (ofilter > 0) { kill(ofilter, SIGCONT); /* to be sure */ @@ -138,10 +168,12 @@ again: } if (nitems == 0) { /* no more work to do */ done: - if (!SF && !tof) - (void) write(ofd, FF, strlen(FF)); - if (TR != NULL) /* output trailer */ - (void) write(ofd, TR, strlen(TR)); + if (count > 0) { /* Files actually printed */ + if (!SF && !tof) + (void) write(ofd, FF, strlen(FF)); + if (TR != NULL) /* output trailer */ + (void) write(ofd, TR, strlen(TR)); + } exit(0); } goto again; @@ -162,6 +194,7 @@ static char ifonts[4][18] = { * Returns 0 if everthing was OK, 1 if we should try to reprint the job and * -1 if a non-recoverable error occured. */ +static printit(file) char *file; { @@ -194,12 +227,12 @@ printit(file) * T -- "title" for pr * H -- "host name" of machine where lpr was done * P -- "person" user's login name - * I -- "indent" changes default indents driver - * must have stty/gtty avaialble + * I -- "indent" amount to indent output * f -- "file name" name of text file to print * l -- "file name" text file with control chars * p -- "file name" text file to print with pr(1) * t -- "file name" troff(1) file to print + * n -- "file name" ditroff(1) file to print * d -- "file name" dvi file to print * g -- "file name" plot(1G) file to print * v -- "file name" plain raster file to print @@ -221,13 +254,13 @@ printit(file) while (getline(cfp)) switch (line[0]) { case 'H': - strcpy(host, line+1); + strcpy(fromhost, line+1); if (class[0] == '\0') - strcpy(class, line+1); + strncpy(class, line+1, sizeof(class)-1); continue; case 'P': - strcpy(logname, line+1); + strncpy(logname, line+1, sizeof(logname)-1); if (RS) { /* restricted */ if (getpwnam(logname) == (struct passwd *)0) { bombed = 2; @@ -239,20 +272,20 @@ printit(file) case 'J': if (line[1] != '\0') - strcpy(jobname, line+1); + strncpy(jobname, line+1, sizeof(jobname)-1); else strcpy(jobname, " "); continue; case 'C': if (line[1] != '\0') - strcpy(class, line+1); + strncpy(class, line+1, sizeof(class)-1); else if (class[0] == '\0') gethostname(class, sizeof (class)); continue; case 'T': /* header title for pr */ - strcpy(title, line+1); + strncpy(title, line+1, sizeof(title)-1); continue; case 'L': /* identification line */ @@ -269,7 +302,11 @@ printit(file) continue; case 'W': /* page width */ - strcpy(width+2, line+1); + strncpy(width+2, line+1, sizeof(width)-3); + continue; + + case 'I': /* indent amount */ + strncpy(indent+2, line+1, sizeof(indent)-3); continue; default: /* some file to print */ @@ -281,7 +318,6 @@ printit(file) title[0] = '\0'; continue; - case 'I': case 'N': case 'U': case 'M': @@ -307,17 +343,18 @@ pass2: */ (void) fclose(cfp); (void) unlink(file); - return(0); + return(bombed ? -1 : 0); } /* * Print a file. - * Set up the chain [ PR [ | {IF, OF} ] ] or {IF, TF, CF, VF}. + * Set up the chain [ PR [ | {IF, OF} ] ] or {IF, RF, TF, NF, DF, CF, VF}. * Return -1 if a non-recoverable error occured, 1 if a recoverable error and * 0 if all is well. * Note: all filters take stdin as the file, stdout as the printer, * stderr as the log file, and must not ignore SIGINT. */ +static print(format, file) int format; char *file; @@ -328,7 +365,7 @@ print(format, file) int pid, p[2], stopped = 0; union wait status; - if ((fi = open(file, FRDONLY, 0)) < 0) { + if ((fi = open(file, O_RDONLY)) < 0) { log("%s: open failure ", file, errno); return(-1); } @@ -381,14 +418,16 @@ print(format, file) prog = IF; av[1] = width; av[2] = length; - n = 3; + av[3] = indent; + n = 4; break; case 'l': /* like 'f' but pass control characters */ prog = IF; - av[1] = "-l"; + av[1] = "-c"; av[2] = width; av[3] = length; - n = 4; + av[4] = indent; + n = 5; break; case 'r': /* print a fortran text file */ prog = RF; @@ -397,6 +436,7 @@ print(format, file) n = 3; break; case 't': /* print troff output */ + case 'n': /* print ditroff output */ case 'd': /* print tex output */ (void) unlink(".railmag"); if ((fo = creat(".railmag", FILMOD)) < 0) { @@ -411,7 +451,7 @@ print(format, file) } (void) close(fo); } - prog = (format == 't') ? TF : DF; + prog = (format == 't') ? TF : (format == 'n') ? NF : DF; av[1] = pxwidth; av[2] = pxlength; n = 3; @@ -446,7 +486,7 @@ print(format, file) av[n++] = "-n"; av[n++] = logname; av[n++] = "-h"; - av[n++] = host; + av[n++] = fromhost; av[n++] = AF; av[n] = 0; fo = pfd; @@ -500,6 +540,7 @@ start: * Return -1 if a non-recoverable error occured, 1 if a recoverable error and * 0 if all is well. */ +static sendit(file) char *file; { @@ -568,6 +609,7 @@ sendit(file) * Send a data file to the remote machine and spool it. * Return positive if we should try resending. */ +static sendfile(type, file) char type, *file; { @@ -576,16 +618,20 @@ sendfile(type, file) char buf[BUFSIZ]; int sizerr; - if ((f = open(file, FRDONLY, 0)) < 0 || fstat(f, &stb) < 0) { + if ((f = open(file, O_RDONLY)) < 0 || fstat(f, &stb) < 0) { log("file (%s) open failure ", file, errno); return(-1); } (void) sprintf(buf, "%c%d %s\n", type, stb.st_size, file); amt = strlen(buf); - if (write(pfd, buf, amt) != amt) + if (write(pfd, buf, amt) != amt) { + (void) close(f); return(1); - if (noresponse()) + } + if (noresponse()) { + (void) close(f); return(1); + } sizerr = 0; for (i = 0; i < stb.st_size; i += BUFSIZ) { amt = BUFSIZ; @@ -593,8 +639,10 @@ sendfile(type, file) amt = stb.st_size - i; if (sizerr == 0 && read(f, buf, amt) != amt) sizerr = 1; - if (write(pfd, buf, amt) != amt) + if (write(pfd, buf, amt) != amt) { + (void) close(f); return(1); + } } (void) close(f); if (sizerr) { @@ -629,6 +677,7 @@ noresponse() /* * Banner printing stuff */ +static banner(name1, name2) char *name1, *name2; { @@ -669,7 +718,7 @@ banner(name1, name2) tof = 1; } -char * +static char * scnline(key, p, c) register char key, *p; char c; @@ -685,6 +734,7 @@ scnline(key, p, c) #define TRC(q) (((q)-' ')&0177) +static scan_out(scfd, scsp, dlm) int scfd; char *scsp, dlm; @@ -718,6 +768,7 @@ scan_out(scfd, scsp, dlm) } } +static dropit(c) char c; { @@ -742,6 +793,7 @@ dropit(c) * sendmail --- * tell people about job completion */ +static sendmail(bombed) int bombed; { @@ -760,12 +812,12 @@ sendmail(bombed) cp++; else cp = MAIL; - sprintf(buf, "%s@%s", line+1, host); + sprintf(buf, "%s@%s", line+1, fromhost); execl(MAIL, cp, buf, 0); exit(0); } else if (stat > 0) { /* parent */ dup2(p[1], 1); - printf("To: %s\n", line+1); + printf("To: %s@%s\n", line+1, fromhost); printf("Subject: printer job\n\n"); printf("Your printer job "); if (*jobname) @@ -793,6 +845,7 @@ sendmail(bombed) /* * dofork - fork with retries on failure */ +static dofork(action) int action; { @@ -825,8 +878,9 @@ dofork(action) } /* - * Cleanup child processes when a SIGINT is caught. + * Cleanup child processes when a signal is caught. */ +static onintr() { kill(0, SIGINT); @@ -837,17 +891,15 @@ onintr() exit(0); } +static init() { int status; - if ((status = pgetent(line, printer)) < 0) { - log("can't open printer description file"); - exit(1); - } else if (status == 0) { - log("unknown printer"); - exit(1); - } + if ((status = pgetent(line, printer)) < 0) + fatal("can't open printer description file"); + else if (status == 0) + fatal("unknown printer"); if ((LP = pgetstr("lp", &bp)) == NULL) LP = DEFDEVLP; if ((RP = pgetstr("rp", &bp)) == NULL) @@ -882,6 +934,7 @@ init() IF = pgetstr("if", &bp); RF = pgetstr("rf", &bp); TF = pgetstr("tf", &bp); + NF = pgetstr("nf", &bp); DF = pgetstr("df", &bp); GF = pgetstr("gf", &bp); VF = pgetstr("vf", &bp); @@ -901,18 +954,20 @@ init() XC = 0; if ((XS = pgetnum("xs")) < 0) XS = 0; + tof = !pgetflag("fo"); } /* * Acquire line printer or remote connection. */ +static openpr() { register int i, n; if (*LP) { for (i = 1; ; i = i < 32 ? i << 1 : i) { - pfd = open(LP, RW ? FRDWR : FWRONLY, 0); + pfd = open(LP, RW ? O_RDWR : O_WRONLY); if (pfd >= 0) break; if (errno == ENOENT) { @@ -1003,6 +1058,7 @@ struct bauds { /* * setup tty lines. */ +static setty() { struct sgttyb ttybuf; @@ -1026,10 +1082,8 @@ setty() } ttybuf.sg_ispeed = ttybuf.sg_ospeed = bp->speed; } - if (FC) - ttybuf.sg_flags &= ~FC; - if (FS) - ttybuf.sg_flags |= FS; + ttybuf.sg_flags &= ~FC; + ttybuf.sg_flags |= FS; if (ioctl(pfd, TIOCSETP, (char *)&ttybuf) < 0) { log("cannot set tty parameters"); exit(1); @@ -1057,8 +1111,10 @@ status(msg, a1, a2, a3) char buf[BUFSIZ]; umask(0); - if ((fd = open(ST, FWRONLY|FCREATE|FTRUNCATE|FEXLOCK, 0664)) < 0) + fd = open(ST, O_WRONLY|O_CREAT, 0664); + if (fd < 0 || flock(fd, LOCK_EX) < 0) fatal("cannot create status file"); + ftruncate(fd, 0); sprintf(buf, msg, a1, a2, a3); strcat(buf, "\n"); (void) write(fd, buf, strlen(buf));