diff options
author | joerg <joerg@FreeBSD.org> | 1996-05-05 22:40:51 +0000 |
---|---|---|
committer | joerg <joerg@FreeBSD.org> | 1996-05-05 22:40:51 +0000 |
commit | 914cbcef2ca2238d808f510c1a2f084eb37952b6 (patch) | |
tree | a2c9a4d920a98c3865b5da51ea401d02253ceae3 /usr.sbin/lpr/lpd | |
parent | 8d1089fb9317c3fa275c4470e8a92463cc828758 (diff) | |
download | FreeBSD-src-914cbcef2ca2238d808f510c1a2f084eb37952b6.zip FreeBSD-src-914cbcef2ca2238d808f510c1a2f084eb37952b6.tar.gz |
Pull a bunch of fixes from the 4.4BSD-Lite2 branch. It's really
surprising how many trivial errors there have been... :-)
Some more cleanup is needed, but i'd like to separate the Lite2 changes
from other work, that's why this goes into a different commit.
People with serial printers should see whether i have broken the stty-
style printcap options (i hope not).
Inspired by: Sergey Shkonda <serg@bcs1.bcs.zaporizhzhe.ua>
Diffstat (limited to 'usr.sbin/lpr/lpd')
-rw-r--r-- | usr.sbin/lpr/lpd/lpd.8 | 10 | ||||
-rw-r--r-- | usr.sbin/lpr/lpd/printjob.c | 248 | ||||
-rw-r--r-- | usr.sbin/lpr/lpd/recvjob.c | 4 |
3 files changed, 175 insertions, 87 deletions
diff --git a/usr.sbin/lpr/lpd/lpd.8 b/usr.sbin/lpr/lpd/lpd.8 index f0b94b1..3eeee0d 100644 --- a/usr.sbin/lpr/lpd/lpd.8 +++ b/usr.sbin/lpr/lpd/lpd.8 @@ -247,13 +247,3 @@ but not under same administrative control. An .Nm daemon appeared in Version 6 AT&T UNIX. -.Sh BUGS -.Nm Lpd -tends to dump core if a request specifies a file format where no filter -is assigned. This may be particular annoying if somebody is not aware -of the file format specification, such as for a DOS client that always -specifies the -.Em v -format. The workaround is to assign a dummy filter for these file -formats, e. g. a -.Xr cat 1 . diff --git a/usr.sbin/lpr/lpd/printjob.c b/usr.sbin/lpr/lpd/printjob.c index ae0b05a..ea2be9f 100644 --- a/usr.sbin/lpr/lpd/printjob.c +++ b/usr.sbin/lpr/lpd/printjob.c @@ -39,7 +39,7 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)printjob.c 8.2 (Berkeley) 4/16/94"; +static char sccsid[] = "@(#)printjob.c 8.7 (Berkeley) 5/10/95"; #endif /* not lint */ @@ -96,7 +96,6 @@ static int ofilter; /* id of output filter, if any */ static int pfd; /* prstatic inter file descriptor */ static int pid; /* pid of lpd process */ static int prchild; /* id of pr process */ -static int remote; /* true if sending files to remote */ static char title[80]; /* ``pr'' title */ static int tof; /* true if at top of form */ @@ -118,6 +117,9 @@ static int dofork __P((int)); static int dropit __P((int)); static void init __P((void)); static void openpr __P((void)); +static void opennet __P((char *)); +static void opentty __P((void)); +static void openrem __P((void)); static int print __P((int, char *)); static int printit __P((char *)); static void pstatus __P((const char *, ...)); @@ -136,8 +138,8 @@ printjob() register struct queue *q, **qp; struct queue **queue; register int i, nitems; - long pidoff; - int count = 0; + off_t pidoff; + int errcnt, count = 0; init(); /* set up capabilities */ (void) write(1, "", 1); /* ack that daemon is started */ @@ -210,8 +212,9 @@ again: q = *qp++; if (stat(q->q_name, &stb) < 0) continue; + errcnt = 0; restart: - (void) lseek(lfd, (off_t)pidoff, 0); + (void) lseek(lfd, pidoff, 0); (void) sprintf(line, "%s\n", q->q_name); i = strlen(line); if (write(lfd, line, i) != i) @@ -240,12 +243,13 @@ again: } if (i == OK) /* file ok and printed */ count++; - else if (i == REPRINT) { /* try reprinting the job */ + else if (i == REPRINT && ++errcnt < 5) { + /* try reprinting the job */ syslog(LOG_INFO, "restarting %s", printer); if (ofilter > 0) { kill(ofilter, SIGCONT); /* to be sure */ (void) close(ofd); - while ((i = wait(0)) > 0 && i != ofilter) + while ((i = wait(NULL)) > 0 && i != ofilter) ; ofilter = 0; } @@ -254,6 +258,17 @@ again: syslog(LOG_WARNING, "%s: %s: %m", printer, LO); openpr(); /* try to reopen printer */ goto restart; + } else { + syslog(LOG_WARNING, "%s: job could not be %s (%s)", printer, + remote ? "sent to remote host" : "printed", q->q_name); + if (i == REPRINT) { + /* insure we don't attempt this job again */ + (void) unlink(q->q_name); + q->q_name[0] = 'd'; + (void) unlink(q->q_name); + if (logname[0]) + sendmail(logname, FATALERR); + } } } free((char *) queue); @@ -329,6 +344,7 @@ printit(file) * H -- "host name" of machine where lpr was done * P -- "person" user's login name * I -- "indent" amount to indent output + * R -- laser dpi "resolution" * 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) @@ -443,6 +459,7 @@ printit(file) case 'N': case 'U': case 'M': + case 'R': continue; } @@ -544,7 +561,6 @@ print(format, file) (void) close(n); execl(_PATH_PR, "pr", width, length, "-h", *title ? title : " ", "-F", 0); - openlog("lpd", LOG_PID, LOG_LPR); syslog(LOG_ERR, "cannot execl %s", _PATH_PR); exit(2); } @@ -623,6 +639,13 @@ print(format, file) printer, format); return(ERROR); } + if (prog == NULL) { + (void) close(fi); + syslog(LOG_ERR, + "%s: no filter found in printcap for format character '%c'", + printer, format); + return(ERROR); + } if ((av[0] = rindex(prog, '/')) != NULL) av[0]++; else @@ -641,8 +664,9 @@ print(format, file) ; if (status.w_stopval != WSTOPPED) { (void) close(fi); - syslog(LOG_WARNING, "%s: output filter died (%d)", - printer, status.w_retcode); + syslog(LOG_WARNING, + "%s: output filter died (retcode=%d termsig=%d)", + printer, status.w_retcode, status.w_termsig); return(REPRINT); } stopped++; @@ -658,7 +682,6 @@ start: for (n = 3; n < NOFILE; n++) (void) close(n); execv(prog, av); - openlog("lpd", LOG_PID, LOG_LPR); syslog(LOG_ERR, "cannot execv %s", prog); exit(2); } @@ -686,7 +709,7 @@ start: } if (!WIFEXITED(status)) { - syslog(LOG_WARNING, "%s: Daemon filter '%c' terminated (%d)", + syslog(LOG_WARNING, "%s: filter '%c' terminated (termsig=%d)", printer, format, status.w_termsig); return(ERROR); } @@ -696,11 +719,12 @@ start: return(OK); case 1: return(REPRINT); - default: - syslog(LOG_WARNING, "%s: Daemon filter '%c' exited (%d)", - printer, format, status.w_retcode); case 2: return(ERROR); + default: + syslog(LOG_WARNING, "%s: filter '%c' exited (retcode=%d)", + printer, format, status.w_retcode); + return(FILTERERR); } } @@ -1022,47 +1046,54 @@ sendmail(user, bombed) cp = _PATH_SENDMAIL; sprintf(buf, "%s@%s", user, fromhost); execl(_PATH_SENDMAIL, cp, buf, 0); - openlog("lpd", LOG_PID, LOG_LPR); - syslog(LOG_ERR, "cannot execl %s", _PATH_SENDMAIL); 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("Subject: %s printer job \"%s\"\n", printer, + *jobname ? jobname : "<unknown>"); + printf("Reply-To: root@%s\n\n", host); printf("Your printer job "); if (*jobname) printf("(%s) ", jobname); switch (bombed) { case OK: printf("\ncompleted successfully\n"); + cp = "OK"; break; default: case FATALERR: printf("\ncould not be printed\n"); + cp = "FATALERR"; break; case NOACCT: printf("\ncould not be printed without an account on %s\n", host); + cp = "NOACCT"; 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"); + printf("\nhad some errors and may not have printed\n"); break; } - printf("\nwas printed but had the following errors:\n"); + printf("\nhad the following errors and may not have printed:\n"); while ((i = getc(fp)) != EOF) putchar(i); (void) fclose(fp); + cp = "FILTERERR"; break; case ACCESS: printf("\nwas not printed because it was not linked to the original file\n"); + cp = "ACCESS"; } fflush(stdout); (void) close(1); } (void) close(p[0]); (void) close(p[1]); - wait(&s); + wait(NULL); + syslog(LOG_INFO, "mail sent to user %s about job %s on printer %s (%s)", + user, *jobname ? jobname : "<unknown>", printer, cp); } /* @@ -1073,7 +1104,6 @@ dofork(action) int action; { register int i, pid; - struct passwd *pwd; for (i = 0; i < 20; i++) { if ((pid = fork()) < 0) { @@ -1083,15 +1113,8 @@ dofork(action) /* * Child should run as daemon instead of root */ - if (pid == 0) { - if ((pwd = getpwuid(DU)) == NULL) { - syslog(LOG_ERR, "Can't lookup default uid in password file"); - break; - } - initgroups(pwd->pw_name, pwd->pw_gid); - setgid(pwd->pw_gid); + if (pid == 0) setuid(DU); - } return(pid); } syslog(LOG_ERR, "can't fork"); @@ -1202,60 +1225,27 @@ init() static void openpr() { - register int i, n; - int resp; + register int i; + char *cp; - 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; + if (!remote && *LP) { + if (cp = index(LP, '@')) + opennet(cp); + else + opentty(); + } else if (remote) { + openrem(); } 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 */ @@ -1269,7 +1259,6 @@ openpr() else cp++; execl(OF, cp, width, length, 0); - openlog("lpd", LOG_PID, LOG_LPR); syslog(LOG_ERR, "%s: %s: %m", printer, OF); exit(1); } @@ -1281,6 +1270,115 @@ openpr() } } +/* + * Printer connected directly to the network + * or to a terminal server on the net + */ +static void +opennet(cp) + char *cp; +{ + register int i; + int resp, port; + char save_ch; + + save_ch = *cp; + *cp = '\0'; + port = atoi(LP); + if (port <= 0) { + syslog(LOG_ERR, "%s: bad port number: %s", printer, LP); + exit(1); + } + *cp++ = save_ch; + + for (i = 1; ; i = i < 256 ? i << 1 : i) { + resp = -1; + pfd = getport(cp, port); + if (pfd < 0 && errno == ECONNREFUSED) + resp = 1; + else if (pfd >= 0) { + /* + * need to delay a bit for rs232 lines + * to stabilize in case printer is + * connected via a terminal server + */ + delay(500); + break; + } + if (i == 1) { + if (resp < 0) + pstatus("waiting for %s to come up", LP); + else + pstatus("waiting for access to printer on %s", LP); + } + sleep(i); + } + pstatus("sending to %s port %d", cp, port); +} + +/* + * Printer is connected to an RS232 port on this host + */ +static void +opentty() +{ + register int i; + int resp, port; + + for (i = 1; ; i = i < 32 ? i << 1 : i) { + pfd = open(LP, RW ? O_RDWR : O_WRONLY); + if (pfd >= 0) { + delay(500); + 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); +} + +/* + * Printer is on a remote host + */ +static void +openrem() +{ + register int i, n; + int resp, port; + + for (i = 1; ; i = i < 256 ? i << 1 : i) { + resp = -1; + pfd = getport(RM, 0); + 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); +} + struct bauds { int baud; int speed; @@ -1352,7 +1450,7 @@ setty() #include <varargs.h> #endif -void +static void #if __STDC__ pstatus(const char *msg, ...) #else diff --git a/usr.sbin/lpr/lpd/recvjob.c b/usr.sbin/lpr/lpd/recvjob.c index e199af1..35f946f 100644 --- a/usr.sbin/lpr/lpd/recvjob.c +++ b/usr.sbin/lpr/lpd/recvjob.c @@ -39,7 +39,7 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)recvjob.c 8.1 (Berkeley) 6/6/93"; +static char sccsid[] = "@(#)recvjob.c 8.2 (Berkeley) 4/27/95"; #endif /* not lint */ /* @@ -342,7 +342,7 @@ frecverr(msg, va_alist) va_dcl #endif { - extern char *fromb; + extern char fromb[]; va_list ap; #if __STDC__ va_start(ap, msg); |