summaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--usr.sbin/lpr/common_source/common.c63
-rw-r--r--usr.sbin/lpr/common_source/displayq.c25
-rw-r--r--usr.sbin/lpr/common_source/lp.h7
-rw-r--r--usr.sbin/lpr/common_source/recvjob.c4
-rw-r--r--usr.sbin/lpr/common_source/rmjob.c6
-rw-r--r--usr.sbin/lpr/lpc/cmds.c3
-rw-r--r--usr.sbin/lpr/lpc/lpc.87
-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
-rw-r--r--usr.sbin/lpr/lpr/lpr.c2
-rw-r--r--usr.sbin/lpr/runqueue/printjob.c248
12 files changed, 421 insertions, 206 deletions
diff --git a/usr.sbin/lpr/common_source/common.c b/usr.sbin/lpr/common_source/common.c
index a5c6ee5..9b9244e 100644
--- a/usr.sbin/lpr/common_source/common.c
+++ b/usr.sbin/lpr/common_source/common.c
@@ -37,11 +37,12 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)common.c 8.2 (Berkeley) 1/21/94";
+static char sccsid[] = "@(#)common.c 8.5 (Berkeley) 4/28/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/stat.h>
+#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -105,18 +106,20 @@ char *printer; /* printer name */
/* host machine name */
char host[MAXHOSTNAMELEN];
char *from = host; /* client's machine name */
-int sendtorem; /* are we sending to a remote? */
+int remote; /* true if sending files to a remote host */
char *printcapdb[2] = { _PATH_PRINTCAP, 0 };
static int compar __P((const void *, const void *));
/*
- * Create a connection to the remote printer server.
+ * Create a TCP connection to host "rhost" at port "rport".
+ * If rport == 0, then use the printer service port.
* Most of this code comes from rcmd.c.
*/
int
-getport(rhost)
+getport(rhost, rport)
char *rhost;
+ int rport;
{
struct hostent *hp;
struct servent *sp;
@@ -129,16 +132,24 @@ getport(rhost)
*/
if (rhost == NULL)
fatal("no remote host to connect to");
- hp = gethostbyname(rhost);
- if (hp == NULL)
- fatal("unknown host %s", rhost);
- sp = getservbyname("printer", "tcp");
- if (sp == NULL)
- fatal("printer/tcp: unknown service");
bzero((char *)&sin, sizeof(sin));
- bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
- sin.sin_family = hp->h_addrtype;
- sin.sin_port = sp->s_port;
+ sin.sin_addr.s_addr = inet_addr(rhost);
+ if (sin.sin_addr.s_addr != INADDR_NONE)
+ sin.sin_family = AF_INET;
+ else {
+ hp = gethostbyname(rhost);
+ if (hp == NULL)
+ fatal("unknown host %s", rhost);
+ bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
+ sin.sin_family = hp->h_addrtype;
+ }
+ if (rport == 0) {
+ sp = getservbyname("printer", "tcp");
+ if (sp == NULL)
+ fatal("printer/tcp: unknown service");
+ sin.sin_port = sp->s_port;
+ } else
+ sin.sin_port = htons(rport);
/*
* Try connecting to the server.
@@ -241,8 +252,9 @@ getq(namelist)
* realloc the maximum size.
*/
if (++nitems > arraysz) {
+ arraysz *= 2;
queue = (struct queue **)realloc((char *)queue,
- (stbuf.st_size/12) * sizeof(struct queue *));
+ arraysz * sizeof(struct queue *));
if (queue == NULL)
goto errdone;
}
@@ -284,8 +296,8 @@ checkremote()
register struct hostent *hp;
static char errbuf[128];
- sendtorem = 0; /* assume printer is local */
- if (RM != (char *)NULL) {
+ remote = 0; /* assume printer is local */
+ if (RM != NULL) {
/* get the official name of the local host */
gethostname(name, sizeof(name));
name[sizeof(name)-1] = '\0';
@@ -310,10 +322,23 @@ checkremote()
* if the two hosts are not the same,
* then the printer must be remote.
*/
- if (strcmp(name, hp->h_name) != 0)
- sendtorem = 1;
+ if (strcasecmp(name, hp->h_name) != 0)
+ remote = 1;
}
- return (char *)0;
+ return NULL;
+}
+
+/* sleep n milliseconds */
+void
+delay(n)
+{
+ struct timeval tdelay;
+
+ if (n <= 0 || n > 10000)
+ fatal("unreasonable delay period (%d)", n);
+ tdelay.tv_sec = n / 1000;
+ tdelay.tv_usec = n * 1000 % 1000000;
+ (void) select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tdelay);
}
#if __STDC__
diff --git a/usr.sbin/lpr/common_source/displayq.c b/usr.sbin/lpr/common_source/displayq.c
index 59d3cc9..e0b6728 100644
--- a/usr.sbin/lpr/common_source/displayq.c
+++ b/usr.sbin/lpr/common_source/displayq.c
@@ -32,11 +32,12 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)displayq.c 8.1 (Berkeley) 6/6/93";
+static char sccsid[] = "@(#)displayq.c 8.4 (Berkeley) 4/28/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/stat.h>
+#include <sys/file.h>
#include <signal.h>
#include <fcntl.h>
@@ -124,7 +125,7 @@ displayq(format)
fatal("cannot examine spooling area\n");
if (stat(LO, &statb) >= 0) {
if (statb.st_mode & 0100) {
- if (sendtorem)
+ if (remote)
printf("%s: ", host);
printf("Warning: %s is down: ", printer);
fd = open(ST, O_RDONLY);
@@ -137,7 +138,7 @@ displayq(format)
putchar('\n');
}
if (statb.st_mode & 010) {
- if (sendtorem)
+ if (remote)
printf("%s: ", host);
printf("Warning: %s queue is turned off\n", printer);
}
@@ -150,8 +151,8 @@ displayq(format)
else {
/* get daemon pid */
cp = current;
- while ((*cp = getc(fp)) != EOF && *cp != '\n')
- cp++;
+ while ((i = getc(fp)) != EOF && i != '\n')
+ *cp++ = i;
*cp = '\0';
i = atoi(current);
if (i <= 0 || kill(i, 0) < 0)
@@ -159,13 +160,13 @@ displayq(format)
else {
/* read current file name */
cp = current;
- while ((*cp = getc(fp)) != EOF && *cp != '\n')
- cp++;
+ while ((i = getc(fp)) != EOF && i != '\n')
+ *cp++ = i;
*cp = '\0';
/*
* Print the status file.
*/
- if (sendtorem)
+ if (remote)
printf("%s: ", host);
fd = open(ST, O_RDONLY);
if (fd >= 0) {
@@ -191,7 +192,7 @@ displayq(format)
}
free(queue);
}
- if (!sendtorem) {
+ if (!remote) {
if (nitems == 0)
puts("no entries");
return;
@@ -215,7 +216,7 @@ displayq(format)
(void) strcpy(cp, user[i]);
}
strcat(line, "\n");
- fd = getport(RM);
+ fd = getport(RM, 0);
if (fd < 0) {
if (from != host)
printf("%s: ", host);
@@ -237,7 +238,7 @@ displayq(format)
void
warn()
{
- if (sendtorem)
+ if (remote)
printf("\n%s: ", host);
puts("Warning: no daemon present");
current[0] = '\0';
@@ -271,7 +272,7 @@ inform(cf)
if (rank < 0)
rank = 0;
- if (sendtorem || garbage || strcmp(cf, current))
+ if (remote || garbage || strcmp(cf, current))
rank++;
j = 0;
while (getline(cfp)) {
diff --git a/usr.sbin/lpr/common_source/lp.h b/usr.sbin/lpr/common_source/lp.h
index 4e3827d..b8f956f 100644
--- a/usr.sbin/lpr/common_source/lp.h
+++ b/usr.sbin/lpr/common_source/lp.h
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)lp.h 8.1 (Berkeley) 6/6/93
+ * @(#)lp.h 8.2 (Berkeley) 4/28/95
*/
@@ -82,7 +82,7 @@ extern char *printer; /* printer name */
/* host machine name */
extern char host[MAXHOSTNAMELEN];
extern char *from; /* client's machine name */
-extern int sendtorem; /* are we sending to a remote? */
+extern int remote; /* true if sending files to a remote host */
extern char *printcapdb[]; /* printcap database array */
/*
* Structure used for building a sorted list of control files.
@@ -104,7 +104,7 @@ void displayq __P((int));
void dump __P((char *, char *, int));
void fatal __P((const char *, ...));
int getline __P((FILE *));
-int getport __P((char *));
+int getport __P((char *, int));
int getq __P((struct queue *(*[])));
void header __P((void));
void inform __P((char *));
@@ -120,4 +120,5 @@ void rmremote __P((void));
void show __P((char *, char *, int));
int startdaemon __P((char *));
void warn __P((void));
+void delay __P((int));
__END_DECLS
diff --git a/usr.sbin/lpr/common_source/recvjob.c b/usr.sbin/lpr/common_source/recvjob.c
index e199af1..35f946f 100644
--- a/usr.sbin/lpr/common_source/recvjob.c
+++ b/usr.sbin/lpr/common_source/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);
diff --git a/usr.sbin/lpr/common_source/rmjob.c b/usr.sbin/lpr/common_source/rmjob.c
index 74a94d8..bdfe853 100644
--- a/usr.sbin/lpr/common_source/rmjob.c
+++ b/usr.sbin/lpr/common_source/rmjob.c
@@ -32,7 +32,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)rmjob.c 8.1 (Berkeley) 6/6/93";
+static char sccsid[] = "@(#)rmjob.c 8.2 (Berkeley) 4/28/95";
#endif /* not lint */
#include <sys/param.h>
@@ -292,7 +292,7 @@ rmremote()
register int i, rem;
char buf[BUFSIZ];
- if (!sendtorem)
+ if (!remote)
return; /* not sending to a remote machine */
/*
@@ -313,7 +313,7 @@ rmremote()
(void) sprintf(cp, " %d", requ[i]);
}
strcat(cp, "\n");
- rem = getport(RM);
+ rem = getport(RM, 0);
if (rem < 0) {
if (from != host)
printf("%s: ", host);
diff --git a/usr.sbin/lpr/lpc/cmds.c b/usr.sbin/lpr/lpc/cmds.c
index 193eac5..84c6a4d 100644
--- a/usr.sbin/lpr/lpc/cmds.c
+++ b/usr.sbin/lpr/lpc/cmds.c
@@ -39,7 +39,7 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)cmds.c 8.1 (Berkeley) 6/6/93";
+static char sccsid[] = "@(#)cmds.c 8.2 (Berkeley) 4/28/95";
#endif /* not lint */
/*
@@ -49,6 +49,7 @@ static char sccsid[] = "@(#)cmds.c 8.1 (Berkeley) 6/6/93";
#include <sys/param.h>
#include <sys/time.h>
#include <sys/stat.h>
+#include <sys/file.h>
#include <signal.h>
#include <fcntl.h>
diff --git a/usr.sbin/lpr/lpc/lpc.8 b/usr.sbin/lpr/lpc/lpc.8
index 63c4f0d..07e4aaf 100644
--- a/usr.sbin/lpr/lpc/lpc.8
+++ b/usr.sbin/lpr/lpc/lpc.8
@@ -29,9 +29,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)lpc.8 8.3 (Berkeley) 4/19/94
+.\" @(#)lpc.8 8.5 (Berkeley) 4/28/95
.\"
-.Dd April 19, 1994
+.Dd April 28, 1995
.Dt LPC 8
.Os BSD 4.2
.Sh NAME
@@ -117,6 +117,7 @@ to put new jobs in the spool queue.
.It Ic exit
.It Ic quit
Exit from lpc.
+.\" ne 1i
.Pp
.It Ic restart No {\ all\ |\ printer\ }
Attempt to start a new printer daemon.
@@ -165,7 +166,7 @@ abbreviation matches more than one command
.It Sy "?Invalid command"
no match was found
.It Sy "?Privileged command"
-command can be executed by root only
+you must be a member of group "operator" or root to execute this command
.El
.Sh HISTORY
The
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);
diff --git a/usr.sbin/lpr/lpr/lpr.c b/usr.sbin/lpr/lpr/lpr.c
index d1f0d8e..efff82a 100644
--- a/usr.sbin/lpr/lpr/lpr.c
+++ b/usr.sbin/lpr/lpr/lpr.c
@@ -44,7 +44,7 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)lpr.c 8.3 (Berkeley) 3/30/94";
+static char sccsid[] = "@(#)lpr.c 8.4 (Berkeley) 4/28/95";
#endif /* not lint */
/*
diff --git a/usr.sbin/lpr/runqueue/printjob.c b/usr.sbin/lpr/runqueue/printjob.c
index ae0b05a..ea2be9f 100644
--- a/usr.sbin/lpr/runqueue/printjob.c
+++ b/usr.sbin/lpr/runqueue/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
OpenPOWER on IntegriCloud