summaryrefslogtreecommitdiffstats
path: root/usr.sbin/lpr/lpd
diff options
context:
space:
mode:
authorjoerg <joerg@FreeBSD.org>1996-05-05 22:40:51 +0000
committerjoerg <joerg@FreeBSD.org>1996-05-05 22:40:51 +0000
commit914cbcef2ca2238d808f510c1a2f084eb37952b6 (patch)
treea2c9a4d920a98c3865b5da51ea401d02253ceae3 /usr.sbin/lpr/lpd
parent8d1089fb9317c3fa275c4470e8a92463cc828758 (diff)
downloadFreeBSD-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.810
-rw-r--r--usr.sbin/lpr/lpd/printjob.c248
-rw-r--r--usr.sbin/lpr/lpd/recvjob.c4
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);
OpenPOWER on IntegriCloud