diff options
author | Thorsten Lockert <tholo@cvs.openbsd.org> | 1996-07-04 05:41:58 +0000 |
---|---|---|
committer | Thorsten Lockert <tholo@cvs.openbsd.org> | 1996-07-04 05:41:58 +0000 |
commit | 290fcc059d9fe17e7c22befa3c3615823eef59d6 (patch) | |
tree | 3d48e15674c15d481ba268cd05cf072f00a9aa21 /usr.sbin/lpr | |
parent | 73e06b23207009eef589976eeefda52b10cd5f05 (diff) |
Integrated 4.4Lite2 source
Fixed potential problem pointed out by bitblt
Diffstat (limited to 'usr.sbin/lpr')
-rw-r--r-- | usr.sbin/lpr/common_source/common.c | 63 | ||||
-rw-r--r-- | usr.sbin/lpr/common_source/displayq.c | 25 | ||||
-rw-r--r-- | usr.sbin/lpr/common_source/lp.h | 7 | ||||
-rw-r--r-- | usr.sbin/lpr/common_source/printcap.c | 38 | ||||
-rw-r--r-- | usr.sbin/lpr/common_source/rmjob.c | 6 | ||||
-rw-r--r-- | usr.sbin/lpr/lpc/cmds.c | 3 | ||||
-rw-r--r-- | usr.sbin/lpr/lpc/lpc.8 | 7 | ||||
-rw-r--r-- | usr.sbin/lpr/lpc/lpc.c | 45 | ||||
-rw-r--r-- | usr.sbin/lpr/lpd/lpd.c | 41 | ||||
-rw-r--r-- | usr.sbin/lpr/lpd/printjob.c | 235 | ||||
-rw-r--r-- | usr.sbin/lpr/lpd/recvjob.c | 2 | ||||
-rw-r--r-- | usr.sbin/lpr/lpq/lpq.1 | 12 | ||||
-rw-r--r-- | usr.sbin/lpr/lpq/lpq.c | 63 | ||||
-rw-r--r-- | usr.sbin/lpr/lpr/lpr.c | 5 |
14 files changed, 414 insertions, 138 deletions
diff --git a/usr.sbin/lpr/common_source/common.c b/usr.sbin/lpr/common_source/common.c index 7d3394be6fe..6d48d7b1768 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> @@ -109,7 +110,7 @@ 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 }; extern uid_t uid, euid; @@ -117,12 +118,14 @@ extern uid_t uid, euid; 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; @@ -135,16 +138,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. @@ -253,8 +264,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; } @@ -296,8 +308,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'; @@ -322,10 +334,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 6abaac86c86..7a1282b8ee4 100644 --- a/usr.sbin/lpr/common_source/displayq.c +++ b/usr.sbin/lpr/common_source/displayq.c @@ -33,11 +33,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> @@ -132,7 +133,7 @@ displayq(format) seteuid(uid); if (ret >= 0) { if (statb.st_mode & 0100) { - if (sendtorem) + if (remote) printf("%s: ", host); printf("Warning: %s is down: ", printer); seteuid(euid); @@ -147,7 +148,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); } @@ -162,8 +163,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) { @@ -178,13 +179,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); seteuid(euid); fd = open(ST, O_RDONLY); @@ -212,7 +213,7 @@ displayq(format) } free(queue); } - if (!sendtorem) { + if (!remote) { if (nitems == 0) puts("no entries"); return; @@ -236,7 +237,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); @@ -258,7 +259,7 @@ displayq(format) void warn() { - if (sendtorem) + if (remote) printf("\n%s: ", host); puts("Warning: no daemon present"); current[0] = '\0'; @@ -294,7 +295,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 8829f64b457..e60ee40b205 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 */ @@ -86,7 +86,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. @@ -108,7 +108,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 *)); @@ -124,4 +124,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/printcap.c b/usr.sbin/lpr/common_source/printcap.c index dbf688d1539..6eee7cd5c01 100644 --- a/usr.sbin/lpr/common_source/printcap.c +++ b/usr.sbin/lpr/common_source/printcap.c @@ -32,7 +32,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)printcap.c 8.1 (Berkeley) 6/6/93"; +static char sccsid[] = "@(#)printcap.c 8.2 (Berkeley) 4/28/95"; #endif /* not lint */ #include <sys/param.h> @@ -83,9 +83,10 @@ static char sccsid[] = "@(#)printcap.c 8.1 (Berkeley) 6/6/93"; static FILE *pfp = NULL; /* printcap data base file pointer */ static char *tbuf; static int hopcount; /* detect infinite loops in termcap, init 0 */ +static int tf; +char *tgetstr __P((char *, char **)); static char *tskip __P((char *)); -static char *tskip __P((char *bp)); static char *tdecode __P((char *, char **)); /* @@ -143,8 +144,18 @@ getprent(bp) void endprent() { - if (pfp != NULL) - fclose(pfp); + if (pfp != NULL) { + /* + * Can't use fclose here because on POSIX-compliant + * systems, fclose() causes the file pointer of the + * underlying file descriptor (which is possibly shared + * with a parent process) to be adjusted, and this + * reeks havoc in the parent because it doesn't know + * the file pointer has changed. + */ + (void) close(fileno(pfp)); + pfp = NULL; + } } /* @@ -160,10 +171,8 @@ tgetent(bp, name) register int c; register int i = 0, cnt = 0; char ibuf[BUFSIZ]; - int tf; tbuf = bp; - tf = 0; #ifndef V6 cp = getenv("TERMCAP"); /* @@ -191,16 +200,12 @@ tgetent(bp, name) */ tf = open(cp, 0); } +#endif if (tf == 0) { seteuid(euid); tf = open(_PATH_PRINTCAP, 0); seteuid(uid); } -#else - seteuid(euid); - tf = open(_PATH_PRINTCAP, 0); - seteuid(uid); -#endif if (tf < 0) return (-1); for (;;) { @@ -210,6 +215,7 @@ tgetent(bp, name) cnt = read(tf, ibuf, BUFSIZ); if (cnt <= 0) { close(tf); + tf = 0; return (0); } i = 0; @@ -234,8 +240,13 @@ tgetent(bp, name) * The real work for the match. */ if (tnamatch(name)) { - close(tf); - return(tnchktc()); + lseek(tf, 0L, 0); + i = tnchktc(); + if (tf) { + close(tf); + tf = 0; + } + return(i); } } } @@ -461,7 +472,6 @@ nextc: c -= '0', i = 2; do c <<= 3, c |= *str++ - '0'; - while (--i && isdigit(*str)); } break; } diff --git a/usr.sbin/lpr/common_source/rmjob.c b/usr.sbin/lpr/common_source/rmjob.c index cf9cf26b117..b3fd6daec92 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> @@ -316,7 +316,7 @@ rmremote() register int i, rem; char buf[BUFSIZ]; - if (!sendtorem) + if (!remote) return; /* not sending to a remote machine */ /* @@ -337,7 +337,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 0b9aff00e2d..b4394914cf8 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 a786adcad94..280a8b27479 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/lpc/lpc.c b/usr.sbin/lpr/lpc/lpc.c index b26728c3f62..fb755a0f84a 100644 --- a/usr.sbin/lpr/lpc/lpc.c +++ b/usr.sbin/lpr/lpc/lpc.c @@ -39,7 +39,7 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)lpc.c 8.1 (Berkeley) 6/6/93"; +static char sccsid[] = "@(#)lpc.c 8.3 (Berkeley) 4/28/95"; #endif /* not lint */ #include <sys/param.h> @@ -53,10 +53,16 @@ static char sccsid[] = "@(#)lpc.c 8.1 (Berkeley) 6/6/93"; #include <stdio.h> #include <ctype.h> #include <string.h> +#include <grp.h> +#include <sys/param.h> #include "lp.h" #include "lpc.h" #include "extern.h" +#ifndef LPR_OPER +#define LPR_OPER "operator" /* group name of lpr operators */ +#endif + /* * lpc -- line printer control program */ @@ -77,6 +83,7 @@ static void cmdscanner __P((int)); static struct cmd *getcmd __P((char *)); static void intr __P((int)); static void makeargv __P((void)); +static int ingroup __P((char *)); int main(argc, argv) @@ -101,7 +108,7 @@ main(argc, argv) printf("?Invalid command\n"); exit(1); } - if (c->c_priv && getuid()) { + if (c->c_priv && getuid() && ingroup(LPR_OPER) == 0) { printf("?Privileged command\n"); exit(1); } @@ -157,7 +164,7 @@ cmdscanner(top) printf("?Invalid command\n"); continue; } - if (c->c_priv && getuid()) { + if (c->c_priv && getuid() && ingroup(LPR_OPER) == 0) { printf("?Privileged command\n"); continue; } @@ -166,7 +173,7 @@ cmdscanner(top) longjmp(toplevel, 0); } -struct cmd * +static struct cmd * getcmd(name) register char *name; { @@ -282,3 +289,33 @@ help(argc, argv) c->c_name, c->c_help); } } + +/* + * return non-zero if the user is a member of the given group + */ +static int +ingroup(grname) + char *grname; +{ + static struct group *gptr=NULL; + static gid_t groups[NGROUPS]; + register gid_t gid; + register int i; + + if (gptr == NULL) { + if ((gptr = getgrnam(grname)) == NULL) { + fprintf(stderr, "Warning: unknown group '%s'\n", + grname); + return(0); + } + if (getgroups(NGROUPS, groups) < 0) { + perror("getgroups"); + exit(1); + } + } + gid = gptr->gr_gid; + for (i = 0; i < NGROUPS; i++) + if (gid == groups[i]) + return(1); + return(0); +} diff --git a/usr.sbin/lpr/lpd/lpd.c b/usr.sbin/lpr/lpd/lpd.c index 05c855d85f0..47c4d8b9551 100644 --- a/usr.sbin/lpr/lpd/lpd.c +++ b/usr.sbin/lpr/lpd/lpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lpd.c,v 1.3 1996/05/05 16:13:58 deraadt Exp $ */ +/* $OpenBSD: lpd.c,v 1.4 1996/07/04 05:41:54 tholo Exp $ */ /* $NetBSD: lpd.c,v 1.7 1996/04/24 14:54:06 mrg Exp $ */ /* @@ -42,7 +42,7 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)lpd.c 8.4 (Berkeley) 4/17/94"; +static char sccsid[] = "@(#)lpd.c 8.7 (Berkeley) 5/10/95"; #endif /* not lint */ /* @@ -80,6 +80,7 @@ static char sccsid[] = "@(#)lpd.c 8.4 (Berkeley) 4/17/94"; #include <sys/socket.h> #include <sys/un.h> #include <sys/stat.h> +#include <sys/file.h> #include <netinet/in.h> #include <netdb.h> @@ -106,6 +107,7 @@ static void mcleanup __P((int)); static void doit __P((void)); static void startup __P((void)); static void chkhost __P((struct sockaddr_in *)); +static int ckqueue __P((char *)); uid_t uid, euid; @@ -176,11 +178,13 @@ main(argc, argv) */ startup(); (void) unlink(_PATH_SOCKETNAME); + (void) umask(07); funix = socket(AF_UNIX, SOCK_STREAM, 0); if (funix < 0) { syslog(LOG_ERR, "socket: %m"); exit(1); } + (void) umask(0); #define mask(s) (1 << ((s) - 1)) omask = sigblock(mask(SIGHUP)|mask(SIGINT)|mask(SIGQUIT)|mask(SIGTERM)); signal(SIGHUP, mcleanup); @@ -436,11 +440,17 @@ startup() * Restart the daemons. */ while (cgetnext(&buf, printcapdb) > 0) { + if (ckqueue(buf) <= 0) { + free(buf); + continue; /* no work to do for this printer */ + } for (cp = buf; *cp; cp++) if (*cp == '|' || *cp == ':') { *cp = '\0'; break; } + if (lflag) + syslog(LOG_INFO, "work for %s", buf); if ((pid = fork()) < 0) { syslog(LOG_WARNING, "startup: cannot fork"); mcleanup(0); @@ -449,8 +459,35 @@ startup() printer = buf; cgetclose(); printjob(); + /* NOTREACHED */ } + else free(buf); + } +} + +/* + * Make sure there's some work to do before forking off a child + */ +static int +ckqueue(cap) + char *cap; +{ + register struct dirent *d; + DIR *dirp; + char *spooldir; + + if (cgetstr(cap, "sd", &spooldir) == -1) + spooldir = _PATH_DEFSPOOL; + if ((dirp = opendir(spooldir)) == NULL) + return (-1); + while ((d = readdir(dirp)) != NULL) { + if (d->d_name[0] != 'c' || d->d_name[1] != 'f') + continue; /* daemon control files only */ + closedir(dirp); + return (1); /* found something */ } + closedir(dirp); + return (0); } #define DUMMY ":nobody::" diff --git a/usr.sbin/lpr/lpd/printjob.c b/usr.sbin/lpr/lpd/printjob.c index 484657db437..445e32769d5 100644 --- a/usr.sbin/lpr/lpd/printjob.c +++ b/usr.sbin/lpr/lpd/printjob.c @@ -1,4 +1,4 @@ -/* $OpenBSD: printjob.c,v 1.3 1996/06/28 18:04:18 deraadt Exp $ */ +/* $OpenBSD: printjob.c,v 1.4 1996/07/04 05:41:55 tholo Exp $ */ /* $NetBSD: printjob.c,v 1.9 1996/04/30 00:07:00 jtc Exp $ */ /* @@ -42,7 +42,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 */ @@ -57,6 +57,7 @@ static char sccsid[] = "@(#)printjob.c 8.2 (Berkeley) 4/16/94"; #include <sys/wait.h> #include <sys/stat.h> #include <sys/types.h> +#include <sys/file.h> #include <pwd.h> #include <unistd.h> @@ -98,7 +99,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 */ @@ -120,6 +120,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 *, ...)); @@ -139,8 +142,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 */ @@ -213,8 +216,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) @@ -243,12 +247,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; } @@ -257,6 +262,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); @@ -332,6 +348,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) @@ -446,6 +463,7 @@ printit(file) case 'N': case 'U': case 'M': + case 'R': continue; } @@ -624,6 +642,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 @@ -642,8 +667,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++; @@ -686,7 +712,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 +722,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); } } @@ -1026,41 +1053,50 @@ sendmail(user, bombed) } 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); } /* @@ -1210,54 +1246,22 @@ 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. */ @@ -1288,6 +1292,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; @@ -1403,7 +1516,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 8c51723cd8b..0b4156c19aa 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 */ /* diff --git a/usr.sbin/lpr/lpq/lpq.1 b/usr.sbin/lpr/lpq/lpq.1 index 50e1474121e..d5eadc581f8 100644 --- a/usr.sbin/lpr/lpq/lpq.1 +++ b/usr.sbin/lpr/lpq/lpq.1 @@ -29,9 +29,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)lpq.1 8.1 (Berkeley) 6/6/93 +.\" @(#)lpq.1 8.2 (Berkeley) 4/28/95 .\" -.Dd June 6, 1993 +.Dd April 28, 1995 .Dt LPQ 1 .Os BSD 4.2 .Sh NAME @@ -39,6 +39,7 @@ .Nd spool queue examination program .Sh SYNOPSIS .Nm lpq +.OP Fl a .Op Fl l .Op Fl P Ns Ar printer .Op job # ... @@ -67,6 +68,9 @@ names or job numbers to filter out only those jobs of interest. Information about each of the files comprising the job entry is printed. Normally, only as much information as will fit on one line is displayed. +.It Fl a +Report on the local queues for all printers, +rather than just the specified printer. .El .Pp For each job submitted (i.e. invocation of @@ -102,7 +106,7 @@ If the following environment variable exists, it is used by Specifies an alternate default printer. .El .Sh FILES -.Bl -tag -width /usr/share/misc/termcap -compact +.Bl -tag -width "/var/spool/*/lock" -compact .It Pa /etc/printcap To determine printer characteristics. .It Pa /var/spool/* @@ -111,8 +115,6 @@ The spooling directory, as determined from printcap. Control files specifying jobs. .It Pa /var/spool/*/lock The lock file to obtain the currently active job. -.It Pa /usr/share/misc/termcap -For manipulating the screen for repeated display. .El .Sh SEE ALSO .Xr lpr 1 , diff --git a/usr.sbin/lpr/lpq/lpq.c b/usr.sbin/lpr/lpq/lpq.c index 02d25b3ca39..828e61badb5 100644 --- a/usr.sbin/lpr/lpq/lpq.c +++ b/usr.sbin/lpr/lpq/lpq.c @@ -39,14 +39,15 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)lpq.c 8.1 (Berkeley) 6/6/93"; +static char sccsid[] = "@(#)lpq.c 8.3 (Berkeley) 5/10/95"; #endif /* not lint */ /* * Spool Queue examination program * - * lpq [-l] [-Pprinter] [user...] [job...] + * lpq [-a] [-l] [-Pprinter] [user...] [job...] * + * -a show all non-null queues on the local machine * -l long output * -P used to identify printer as per lpr/lprm */ @@ -61,6 +62,7 @@ static char sccsid[] = "@(#)lpq.c 8.1 (Berkeley) 6/6/93"; #include <ctype.h> #include "lp.h" #include "lp.local.h" +#include "pathnames.h" int requ[MAXREQUESTS]; /* job number of spool entries */ int requests; /* # of spool requests */ @@ -69,6 +71,7 @@ int users; /* # of users in user array */ uid_t uid, euid; +static int ckqueue __P((char *)); void usage __P((void)); int @@ -78,7 +81,8 @@ main(argc, argv) { extern char *optarg; extern int optind; - int ch, lflag; /* long output option */ + int ch, aflag, lflag; + char *buf, *cp; euid = geteuid(); uid = getuid(); @@ -90,9 +94,12 @@ main(argc, argv) } openlog("lpd", 0, LOG_LPR); - lflag = 0; - while ((ch = getopt(argc, argv, "lP:")) != EOF) + aflag = lflag = 0; + while ((ch = getopt(argc, argv, "alP:")) != EOF) switch((char)ch) { + case 'a': + ++aflag; + break; case 'l': /* long output */ ++lflag; break; @@ -104,7 +111,7 @@ main(argc, argv) usage(); } - if (printer == NULL) { + if (!aflag && printer == NULL) { char *p; printer = DEFLP; @@ -124,13 +131,53 @@ main(argc, argv) user[users++] = *argv; } - displayq(lflag); + if (aflag) { + while (cgetnext(&buf, printcapdb) > 0) { + if (ckqueue(buf) <= 0) { + free(buf); + continue; /* no jobs */ + } + for (cp = buf; *cp; cp++) + if (*cp == '|' || *cp == ':') { + *cp = '\0'; + break; + } + printer = buf; + printf("%s:\n", printer); + displayq(lflag); + free(buf); + printf("\n"); + } + } else + displayq(lflag); exit(0); } +static int +ckqueue(cap) + char *cap; +{ + register struct dirent *d; + DIR *dirp; + char *spooldir; + + if (cgetstr(cap, "sd", &spooldir) == -1) + spooldir = _PATH_DEFSPOOL; + if ((dirp = opendir(spooldir)) == NULL) + return (-1); + while ((d = readdir(dirp)) != NULL) { + if (d->d_name[0] != 'c' || d->d_name[1] != 'f') + continue; /* daemon control files only */ + closedir(dirp); + return (1); /* found something */ + } + closedir(dirp); + return (0); +} + void usage() { - puts("usage: lpq [-l] [-Pprinter] [user ...] [job ...]"); + puts("usage: lpq [-a] [-l] [-Pprinter] [user ...] [job ...]"); exit(1); } diff --git a/usr.sbin/lpr/lpr/lpr.c b/usr.sbin/lpr/lpr/lpr.c index 033395bd14d..db29164c20f 100644 --- a/usr.sbin/lpr/lpr/lpr.c +++ b/usr.sbin/lpr/lpr/lpr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lpr.c,v 1.5 1996/05/15 13:41:58 pefo Exp $ */ +/* $OpenBSD: lpr.c,v 1.6 1996/07/04 05:41:57 tholo Exp $ */ /* $NetBSD: lpr.c,v 1.10 1996/03/21 18:12:25 jtc Exp $ */ /* @@ -47,7 +47,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 */ /* @@ -59,6 +59,7 @@ static char sccsid[] = "@(#)lpr.c 8.3 (Berkeley) 3/30/94"; #include <sys/param.h> #include <sys/stat.h> +#include <sys/file.h> #include <dirent.h> #include <fcntl.h> |