diff options
39 files changed, 1873 insertions, 1387 deletions
diff --git a/usr.sbin/lpr/common_source/common.c b/usr.sbin/lpr/common_source/common.c index 1a97a90fe70..b27da16cd8d 100644 --- a/usr.sbin/lpr/common_source/common.c +++ b/usr.sbin/lpr/common_source/common.c @@ -1,4 +1,5 @@ -/* $OpenBSD: common.c,v 1.16 2002/02/19 19:39:40 millert Exp $ */ +/* $OpenBSD: common.c,v 1.17 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: common.c,v 1.21 2000/08/09 14:28:50 itojun Exp $ */ /* * Copyright (c) 1983, 1993 @@ -42,7 +43,7 @@ #if 0 static const char sccsid[] = "@(#)common.c 8.5 (Berkeley) 4/28/95"; #else -static const char rcsid[] = "$OpenBSD: common.c,v 1.16 2002/02/19 19:39:40 millert Exp $"; +static const char rcsid[] = "$OpenBSD: common.c,v 1.17 2002/05/20 23:13:50 millert Exp $"; #endif #endif /* not lint */ @@ -61,7 +62,9 @@ static const char rcsid[] = "$OpenBSD: common.c,v 1.16 2002/02/19 19:39:40 mille #include <stdlib.h> #include <stdio.h> #include <string.h> +#include <signal.h> #include <stdarg.h> +#include <ifaddrs.h> #include "lp.h" #include "pathnames.h" @@ -112,15 +115,7 @@ long XC; /* flags to clear for local mode */ long XS; /* flags to set for local mode */ char line[BUFSIZ]; -char *bp; /* pointer into printcap buffer. */ -char *printer; /* printer name */ - /* host machine name */ -char host[MAXHOSTNAMELEN]; -char *from = host; /* client's machine name */ int remote; /* true if sending files to a remote host */ -char *printcapdb[2] = { _PATH_PRINTCAP, 0 }; - -extern uid_t uid, euid; static int compar(const void *, const void *); @@ -134,79 +129,75 @@ getport(rhost, rport) char *rhost; int rport; { - struct hostent *hp; - struct servent *sp; - struct sockaddr_in sin; - int s, timo = 1, on = 1, lport = IPPORT_RESERVED - 1; - int err; + struct addrinfo hints, *res, *r; + u_int timo = 1; + int s, lport = IPPORT_RESERVED - 1; + int error; + int refuse, trial; + char pbuf[NI_MAXSERV]; /* * Get the host address and port number to connect to. */ if (rhost == NULL) fatal("no remote host to connect to"); - bzero((char *)&sin, sizeof(sin)); - if (inet_aton(rhost, &sin.sin_addr) == 1) - sin.sin_family = AF_INET; - else { - siginterrupt(SIGINT, 1); - hp = gethostbyname(rhost); - if (hp == NULL) { - if (errno == EINTR && gotintr) { - siginterrupt(SIGINT, 0); - return (-1); - } - siginterrupt(SIGINT, 0); - fatal("unknown host %s", rhost); - } - siginterrupt(SIGINT, 0); - 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); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + if (rport) + snprintf(pbuf, sizeof(pbuf), "%d", rport); + else + snprintf(pbuf, sizeof(pbuf), "printer"); + siginterrupt(SIGINT, 1); + error = getaddrinfo(rhost, pbuf, &hints, &res); + siginterrupt(SIGINT, 0); + if (error) + fatal("printer/tcp: %s", gai_strerror(error)); /* * Try connecting to the server. */ retry: - seteuid(euid); - siginterrupt(SIGINT, 1); - s = rresvport(&lport); - siginterrupt(SIGINT, 0); - seteuid(uid); - if (s < 0) - return(-1); - siginterrupt(SIGINT, 1); - if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { - err = errno; - (void) close(s); - siginterrupt(SIGINT, 0); - errno = err; - if (errno == EINTR && gotintr) { - close(s); - return (-1); - } - if (errno == EADDRINUSE) { - lport--; - goto retry; - } - if (errno == ECONNREFUSED && timo <= 16) { - sleep(timo); - timo *= 2; - goto retry; + s = -1; + refuse = trial = 0; + for (r = res; r; r = r->ai_next) { + trial++; +retryport: + seteuid(euid); + s = rresvport_af(&lport, r->ai_family); + seteuid(uid); + if (s < 0) + return(-1); + siginterrupt(SIGINT, 1); + if (connect(s, r->ai_addr, r->ai_addrlen) < 0) { + error = errno; + siginterrupt(SIGINT, 0); + (void)close(s); + s = -1; + errno = error; + if (errno == EADDRINUSE) { + lport--; + goto retryport; + } else if (errno == ECONNREFUSED) + refuse++; + continue; + } else { + siginterrupt(SIGINT, 0); + break; } - return(-1); } - siginterrupt(SIGINT, 0); - - /* Don't bother if we get an error here. */ - setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *)&on, sizeof on); + if (s < 0 && trial == refuse && timo <= 16) { + sleep(timo); + timo *= 2; + goto retry; + } + if (res) + freeaddrinfo(res); + + /* Don't worry if we get an error from setsockopt(). */ + trial = 1; + setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &trial, sizeof(trial)); + return(s); } @@ -230,7 +221,7 @@ getline(cfp) do { *lp++ = ' '; linel++; - } while ((linel & 07) != 0 && linel+1<sizeof(line)); + } while ((linel & 07) != 0 && linel+1 < sizeof(line)); continue; } *lp++ = c; @@ -251,16 +242,14 @@ getq(namelist) { struct dirent *d; struct queue *q, **queue; - int nitems; + size_t nitems, arraysz; struct stat stbuf; DIR *dirp; - int arraysz; - seteuid(euid); dirp = opendir(SD); seteuid(uid); - if (dirp== NULL) + if (dirp == NULL) return(-1); if (fstat(dirp->dd_fd, &stbuf) < 0) goto errdone; @@ -288,14 +277,14 @@ getq(namelist) if (q == NULL) goto errdone; q->q_time = stbuf.st_mtime; - strcpy(q->q_name, d->d_name); + strcpy(q->q_name, d->d_name); /* safe */ /* * Check to make sure the array has space left and * realloc the maximum size. */ if (++nitems > arraysz) { arraysz *= 2; - queue = (struct queue **)realloc((char *)queue, + queue = (struct queue **)realloc(queue, arraysz * sizeof(struct queue *)); if (queue == NULL) goto errdone; @@ -332,70 +321,110 @@ compar(p1, p2) * as the remote machine (RM) entry (if it exists). */ char * -checkremote() +checkremote(void) { - char name[MAXHOSTNAMELEN]; - struct hostent *hp; + char lname[NI_MAXHOST], rname[NI_MAXHOST]; + struct addrinfo hints, *res, *res0; static char errbuf[128]; - char *rp, *rp_b; + int error; + struct ifaddrs *ifap, *ifa; +#ifdef NI_WITHSCOPEID + const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID; +#else + const int niflags = NI_NUMERICHOST; +#endif +#ifdef __KAME__ + struct sockaddr_in6 sin6; + struct sockaddr_in6 *sin6p; +#endif + + remote = 0; /* assume printer is local on failure */ - 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'; + if (RM == NULL) + return NULL; + + /* get the local interface addresses */ + siginterrupt(SIGINT, 1); + if (getifaddrs(&ifap) < 0) { + (void)snprintf(errbuf, sizeof(errbuf), + "unable to get local interface address: %s", + strerror(errno)); + siginterrupt(SIGINT, 0); + return errbuf; + } + siginterrupt(SIGINT, 0); + + /* get the remote host addresses (RM) */ + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_CANONNAME; + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + res = NULL; + siginterrupt(SIGINT, 1); + error = getaddrinfo(RM, NULL, &hints, &res0); + siginterrupt(SIGINT, 0); + if (error) { + (void)snprintf(errbuf, sizeof(errbuf), + "unable to resolve remote machine %s: %s", + RM, gai_strerror(error)); + freeifaddrs(ifap); + return errbuf; + } + + remote = 1; /* assume printer is remote */ + + for (res = res0; res; res = res->ai_next) { siginterrupt(SIGINT, 1); - hp = gethostbyname(name); - if (hp == (struct hostent *) NULL) { - if (errno == EINTR && gotintr) { + error = getnameinfo(res->ai_addr, res->ai_addrlen, + rname, sizeof(rname), NULL, 0, niflags); + siginterrupt(SIGINT, 0); + if (error != 0) + continue; + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { +#ifdef __KAME__ + sin6p = (struct sockaddr_in6 *)ifa->ifa_addr; + if (ifa->ifa_addr->sa_family == AF_INET6 && + ifa->ifa_addr->sa_len == sizeof(sin6) && + IN6_IS_ADDR_LINKLOCAL(&sin6p->sin6_addr) && + *(u_int16_t *)&sin6p->sin6_addr.s6_addr[2]) { + /* kame scopeid hack */ + memcpy(&sin6, ifa->ifa_addr, sizeof(sin6)); + sin6.sin6_scope_id = + ntohs(*(u_int16_t *)&sin6p->sin6_addr.s6_addr[2]); + sin6.sin6_addr.s6_addr[2] = 0; + sin6.sin6_addr.s6_addr[3] = 0; + siginterrupt(SIGINT, 1); + error = getnameinfo((struct sockaddr *)&sin6, + sin6.sin6_len, lname, sizeof(lname), + NULL, 0, niflags); siginterrupt(SIGINT, 0); - return NULL; - } + if (error != 0) + continue; + } else +#endif + siginterrupt(SIGINT, 1); + error = getnameinfo(ifa->ifa_addr, + ifa->ifa_addr->sa_len, lname, sizeof(lname), NULL, + 0, niflags); siginterrupt(SIGINT, 0); - (void) snprintf(errbuf, sizeof(errbuf), - "unable to get official name for local machine %s", - name); - return errbuf; - } else - strlcpy(name, hp->h_name, sizeof name); - siginterrupt(SIGINT, 0); - - /* get the official name of RM */ - hp = gethostbyname(RM); - if (hp == (struct hostent *) NULL) { - (void) snprintf(errbuf, sizeof(errbuf), - "unable to get official name for remote machine %s", - RM); - return errbuf; - } + if (error != 0) + continue; - /* - * if the two hosts are not the same, - * then the printer must be remote. - */ - if (strcasecmp(name, hp->h_name) != 0) - remote = 1; - else if (cgetstr(bp, "rp", &rp) > 0) { - if (cgetent(&rp_b, printcapdb, rp) == 0) { - if (cgetmatch(rp_b, printer) != 0) - remote = 1; - free(rp_b); - } else { - (void) snprintf(errbuf, sizeof(errbuf), - "can't find (local) remote printer %s", - rp); - free(rp); - return errbuf; + if (strcmp(rname, lname) == 0) { + remote = 0; + goto done; } - free(rp); } } +done: + freeaddrinfo(res0); + freeifaddrs(ifap); return NULL; } /* sleep n milliseconds */ void -delay(n) +delay(int n) { struct timeval tdelay; diff --git a/usr.sbin/lpr/common_source/common_vars.c b/usr.sbin/lpr/common_source/common_vars.c new file mode 100644 index 00000000000..241bfad642e --- /dev/null +++ b/usr.sbin/lpr/common_source/common_vars.c @@ -0,0 +1,57 @@ +/* $OpenBSD: common_vars.c,v 1.1 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: common.c,v 1.15 1999/09/26 10:32:27 mrg Exp $ */ + +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static const char rcsid[] = "$OpenBSD: common_vars.c,v 1.1 2002/05/20 23:13:50 millert Exp $"; +#endif /* not lint */ + +#include <sys/param.h> + +#include "pathnames.h" + +char *name; /* program name */ +char *printer; /* printer name */ +char host[MAXHOSTNAMELEN+1]; /* host machine name */ +char *from = host; /* client's machine name */ +char *printcapdb[2] = { _PATH_PRINTCAP, 0 }; +char *bp; /* pointer into printcap buffer. */ +uid_t uid, euid; /* real and effective uids */ +u_int wait_time = 300; /* time out after 5 minutes by default */ diff --git a/usr.sbin/lpr/common_source/displayq.c b/usr.sbin/lpr/common_source/displayq.c index 5cac1627f02..e19e7f3f9e2 100644 --- a/usr.sbin/lpr/common_source/displayq.c +++ b/usr.sbin/lpr/common_source/displayq.c @@ -1,4 +1,5 @@ -/* $OpenBSD: displayq.c,v 1.15 2001/11/01 18:02:32 mickey Exp $ */ +/* $OpenBSD: displayq.c,v 1.16 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: displayq.c,v 1.21 2001/08/30 00:51:50 itojun Exp $ */ /* * Copyright (c) 1983, 1993 @@ -37,7 +38,7 @@ #if 0 static const char sccsid[] = "@(#)displayq.c 8.4 (Berkeley) 4/28/95"; #else -static const char rcsid[] = "$OpenBSD: displayq.c,v 1.15 2001/11/01 18:02:32 mickey Exp $"; +static const char rcsid[] = "$OpenBSD: displayq.c,v 1.16 2002/05/20 23:13:50 millert Exp $"; #endif #endif /* not lint */ @@ -73,8 +74,6 @@ extern int requests; /* # of spool requests */ extern char *user[]; /* users to process */ extern int users; /* # of users in user array */ -extern uid_t uid, euid; - static int termwidth; static int col; /* column on screen */ static char current[NAME_MAX]; /* current file being printed */ @@ -83,17 +82,18 @@ static int first; /* first file in ``files'' column? */ static int garbage; /* # of garbage cf files */ static int lflag; /* long output option */ static int rank; /* order to be printed (-1=none, 0=active) */ -static long totsize; /* total print job size in bytes */ +static off_t totsize; /* total print job size in bytes */ + +static const char *head0 = "Rank Owner Job Files"; +static const char *head1 = "Total Size\n"; -static char *head0 = "Rank Owner Job Files"; -static char *head1 = "Total Size\n"; +static void alarmer(int); /* * Display the current state of the queue. Format = 1 if long format. */ void -displayq(format) - int format; +displayq(int format) { struct queue *q; int i, nitems, fd, ret, len; @@ -121,7 +121,7 @@ displayq(format) fatal("unknown printer"); else if (i == -3) fatal("potential reference loop detected in printcap file"); - if (cgetstr(bp, "lp", &LP) < 0) + if (cgetstr(bp, DEFLP, &LP) < 0) LP = _PATH_DEFDEVLP; if (cgetstr(bp, "rp", &RP) < 0) RP = DEFLP; @@ -132,7 +132,7 @@ displayq(format) if (cgetstr(bp, "st", &ST) < 0) ST = DEFSTAT; cgetstr(bp, "rm", &RM); - if ((cp = checkremote())) + if ((cp = checkremote()) != NULL) printf("Warning: %s\n", cp); /* @@ -157,10 +157,10 @@ displayq(format) fd = open(ST, O_RDONLY); seteuid(uid); if (fd >= 0) { - (void) flock(fd, LOCK_SH); + (void)flock(fd, LOCK_SH); while ((i = read(fd, line, sizeof(line))) > 0) - (void) fwrite(line, 1, i, stdout); - (void) close(fd); /* unlocks as well */ + (void)fwrite(line, 1, i, stdout); + (void)close(fd); /* unlocks as well */ } else putchar('\n'); } @@ -214,14 +214,14 @@ displayq(format) fd = open(ST, O_RDONLY); seteuid(uid); if (fd >= 0) { - (void) flock(fd, LOCK_SH); + (void)flock(fd, LOCK_SH); while ((i = read(fd, line, sizeof(line))) > 0) - (void) fwrite(line, 1, i, stdout); - (void) close(fd); /* unlocks as well */ + (void)fwrite(line, 1, i, stdout); + (void)close(fd); /* unlocks as well */ } else putchar('\n'); } - (void) fclose(fp); + (void)fclose(fp); } /* * Now, examine the control files and print out the jobs to @@ -248,50 +248,68 @@ displayq(format) */ if (nitems) putchar('\n'); - (void) snprintf(line, sizeof line, "%c%s", format + '\3', RP); + (void)snprintf(line, sizeof(line), "%c%s", format + '\3', RP); cp = line; cp += strlen(cp); - for (i = 0; i < requests && cp-line < sizeof(line) - 1; i++) { - len = line + sizeof line - cp; + for (i = 0; i < requests && cp - line < sizeof(line) - 1; i++) { + len = line + sizeof(line) - cp; if (snprintf(cp, len, " %d", requ[i]) >= len) { cp += strlen(cp); break; } cp += strlen(cp); } - for (i = 0; i < users && cp-line < sizeof(line) - 1; i++) { - len = line + sizeof line - cp; + for (i = 0; i < users && cp - line < sizeof(line) - 1; i++) { + len = line + sizeof(line) - cp; if (snprintf(cp, len, " %s", user[i]) >= len) { cp += strlen(cp); break; } } - if (cp-line < sizeof(line) - 1) { + if (cp-line < sizeof(line) - 1) strcat(line, "\n"); - } else { - line[sizeof line-2] = '\n'; - } + else + line[sizeof(line) - 2] = '\n'; fd = getport(RM, 0); if (fd < 0) { if (from != host) printf("%s: ", host); - printf("connection to %s is down\n", RM); + (void)printf("connection to %s is down\n", RM); } else { + struct sigaction osa, nsa; + i = strlen(line); if (write(fd, line, i) != i) fatal("Lost connection"); - while ((i = read(fd, line, sizeof(line))) > 0) - (void) fwrite(line, 1, i, stdout); - (void) close(fd); + memset(&nsa, 0, sizeof(nsa)); + nsa.sa_handler = alarmer; + sigemptyset(&nsa.sa_mask); + sigaddset(&nsa.sa_mask, SIGALRM); + nsa.sa_flags = 0; + (void)sigaction(SIGALRM, &nsa, &osa); + alarm(wait_time); + while ((i = read(fd, line, sizeof(line))) > 0) { + (void)fwrite(line, 1, i, stdout); + alarm(wait_time); + } + alarm(0); + (void)sigaction(SIGALRM, &osa, NULL); + (void)close(fd); } } +static void +alarmer(int s) +{ + /* nothing */ +} + /* * Print a warning message if there is no daemon present. */ void -nodaemon() +nodaemon(void) { if (remote) printf("\n%s: ", host); @@ -303,7 +321,7 @@ nodaemon() * Print the header for the short listing format */ void -header() +header(void) { printf(head0); col = strlen(head0)+1; @@ -312,8 +330,7 @@ header() } void -inform(cf) - char *cf; +inform(char *cf) { int j; FILE *cfp; @@ -357,9 +374,8 @@ inform(cf) default: /* some format specifer and file name? */ if (line[0] < 'a' || line[0] > 'z') continue; - if (j == 0 || strcmp(file, line+1) != 0) { - (void) strlcpy(file, line+1, sizeof(file)); - } + if (j == 0 || strcmp(file, line+1) != 0) + (void)strlcpy(file, line+1, sizeof(file)); j++; continue; case 'N': @@ -371,14 +387,13 @@ inform(cf) fclose(cfp); if (!lflag) { blankfill(termwidth - (80 - SIZCOL)); - printf("%ld bytes\n", totsize); + printf("%lld bytes\n", (long long)totsize); totsize = 0; } } int -inlist(name, file) - char *name, *file; +inlist(char *name, char *file) { int *r, n; char **u, *cp; @@ -403,9 +418,7 @@ inlist(name, file) } void -show(nfile, file, copies) - char *nfile, *file; - int copies; +show(char *nfile, char *file, int copies) { if (strcmp(nfile, " ") == 0) nfile = "(standard input)"; @@ -419,8 +432,7 @@ show(nfile, file, copies) * Fill the line with blanks to the specified column */ void -blankfill(n) - int n; +blankfill(int n) { while (col++ < n) putchar(' '); @@ -430,9 +442,7 @@ blankfill(n) * Give the abbreviated dump of the file names */ void -dump(nfile, file, copies) - char *nfile, *file; - int copies; +dump(char *nfile, char *file, int copies) { int n, fill; struct stat lbuf; @@ -466,9 +476,7 @@ dump(nfile, file, copies) * Print the long info about the file */ void -ldump(nfile, file, copies) - char *nfile, *file; - int copies; +ldump(char *nfile, char *file, int copies) { struct stat lbuf; @@ -478,7 +486,7 @@ ldump(nfile, file, copies) else printf("%-32s", nfile); if (*file && !stat(file, &lbuf)) - printf(" %qd bytes", lbuf.st_size); + printf(" %lld bytes", (long long)lbuf.st_size); else printf(" ??? bytes"); putchar('\n'); @@ -489,8 +497,7 @@ ldump(nfile, file, copies) * update col for screen management */ void -prank(n) - int n; +prank(int n) { char rline[100]; static char *r[] = { diff --git a/usr.sbin/lpr/common_source/lp.h b/usr.sbin/lpr/common_source/lp.h index d65735ea160..9a3cedb372a 100644 --- a/usr.sbin/lpr/common_source/lp.h +++ b/usr.sbin/lpr/common_source/lp.h @@ -1,4 +1,5 @@ -/* $OpenBSD: lp.h,v 1.8 2002/02/17 19:42:36 millert Exp $ */ +/* $OpenBSD: lp.h,v 1.9 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: lp.h,v 1.14 2000/04/16 14:43:58 mrg Exp $ */ /* * Copyright (c) 1983, 1993 @@ -44,7 +45,7 @@ extern char *AF; /* accounting file */ extern long BR; /* baud rate if lp is a tty */ extern char *CF; /* name of cifplot filter (per job) */ extern char *DF; /* name of tex filter (per job) */ -extern long DU; /* daeomon user-id */ +extern long DU; /* daemon user-id */ extern long FC; /* flags to clear if lp is a tty */ extern char *FF; /* form feed string */ extern long FS; /* flags to set if lp is a tty */ @@ -56,7 +57,7 @@ extern char *LO; /* lock file name */ extern char *LP; /* line printer device name */ extern long MC; /* maximum number of copies allowed */ extern char *MS; /* stty flags to set if lp is a tty */ -extern long MX; /* maximum number of blocks to copy */ +extern long MX; /* maximum number of blocks to copy */ extern char *NF; /* name of ditroff(1) filter (per job) */ extern char *OF; /* name of output filter (created once) */ extern long PL; /* page length */ @@ -88,7 +89,10 @@ extern char *printer; /* printer name */ extern char host[MAXHOSTNAMELEN]; extern char *from; /* client's machine name */ extern int remote; /* true if sending files to a remote host */ -extern char *printcapdb[]; /* printcap database array */ +extern char *printcapdb[]; /* printcap database array */ +extern u_int wait_time; /* time to wait for remote responses */ + +extern uid_t uid, euid; /* real and effective user id's */ extern volatile sig_atomic_t gotintr; @@ -110,7 +114,8 @@ char *checkremote(void); int chk(char *); void displayq(int); void dump(char *, char *, int); -void fatal(const char *, ...); +void fatal(const char *, ...) + __attribute__((__format__(__printf__, 1, 2))); int getline(FILE *); int getport(char *, int); int getq(struct queue *(*[])); diff --git a/usr.sbin/lpr/common_source/pathnames.h b/usr.sbin/lpr/common_source/pathnames.h index 9c7d15d7375..ff0239a8f56 100644 --- a/usr.sbin/lpr/common_source/pathnames.h +++ b/usr.sbin/lpr/common_source/pathnames.h @@ -1,4 +1,5 @@ -/* $OpenBSD: pathnames.h,v 1.2 1997/01/17 16:11:37 millert Exp $ */ +/* $OpenBSD: pathnames.h,v 1.3 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: pathnames.h,v 1.5 1995/11/28 19:43:27 jtc Exp $ */ /* * Copyright (c) 1989, 1993 @@ -41,7 +42,7 @@ #define _PATH_DEFSPOOL "/var/spool/output/lpd" #define _PATH_HOSTSEQUIV "/etc/hosts.equiv" #define _PATH_HOSTSLPD "/etc/hosts.lpd" -#define _PATH_MASTERLOCK "/var/spool/output/lpd.lock" +#define _PATH_MASTERLOCK "/var/run/lpd.pid" #define _PATH_PR "/usr/bin/pr" #define _PATH_PRINTCAP "/etc/printcap" #define _PATH_SOCKETNAME "/var/run/printer" diff --git a/usr.sbin/lpr/common_source/rmjob.c b/usr.sbin/lpr/common_source/rmjob.c index fe7e125c3b9..c3712e246a8 100644 --- a/usr.sbin/lpr/common_source/rmjob.c +++ b/usr.sbin/lpr/common_source/rmjob.c @@ -1,4 +1,5 @@ -/* $OpenBSD: rmjob.c,v 1.12 2002/02/16 21:28:03 millert Exp $ */ +/* $OpenBSD: rmjob.c,v 1.13 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: rmjob.c,v 1.16 2000/04/16 14:43:58 mrg Exp $ */ /* * Copyright (c) 1983, 1993 @@ -37,7 +38,7 @@ #if 0 static const char sccsid[] = "@(#)rmjob.c 8.2 (Berkeley) 4/28/95"; #else -static const char rcsid[] = "$OpenBSD: rmjob.c,v 1.12 2002/02/16 21:28:03 millert Exp $"; +static const char rcsid[] = "$OpenBSD: rmjob.c,v 1.13 2002/05/20 23:13:50 millert Exp $"; #endif #endif /* not lint */ @@ -73,12 +74,11 @@ static int all = 0; /* eliminate all files (root only) */ static int cur_daemon; /* daemon's pid */ static char current[NAME_MAX]; /* active control file name */ -extern uid_t uid, euid; /* real and effective user id's */ - static void do_unlink(char *); +static void alarmer(int); void -rmjob() +rmjob(void) { int i, nitems; int assasinated = 0; @@ -91,7 +91,7 @@ rmjob() fatal("unknown printer"); else if (i == -3) fatal("potential reference loop detected in printcap file"); - if (cgetstr(bp, "lp", &LP) < 0) + if (cgetstr(bp, DEFLP, &LP) < 0) LP = _PATH_DEFDEVLP; if (cgetstr(bp, "rp", &RP) < 0) RP = DEFLP; @@ -100,7 +100,7 @@ rmjob() if (cgetstr(bp,"lo", &LO) < 0) LO = DEFLOCK; cgetstr(bp, "rm", &RM); - if ((cp = checkremote())) + if ((cp = checkremote()) != NULL) printf("Warning: %s\n", cp); /* @@ -163,8 +163,7 @@ rmjob() * Return boolean indicating existence of a lock file. */ int -lockchk(s) - char *s; +lockchk(char *s) { FILE *fp; int i, n; @@ -178,12 +177,12 @@ lockchk(s) } seteuid(uid); if (!getline(fp)) { - (void) fclose(fp); + (void)fclose(fp); return(0); /* no daemon present */ } cur_daemon = atoi(line); if (kill(cur_daemon, 0) < 0 && errno != EPERM) { - (void) fclose(fp); + (void)fclose(fp); return(0); /* no daemon present */ } for (i = 1; (n = fread(current, sizeof(char), sizeof(current), fp)) <= 0; i++) { @@ -194,7 +193,7 @@ lockchk(s) sleep(i); } current[n-1] = '\0'; - (void) fclose(fp); + (void)fclose(fp); return(1); } @@ -202,8 +201,7 @@ lockchk(s) * Process a control file. */ void -process(file) - char *file; +process(char *file) { FILE *cfp; @@ -221,13 +219,12 @@ process(file) do_unlink(line+1); } } - (void) fclose(cfp); + (void)fclose(cfp); do_unlink(file); } static void -do_unlink(file) - char *file; +do_unlink(char *file) { int ret; @@ -243,8 +240,7 @@ do_unlink(file) * Do the dirty work in checking */ int -chk(file) - char *file; +chk(char *file) { int *r, n; char **u, *cp; @@ -270,7 +266,7 @@ chk(file) if (line[0] == 'P') break; } - (void) fclose(cfp); + (void)fclose(cfp); if (line[0] != 'P') return(0); @@ -300,8 +296,7 @@ chk(file) * Normal users can only remove the file from where it was sent. */ int -isowner(owner, file) - char *owner, *file; +isowner(char *owner, char *file) { if (!strcmp(person, root) && (from == host || !strcmp(from, file+6))) return(1); @@ -318,7 +313,7 @@ isowner(owner, file) * then try removing files on the remote machine. */ void -rmremote() +rmremote(void) { char *cp; int i, rem; @@ -342,7 +337,7 @@ rmremote() } for (i = 0; i < requests && cp-buf+10 < sizeof(buf) - 2; i++) { cp += strlen(cp); - (void) sprintf(cp, " %d", requ[i]); + (void)sprintf(cp, " %d", requ[i]); } strcat(cp, "\n"); rem = getport(RM, 0); @@ -351,21 +346,37 @@ rmremote() printf("%s: ", host); printf("connection to %s is down\n", RM); } else { + struct sigaction osa, nsa; + + memset(&nsa, 0, sizeof(nsa)); + nsa.sa_handler = alarmer; + sigemptyset(&nsa.sa_mask); + nsa.sa_flags = 0; + (void)sigaction(SIGALRM, &nsa, &osa); + alarm(wait_time); + i = strlen(buf); if (write(rem, buf, i) != i) fatal("Lost connection"); while ((i = read(rem, buf, sizeof(buf))) > 0) - (void) fwrite(buf, 1, i, stdout); - (void) close(rem); + (void)fwrite(buf, 1, i, stdout); + alarm(0); + (void)sigaction(SIGALRM, &osa, NULL); + (void)close(rem); } } +static void +alarmer(int s) +{ + /* nothing */ +} + /* * Return 1 if the filename begins with 'cf' */ int -iscf(d) - struct dirent *d; +iscf(struct dirent *d) { return(d->d_name[0] == 'c' && d->d_name[1] == 'f'); } diff --git a/usr.sbin/lpr/common_source/startdaemon.c b/usr.sbin/lpr/common_source/startdaemon.c index 971c6482a9a..8a25bfdcbd0 100644 --- a/usr.sbin/lpr/common_source/startdaemon.c +++ b/usr.sbin/lpr/common_source/startdaemon.c @@ -1,4 +1,5 @@ -/* $OpenBSD: startdaemon.c,v 1.6 2001/12/06 03:12:30 ericj Exp $ */ +/* $OpenBSD: startdaemon.c,v 1.7 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: startdaemon.c,v 1.10 1998/07/18 05:04:39 lukem Exp $ */ /* * Copyright (c) 1983, 1993, 1994 @@ -37,7 +38,7 @@ #if 0 static const char sccsid[] = "@(#)startdaemon.c 8.2 (Berkeley) 4/17/94"; #else -static const char rcsid[] = "$OpenBSD: startdaemon.c,v 1.6 2001/12/06 03:12:30 ericj Exp $"; +static const char rcsid[] = "$OpenBSD: startdaemon.c,v 1.7 2002/05/20 23:13:50 millert Exp $"; #endif #endif /* not lint */ @@ -46,35 +47,35 @@ static const char rcsid[] = "$OpenBSD: startdaemon.c,v 1.6 2001/12/06 03:12:30 e #include <sys/un.h> #include <dirent.h> +#include <err.h> #include <errno.h> #include <stdio.h> #include <unistd.h> #include <string.h> +#include <signal.h> #include "lp.h" #include "pathnames.h" -extern uid_t uid, euid; - /* * Tell the printer daemon that there are new files in the spool directory. */ int -startdaemon(printer) - char *printer; +startdaemon(char *printer) { struct sockaddr_un un; - int s, n; + int s; + size_t n; char buf[BUFSIZ]; - s = socket(AF_UNIX, SOCK_STREAM, 0); + s = socket(AF_LOCAL, SOCK_STREAM, 0); if (s < 0) { - perror("socket"); + warn("socket"); return(0); } memset(&un, 0, sizeof(un)); - un.sun_family = AF_UNIX; - strcpy(un.sun_path, _PATH_SOCKETNAME); + un.sun_family = AF_LOCAL; + strlcpy(un.sun_path, _PATH_SOCKETNAME, sizeof(un.sun_path)); #ifndef SUN_LEN #define SUN_LEN(unp) (strlen((unp)->sun_path) + 2) #endif @@ -90,33 +91,32 @@ startdaemon(printer) siginterrupt(SIGINT, 0); seteuid(uid); perror("connect"); - (void) close(s); + (void)close(s); return(0); } siginterrupt(SIGINT, 0); seteuid(uid); - if (snprintf(buf, sizeof buf, "\1%s\n", printer) > sizeof buf-1) { + n = snprintf(buf, sizeof(buf), "\1%s\n", printer); + if (n >= sizeof(buf) || n == -1) { close(s); return (0); } - n = strlen(buf); /* XXX atomicio inside siginterrupt? */ if (write(s, buf, n) != n) { - perror("write"); - (void) close(s); + warn("write"); + (void)close(s); return(0); } if (read(s, buf, 1) == 1) { if (buf[0] == '\0') { /* everything is OK */ - (void) close(s); + (void)close(s); return(1); } putchar(buf[0]); } while ((n = read(s, buf, sizeof(buf))) > 0) fwrite(buf, 1, n, stdout); - - (void) close(s); + (void)close(s); return(0); } diff --git a/usr.sbin/lpr/filters/lpf.c b/usr.sbin/lpr/filters/lpf.c index 51b460bb028..66d5e83adef 100644 --- a/usr.sbin/lpr/filters/lpf.c +++ b/usr.sbin/lpr/filters/lpf.c @@ -1,4 +1,5 @@ -/* $OpenBSD: lpf.c,v 1.6 2002/02/24 08:04:55 pvalchev Exp $ */ +/* $OpenBSD: lpf.c,v 1.7 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: lpf.c,v 1.8 2000/04/29 00:12:32 abs Exp $ */ /* * Copyright (c) 1983, 1993 @@ -43,7 +44,7 @@ static const char copyright[] = #if 0 static const char sccsid[] = "@(#)lpf.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: lpf.c,v 1.6 2002/02/24 08:04:55 pvalchev Exp $"; +static const char rcsid[] = "$OpenBSD: lpf.c,v 1.7 2002/05/20 23:13:50 millert Exp $"; #endif #endif /* not lint */ @@ -55,9 +56,10 @@ static const char rcsid[] = "$OpenBSD: lpf.c,v 1.6 2002/02/24 08:04:55 pvalchev */ #include <signal.h> -#include <unistd.h> #include <stdlib.h> #include <stdio.h> +#include <string.h> +#include <unistd.h> #define MAXWIDTH 132 #define MAXREP 10 @@ -75,6 +77,8 @@ char *name; /* user's login name */ char *host; /* user's machine name */ char *acctfile; /* accounting information file */ +__dead void usage(void); + int main(argc, argv) int argc; @@ -86,45 +90,40 @@ main(argc, argv) int done, linedone, maxrep, ch; char *limit; - while (--argc) { - if (*(cp = *++argv) == '-') { - switch (cp[1]) { - case 'n': - argc--; - name = *++argv; - break; - - case 'h': - argc--; - host = *++argv; - break; - - case 'w': - if ((i = atoi(&cp[2])) > 0 && i <= MAXWIDTH) - width = i; - break; - - case 'l': - length = atoi(&cp[2]); - break; - - case 'i': - indent = atoi(&cp[2]); - break; - - case 'r': /* map nl->cr-nl */ - onlcr++; - break; - - case 'c': /* Print control chars */ - literal++; - break; - } - } else - acctfile = cp; + while ((ch = getopt(argc, argv, "chr:i:l:n:w:")) != -1) { + switch (ch) { + case 'n': + name = optarg; + break; + case 'h': + host = optarg; + break; + case 'w': + if ((i = atoi(optarg)) > 0 && i <= MAXWIDTH) + width = i; + break; + case 'l': + length = atoi(optarg); + break; + case 'i': + indent = atoi(optarg); + break; + case 'r': /* map nl->cr-nl */ + onlcr++; + break; + case 'c': /* Print control chars */ + literal++; + break; + default: + usage(); + } } + argc -= optind; + argv += optind; + if (argc) + acctfile = *argv; - for (cp = buf[0], limit = buf[MAXREP]; cp < limit; *cp++ = ' '); + memset(buf, ' ', sizeof(buf)); done = 0; while (!done) { @@ -175,7 +174,7 @@ main(argc, argv) } default: - if ((col >= width) || (!literal && ch < ' ')) { + if (col >= width || (!literal && ch < ' ')) { col++; break; } @@ -227,3 +226,13 @@ main(argc, argv) } exit(0); } + +__dead void +usage(void) +{ + extern char *__progname; + + fprintf(stderr, "usage: %s [-c] [-r] [-h host] [-i indent] [-l length]" + " [-n name] [-w width] [acctfile]\n", __progname); + exit(1); +} diff --git a/usr.sbin/lpr/lpc/Makefile b/usr.sbin/lpr/lpc/Makefile index 419c5f33bb4..805423e75bd 100644 --- a/usr.sbin/lpr/lpc/Makefile +++ b/usr.sbin/lpr/lpc/Makefile @@ -1,10 +1,10 @@ # from: @(#)Makefile 8.1 (Berkeley) 6/6/93 -# $OpenBSD: Makefile,v 1.2 1997/01/17 16:12:34 millert Exp $ +# $OpenBSD: Makefile,v 1.3 2002/05/20 23:13:50 millert Exp $ PROG= lpc CFLAGS+=-I${.CURDIR}/../common_source MAN= lpc.8 -SRCS= lpc.c cmds.c cmdtab.c startdaemon.c common.c +SRCS= lpc.c cmds.c cmdtab.c startdaemon.c common.c common_vars.c BINGRP= daemon BINMODE=2555 .PATH: ${.CURDIR}/../common_source diff --git a/usr.sbin/lpr/lpc/cmds.c b/usr.sbin/lpr/lpc/cmds.c index ac98baf23c4..86608fe3bda 100644 --- a/usr.sbin/lpr/lpc/cmds.c +++ b/usr.sbin/lpr/lpc/cmds.c @@ -1,4 +1,5 @@ -/* $OpenBSD: cmds.c,v 1.15 2002/02/16 21:28:03 millert Exp $ */ +/* $OpenBSD: cmds.c,v 1.16 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: cmds.c,v 1.12 1997/10/05 15:12:06 mrg Exp $ */ /* * Copyright (c) 1983, 1993 @@ -44,7 +45,7 @@ static const char copyright[] = #if 0 static const char sccsid[] = "@(#)cmds.c 8.2 (Berkeley) 4/28/95"; #else -static const char rcsid[] = "$OpenBSD: cmds.c,v 1.15 2002/02/16 21:28:03 millert Exp $"; +static const char rcsid[] = "$OpenBSD: cmds.c,v 1.16 2002/05/20 23:13:50 millert Exp $"; #endif #endif /* not lint */ @@ -74,28 +75,26 @@ static const char rcsid[] = "$OpenBSD: cmds.c,v 1.15 2002/02/16 21:28:03 millert extern uid_t uid, euid; -void abortpr(int); -void cleanpr(void); -void disablepr(void); -int doarg(char *); -int doselect(struct dirent *); -void enablepr(void); -void prstat(void); -void putmsg(int, char **); -int sortq(const void *, const void *); -void startpr(int); -void stoppr(void); -int touch(struct queue *); -void unlinkf(char *); -void upstat(char *); +static void abortpr(int); +static void cleanpr(void); +static void disablepr(void); +static int doarg(char *); +static int doselect(struct dirent *); +static void enablepr(void); +static void prstat(void); +static void putmsg(int, char **); +static int sortq(const void *, const void *); +static void startpr(int); +static void stoppr(void); +static int touch(struct queue *); +static void unlinkf(char *); +static void upstat(char *); /* * kill an existing daemon and disable printing. */ void -doabort(argc, argv) - int argc; - char *argv[]; +doabort(int argc, char **argv) { int c, status; char *cp1, *cp2; @@ -105,7 +104,7 @@ doabort(argc, argv) printf("Usage: abort {all | printer ...}\n"); return; } - if (argc == 2 && !strcmp(argv[1], "all")) { + if (argc == 2 && strcmp(argv[1], "all") == 0) { printer = prbuf; while (cgetnext(&bp, printcapdb) > 0) { cp1 = prbuf; @@ -132,9 +131,8 @@ doabort(argc, argv) } } -void -abortpr(dis) - int dis; +static void +abortpr(int dis) { FILE *fp; struct stat stbuf; @@ -144,7 +142,7 @@ abortpr(dis) SD = _PATH_DEFSPOOL; if (cgetstr(bp, "lo", &LO) == -1) LO = DEFLOCK; - (void) snprintf(line, sizeof(line), "%s/%s", SD, LO); + (void)snprintf(line, sizeof(line), "%s/%s", SD, LO); printf("%s:\n", printer); /* @@ -163,7 +161,7 @@ abortpr(dis) if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) printf("\tcannot create lock file\n"); else { - (void) close(fd); + (void)close(fd); upstat("printing disabled\n"); printf("\tprinting disabled\n"); printf("\tno daemon to abort\n"); @@ -182,11 +180,11 @@ abortpr(dis) goto out; } if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) { - (void) fclose(fp); /* unlocks as well */ + (void)fclose(fp); /* unlocks as well */ printf("\tno daemon to abort\n"); goto out; } - (void) fclose(fp); + (void)fclose(fp); if (kill(pid = atoi(line), SIGTERM) < 0) { if (errno == ESRCH) printf("\tno daemon to abort\n"); @@ -201,37 +199,34 @@ out: /* * Write a message into the status file. */ -void -upstat(msg) - char *msg; +static void +upstat(char *msg) { int fd; char statfile[MAXPATHLEN]; if (cgetstr(bp, "st", &ST) == -1) ST = DEFSTAT; - (void) snprintf(statfile, sizeof(statfile), "%s/%s", SD, ST); + (void)snprintf(statfile, sizeof(statfile), "%s/%s", SD, ST); umask(0); fd = open(statfile, O_WRONLY|O_CREAT, 0664); if (fd < 0 || flock(fd, LOCK_EX) < 0) { printf("\tcannot create status file\n"); return; } - (void) ftruncate(fd, 0); + (void)ftruncate(fd, 0); if (msg == (char *)NULL) - (void) write(fd, "\n", 1); + (void)write(fd, "\n", 1); else - (void) write(fd, msg, strlen(msg)); - (void) close(fd); + (void)write(fd, msg, strlen(msg)); + (void)close(fd); } /* * Remove all spool files and temporaries from the spooling area. */ void -clean(argc, argv) - int argc; - char *argv[]; +clean(int argc, char **argv) { int c, status; char *cp1, *cp2; @@ -241,7 +236,7 @@ clean(argc, argv) printf("Usage: clean {all | printer ...}\n"); return; } - if (argc == 2 && !strcmp(argv[1], "all")) { + if (argc == 2 && strcmp(argv[1], "all") == 0) { printer = prbuf; while (cgetnext(&bp, printcapdb) > 0) { cp1 = prbuf; @@ -269,9 +264,8 @@ clean(argc, argv) } } -int -doselect(d) - struct dirent *d; +static int +doselect(struct dirent *d) { int c = d->d_name[0]; @@ -284,16 +278,15 @@ doselect(d) * Comparison routine for scandir. Sort by job number and machine, then * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z. */ -int -sortq(a, b) - const void *a, *b; +static int +sortq(const void *a, const void *b) { - struct dirent **d1, **d2; + const struct dirent **d1, **d2; int c1, c2; - d1 = (struct dirent **)a; - d2 = (struct dirent **)b; - if ((c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3))) + d1 = (const struct dirent **)a; + d2 = (const struct dirent **)b; + if ((c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3)) != 0) return(c1); c1 = (*d1)->d_name[0]; c2 = (*d2)->d_name[0]; @@ -309,8 +302,8 @@ sortq(a, b) /* * Remove incomplete jobs from spooling area. */ -void -cleanpr() +static void +cleanpr(void) { int i, n; char *cp, *cp1, *lp; @@ -321,7 +314,9 @@ cleanpr() SD = _PATH_DEFSPOOL; printf("%s:\n", printer); - for (lp = line, cp = SD; (lp - line) < sizeof(line) && (*lp++ = *cp++);) + /* XXX depends on SD being non-NUL */ + for (lp = line, cp = SD; (lp - line) < sizeof(line) && + (*lp++ = *cp++) != '\0'; ) ; lp[-1] = '/'; if (lp - line >= sizeof(line)) { @@ -351,8 +346,8 @@ cleanpr() n++; } if (n == 0) { - if (strlcpy(lp, cp, sizeof(line) - (lp - line)) >= - sizeof(line) - (lp - line)) + if (strlcpy(lp, cp, sizeof(line) - (lp - line)) + >= sizeof(line) - (lp - line)) printf("\tpath too long, %s/%s", SD, cp); else unlinkf(line); @@ -372,9 +367,8 @@ cleanpr() } while (++i < nitems); } -void -unlinkf(name) - char *name; +static void +unlinkf(char *name) { seteuid(euid); if (unlink(name) < 0) @@ -388,9 +382,7 @@ unlinkf(name) * Enable queuing to the printer (allow lpr's). */ void -enable(argc, argv) - int argc; - char *argv[]; +enable(int argc, char **argv) { int c, status; char *cp1, *cp2; @@ -400,7 +392,7 @@ enable(argc, argv) printf("Usage: enable {all | printer ...}\n"); return; } - if (argc == 2 && !strcmp(argv[1], "all")) { + if (argc == 2 && strcmp(argv[1], "all") == 0) { printer = prbuf; while (cgetnext(&bp, printcapdb) > 0) { cp1 = prbuf; @@ -428,8 +420,8 @@ enable(argc, argv) } } -void -enablepr() +static void +enablepr(void) { struct stat stbuf; @@ -437,7 +429,7 @@ enablepr() SD = _PATH_DEFSPOOL; if (cgetstr(bp, "lo", &LO) == -1) LO = DEFLOCK; - (void) snprintf(line, sizeof(line), "%s/%s", SD, LO); + (void)snprintf(line, sizeof(line), "%s/%s", SD, LO); printf("%s:\n", printer); /* @@ -457,9 +449,7 @@ enablepr() * Disable queuing. */ void -disable(argc, argv) - int argc; - char *argv[]; +disable(int argc, char **argv) { int c, status; char *cp1, *cp2; @@ -469,7 +459,7 @@ disable(argc, argv) printf("Usage: disable {all | printer ...}\n"); return; } - if (argc == 2 && !strcmp(argv[1], "all")) { + if (argc == 2 && strcmp(argv[1], "all") == 0) { printer = prbuf; while (cgetnext(&bp, printcapdb) > 0) { cp1 = prbuf; @@ -497,8 +487,8 @@ disable(argc, argv) } } -void -disablepr() +static void +disablepr(void) { int fd; struct stat stbuf; @@ -507,7 +497,7 @@ disablepr() SD = _PATH_DEFSPOOL; if (cgetstr(bp, "lo", &LO) == -1) LO = DEFLOCK; - (void) snprintf(line, sizeof(line), "%s/%s", SD, LO); + (void)snprintf(line, sizeof(line), "%s/%s", SD, LO); printf("%s:\n", printer); /* * Turn on the group execute bit of the lock file to disable queuing. @@ -522,7 +512,7 @@ disablepr() if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0) printf("\tcannot create lock file\n"); else { - (void) close(fd); + (void)close(fd); printf("\tqueuing disabled\n"); } } else @@ -535,9 +525,7 @@ disablepr() * (reason for being down). */ void -down(argc, argv) - int argc; - char *argv[]; +down(int argc, char **argv) { int c, status; char *cp1, *cp2; @@ -547,7 +535,7 @@ down(argc, argv) printf("Usage: down {all | printer} [message ...]\n"); return; } - if (!strcmp(argv[1], "all")) { + if (strcmp(argv[1], "all") == 0) { printer = prbuf; while (cgetnext(&bp, printcapdb) > 0) { cp1 = prbuf; @@ -573,10 +561,8 @@ down(argc, argv) putmsg(argc - 2, argv + 2); } -void -putmsg(argc, argv) - int argc; - char **argv; +static void +putmsg(int argc, char **argv) { int fd; char *cp1, *cp2; @@ -594,7 +580,7 @@ putmsg(argc, argv) * Turn on the group execute bit of the lock file to disable queuing and * turn on the owner execute bit of the lock file to disable printing. */ - (void) snprintf(line, sizeof(line), "%s/%s", SD, LO); + (void)snprintf(line, sizeof(line), "%s/%s", SD, LO); seteuid(euid); if (stat(line, &stbuf) >= 0) { if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0) @@ -605,7 +591,7 @@ putmsg(argc, argv) if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0) printf("\tcannot create lock file\n"); else { - (void) close(fd); + (void)close(fd); printf("\tprinter and queuing disabled\n"); } seteuid(uid); @@ -615,7 +601,7 @@ putmsg(argc, argv) /* * Write the message into the status file. */ - (void) snprintf(line, sizeof(line), "%s/%s", SD, ST); + (void)snprintf(line, sizeof(line), "%s/%s", SD, ST); fd = open(line, O_WRONLY|O_CREAT, 0664); if (fd < 0 || flock(fd, LOCK_EX) < 0) { printf("\tcannot create status file\n"); @@ -623,10 +609,10 @@ putmsg(argc, argv) return; } seteuid(uid); - (void) ftruncate(fd, 0); + (void)ftruncate(fd, 0); if (argc <= 0) { - (void) write(fd, "\n", 1); - (void) close(fd); + (void)write(fd, "\n", 1); + (void)close(fd); return; } cp1 = buf; @@ -638,17 +624,15 @@ putmsg(argc, argv) } cp1[-1] = '\n'; *cp1 = '\0'; - (void) write(fd, buf, strlen(buf)); - (void) close(fd); + (void)write(fd, buf, strlen(buf)); + (void)close(fd); } /* * Exit lpc */ void -quit(argc, argv) - int argc; - char *argv[]; +quit(int argc, char **argv) { exit(0); } @@ -657,9 +641,7 @@ quit(argc, argv) * Kill and restart the daemon. */ void -restart(argc, argv) - int argc; - char *argv[]; +restart(int argc, char **argv) { int c, status; char *cp1, *cp2; @@ -669,7 +651,7 @@ restart(argc, argv) printf("Usage: restart {all | printer ...}\n"); return; } - if (argc == 2 && !strcmp(argv[1], "all")) { + if (argc == 2 && strcmp(argv[1], "all") == 0) { printer = prbuf; while (cgetnext(&bp, printcapdb) > 0) { cp1 = prbuf; @@ -703,9 +685,7 @@ restart(argc, argv) * Enable printing on the specified printer and startup the daemon. */ void -startcmd(argc, argv) - int argc; - char *argv[]; +startcmd(int argc, char **argv) { int c, status; char *cp1, *cp2; @@ -715,7 +695,7 @@ startcmd(argc, argv) printf("Usage: start {all | printer ...}\n"); return; } - if (argc == 2 && !strcmp(argv[1], "all")) { + if (argc == 2 && strcmp(argv[1], "all") == 0) { printer = prbuf; while (cgetnext(&bp, printcapdb) > 0) { cp1 = prbuf; @@ -743,9 +723,8 @@ startcmd(argc, argv) } } -void -startpr(enable) - int enable; +static void +startpr(int enable) { struct stat stbuf; @@ -753,7 +732,7 @@ startpr(enable) SD = _PATH_DEFSPOOL; if (cgetstr(bp, "lo", &LO) == -1) LO = DEFLOCK; - (void) snprintf(line, sizeof(line), "%s/%s", SD, LO); + (void)snprintf(line, sizeof(line), "%s/%s", SD, LO); printf("%s:\n", printer); /* @@ -777,15 +756,13 @@ startpr(enable) * Print the status of each queue listed or all the queues. */ void -status(argc, argv) - int argc; - char *argv[]; +status(int argc, char **argv) { int c, status; char *cp1, *cp2; char prbuf[100]; - if (argc == 1 || (argc == 2 && !strcmp(argv[1], "all"))) { + if (argc == 1 || (argc == 2 && strcmp(argv[1], "all") == 0)) { printer = prbuf; while (cgetnext(&bp, printcapdb) > 0) { cp1 = prbuf; @@ -816,8 +793,8 @@ status(argc, argv) /* * Print the status of the printer queue. */ -void -prstat() +static void +prstat(void) { struct stat stbuf; int fd, i; @@ -831,7 +808,7 @@ prstat() if (cgetstr(bp, "st", &ST) == -1) ST = DEFSTAT; printf("%s:\n", printer); - (void) snprintf(line, sizeof(line), "%s/%s", SD, LO); + (void)snprintf(line, sizeof(line), "%s/%s", SD, LO); if (stat(line, &stbuf) >= 0) { printf("\tqueuing is %s\n", (stbuf.st_mode & 010) ? "disabled" : "enabled"); @@ -859,19 +836,21 @@ prstat() printf("\t%d entries in spool area\n", i); fd = open(line, O_RDONLY); if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) { - (void) close(fd); /* unlocks as well */ + (void)close(fd); /* unlocks as well */ printf("\tprinter idle\n"); return; } - (void) close(fd); - putchar('\t'); - (void) snprintf(line, sizeof(line), "%s/%s", SD, ST); + (void)close(fd); + (void)snprintf(line, sizeof(line), "%s/%s", SD, ST); fd = open(line, O_RDONLY); if (fd >= 0) { - (void) flock(fd, LOCK_SH); - while ((i = read(fd, line, sizeof(line))) > 0) - (void) fwrite(line, 1, i, stdout); - (void) close(fd); /* unlocks as well */ + (void)flock(fd, LOCK_SH); + if (fstat(fd, &stbuf) == 0 && stbuf.st_size > 0) { + putchar('\t'); + while ((i = read(fd, line, sizeof(line))) > 0) + (void)fwrite(line, 1, i, stdout); + } + (void)close(fd); /* unlocks as well */ } } @@ -880,9 +859,7 @@ prstat() * printing. */ void -stop(argc, argv) - int argc; - char *argv[]; +stop(int argc, char **argv) { int c, status; char *cp1, *cp2; @@ -892,7 +869,7 @@ stop(argc, argv) printf("Usage: stop {all | printer ...}\n"); return; } - if (argc == 2 && !strcmp(argv[1], "all")) { + if (argc == 2 && strcmp(argv[1], "all") == 0) { printer = prbuf; while (cgetnext(&bp, printcapdb) > 0) { cp1 = prbuf; @@ -920,8 +897,8 @@ stop(argc, argv) } } -void -stoppr() +static void +stoppr(void) { int fd; struct stat stbuf; @@ -930,7 +907,7 @@ stoppr() SD = _PATH_DEFSPOOL; if (cgetstr(bp, "lo", &LO) == -1) LO = DEFLOCK; - (void) snprintf(line, sizeof(line), "%s/%s", SD, LO); + (void)snprintf(line, sizeof(line), "%s/%s", SD, LO); printf("%s:\n", printer); /* @@ -948,7 +925,7 @@ stoppr() if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0) printf("\tcannot create lock file\n"); else { - (void) close(fd); + (void)close(fd); upstat("printing disabled\n"); printf("\tprinting disabled\n"); } @@ -965,9 +942,7 @@ time_t mtime; * Put the specified jobs at the top of printer queue. */ void -topq(argc, argv) - int argc; - char *argv[]; +topq(int argc, char **argv) { int i; struct stat stbuf; @@ -1027,7 +1002,7 @@ topq(argc, argv) */ seteuid(euid); if (changed && stat(LO, &stbuf) >= 0) - (void) chmod(LO, (stbuf.st_mode & 0777) | 01); + (void)chmod(LO, (stbuf.st_mode & 0777) | 01); out: seteuid(uid); @@ -1037,9 +1012,8 @@ out: * Reposition the job by changing the modification time of * the control file. */ -int -touch(q) - struct queue *q; +static int +touch(struct queue *q) { struct timeval tvp[2]; int ret; @@ -1057,8 +1031,7 @@ touch(q) * Returns: negative (-1) if argument name is not in the queue. */ int -doarg(job) - char *job; +doarg(char *job) { struct queue **qq; int jobnum, n; @@ -1114,7 +1087,7 @@ doarg(job) while (getline(fp) > 0) if (line[0] == 'P') break; - (void) fclose(fp); + (void)fclose(fp); if (line[0] != 'P' || strcmp(job, line+1) != 0) continue; if (touch(*qq) == 0) { @@ -1129,9 +1102,7 @@ doarg(job) * Enable everything and start printer (undo `down'). */ void -up(argc, argv) - int argc; - char *argv[]; +up(int argc, char **argv) { int c, status; char *cp1, *cp2; @@ -1141,7 +1112,7 @@ up(argc, argv) printf("Usage: up {all | printer ...}\n"); return; } - if (argc == 2 && !strcmp(argv[1], "all")) { + if (argc == 2 && strcmp(argv[1], "all") == 0) { printer = prbuf; while (cgetnext(&bp, printcapdb) > 0) { cp1 = prbuf; diff --git a/usr.sbin/lpr/lpc/cmdtab.c b/usr.sbin/lpr/lpc/cmdtab.c index c5eed18d597..2842b81dfbd 100644 --- a/usr.sbin/lpr/lpc/cmdtab.c +++ b/usr.sbin/lpr/lpc/cmdtab.c @@ -1,4 +1,5 @@ -/* $OpenBSD: cmdtab.c,v 1.3 2001/08/30 17:38:13 millert Exp $ */ +/* $OpenBSD: cmdtab.c,v 1.4 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: cmdtab.c,v 1.4 1995/11/15 22:27:34 pk Exp $ */ /* * Copyright (c) 1983, 1993 @@ -37,7 +38,7 @@ #if 0 static const char sccsid[] = "@(#)cmdtab.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: cmdtab.c,v 1.3 2001/08/30 17:38:13 millert Exp $"; +static const char rcsid[] = "$OpenBSD: cmdtab.c,v 1.4 2002/05/20 23:13:50 millert Exp $"; #endif #endif /* not lint */ diff --git a/usr.sbin/lpr/lpc/extern.h b/usr.sbin/lpr/lpc/extern.h index 16a1c725bb4..84efdd9bd83 100644 --- a/usr.sbin/lpr/lpc/extern.h +++ b/usr.sbin/lpr/lpc/extern.h @@ -1,4 +1,5 @@ -/* $OpenBSD: extern.h,v 1.3 2002/02/16 21:28:03 millert Exp $ */ +/* $OpenBSD: extern.h,v 1.4 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: extern.h,v 1.2 1995/11/15 22:27:36 pk Exp $ */ /* * Copyright (c) 1989, 1993 diff --git a/usr.sbin/lpr/lpc/lpc.8 b/usr.sbin/lpr/lpc/lpc.8 index 74754f3d334..b4781c1847a 100644 --- a/usr.sbin/lpr/lpc/lpc.8 +++ b/usr.sbin/lpr/lpc/lpc.8 @@ -1,4 +1,5 @@ -.\" $OpenBSD: lpc.8,v 1.9 2000/04/15 11:45:59 aaron Exp $ +.\" $OpenBSD: lpc.8,v 1.10 2002/05/20 23:13:50 millert Exp $ +.\" $NetBSD: lpc.8,v 1.14 2002/01/19 03:22:19 wiz Exp $ .\" .\" Copyright (c) 1983, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -41,10 +42,12 @@ .Nd line printer control program .Sh SYNOPSIS .Nm lpc +.Bk -words .Oo .Ar command .Op Ar argument ... .Oc +.Ek .Sh DESCRIPTION .Nm is used by the system administrator to control the @@ -87,7 +90,7 @@ or, if no argument is given, a list of the recognized commands. .It Ic abort No {\ all\ |\ printer\ } Terminate an active spooling daemon on the local host immediately and then disable printing (preventing new daemons from being started by -.Xr lpr ) +.Xr lpr 1 ) for the specified printers. .Pp .It Ic clean No {\ all\ |\ printer\ } @@ -98,7 +101,7 @@ from the specified printer queue(s) on the local machine. .It Ic disable No {\ all\ |\ printer\ } Turn the specified printer queues off. This prevents new printer jobs from being entered into the queue by -.Xr lpr . +.Xr lpr 1 . .Pp .It Xo Ic down No {\ all\ |\ printer\ } Ar message .Op Ar ... @@ -128,7 +131,7 @@ Exit from Attempt to start a new printer daemon. This is useful when some abnormal condition causes the daemon to die unexpectedly, leaving jobs in the queue. -.Xr Lpq +.Xr lpq 1 will report that there is no daemon present when this condition occurs. If the user is the superuser, try to abort the current daemon first (i.e., kill and restart a stuck daemon). @@ -152,20 +155,14 @@ Undoes the effects of .Ic down . .El .Sh FILES -.Bl -tag -width /var/spool/*/lockx -compact +.Bl -tag -width /var/spool/output/*/lock -compact .It Pa /etc/printcap printer description file -.It Pa /var/spool/* +.It Pa /var/spool/output/* spool directories -.It Pa /var/spool/*/lock +.It Pa /var/spool/output/*/lock lock file for queue control .El -.Sh SEE ALSO -.Xr lpq 1 , -.Xr lpr 1 , -.Xr lprm 1 , -.Xr printcap 5 , -.Xr lpd 8 .Sh DIAGNOSTICS .Bl -tag -width Ds .It Sy "?Ambiguous command" @@ -179,6 +176,12 @@ or user .Dq root to execute this command. .El +.Sh SEE ALSO +.Xr lpq 1 , +.Xr lpr 1 , +.Xr lprm 1 , +.Xr printcap 5 , +.Xr lpd 8 .Sh HISTORY The .Nm diff --git a/usr.sbin/lpr/lpc/lpc.c b/usr.sbin/lpr/lpc/lpc.c index 5b4cfc20c2a..adaf078440e 100644 --- a/usr.sbin/lpr/lpc/lpc.c +++ b/usr.sbin/lpr/lpc/lpc.c @@ -1,4 +1,5 @@ -/* $OpenBSD: lpc.c,v 1.12 2002/02/16 21:28:03 millert Exp $ */ +/* $OpenBSD: lpc.c,v 1.13 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: lpc.c,v 1.11 2001/11/14 03:01:15 enami Exp $ */ /* * Copyright (c) 1983, 1993 @@ -44,7 +45,7 @@ static const char copyright[] = #if 0 static const char sccsid[] = "@(#)lpc.c 8.3 (Berkeley) 4/28/95"; #else -static const char rcsid[] = "$OpenBSD: lpc.c,v 1.12 2002/02/16 21:28:03 millert Exp $"; +static const char rcsid[] = "$OpenBSD: lpc.c,v 1.13 2002/05/20 23:13:50 millert Exp $"; #endif #endif /* not lint */ @@ -56,11 +57,12 @@ static const char rcsid[] = "$OpenBSD: lpc.c,v 1.12 2002/02/16 21:28:03 millert #include <unistd.h> #include <stdlib.h> #include <stdio.h> +#include <err.h> #include <errno.h> #include <ctype.h> #include <string.h> #include <grp.h> -#include <sys/param.h> + #include "lp.h" #include "lpc.h" #include "extern.h" @@ -80,25 +82,22 @@ int fromatty; char cmdline[MAX_CMDLINE]; int margc; char *margv[MAX_MARGV]; -uid_t uid, euid; -void cmdscanner(void); -struct cmd *getcmd(char *); -void intr(int); -void makeargv(void); -int ingroup(char *); +static void cmdscanner(void); +static struct cmd *getcmd(char *); +static void intr(int); +static void makeargv(void); +static int ingroup(char *); int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char **argv) { struct cmd *c; euid = geteuid(); uid = getuid(); seteuid(uid); - openlog("lpd", 0, LOG_LPR); + openlog("lpc", 0, LOG_LPR); if (--argc > 0) { c = getcmd(*++argv); @@ -125,9 +124,8 @@ main(argc, argv) volatile sig_atomic_t gotintr; -void -intr(signo) - int signo; +static void +intr(int signo) { if (!fromatty) _exit(0); @@ -137,7 +135,7 @@ intr(signo) /* * Command parser. */ -void +static void cmdscanner(void) { struct cmd *c; @@ -183,9 +181,8 @@ cmdscanner(void) } } -struct cmd * -getcmd(name) - char *name; +static struct cmd * +getcmd(char *name) { char *p, *q; struct cmd *c, *found; @@ -194,7 +191,7 @@ getcmd(name) longest = 0; nmatches = 0; found = 0; - for (c = cmdtab; (p = c->c_name); c++) { + for (c = cmdtab; (p = c->c_name) != NULL; c++) { for (q = name; *q == *p++; q++) if (*q == 0) /* exact match? */ return(c); @@ -215,8 +212,8 @@ getcmd(name) /* * Slice a string up into argc/argv. */ -void -makeargv() +static void +makeargv(void) { char *cp; char **argp = margv; @@ -240,22 +237,19 @@ makeargv() *argp++ = 0; } -#define HELPINDENT (sizeof ("directory")) +#define HELPINDENT ((int)sizeof("directory")) /* * Help command. */ void -help(argc, argv) - int argc; - char *argv[]; +help(int argc, char **argv) { struct cmd *c; if (argc == 1) { int i, j, w; int columns, width = 0, lines; - extern int NCMDS; printf("Commands may be abbreviated. Commands are:\n\n"); for (c = cmdtab; c->c_name; c++) { @@ -304,29 +298,25 @@ help(argc, argv) /* * return non-zero if the user is a member of the given group */ -int -ingroup(grname) - char *grname; +static int +ingroup(char *grname) { - gid_t gid; - int i; static struct group *gptr = NULL; static gid_t groups[NGROUPS]; - static int maxgroups; + static int ngroups; + gid_t gid; + int i; if (gptr == NULL) { if ((gptr = getgrnam(grname)) == NULL) { - fprintf(stderr, "Warning: unknown group '%s'\n", - grname); + warnx("Warning: unknown group `%s'", grname); return(0); } - if ((maxgroups = getgroups(NGROUPS, groups)) < 0) { - perror("getgroups"); - exit(1); - } + if ((ngroups = getgroups(NGROUPS, groups)) < 0) + err(1, "getgroups"); } gid = gptr->gr_gid; - for (i = 0; i < maxgroups; i++) + for (i = 0; i < ngroups; i++) if (gid == groups[i]) return(1); return(0); diff --git a/usr.sbin/lpr/lpc/lpc.h b/usr.sbin/lpr/lpc/lpc.h index 281eb2d2c1e..0fac84511ea 100644 --- a/usr.sbin/lpr/lpc/lpc.h +++ b/usr.sbin/lpr/lpc/lpc.h @@ -1,4 +1,5 @@ -/* $OpenBSD: lpc.h,v 1.3 2002/02/16 21:28:03 millert Exp $ */ +/* $OpenBSD: lpc.h,v 1.4 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: lpc.h,v 1.2 1995/11/15 22:27:44 pk Exp $ */ /* * Copyright (c) 1983, 1993 diff --git a/usr.sbin/lpr/lpd/Makefile b/usr.sbin/lpr/lpd/Makefile index 5bc1260e801..5698aed8d73 100644 --- a/usr.sbin/lpr/lpd/Makefile +++ b/usr.sbin/lpr/lpd/Makefile @@ -1,11 +1,11 @@ # from: @(#)Makefile 8.1 (Berkeley) 6/6/93 -# $OpenBSD: Makefile,v 1.2 1997/01/17 16:12:39 millert Exp $ +# $OpenBSD: Makefile,v 1.3 2002/05/20 23:13:50 millert Exp $ PROG= lpd CFLAGS+=-I${.CURDIR}/../common_source MAN= lpd.8 SRCS= lpd.c printjob.c recvjob.c displayq.c rmjob.c startdaemon.c \ - lpdchar.c common.c key.c modes.c ttcompat.c + lpdchar.c common.c key.c modes.c ttcompat.c common_vars.c .PATH: ${.CURDIR}/../common_source .include "../../Makefile.inc" diff --git a/usr.sbin/lpr/lpd/extern.h b/usr.sbin/lpr/lpd/extern.h index 9c1ff356469..3314226f517 100644 --- a/usr.sbin/lpr/lpd/extern.h +++ b/usr.sbin/lpr/lpd/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.4 2002/02/16 21:28:03 millert Exp $ */ +/* $OpenBSD: extern.h,v 1.5 2002/05/20 23:13:50 millert Exp $ */ /* * Copyright (c) 1989, 1993 @@ -36,8 +36,8 @@ */ #include <sys/cdefs.h> -#include <termios.h> #include <sys/ioctl.h> +#include <termios.h> /* * from stty.h @@ -53,11 +53,11 @@ struct info { struct winsize win; /* window info */ }; +int ksearch(char ***, struct info *); +int msearch(char ***, struct info *); void printjob(void); void recvjob(void); void sttyclearflags(struct termios *tp, int flags); void sttysetflags(struct termios *tp, int flags); void sttyclearlflags(struct termios *tp, int flags); void sttysetlflags(struct termios *tp, int flags); -int ksearch(char ***, struct info *); -int msearch(char ***, struct info *); diff --git a/usr.sbin/lpr/lpd/key.c b/usr.sbin/lpr/lpd/key.c index 259e97f28a6..bb1b136dfc8 100644 --- a/usr.sbin/lpr/lpd/key.c +++ b/usr.sbin/lpr/lpd/key.c @@ -1,4 +1,5 @@ -/* $OpenBSD: key.c,v 1.4 2002/02/16 21:28:03 millert Exp $ */ +/* $OpenBSD: key.c,v 1.5 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: key.c,v 1.3 1997/10/20 08:08:28 scottr Exp $ */ /*- * Copyright (c) 1991, 1993, 1994 @@ -37,7 +38,7 @@ #if 0 static const char sccsid[] = "@(#)key.c 8.3 (Berkeley) 4/2/94"; #else -static const char rcsid[] = "$OpenBSD: key.c,v 1.4 2002/02/16 21:28:03 millert Exp $"; +static const char rcsid[] = "$OpenBSD: key.c,v 1.5 2002/05/20 23:13:50 millert Exp $"; #endif #endif /* not lint */ @@ -56,6 +57,8 @@ static const char rcsid[] = "$OpenBSD: key.c,v 1.4 2002/02/16 21:28:03 millert E #include "extern.h" __BEGIN_DECLS +static int + c_key(const void *, const void *); void f_cbreak(struct info *); void f_columns(struct info *); void f_dec(struct info *); @@ -75,7 +78,7 @@ static struct key { #define F_NEEDARG 0x01 /* needs an argument */ #define F_OFFOK 0x02 /* can turn off */ int flags; -} keys[] = { +} const keys[] = { { "cbreak", f_cbreak, F_OFFOK }, { "cols", f_columns, F_NEEDARG }, { "columns", f_columns, F_NEEDARG }, @@ -94,17 +97,14 @@ static struct key { }; static int -c_key(a, b) - const void *a, *b; +c_key(const void *a, const void *b) { return (strcmp(((struct key *)a)->name, ((struct key *)b)->name)); } int -ksearch(argvp, ip) - char ***argvp; - struct info *ip; +ksearch(char ***argvp, struct info *ip) { char *name; struct key *kp, tmp; @@ -134,8 +134,7 @@ ksearch(argvp, ip) } void -f_cbreak(ip) - struct info *ip; +f_cbreak(struct info *ip) { if (ip->off) @@ -150,8 +149,7 @@ f_cbreak(ip) } void -f_columns(ip) - struct info *ip; +f_columns(struct info *ip) { ip->win.ws_col = atoi(ip->arg); @@ -159,8 +157,7 @@ f_columns(ip) } void -f_dec(ip) - struct info *ip; +f_dec(struct info *ip) { ip->t.c_cc[VERASE] = (u_char)0177; @@ -173,8 +170,7 @@ f_dec(ip) } void -f_extproc(ip) - struct info *ip; +f_extproc(struct info *ip) { if (ip->set) { @@ -187,8 +183,7 @@ f_extproc(ip) } void -f_ispeed(ip) - struct info *ip; +f_ispeed(struct info *ip) { cfsetispeed(&ip->t, atoi(ip->arg)); @@ -196,8 +191,7 @@ f_ispeed(ip) } void -f_nl(ip) - struct info *ip; +f_nl(struct info *ip) { if (ip->off) { @@ -211,8 +205,7 @@ f_nl(ip) } void -f_ospeed(ip) - struct info *ip; +f_ospeed(struct info *ip) { cfsetospeed(&ip->t, atoi(ip->arg)); @@ -220,8 +213,7 @@ f_ospeed(ip) } void -f_raw(ip) - struct info *ip; +f_raw(struct info *ip) { if (ip->off) @@ -235,8 +227,7 @@ f_raw(ip) } void -f_rows(ip) - struct info *ip; +f_rows(struct info *ip) { ip->win.ws_row = atoi(ip->arg); @@ -244,8 +235,7 @@ f_rows(ip) } void -f_sane(ip) - struct info *ip; +f_sane(struct info *ip) { ip->t.c_cflag = TTYDEF_CFLAG | (ip->t.c_cflag & (CLOCAL|CRTSCTS)); @@ -259,8 +249,7 @@ f_sane(ip) } void -f_tty(ip) - struct info *ip; +f_tty(struct info *ip) { int tmp; diff --git a/usr.sbin/lpr/lpd/lpd.8 b/usr.sbin/lpr/lpd/lpd.8 index 1bf56259249..01509468aca 100644 --- a/usr.sbin/lpr/lpd/lpd.8 +++ b/usr.sbin/lpr/lpd/lpd.8 @@ -1,4 +1,5 @@ -.\" $OpenBSD: lpd.8,v 1.10 2000/03/19 17:57:06 aaron Exp $ +.\" $OpenBSD: lpd.8,v 1.11 2002/05/20 23:13:50 millert Exp $ +.\" $NetBSD: lpd.8,v 1.23 2002/02/08 01:38:50 ross Exp $ .\" .\" Copyright (c) 1983, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -33,7 +34,7 @@ .\" .\" @(#)lpd.8 8.3 (Berkeley) 4/19/94 .\" -.Dd April 19, 1994 +.Dd May 18, 2002 .Dt LPD 8 .Os .Sh NAME @@ -41,7 +42,11 @@ .Nd line printer spooler daemon .Sh SYNOPSIS .Nm lpd -.Op Fl l +.Op Fl dlsrW +.Op Fl b Ar bind-address +.Op Fl n Ar maxchild +.Op Fl w Ar maxwait +.Op port .Sh DESCRIPTION .Nm is the line printer daemon (spool area handler) and is normally invoked @@ -50,37 +55,123 @@ at boot time from the file. It makes a single pass through the .Xr printcap 5 -file to find out about the existing printers and -prints any files left after a crash. +file to find out about the existing printers and prints any files +left after a crash. It then uses the system calls .Xr listen 2 and .Xr accept 2 -to receive requests to print files in the queue, -transfer files to the spooling area, display the queue, -or remove jobs from the queue. -In each case, it forks a child to handle -the request so the parent can continue to listen for more requests. +to receive requests to print files in the queue, transfer files to +the spooling area, display the queue, or remove jobs from the queue. +In each case, it forks a child to handle the request so the parent +can continue to listen for more requests. .Pp The options are as follows: .Bl -tag -width Ds +.It Fl b +Normally, if the +.Fl s +option is not specified, +.Nm +will listen on all network interfaces for incoming TCP connections. +The +.Fl b +option, followed by a +.Ar bind-address +specifies that +.Nm +should listen on that address instead of INADDR_ANY. +Multiple +.Fl b +options are permitted, allowing a list of addresses to be specified. +Use of this option silently overrides the +.Fl s +option if it is also present on the command line. +.Ar bind-address +can be a numeric host name in IPV4 or IPV6 notation, or a symbolic host +name which will be looked up in the normal way. +.It Fl d +The +.Fl d +option turns on the +.Dv SO_DEBUG +.Xr socket 2 +option. See +.Xr setsockopt 2 +for more details. .It Fl l -Cause +The +.Fl l +flag causes .Nm to log valid requests received from the network. This can be useful for debugging purposes. +.It Fl n +The +.Fl n +flag sets +.Ar maxchild +as the maximum number of child processes that +.Nm +will spawn. The default is 32. +.It Fl r +The +.Fl r +flag allows the +.Dq of +filter to be use if specified for a remote +printer. Traditionally, +.Nm +would not use the output filter for remote printers. +.It Fl s +The +.Fl s +flag selects +.Dq secure +mode, in which +.Nm +does not listen on a TCP socket but only takes commands from a +.Ux +domain socket. +This is valuable when the machine on which +.Nm +runs is subject to attack over the network and it is desired that the +machine be protected from attempts to remotely fill spools and similar +attacks. +.It Fl w +The +.Fl w +flag sets +.Ar maxwait +as the wait time (in seconds) for dead remote server detection. If +no response is returned from a connected server within this period, +the connection is closed and a message logged. The default is +120 seconds. +.It Fl W +The +.Fl W +option will instruct lpd not to verify a remote tcp connection +comes from a reserved port (<1024). .El .Pp +If the +.Op port +parameter is passed, +.Nm +listens on this port instead of the usual +.Dq printer/tcp +port from +.Pa /etc/services . +.Pp Access control is provided by two means. -First, all requests must come from -one of the machines listed in the file +First, all requests must come from one of the machines listed in the file .Pa /etc/hosts.equiv or .Pa /etc/hosts.lpd . Second, if the .Dq rs capability is specified in the -.Xr printcap +.Xr printcap 5 entry for the printer being accessed, .Em lpr requests will only be honored for those users with accounts on the @@ -102,10 +193,9 @@ for files beginning with .Em cf . Lines in each .Em cf -file specify files to be printed or non-printing actions to be -performed. -Each such line begins with a key character -to specify what to do with the remainder of the line. +file specify files to be printed or non-printing actions to be performed. +Each such line begins with a key character to specify what to do +with the remainder of the line. .Bl -tag -width Ds .It J Job Name. @@ -115,8 +205,8 @@ Classification. String to be used for the classification line on the burst page. .It L Literal. -The line contains identification info from -the password file and causes the banner page to be printed. +The line contains identification info from the password file and +causes the banner page to be printed. .It T Title. String to be used as the title for @@ -162,11 +252,11 @@ DVI format from Standford. .It g Graph File. The file contains data produced by -.Xr plot 3 . +.Ic plot . .It c Cifplot File. The file contains data produced by -.Em cifplot . +.Ic cifplot . .It v The file contains a raster image. .It r @@ -197,8 +287,8 @@ Unlink. Name of file to remove upon completion of printing. .It N File name. -The name of the file which is being printed, or a blank -for the standard input (when +The name of the file which is being printed, or a blank for the +standard input (when .Xr lpr 1 is invoked in a pipeline). .El @@ -209,17 +299,16 @@ using the .Dv LOG_LPR facility. .Nm -will try up to 20 times -to reopen a file it expects to be there, after which it will -skip the file to be printed. +will try up to 20 times to reopen a file it expects to be there, +after which it will skip the file to be printed. .Pp .Nm uses .Xr flock 2 to provide exclusive access to the lock file and to prevent multiple daemons from becoming active simultaneously. -If the daemon should be killed -or die unexpectedly, the lock file need not be removed. +If the daemon should be killed or die unexpectedly, the lock file +need not be removed. The lock file is kept in a readable .Tn ASCII form @@ -233,12 +322,15 @@ for the programs and .Xr lprm 1 . .Sh FILES -.Bl -tag -width "/var/spool/*/minfree" -compact +.Bl -tag -width "/var/spool/output/*/minfree" -compact .It Pa /etc/printcap printer description file -.It Pa /var/spool/* +.It Pa /var/run/lpd.pid +lock file for +.Nm +.It Pa /var/spool/output/* spool directories -.It Pa /var/spool/*/minfree +.It Pa /var/spool/output/*/minfree minimum free space to leave .It Pa /dev/lp* line printer devices @@ -248,18 +340,19 @@ socket for local requests lists machine names allowed printer access .It Pa /etc/hosts.lpd lists machine names allowed printer access, -but not under same administrative control +but not under same administrative control. .El .Sh SEE ALSO .Xr lpq 1 , .Xr lpr 1 , .Xr lprm 1 , .Xr syslog 3 , +.Xr hosts.equiv 5 , .Xr printcap 5 , .Xr lpc 8 , .Xr pac 8 .Rs -.%T "BSD 4.3 Line printer manual" +.%T "4.3BSD Line Printer Spooler Manual" .Re .Sh HISTORY An diff --git a/usr.sbin/lpr/lpd/lpd.c b/usr.sbin/lpr/lpd/lpd.c index d9465a32cc9..a1003852ed2 100644 --- a/usr.sbin/lpr/lpd/lpd.c +++ b/usr.sbin/lpr/lpd/lpd.c @@ -1,5 +1,5 @@ -/* $OpenBSD: lpd.c,v 1.28 2002/02/16 21:28:03 millert Exp $ */ -/* $NetBSD: lpd.c,v 1.7 1996/04/24 14:54:06 mrg Exp $ */ +/* $OpenBSD: lpd.c,v 1.29 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: lpd.c,v 1.33 2002/01/21 14:42:29 wiz Exp $ */ /* * Copyright (c) 1983, 1993, 1994 @@ -45,7 +45,7 @@ static const char copyright[] = #if 0 static const char sccsid[] = "@(#)lpd.c 8.7 (Berkeley) 5/10/95"; #else -static const char rcsid[] = "$OpenBSD: lpd.c,v 1.28 2002/02/16 21:28:03 millert Exp $"; +static const char rcsid[] = "$OpenBSD: lpd.c,v 1.29 2002/05/20 23:13:50 millert Exp $"; #endif #endif /* not lint */ @@ -88,72 +88,146 @@ static const char rcsid[] = "$OpenBSD: lpd.c,v 1.28 2002/02/16 21:28:03 millert #include <netinet/in.h> #include <arpa/inet.h> -#include <netdb.h> -#include <unistd.h> -#include <syslog.h> -#include <signal.h> +#include <ctype.h> +#include <dirent.h> +#include <err.h> #include <errno.h> #include <fcntl.h> -#include <dirent.h> +#include <netdb.h> +#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <ctype.h> +#include <syslog.h> +#include <unistd.h> + #include "lp.h" #include "lp.local.h" #include "pathnames.h" #include "extern.h" -extern int __ivaliduser(FILE *, in_addr_t, const char *, const char *); +#define LPD_NOPORTCHK 0001 /* skip reserved-port check */ int lflag; /* log requests flag */ +int rflag; /* allow 'of' for remote printers */ +int sflag; /* secure (no inet) flag */ int from_remote; /* from remote socket */ +char **blist; /* list of addresses to bind(2) to */ +int blist_size; +int blist_addrs; + +volatile sig_atomic_t child_count; /* number of kids forked */ -static void reapchild(int); -static void mcleanup(int); -static void doit(void); -static void startup(void); -static void chkhost(struct sockaddr_in *); -static int ckqueue(char *); +static void reapchild(int); +static void mcleanup(int); +static void doit(void); +static void startup(void); +static void chkhost(struct sockaddr *, int); +static int ckqueue(char *); +static __dead void usage(void); +static int *socksetup(int, int, const char *); + +extern int __ivaliduser_sa(FILE *, struct sockaddr *, socklen_t, + const char *, const char *); /* unused, needed for lpc */ volatile sig_atomic_t gotintr; -uid_t uid, euid; - int -main(argc, argv) - int argc; - char **argv; +main(int argc, char **argv) { - int f, lfd, funix, finet, options, fromlen; fd_set defreadfds; - int maxfd = 0; struct sockaddr_un un, fromunix; - struct sockaddr_in sin, frominet; + struct sockaddr_storage frominet; sigset_t mask, omask; + int lfd, i, f, funix, *finet; + int options, check_options, maxfd; + long l; + long child_max = 32; /* more then enough to hose the system */ + struct servent *sp; + const char *port = "printer"; + char *cp; euid = geteuid(); /* these shouldn't be different */ uid = getuid(); - options = 0; + maxfd = options = check_options = 0; gethostname(host, sizeof(host)); - if (euid != 0) { - fprintf(stderr,"lpd: must run as root\n"); - exit(1); - } - - while (--argc > 0) { - argv++; - if (argv[0][0] == '-') - switch (argv[0][1]) { - case 'd': - options |= SO_DEBUG; - break; - case 'l': - lflag++; - break; + if (euid != 0) + errx(1, "must run as root"); + + while ((i = getopt(argc, argv, "b:cdln:rsw:W")) != -1) { + switch (i) { + case 'b': + if (blist_addrs >= blist_size) { + blist_size += sizeof(char *) * 4; + if (blist == NULL) + blist = malloc(blist_size); + else + blist = realloc(blist, blist_size); + if (blist == NULL) + err(1, "cant allocate bind addr list"); } + blist[blist_addrs] = strdup(optarg); + if (blist[blist_addrs++] == NULL) + err(1, NULL); + break; + case 'd': + options |= SO_DEBUG; + break; + case 'l': + lflag++; + break; + case 'n': + child_max = strtol(optarg, &cp, 10); + if (*cp != '\0' || child_max < 0 || child_max > 1024) + errx(1, "invalid number of children: %s", + optarg); + break; + case 'r': + rflag++; + break; + case 's': + sflag++; + break; + case 'w': + l = strtol(optarg, &cp, 10); + if (*cp != '\0' || l < 0 || l >= INT_MAX) + errx(1, "wait time must be postive integer: %s", + optarg); + wait_time = (u_int)l; + if (wait_time < 30) + warnx("warning: wait time less than 30 seconds"); + break; + case 'W': + /* + * Allow connections coming from a non-reserved port. + * (done by some lpr-implementations for MS-Windows) + */ + check_options |= LPD_NOPORTCHK; + break; + default: + usage(); + break; + } + } + argc -= optind; + argv += optind; + + switch (argc) { + case 1: + port = argv[0]; + l = strtol(port, &cp, 10); + if (*cp != '\0' || l <= 0 || l > USHRT_MAX) + errx(1, "port # %s is invalid", port); + break; + case 0: + sp = getservbyname(port, "tcp"); + if (sp == NULL) + errx(1, "%s/tcp: unknown service", port); + break; + default: + usage(); } #ifndef DEBUG @@ -165,7 +239,7 @@ main(argc, argv) openlog("lpd", LOG_PID, LOG_LPR); syslog(LOG_INFO, "restarted"); - (void) umask(0); + (void)umask(0); lfd = open(_PATH_MASTERLOCK, O_WRONLY|O_CREAT, 0644); if (lfd < 0) { syslog(LOG_ERR, "%s: %m", _PATH_MASTERLOCK); @@ -181,7 +255,7 @@ main(argc, argv) /* * write process id for others to know */ - sprintf(line, "%u\n", getpid()); + (void)snprintf(line, sizeof(line), "%u\n", getpid()); f = strlen(line); if (write(lfd, line, f) != f) { syslog(LOG_ERR, "%s: %m", _PATH_MASTERLOCK); @@ -192,26 +266,28 @@ main(argc, argv) * Restart all the printers. */ startup(); - (void) unlink(_PATH_SOCKETNAME); - funix = socket(AF_UNIX, SOCK_STREAM, 0); + (void)unlink(_PATH_SOCKETNAME); + funix = socket(AF_LOCAL, SOCK_STREAM, 0); if (funix < 0) { syslog(LOG_ERR, "socket: %m"); exit(1); } + sigemptyset(&mask); sigaddset(&mask, SIGHUP); sigaddset(&mask, SIGINT); sigaddset(&mask, SIGQUIT); sigaddset(&mask, SIGTERM); sigprocmask(SIG_BLOCK, &mask, &omask); - (void) umask(07); + + (void)umask(07); signal(SIGHUP, mcleanup); signal(SIGINT, mcleanup); signal(SIGQUIT, mcleanup); signal(SIGTERM, mcleanup); memset(&un, 0, sizeof(un)); - un.sun_family = AF_UNIX; - strcpy(un.sun_path, _PATH_SOCKETNAME); + un.sun_family = AF_LOCAL; + strlcpy(un.sun_path, _PATH_SOCKETNAME, sizeof(un.sun_path)); #ifndef SUN_LEN #define SUN_LEN(unp) (strlen((unp)->sun_path) + 2) #endif @@ -219,42 +295,29 @@ main(argc, argv) syslog(LOG_ERR, "ubind: %m"); exit(1); } - (void) umask(0); + (void)umask(0); sigprocmask(SIG_SETMASK, &omask, NULL); FD_ZERO(&defreadfds); FD_SET(funix, &defreadfds); if (funix > maxfd) maxfd = funix; listen(funix, 5); - finet = socket(AF_INET, SOCK_STREAM, 0); - if (finet >= 0) { - struct servent *sp; - - if (options & SO_DEBUG) { - if (setsockopt(finet, SOL_SOCKET, SO_DEBUG, 0, 0) < 0) { - syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m"); - mcleanup(0); - } - } - f = 1; - (void) setsockopt(finet, SOL_SOCKET, SO_REUSEADDR, &f, - sizeof(f)); - sp = getservbyname("printer", "tcp"); - if (sp == NULL) { - syslog(LOG_ERR, "printer/tcp: unknown service"); - mcleanup(0); - } - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_port = sp->s_port; - if (bind(finet, (struct sockaddr *)&sin, sizeof(sin)) < 0) { - syslog(LOG_ERR, "bind: %m"); - mcleanup(0); + if (!sflag || blist_addrs) + finet = socksetup(PF_UNSPEC, options, port); + else + finet = NULL; /* pretend we couldn't open TCP socket. */ + + if (blist != NULL) { + for (i = 0; i < blist_addrs; i++) + free(blist[i]); + free(blist); + } + + if (finet) { + for (i = 1; i <= *finet; i++) { + FD_SET(finet[i], &defreadfds); + listen(finet[i], 5); } - FD_SET(finet, &defreadfds); - if (finet > maxfd) - maxfd = finet; - listen(finet, 5); } /* * Main loop: accept, do a request, continue. @@ -262,8 +325,21 @@ main(argc, argv) memset(&frominet, 0, sizeof(frominet)); memset(&fromunix, 0, sizeof(fromunix)); for (;;) { - int domain, nfds, s; + int domain, nfds, s, fromlen; fd_set readfds; + short sleeptime = 10; /* overflows in about 2 hours */ + + while (child_max < child_count) { + syslog(LOG_WARNING, + "too many children, sleeping for %d seconds", + sleeptime); + sleep(sleeptime); + sleeptime <<= 1; + if (sleeptime < 0) { + syslog(LOG_CRIT, "sleeptime overflowed! help!"); + sleeptime = 10; + } + } FD_COPY(&defreadfds, &readfds); nfds = select(maxfd + 1, &readfds, 0, 0, 0); @@ -273,62 +349,93 @@ main(argc, argv) continue; } if (FD_ISSET(funix, &readfds)) { - domain = AF_UNIX, fromlen = sizeof(fromunix); + domain = AF_LOCAL; + fromlen = sizeof(fromunix); s = accept(funix, (struct sockaddr *)&fromunix, &fromlen); - } else /* if (FD_ISSET(finet, &readfds)) */ { - domain = AF_INET, fromlen = sizeof(frominet); - s = accept(finet, - (struct sockaddr *)&frominet, &fromlen); - if (frominet.sin_port == htons(20)) { - close(s); - continue; - } + } else { + domain = AF_INET; + s = -1; + for (i = 1; i <= *finet; i++) + if (FD_ISSET(finet[i], &readfds)) { + in_port_t port; + + fromlen = sizeof(frominet); + s = accept(finet[i], + (struct sockaddr *)&frominet, + &fromlen); + switch (frominet.ss_family) { + case AF_INET: + port = ((struct sockaddr_in *) + &frominet)->sin_port; + break; + case AF_INET6: + port = ((struct sockaddr_in6 *) + &frominet)->sin6_port; + break; + default: + port = 0; + } + /* check for ftp bounce attack */ + if (port == htons(20)) { + close(s); + continue; + } + } } if (s < 0) { if (errno != EINTR) syslog(LOG_WARNING, "accept: %m"); continue; } - if (fork() == 0) { + + switch (fork()) { + case 0: signal(SIGCHLD, SIG_DFL); signal(SIGHUP, SIG_IGN); signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGTERM, SIG_IGN); - (void) close(funix); - (void) close(finet); + (void)close(funix); + if (!sflag && finet) + for (i = 1; i <= *finet; i++) + (void)close(finet[i]); if (s != STDOUT_FILENO) { dup2(s, STDOUT_FILENO); - (void) close(s); + (void)close(s); } if (domain == AF_INET) { + /* for both AF_INET and AF_INET6 */ from_remote = 1; - chkhost(&frominet); + chkhost((struct sockaddr *)&frominet, check_options); } else from_remote = 0; doit(); exit(0); + case -1: + syslog(LOG_WARNING, "fork: %m, sleeping for 10 seconds..."); + sleep(10); + continue; + default: + child_count++; } - (void) close(s); + (void)close(s); } } static void -reapchild(signo) - int signo; +reapchild(int signo) { int save_errno = errno; int status; while (waitpid((pid_t)-1, &status, WNOHANG) > 0) - ; + child_count--; errno = save_errno; } static void -mcleanup(signo) - int signo; +mcleanup(int signo) { struct syslog_data sdata = SYSLOG_DATA_INIT; @@ -347,7 +454,7 @@ int requ[MAXREQUESTS]; /* job number of spool entries */ int requests; /* # of spool requests */ char *person; /* name of person doing lprm */ -char fromb[MAXHOSTNAMELEN]; /* buffer for client's machine name */ +char fromb[NI_MAXHOST]; /* buffer for client's machine name */ char cbuf[BUFSIZ]; /* command line buffer */ char *cmdnames[] = { "null", @@ -359,7 +466,7 @@ char *cmdnames[] = { }; static void -doit() +doit(void) { char *cp; int n; @@ -369,7 +476,7 @@ doit() do { if (cp >= &cbuf[sizeof(cbuf) - 1]) fatal("Command line too long"); - if ((n = read(1, cp, 1)) != 1) { + if ((n = read(STDOUT_FILENO, cp, 1)) != 1) { if (n < 0) fatal("Lost connection"); return; @@ -378,16 +485,20 @@ doit() *--cp = '\0'; cp = cbuf; if (lflag) { - if (*cp >= '\1' && *cp <= '\5') + if (*cp >= '\1' && *cp <= '\5') { syslog(LOG_INFO, "%s requests %s %s", from, cmdnames[(int)*cp], cp+1); - else + setproctitle("serving %s: %s %s", from, + cmdnames[(int)*cp], cp+1); + } else syslog(LOG_INFO, "bad request (%d) from %s", *cp, from); } switch (*cp++) { case '\1': /* check the queue and print any jobs there */ printer = cp; + if (*printer == '\0') + printer = DEFLP; printjob(); break; case '\2': /* receive files to be queued */ @@ -396,11 +507,15 @@ doit() exit(1); } printer = cp; + if (*printer == '\0') + printer = DEFLP; recvjob(); break; case '\3': /* display the queue (short form) */ case '\4': /* display the queue (long form) */ printer = cp; + if (*printer == '\0') + printer = DEFLP; while (*cp) { if (*cp != ' ') { cp++; @@ -429,6 +544,8 @@ doit() exit(1); } printer = cp; + if (*printer == '\0') + printer = DEFLP; while (*cp && *cp != ' ') cp++; if (!*cp) @@ -467,11 +584,10 @@ doit() * files left from the last time the machine went down. */ static void -startup() +startup(void) { char *buf; char *cp; - int pid; /* * Restart the daemons. @@ -488,17 +604,21 @@ startup() } if (lflag) syslog(LOG_INFO, "work for %s", buf); - if ((pid = fork()) < 0) { + switch (fork()) { + case -1: syslog(LOG_WARNING, "startup: cannot fork"); mcleanup(0); - } - if (!pid) { + /* NOTREACHED */ + case 0: printer = buf; + setproctitle("working on printer %s", printer); cgetclose(); printjob(); /* NOTREACHED */ + default: + child_count++; + free(buf); } - else free(buf); } } @@ -506,8 +626,7 @@ startup() * Make sure there's some work to do before forking off a child */ static int -ckqueue(cap) - char *cap; +ckqueue(char *cap) { struct dirent *d; DIR *dirp; @@ -533,47 +652,74 @@ ckqueue(cap) * Check to see if the from host has access to the line printer. */ static void -chkhost(f) - struct sockaddr_in *f; +chkhost(struct sockaddr *f, int check_opts) { - struct hostent *hp; + struct addrinfo hints, *res, *r; FILE *hostf; int first = 1; int good = 0; + char host[NI_MAXHOST], ip[NI_MAXHOST]; + char serv[NI_MAXSERV]; + int error; + + error = getnameinfo(f, f->sa_len, NULL, 0, serv, sizeof(serv), + NI_NUMERICSERV); + if (error) + fatal("Malformed from address"); + + if (!(check_opts & LPD_NOPORTCHK) && + atoi(serv) >= IPPORT_RESERVED) + fatal("Connect from invalid port (%s)", serv); /* Need real hostname for temporary filenames */ - hp = gethostbyaddr((char *)&f->sin_addr, - sizeof(struct in_addr), f->sin_family); - if (hp == NULL) - fatal("Host name for your address (%s) unknown", - inet_ntoa(f->sin_addr)); + error = getnameinfo(f, f->sa_len, host, sizeof(host), NULL, 0, + NI_NAMEREQD); + if (error) { + error = getnameinfo(f, f->sa_len, host, sizeof(host), NULL, 0, + NI_NUMERICHOST); + if (error) + fatal("Host name for your address unknown"); + else + fatal("Host name for your address (%s) unknown", host); + } - (void) strlcpy(fromb, hp->h_name, sizeof(fromb)); + (void)strlcpy(fromb, host, sizeof(fromb)); from = fromb; + /* need address in stringform for comparison (no DNS lookup here) */ + error = getnameinfo(f, f->sa_len, host, sizeof(host), NULL, 0, + NI_NUMERICHOST); + if (error) + fatal("Cannot print address"); + /* Check for spoof, ala rlogind */ - hp = gethostbyname(fromb); - if (!hp) - fatal("hostname for your address (%s) unknown", - inet_ntoa(f->sin_addr)); - for (; good == 0 && hp->h_addr_list[0] != NULL; hp->h_addr_list++) { - if (!bcmp(hp->h_addr_list[0], (caddr_t)&f->sin_addr, - sizeof(f->sin_addr))) + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; /*dummy*/ + error = getaddrinfo(fromb, NULL, &hints, &res); + if (error) { + fatal("hostname for your address (%s) unknown: %s", host, + gai_strerror(error)); + } + for (good = 0, r = res; good == 0 && r; r = r->ai_next) { + error = getnameinfo(r->ai_addr, r->ai_addrlen, ip, sizeof(ip), + NULL, 0, NI_NUMERICHOST); + if (!error && !strcmp(host, ip)) good = 1; } + if (res) + freeaddrinfo(res); if (good == 0) - fatal("address for your hostname (%s) not matched", - inet_ntoa(f->sin_addr)); - + fatal("address for your hostname (%s) not matched", host); + setproctitle("serving %s", from); hostf = fopen(_PATH_HOSTSEQUIV, "r"); again: if (hostf) { - if (__ivaliduser(hostf, f->sin_addr.s_addr, - DUMMY, DUMMY) == 0) { - (void) fclose(hostf); + if (__ivaliduser_sa(hostf, f, f->sa_len, DUMMY, DUMMY) == 0) { + (void)fclose(hostf); return; } - (void) fclose(hostf); + (void)fclose(hostf); } if (first == 1) { first = 0; @@ -583,3 +729,93 @@ again: fatal("Your host does not have line printer access"); /*NOTREACHED*/ } + +static __dead void +usage(void) +{ + extern char *__progname; + + fprintf(stderr, "usage: %s [-dlrsW] [-b bind-address] [-n maxchild] " + "[-w maxwait] [port]\n", __progname); + exit(1); +} + +/* + * Setup server socket for specified address family. + * If af is PF_UNSPEC more than one socket may be returned. + * The returned list is dynamically allocated, so the caller needs to free it. + */ +int * +socksetup(int af, int options, const char *port) +{ + struct addrinfo hints, *res, *r; + int error, maxs = 0, *s, *socks = NULL, blidx = 0; + const int on = 1; + + do { + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_PASSIVE; + hints.ai_family = af; + hints.ai_socktype = SOCK_STREAM; + error = getaddrinfo((blist_addrs == 0) ? NULL : blist[blidx], + port ? port : "printer", &hints, &res); + if (error) { + if (blist_addrs) + syslog(LOG_ERR, "%s: %s", blist[blidx], + gai_strerror(error)); + else + syslog(LOG_ERR, "%s", gai_strerror(error)); + mcleanup(0); + } + + /* Count max number of sockets we may open */ + for (r = res; r; r = r->ai_next, maxs++) + ; + if (socks == NULL) { + socks = malloc((maxs + 1) * sizeof(int)); + if (socks) + *socks = 0; /* num of sockets ctr at start */ + } else + socks = realloc(socks, (maxs + 1) * sizeof(int)); + if (!socks) { + syslog(LOG_ERR, "couldn't allocate memory for sockets"); + mcleanup(0); + } + + s = socks + *socks + 1; + for (r = res; r; r = r->ai_next) { + *s = socket(r->ai_family, r->ai_socktype, + r->ai_protocol); + if (*s < 0) { + syslog(LOG_DEBUG, "socket(): %m"); + continue; + } + if (options & SO_DEBUG) + if (setsockopt(*s, SOL_SOCKET, SO_DEBUG, + &on, sizeof(on)) < 0) { + syslog(LOG_ERR, + "setsockopt (SO_DEBUG): %m"); + close (*s); + continue; + } + if (bind(*s, r->ai_addr, r->ai_addrlen) < 0) { + syslog(LOG_DEBUG, "bind(): %m"); + close (*s); + continue; + } + *socks = *socks + 1; + s++; + } + + if (res) + freeaddrinfo(res); + } while (++blidx < blist_addrs); + + if (socks == NULL || *socks == 0) { + syslog(LOG_ERR, "Couldn't bind to any socket"); + if (socks != NULL) + free(socks); + mcleanup(0); + } + return(socks); +} diff --git a/usr.sbin/lpr/lpd/lpdchar.c b/usr.sbin/lpr/lpd/lpdchar.c index 2035c70e8f1..17aa3ec122f 100644 --- a/usr.sbin/lpr/lpd/lpdchar.c +++ b/usr.sbin/lpr/lpd/lpdchar.c @@ -1,4 +1,5 @@ -/* $OpenBSD: lpdchar.c,v 1.3 2001/08/30 17:38:13 millert Exp $ */ +/* $OpenBSD: lpdchar.c,v 1.4 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: lpdchar.c,v 1.5 1997/07/17 05:44:32 mikel Exp $ */ /* * Copyright (c) 1983, 1993 @@ -37,7 +38,7 @@ #if 0 static const char sccsid[] = "@(#)lpdchar.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: lpdchar.c,v 1.3 2001/08/30 17:38:13 millert Exp $"; +static const char rcsid[] = "$OpenBSD: lpdchar.c,v 1.4 2002/05/20 23:13:50 millert Exp $"; #endif #endif /* not lint */ @@ -107,7 +108,7 @@ static const char rcsid[] = "$OpenBSD: lpdchar.c,v 1.3 2001/08/30 17:38:13 mille #define c111111_ 0176 #define c1111111 0177 -char scnkey[][HEIGHT] = /* this is relatively easy to modify */ +const char scnkey[][HEIGHT] = /* this is relatively easy to modify */ /* just look: */ { { c_______, diff --git a/usr.sbin/lpr/lpd/modes.c b/usr.sbin/lpr/lpd/modes.c index 786bc524493..19d9bcd2968 100644 --- a/usr.sbin/lpr/lpd/modes.c +++ b/usr.sbin/lpr/lpd/modes.c @@ -1,5 +1,5 @@ -/* $OpenBSD: modes.c,v 1.4 2001/08/30 17:38:13 millert Exp $ */ -/* $NetBSD: modes.c,v 1.1 1995/10/03 15:02:45 hpeyerl Exp $ */ +/* $OpenBSD: modes.c,v 1.5 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: modes.c,v 1.3 1997/10/20 08:08:31 scottr Exp $ */ /*- * Copyright (c) 1991, 1993, 1994 @@ -38,7 +38,7 @@ #if 0 static const char sccsid[] = "@(#)modes.c 8.3 (Berkeley) 4/2/94"; #else -static const char rcsid[] = "$OpenBSD: modes.c,v 1.4 2001/08/30 17:38:13 millert Exp $"; +static const char rcsid[] = "$OpenBSD: modes.c,v 1.5 2002/05/20 23:13:50 millert Exp $"; #endif #endif /* not lint */ @@ -59,7 +59,7 @@ struct modes { * The code in optlist() depends on minus options following regular * options, i.e. "foo" must immediately precede "-foo". */ -struct modes cmodes[] = { +const struct modes cmodes[] = { { "cs5", CS5, CSIZE }, { "cs6", CS6, CSIZE }, { "cs7", CS7, CSIZE }, @@ -93,7 +93,7 @@ struct modes cmodes[] = { { NULL }, }; -struct modes imodes[] = { +const struct modes imodes[] = { { "ignbrk", IGNBRK, 0 }, { "-ignbrk", 0, IGNBRK }, { "brkint", BRKINT, 0 }, @@ -131,7 +131,7 @@ struct modes imodes[] = { { NULL }, }; -struct modes lmodes[] = { +const struct modes lmodes[] = { { "echo", ECHO, 0 }, { "-echo", 0, ECHO }, { "echoe", ECHOE, 0 }, @@ -185,7 +185,7 @@ struct modes lmodes[] = { { NULL }, }; -struct modes omodes[] = { +const struct modes omodes[] = { { "opost", OPOST, 0 }, { "-opost", 0, OPOST }, { "litout", 0, OPOST }, @@ -210,11 +210,9 @@ struct modes omodes[] = { #define CHK(s) (*name == s[0] && !strcmp(name, s)) int -msearch(argvp, ip) - char ***argvp; - struct info *ip; +msearch(char ***argvp, struct info *ip) { - struct modes *mp; + const struct modes *mp; char *name; name = **argvp; diff --git a/usr.sbin/lpr/lpd/printjob.c b/usr.sbin/lpr/lpd/printjob.c index 68b48b5f3e4..a1578c9e43a 100644 --- a/usr.sbin/lpr/lpd/printjob.c +++ b/usr.sbin/lpr/lpd/printjob.c @@ -1,5 +1,5 @@ -/* $OpenBSD: printjob.c,v 1.31 2002/02/19 19:39:40 millert Exp $ */ -/* $NetBSD: printjob.c,v 1.9.4.3 1996/07/12 22:31:39 jtc Exp $ */ +/* $OpenBSD: printjob.c,v 1.32 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: printjob.c,v 1.31 2002/01/21 14:42:30 wiz Exp $ */ /* * Copyright (c) 1983, 1993 @@ -127,7 +127,8 @@ static void opentty(void); static void openrem(void); static int print(int, char *); static int printit(char *); -static void pstatus(const char *, ...); +static void pstatus(const char *, ...) + __attribute__((__format__(__printf__, 1, 2))); static char response(void); static void scan_out(int, char *, int); static char *scnline(int, char *, int); @@ -135,9 +136,10 @@ static int sendfile(int, char *); static int sendit(char *); static void sendmail(char *, int); static void setty(void); +static void alarmer(int); void -printjob() +printjob(void) { struct stat stb; struct queue *q, **qp; @@ -147,11 +149,11 @@ printjob() int errcnt, count = 0; init(); /* set up capabilities */ - (void) write(1, "", 1); /* ack that daemon is started */ - (void) close(2); /* set up log file */ + (void)write(STDOUT_FILENO, "", 1); /* ack that daemon is started */ + (void)close(STDERR_FILENO); /* set up log file */ if (open(LF, O_WRONLY|O_APPEND, 0664) < 0) { syslog(LOG_ERR, "%s: %m", LF); - (void) open(_PATH_DEVNULL, O_WRONLY); + (void)open(_PATH_DEVNULL, O_WRONLY); } setgid(getegid()); pid = getpid(); /* for use with lprm */ @@ -161,7 +163,7 @@ printjob() signal(SIGQUIT, abortpr); signal(SIGTERM, abortpr); - (void) mktemp(tempfile); + (void)mktemp(tempfile); /* safe */ /* * uses short form file names @@ -170,7 +172,7 @@ printjob() syslog(LOG_ERR, "%s: %m", SD); exit(1); } - if (stat(LO, &stb) == 0 && (stb.st_mode & 0100)) + if (stat(LO, &stb) == 0 && (stb.st_mode & S_IXUSR)) exit(0); /* printing disabled */ lfd = open(LO, O_WRONLY|O_CREAT, 0644); if (lfd < 0) { @@ -187,8 +189,11 @@ printjob() /* * write process id for others to know */ - sprintf(line, "%d\n", pid); - pidoff = i = strlen(line); + pidoff = i = snprintf(line, sizeof(line), "%d\n", pid); + if (pidoff >= sizeof(line)) { + syslog(LOG_ERR, "impossibly large pid: %u", pid); + exit(1); + } if (write(lfd, line, i) != i) { syslog(LOG_ERR, "%s: %s: %m", printer, LO); exit(1); @@ -202,7 +207,7 @@ printjob() } if (nitems == 0) /* no work to do */ exit(0); - if (stb.st_mode & 01) { /* reset queue flag */ + if (stb.st_mode & S_IXOTH) { /* reset queue flag */ if (fchmod(lfd, stb.st_mode & 0776) < 0) syslog(LOG_ERR, "%s: %s: %m", printer, LO); } @@ -219,9 +224,10 @@ again: continue; errcnt = 0; restart: - (void) lseek(lfd, pidoff, 0); - (void) snprintf(line, sizeof line, "%s\n", q->q_name); - i = strlen(line); + (void)lseek(lfd, pidoff, 0); + i = snprintf(line, sizeof(line), "%s\n", q->q_name); + if (i >= sizeof(line)) + i = sizeof(line) - 1; /* can't happen */ if (write(lfd, line, i) != i) syslog(LOG_ERR, "%s: %s: %m", printer, LO); if (!remote) @@ -234,10 +240,10 @@ again: */ if (fstat(lfd, &stb) == 0) { /* stop printing before starting next job? */ - if (stb.st_mode & 0100) + if (stb.st_mode & S_IXUSR) goto done; /* rebuild queue (after lpc topq) */ - if (stb.st_mode & 01) { + if (stb.st_mode & S_IXOTH) { for (free((char *) q); nitems--; free((char *) q)) q = *qp++; if (fchmod(lfd, stb.st_mode & 0776) < 0) @@ -253,12 +259,12 @@ again: syslog(LOG_INFO, "restarting %s", printer); if (ofilter > 0) { kill(ofilter, SIGCONT); /* to be sure */ - (void) close(ofd); + (void)close(ofd); while ((i = wait(NULL)) > 0 && i != ofilter) ; ofilter = 0; } - (void) close(pfd); /* close printer */ + (void)close(pfd); /* close printer */ if (ftruncate(lfd, pidoff) < 0) syslog(LOG_WARNING, "%s: %s: %m", printer, LO); openpr(); /* try to reopen printer */ @@ -268,9 +274,9 @@ again: remote ? "sent to remote host" : "printed", q->q_name); if (i == REPRINT) { /* ensure we don't attempt this job again */ - (void) unlink(q->q_name); + (void)unlink(q->q_name); q->q_name[0] = 'd'; - (void) unlink(q->q_name); + (void)unlink(q->q_name); if (logname[0]) sendmail(logname, FATALERR); } @@ -288,19 +294,20 @@ again: done: if (count > 0) { /* Files actually printed */ if (!SF && !tof) - (void) write(ofd, FF, strlen(FF)); + (void)write(ofd, FF, strlen(FF)); if (TR != NULL) /* output trailer */ - (void) write(ofd, TR, strlen(TR)); + (void)write(ofd, TR, strlen(TR)); } - (void) close(ofd); - (void) wait(NULL); - (void) unlink(tempfile); + (void)close(ofd); + (void)wait(NULL); + (void)unlink(tempfile); exit(0); } goto again; } -char fonts[4][50]; /* fonts for troff */ +#define FONTLEN 50 +char fonts[4][FONTLEN]; /* fonts for troff */ char ifonts[4][40] = { _PATH_VFONTR, @@ -314,8 +321,7 @@ char ifonts[4][40] = { * and performing the various actions. */ static int -printit(file) - char *file; +printit(char *file) { int i; char *cp; @@ -332,9 +338,10 @@ printit(file) * Reset troff fonts. */ for (i = 0; i < 4; i++) - strcpy(fonts[i], ifonts[i]); - sprintf(&width[2], "%ld", PW); - strcpy(indent+2, "0"); + strlcpy(fonts[i], ifonts[i], FONTLEN); + (void)snprintf(&width[2], sizeof(width) - 2, "%ld", PW); + indent[2] = '0'; + indent[3] = '\0'; /* * read the control file for work to do @@ -379,9 +386,8 @@ printit(file) switch (line[0]) { case 'H': strlcpy(fromhost, line+1, sizeof(fromhost)); - if (class[0] == '\0') { + if (class[0] == '\0') strlcpy(class, line+1, sizeof(class)); - } continue; case 'P': @@ -409,10 +415,12 @@ printit(file) continue; case 'J': - if (line[1] != '\0') { + if (line[1] != '\0') strlcpy(jobname, line+1, sizeof(jobname)); - } else - strcpy(jobname, " "); + else { + jobname[0] = ' '; + jobname[1] = '\0'; + } continue; case 'C': @@ -435,18 +443,16 @@ printit(file) case '2': case '3': case '4': - if (line[1] != '\0') { - strlcpy(fonts[line[0]-'1'], line+1, - 50); - } + if (line[1] != '\0') + strlcpy(fonts[line[0]-'1'], line+1, FONTLEN); continue; case 'W': /* page width */ - strlcpy(width+2, line+1, sizeof(width)-2); + strlcpy(width+2, line+1, sizeof(width) - 2); continue; case 'I': /* indent amount */ - strlcpy(indent+2, line+1, sizeof(indent)-2); + strlcpy(indent+2, line+1, sizeof(indent) - 2); continue; default: /* some file to print */ @@ -456,7 +462,7 @@ printit(file) bombed = FATALERR; break; case REPRINT: - (void) fclose(cfp); + (void)fclose(cfp); return(REPRINT); case FILTERERR: case ACCESS: @@ -492,13 +498,13 @@ pass2: case 'U': if (strchr(line+1, '/')) continue; - (void) unlink(line+1); + (void)unlink(line+1); } /* * clean-up in case another control file exists */ - (void) fclose(cfp); - (void) unlink(file); + (void)fclose(cfp); + (void)unlink(file); return(bombed == OK ? OK : ERROR); } @@ -513,18 +519,13 @@ pass2: * stderr as the log file, and must not ignore SIGINT. */ static int -print(format, file) - int format; - char *file; +print(int format, char *file) { - int n; - char *prog; - int fi, fo; FILE *fp; - char *av[15], buf[BUFSIZ]; - int pid, p[2], stopped = 0, nofile; - union wait status; + int status, serrno; struct stat stb; + char *prog, *av[15], buf[BUFSIZ]; + int n, fi, fo, pid, p[2], stopped = 0, nofile; if (lstat(file, &stb) < 0 || (fi = open(file, O_RDONLY)) < 0) return(ERROR); @@ -533,21 +534,21 @@ print(format, file) * still point to the same file or someone is trying to print * something he shouldn't. */ - if ((stb.st_mode & S_IFMT) == S_IFLNK && fstat(fi, &stb) == 0 && + if (S_ISLNK(stb.st_mode) && fstat(fi, &stb) == 0 && (stb.st_dev != fdev || stb.st_ino != fino)) return(ACCESS); if (!SF && !tof) { /* start on a fresh page */ - (void) write(ofd, FF, strlen(FF)); + (void)write(ofd, FF, strlen(FF)); tof = 1; } if (IF == NULL && (format == 'f' || format == 'l')) { tof = 0; while ((n = read(fi, buf, BUFSIZ)) > 0) if (write(ofd, buf, n) != n) { - (void) close(fi); + (void)close(fi); return(REPRINT); } - (void) close(fi); + (void)close(fi); return(OK); } switch (format) { @@ -559,7 +560,7 @@ print(format, file) av[2] = length; av[3] = "-h"; av[4] = *title ? title : " "; - av[5] = 0; + av[5] = NULL; fo = ofd; goto start; } @@ -568,18 +569,19 @@ print(format, file) dup2(fi, 0); /* file is stdin */ dup2(p[1], 1); /* pipe is stdout */ closelog(); - for (n = 3, nofile = sysconf(_SC_OPEN_MAX); n < nofile; n++) - (void) close(n); + nofile = sysconf(_SC_OPEN_MAX); + for (n = 3; n < nofile; n++) + (void)close(n); execl(_PATH_PR, "pr", width, length, "-h", *title ? title : " ", (char *)NULL); syslog(LOG_ERR, "cannot execl %s", _PATH_PR); exit(2); } - (void) close(p[1]); /* close output side */ - (void) close(fi); + (void)close(p[1]); /* close output side */ + (void)close(fi); if (prchild < 0) { prchild = 0; - (void) close(p[0]); + (void)close(p[0]); return(ERROR); } fi = p[0]; /* use pipe for input */ @@ -589,7 +591,7 @@ print(format, file) * the standard LPF_INPUT filter will recognize that it * is postscript and know what to do with it. These * 'o'-file requests could come from MacOS 10.1 systems. - */ + */ /* FALLTHROUGH */ case 'f': /* print plain text file */ prog = IF; @@ -615,19 +617,19 @@ print(format, file) case 't': /* print troff output */ case 'n': /* print ditroff output */ case 'd': /* print tex output */ - (void) unlink(".railmag"); + (void)unlink(".railmag"); if ((fo = creat(".railmag", FILMOD)) < 0) { syslog(LOG_ERR, "%s: cannot create .railmag", printer); - (void) unlink(".railmag"); + (void)unlink(".railmag"); } else { for (n = 0; n < 4; n++) { if (fonts[n][0] != '/') - (void) write(fo, _PATH_VFONT, + (void)write(fo, _PATH_VFONT, sizeof(_PATH_VFONT) - 1); - (void) write(fo, fonts[n], strlen(fonts[n])); - (void) write(fo, "\n", 1); + (void)write(fo, fonts[n], strlen(fonts[n])); + (void)write(fo, "\n", 1); } - (void) close(fo); + (void)close(fo); } prog = (format == 't') ? TF : (format == 'n') ? NF : DF; av[1] = pxwidth; @@ -653,16 +655,16 @@ print(format, file) n = 3; break; default: - (void) close(fi); + (void)close(fi); syslog(LOG_ERR, "%s: illegal format character '%c'", printer, format); return(ERROR); } if (prog == NULL) { - (void) close(fi); + (void)close(fi); syslog(LOG_ERR, - "%s: no filter found in printcap for format character '%c'", - printer, format); + "%s: no filter found in printcap for format character '%c'", + printer, format); return(ERROR); } if ((av[0] = strrchr(prog, '/')) != NULL) @@ -678,14 +680,14 @@ print(format, file) fo = pfd; if (ofilter > 0) { /* stop output filter */ write(ofd, "\031\1", 2); - while ((pid = waitpid((pid_t)-1, (int *)&status, WUNTRACED)) > 0 + while ((pid = waitpid((pid_t)-1, &status, WUNTRACED)) > 0 && pid != ofilter) ; - if (status.w_stopval != WSTOPPED) { - (void) close(fi); + if (WIFSTOPPED(status) == 0) { + (void)close(fi); syslog(LOG_WARNING, "%s: output filter died (retcode=%d termsig=%d)", - printer, status.w_retcode, status.w_termsig); + printer, WEXITSTATUS(status), WTERMSIG(status)); return(REPRINT); } stopped++; @@ -694,22 +696,28 @@ start: if ((child = dofork(DORETURN)) == 0) { /* child */ dup2(fi, 0); dup2(fo, 1); - n = open(tempfile, O_WRONLY|O_CREAT|O_TRUNC, 0664); + unlink(tempfile); + n = open(tempfile, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0664); if (n >= 0) dup2(n, 2); closelog(); - for (n = 3, nofile = sysconf(_SC_OPEN_MAX); n < nofile; n++) - (void) close(n); + nofile = sysconf(_SC_OPEN_MAX); + for (n = 3; n < nofile; n++) + (void)close(n); execv(prog, av); syslog(LOG_ERR, "cannot execv %s", prog); - exit(2); + _exit(2); } - (void) close(fi); - if (child < 0) - status.w_retcode = 100; - else - while ((pid = wait((int *)&status)) > 0 && pid != child) - ; + serrno = errno; + (void)close(fi); + errno = serrno; + if (child < 0) { + child = prchild = tof = 0; + syslog(LOG_ERR, "cannot start child process: %m"); + return (ERROR); + } + while ((pid = wait(&status)) > 0 && pid != child) + ; child = 0; prchild = 0; if (stopped) { /* restart output filter */ @@ -721,7 +729,7 @@ start: tof = 0; /* Copy filter output to "lf" logfile */ - if ((fp = fopen(tempfile, "r"))) { + if ((fp = fopen(tempfile, "r")) != NULL) { while (fgets(buf, sizeof(buf), fp)) fputs(buf, stderr); fclose(fp); @@ -729,10 +737,10 @@ start: if (!WIFEXITED(status)) { syslog(LOG_WARNING, "%s: filter '%c' terminated (termsig=%d)", - printer, format, status.w_termsig); + printer, format, WTERMSIG(status)); return(ERROR); } - switch (status.w_retcode) { + switch (WEXITSTATUS(status)) { case 0: tof = 1; return(OK); @@ -742,7 +750,7 @@ start: return(ERROR); default: syslog(LOG_WARNING, "%s: filter '%c' exited (retcode=%d)", - printer, format, status.w_retcode); + printer, format, WEXITSTATUS(status)); return(FILTERERR); } } @@ -753,8 +761,7 @@ start: * 0 if all is well. */ static int -sendit(file) - char *file; +sendit(char *file) { int i, err = OK; char *cp, last[BUFSIZ]; @@ -795,8 +802,8 @@ sendit(file) continue; } if (line[0] >= 'a' && line[0] <= 'z') { - strcpy(last, line); - while ((i = getline(cfp))) + strlcpy(last, line, sizeof(last)); + while ((i = getline(cfp)) != 0) if (strcmp(last, line)) break; switch (sendfile('\3', last+1)) { @@ -805,7 +812,7 @@ sendit(file) goto again; break; case REPRINT: - (void) fclose(cfp); + (void)fclose(cfp); return(REPRINT); case ACCESS: sendmail(logname, ACCESS); @@ -816,7 +823,7 @@ sendit(file) } } if (err == OK && sendfile('\2', file) > 0) { - (void) fclose(cfp); + (void)fclose(cfp); return(REPRINT); } /* @@ -824,13 +831,13 @@ sendit(file) */ fseek(cfp, 0L, 0); while (getline(cfp)) - if (line[0] == 'U' && !strchr(line+1, '/')) - (void) unlink(line+1); + if (line[0] == 'U' && strchr(line+1, '/') == 0) + (void)unlink(line+1); /* * clean-up in case another control file exists */ - (void) fclose(cfp); - (void) unlink(file); + (void)fclose(cfp); + (void)unlink(file); return(err); } @@ -839,9 +846,7 @@ sendit(file) * Return positive if we should try resending. */ static int -sendfile(type, file) - int type; - char *file; +sendfile(int type, char *file) { int f, i, amt; struct stat stb; @@ -855,17 +860,17 @@ sendfile(type, file) * still point to the same file or someone is trying to print something * he shouldn't. */ - if ((stb.st_mode & S_IFMT) == S_IFLNK && fstat(f, &stb) == 0 && + if (S_ISLNK(stb.st_mode) && fstat(f, &stb) == 0 && (stb.st_dev != fdev || stb.st_ino != fino)) return(ACCESS); - if (snprintf(buf, sizeof buf, "%c%qd %s\n", type, - stb.st_size, file) > sizeof buf-1) + amt = snprintf(buf, sizeof(buf), "%c%lld %s\n", type, + (long long)stb.st_size, file); + if (amt >= sizeof(buf)) return (ACCESS); /* XXX hack */ - amt = strlen(buf); for (i = 0; ; i++) { if (write(pfd, buf, amt) != amt || (resp = response()) < 0 || resp == '\1') { - (void) close(f); + (void)close(f); return(REPRINT); } else if (resp == '\0') break; @@ -880,22 +885,34 @@ sendfile(type, file) pstatus("sending to %s", RM); sizerr = 0; for (i = 0; i < stb.st_size; i += BUFSIZ) { + struct sigaction osa, nsa; + amt = BUFSIZ; if (i + amt > stb.st_size) amt = stb.st_size - i; if (sizerr == 0 && read(f, buf, amt) != amt) sizerr = 1; + memset(&nsa, 0, sizeof(nsa)); + nsa.sa_handler = alarmer; + sigemptyset(&nsa.sa_mask); + nsa.sa_flags = 0; + (void)sigaction(SIGALRM, &nsa, &osa); + alarm(wait_time); if (write(pfd, buf, amt) != amt) { - (void) close(f); + alarm(0); + (void)sigaction(SIGALRM, &osa, NULL); + (void)close(f); return(REPRINT); } + alarm(0); + (void)sigaction(SIGALRM, &osa, NULL); } - (void) close(f); + (void)close(f); if (sizerr) { syslog(LOG_INFO, "%s: %s: changed size", printer, file); /* tell recvjob to ignore this file */ - (void) write(pfd, "\1", 1); + (void)write(pfd, "\1", 1); return(ERROR); } if (write(pfd, "", 1) != 1 || response()) @@ -909,65 +926,70 @@ sendfile(type, file) * Return non-zero if the connection was lost. */ static char -response() +response(void) { + struct sigaction osa, nsa; char resp; + memset(&nsa, 0, sizeof(nsa)); + nsa.sa_handler = alarmer; + sigemptyset(&nsa.sa_mask); + nsa.sa_flags = 0; + (void)sigaction(SIGALRM, &nsa, &osa); + alarm(wait_time); if (read(pfd, &resp, 1) != 1) { syslog(LOG_INFO, "%s: lost connection", printer); - return(-1); + resp = -1; } - return(resp); + alarm(0); + (void)sigaction(SIGALRM, &osa, NULL); + return (resp); } /* * Banner printing stuff */ static void -banner(name1, name2) - char *name1, *name2; +banner(char *name1, char *name2) { time_t tvec; time(&tvec); if (!SF && !tof) - (void) write(ofd, FF, strlen(FF)); + (void)write(ofd, FF, strlen(FF)); if (SB) { /* short banner only */ if (class[0]) { - (void) write(ofd, class, strlen(class)); - (void) write(ofd, ":", 1); + (void)write(ofd, class, strlen(class)); + (void)write(ofd, ":", 1); } - (void) write(ofd, name1, strlen(name1)); - (void) write(ofd, " Job: ", 7); - (void) write(ofd, name2, strlen(name2)); - (void) write(ofd, " Date: ", 8); - (void) write(ofd, ctime(&tvec), 24); - (void) write(ofd, "\n", 1); + (void)write(ofd, name1, strlen(name1)); + (void)write(ofd, " Job: ", 7); + (void)write(ofd, name2, strlen(name2)); + (void)write(ofd, " Date: ", 8); + (void)write(ofd, ctime(&tvec), 24); + (void)write(ofd, "\n", 1); } else { /* normal banner */ - (void) write(ofd, "\n\n\n", 3); + (void)write(ofd, "\n\n\n", 3); scan_out(ofd, name1, '\0'); - (void) write(ofd, "\n\n", 2); + (void)write(ofd, "\n\n", 2); scan_out(ofd, name2, '\0'); if (class[0]) { - (void) write(ofd,"\n\n\n",3); + (void)write(ofd,"\n\n\n",3); scan_out(ofd, class, '\0'); } - (void) write(ofd, "\n\n\n\n\t\t\t\t\tJob: ", 15); - (void) write(ofd, name2, strlen(name2)); - (void) write(ofd, "\n\t\t\t\t\tDate: ", 12); - (void) write(ofd, ctime(&tvec), 24); - (void) write(ofd, "\n", 1); + (void)write(ofd, "\n\n\n\n\t\t\t\t\tJob: ", 15); + (void)write(ofd, name2, strlen(name2)); + (void)write(ofd, "\n\t\t\t\t\tDate: ", 12); + (void)write(ofd, ctime(&tvec), 24); + (void)write(ofd, "\n", 1); } if (!SF) - (void) write(ofd, FF, strlen(FF)); + (void)write(ofd, FF, strlen(FF)); tof = 1; } static char * -scnline(key, p, c) - int key; - char *p; - int c; +scnline(int key, char *p, int c) { int scnwidth; @@ -981,9 +1003,7 @@ scnline(key, p, c) #define TRC(q) (((q)-' ')&0177) static void -scan_out(scfd, scsp, dlm) - int scfd, dlm; - char *scsp; +scan_out(int scfd, char *scsp, int dlm) { char *strp; int nchrs, j; @@ -1000,8 +1020,10 @@ scan_out(scfd, scsp, dlm) for (j = WIDTH; --j;) *strp++ = BACKGND; else - strp = scnline(scnkey[(int)c][scnhgt-1-d], strp, cc); - if (*sp == dlm || *sp == '\0' || nchrs++ >= PW/(WIDTH+1)-1) + strp = scnline(scnkey[(int)c][scnhgt-1-d], + strp, cc); + if (*sp == dlm || *sp == '\0' || + nchrs++ >= PW/(WIDTH+1)-1) break; *strp++ = BACKGND; *strp++ = BACKGND; @@ -1010,13 +1032,12 @@ scan_out(scfd, scsp, dlm) ; strp++; *strp++ = '\n'; - (void) write(scfd, outbuf, strp-outbuf); + (void)write(scfd, outbuf, strp-outbuf); } } static int -dropit(c) - int c; +dropit(int c) { switch(c) { @@ -1040,12 +1061,9 @@ dropit(c) * tell people about job completion */ static void -sendmail(user, bombed) - char *user; - int bombed; +sendmail(char *user, int bombed) { - int i, nofile; - int p[2], s; + int i, p[2], s, nofile; char *cp = NULL; struct stat stb; FILE *fp; @@ -1056,14 +1074,15 @@ sendmail(user, bombed) if ((s = dofork(DORETURN)) == 0) { /* child */ dup2(p[0], 0); closelog(); - for (i = 3, nofile = sysconf(_SC_OPEN_MAX); i < nofile; i++) - (void) close(i); + nofile = sysconf(_SC_OPEN_MAX); + for (i = 3; i < nofile; i++) + (void)close(i); if ((cp = strrchr(_PATH_SENDMAIL, '/')) != NULL) cp++; else cp = _PATH_SENDMAIL; execl(_PATH_SENDMAIL, cp, "-t", (char *)NULL); - exit(0); + _exit(0); } else if (s > 0) { /* parent */ dup2(p[1], 1); printf("To: %s@%s\n", user, fromhost); @@ -1096,7 +1115,7 @@ sendmail(user, bombed) printf("\nhad the following errors and may not have printed:\n"); while ((i = getc(fp)) != EOF) putchar(i); - (void) fclose(fp); + (void)fclose(fp); cp = "FILTERERR"; break; case ACCESS: @@ -1104,10 +1123,12 @@ sendmail(user, bombed) cp = "ACCESS"; } fflush(stdout); - (void) close(1); + (void)close(1); + } else { + syslog(LOG_ERR, "fork for sendmail failed: %m"); } - (void) close(p[0]); - (void) close(p[1]); + (void)close(p[0]); + (void)close(p[1]); if (s != -1) { wait(NULL); syslog(LOG_INFO, @@ -1120,8 +1141,7 @@ sendmail(user, bombed) * dofork - fork with retries on failure */ static int -dofork(action) - int action; +dofork(int action) { int i, pid; struct passwd *pw; @@ -1137,8 +1157,8 @@ dofork(action) if (pid == 0) { pw = getpwuid(DU); if (pw == 0) { - syslog(LOG_ERR, "uid %u not in password file", - (uid_t)DU); + syslog(LOG_ERR, "uid %ld not in password file", + DU); break; } initgroups(pw->pw_name, pw->pw_gid); @@ -1166,10 +1186,9 @@ dofork(action) * Kill child processes to abort current job. */ static void -abortpr(signo) - int signo; +abortpr(int signo) { - (void) unlink(tempfile); + (void)unlink(tempfile); kill(0, SIGINT); if (ofilter > 0) kill(ofilter, SIGCONT); @@ -1179,7 +1198,7 @@ abortpr(signo) } static void -init() +init(void) { int status; char *s; @@ -1193,7 +1212,7 @@ init() } else if (status == -3) fatal("potential reference loop detected in printcap file"); - if (cgetstr(bp, "lp", &LP) == -1) + if (cgetstr(bp, DEFLP, &LP) == -1) LP = _PATH_DEFDEVLP; if (cgetstr(bp, "rp", &RP) == -1) RP = DEFLP; @@ -1211,18 +1230,18 @@ init() FF = DEFFF; if (cgetnum(bp, "pw", &PW) < 0) PW = DEFWIDTH; - sprintf(&width[2], "%ld", PW); + (void)snprintf(&width[2], sizeof(width) - 2, "%ld", PW); if (cgetnum(bp, "pl", &PL) < 0) PL = DEFLENGTH; - sprintf(&length[2], "%ld", PL); + (void)snprintf(&length[2], sizeof(length) - 2, "%ld", PL); if (cgetnum(bp,"px", &PX) < 0) PX = 0; - sprintf(&pxwidth[2], "%ld", PX); + (void)snprintf(&pxwidth[2], sizeof(pxwidth) - 2, "%ld", PX); if (cgetnum(bp, "py", &PY) < 0) PY = 0; - sprintf(&pxlength[2], "%ld", PY); + (void)snprintf(&pxlength[2], sizeof(pxlength) - 2, "%ld", PY); cgetstr(bp, "rm", &RM); - if ((s = checkremote())) + if ((s = checkremote()) != NULL) syslog(LOG_WARNING, "%s", s); cgetstr(bp, "af", &AF); @@ -1262,10 +1281,11 @@ init() * Acquire line printer or remote connection. */ static void -openpr() +openpr(void) { int i, nofile; char *cp; + extern int rflag; if (!remote && *LP) { if ((cp = strchr(LP, '@'))) @@ -1283,17 +1303,17 @@ openpr() /* * Start up an output filter, if needed. */ - if (!remote && OF) { + if ((!remote || rflag) && OF) { int p[2]; - char *cp; pipe(p); if ((ofilter = dofork(DOABORT)) == 0) { /* child */ dup2(p[0], 0); /* pipe is std in */ dup2(pfd, 1); /* printer is std out */ closelog(); - for (i = 3, nofile = sysconf(_SC_OPEN_MAX); i < nofile; i++) - (void) close(i); + nofile = sysconf(_SC_OPEN_MAX); + for (i = 3; i < nofile; i++) + (void)close(i); if ((cp = strrchr(OF, '/')) == NULL) cp = OF; else @@ -1302,7 +1322,7 @@ openpr() syslog(LOG_ERR, "%s: %s: %m", printer, OF); exit(1); } - (void) close(p[0]); /* close input side */ + (void)close(p[0]); /* close input side */ ofd = p[1]; /* use pipe for output */ } else { ofd = pfd; @@ -1315,8 +1335,7 @@ openpr() * or to a terminal server on the net */ static void -opennet(cp) - char *cp; +opennet(char *cp) { int i; int resp, port; @@ -1360,7 +1379,7 @@ opennet(cp) * Printer is connected to an RS232 port on this host */ static void -opentty() +opentty(void) { int i; @@ -1388,7 +1407,7 @@ opentty() * Printer is on a remote host */ static void -openrem() +openrem(void) { int i, n; int resp; @@ -1397,12 +1416,13 @@ openrem() resp = -1; pfd = getport(RM, 0); if (pfd >= 0) { - (void) snprintf(line, sizeof line, "\2%s\n", RP); - n = strlen(line); + n = snprintf(line, sizeof(line), "\2%s\n", RP); + if (n >= sizeof(line)) + n = sizeof(line) - 1; if (write(pfd, line, n) == n && (resp = response()) == '\0') break; - (void) close(pfd); + (void)close(pfd); } if (i == 1) { if (resp < 0) @@ -1418,6 +1438,12 @@ openrem() pstatus("sending to %s", RM); } +static void +alarmer(int s) +{ + /* nothing */ +} + #if !defined(__NetBSD__) && !defined(__OpenBSD__) struct bauds { int baud; @@ -1439,6 +1465,7 @@ struct bauds { 19200, B19200, 38400, B38400, 57600, B57600, + 115200, B115200, 0, 0 }; #endif @@ -1447,7 +1474,7 @@ struct bauds { * setup tty lines. */ static void -setty() +setty(void) { struct info i; char **argv, **ap, *p, *val; @@ -1540,7 +1567,7 @@ setty() static void pstatus(const char *msg, ...) { - int fd; + int fd, len; char buf[BUFSIZ]; va_list ap; @@ -1552,9 +1579,11 @@ pstatus(const char *msg, ...) exit(1); } ftruncate(fd, 0); - (void)vsnprintf(buf, sizeof(buf) - 1, msg, ap); + len = vsnprintf(buf, sizeof(buf), msg, ap); va_end(ap); - strcat(buf, "\n"); - (void) write(fd, buf, strlen(buf)); - (void) close(fd); + if (len >= sizeof(buf)) + len = sizeof(buf) - 1; + buf[len++] = '\n'; /* replace NUL with newline */ + (void)write(fd, buf, len); + (void)close(fd); } diff --git a/usr.sbin/lpr/lpd/recvjob.c b/usr.sbin/lpr/lpd/recvjob.c index 251af2c92d0..2d2d9b0c0cc 100644 --- a/usr.sbin/lpr/lpd/recvjob.c +++ b/usr.sbin/lpr/lpd/recvjob.c @@ -1,4 +1,5 @@ -/* $OpenBSD: recvjob.c,v 1.19 2002/02/19 19:39:40 millert Exp $ */ +/* $OpenBSD: recvjob.c,v 1.20 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: recvjob.c,v 1.14 2001/12/04 22:52:44 christos Exp $ */ /* * Copyright (c) 1983, 1993 @@ -44,7 +45,7 @@ static const char copyright[] = #if 0 static const char sccsid[] = "@(#)recvjob.c 8.2 (Berkeley) 4/27/95"; #else -static const char rcsid[] = "$OpenBSD: recvjob.c,v 1.19 2002/02/19 19:39:40 millert Exp $"; +static const char rcsid[] = "$OpenBSD: recvjob.c,v 1.20 2002/05/20 23:13:50 millert Exp $"; #endif #endif /* not lint */ @@ -71,7 +72,7 @@ static const char rcsid[] = "$OpenBSD: recvjob.c,v 1.19 2002/02/19 19:39:40 mill #include "extern.h" #include "pathnames.h" -#define ack() (void) write(1, sp, 1); +#define ack() (void)write(STDOUT_FILENO, sp, 1); static char dfname[NAME_MAX]; /* data files */ static int minfree; /* keep at least minfree blocks available */ @@ -79,7 +80,8 @@ static char *sp = ""; static char tfname[NAME_MAX]; /* tmp copy of cf before linking */ static int chksize(int); -static void frecverr(const char *, ...); +static void frecverr(const char *, ...) + __attribute__((__format__(__printf__, 1, 2))); static int noresponse(void); static void rcleanup(int); static int read_number(char *); @@ -88,7 +90,7 @@ static int readjob(void); void -recvjob() +recvjob(void) { struct stat stb; int status; @@ -110,10 +112,10 @@ recvjob() if (cgetstr(bp, "lo", &LO) == -1) LO = DEFLOCK; - (void) close(2); /* set up log file */ + (void)close(2); /* set up log file */ if (open(LF, O_WRONLY|O_APPEND, 0664) < 0) { syslog(LOG_ERR, "%s: %m", LF); - (void) open(_PATH_DEVNULL, O_WRONLY); + (void)open(_PATH_DEVNULL, O_WRONLY); } if (chdir(SD) < 0) @@ -139,7 +141,7 @@ recvjob() * Return the number of jobs successfully transferred. */ static int -readjob() +readjob(void) { int size, nfiles; char *cp; @@ -152,14 +154,14 @@ readjob() */ cp = line; do { - if ((size = read(1, cp, 1)) != 1) { + if ((size = read(STDOUT_FILENO, cp, 1)) != 1) { if (size < 0) frecverr("%s: Lost connection", printer); return(nfiles); } - } while (*cp++ != '\n' && (cp - line + 1) < sizeof line); - if (cp - line + 1 >= sizeof line) + } while (*cp++ != '\n' && (cp - line + 1) < sizeof(line)); + if (cp - line + 1 >= sizeof(line)) frecverr("readjob overflow"); *--cp = '\0'; cp = line; @@ -183,10 +185,10 @@ readjob() strlcpy(cp + 6, from, sizeof(line) + line - cp - 6); if (strchr(cp, '/')) frecverr("readjob: %s: illegal path name", cp); - strlcpy(tfname, cp, sizeof tfname); + strlcpy(tfname, cp, sizeof(tfname)); tfname[0] = 't'; if (!chksize(size)) { - (void) write(1, "\2", 1); + (void)write(STDOUT_FILENO, "\2", 1); continue; } if (!readfile(tfname, size)) { @@ -195,7 +197,7 @@ readjob() } if (link(tfname, cp) < 0) frecverr("%s: %m", tfname); - (void) unlink(tfname); + (void)unlink(tfname); tfname[0] = '\0'; nfiles++; continue; @@ -209,11 +211,11 @@ readjob() if (strchr(cp, '/')) frecverr("readjob: %s: illegal path name", cp); if (!chksize(size)) { - (void) write(1, "\2", 1); + (void)write(STDOUT_FILENO, "\2", 1); continue; } - (void) strlcpy(dfname, cp, sizeof dfname); - (void) readfile(dfname, size); + (void)strlcpy(dfname, cp, sizeof(dfname)); + (void)readfile(dfname, size); continue; } frecverr("protocol screwup: %s", line); @@ -224,9 +226,7 @@ readjob() * Read files send by lpd and copy them to the spooling directory. */ static int -readfile(file, size) - char *file; - int size; +readfile(char *file, int size) { char *cp; char buf[BUFSIZ]; @@ -244,7 +244,7 @@ readfile(file, size) if (i + amt > size) amt = size - i; do { - j = read(1, cp, amt); + j = read(STDOUT_FILENO, cp, amt); if (j <= 0) frecverr("Lost connection"); amt -= j; @@ -258,12 +258,12 @@ readfile(file, size) break; } } - (void) close(fd); + (void)close(fd); if (err) frecverr("%s: write error", file); if (noresponse()) { /* file sent had bad data in it */ if (strchr(file, '/') == NULL) - (void) unlink(file); + (void)unlink(file); return(0); } ack(); @@ -271,11 +271,11 @@ readfile(file, size) } static int -noresponse() +noresponse(void) { char resp; - if (read(1, &resp, 1) != 1) + if (read(STDOUT_FILENO, &resp, 1) != 1) frecverr("Lost connection"); if (resp == '\0') return(0); @@ -287,8 +287,7 @@ noresponse() * 1 == OK, 0 == Not OK. */ static int -chksize(size) - int size; +chksize(int size) { int spacefree; struct statfs sfb; @@ -305,8 +304,7 @@ chksize(size) } static int -read_number(fn) - char *fn; +read_number(char *fn) { char lin[80]; FILE *fp; @@ -325,17 +323,16 @@ read_number(fn) * Remove all the files associated with the current job being transferred. */ static void -rcleanup(signo) - int signo; +rcleanup(int signo) { int save_errno = errno; if (tfname[0] && strchr(tfname, '/') == NULL) - (void) unlink(tfname); + (void)unlink(tfname); if (dfname[0] && strchr(dfname, '/') == NULL) { do { do - (void) unlink(dfname); + (void)unlink(dfname); while (dfname[2]-- != 'A'); dfname[2] = 'z'; } while (dfname[0]-- != 'd'); diff --git a/usr.sbin/lpr/lpd/ttcompat.c b/usr.sbin/lpr/lpd/ttcompat.c index 83e2cd9ac40..a85e6af94af 100644 --- a/usr.sbin/lpr/lpd/ttcompat.c +++ b/usr.sbin/lpr/lpd/ttcompat.c @@ -1,4 +1,5 @@ -/* $OpenBSD: ttcompat.c,v 1.4 2001/08/30 17:38:13 millert Exp $ */ +/* $OpenBSD: ttcompat.c,v 1.5 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: ttcompat.c,v 1.9 1995/11/15 22:50:00 pk Exp $ */ /* * Copyright (c) 1995 @@ -40,7 +41,7 @@ */ #ifndef lint -static const char rcsid[] = "$OpenBSD: ttcompat.c,v 1.4 2001/08/30 17:38:13 millert Exp $"; +static const char rcsid[] = "$OpenBSD: ttcompat.c,v 1.5 2002/05/20 23:13:50 millert Exp $"; #endif /* not lint */ #include <sys/param.h> @@ -63,9 +64,11 @@ static const char rcsid[] = "$OpenBSD: ttcompat.c,v 1.4 2001/08/30 17:38:13 mill #define CLR(t, f) (t) &= ~(f) #define ISSET(t, f) ((t) & (f)) +static int sttygetoflags(struct termios *); +static void sttysetoflags(struct termios *, int); + static int -sttygetoflags(tp) - struct termios *tp; +sttygetoflags(struct termios *tp) { tcflag_t iflag = tp->c_iflag; tcflag_t lflag = tp->c_lflag; @@ -104,9 +107,7 @@ sttygetoflags(tp) } static void -sttysetoflags(tp, flags) - struct termios *tp; - int flags; +sttysetoflags(struct termios *tp, int flags) { tcflag_t iflag = tp->c_iflag; tcflag_t oflag = tp->c_oflag; @@ -172,9 +173,7 @@ sttysetoflags(tp, flags) } void -sttyclearflags(tp, flags) - struct termios *tp; - int flags; +sttyclearflags(struct termios *tp, int flags) { tcflag_t iflag = tp->c_iflag; tcflag_t oflag = tp->c_oflag; @@ -208,9 +207,7 @@ sttyclearflags(tp, flags) } void -sttysetflags(tp, flags) - struct termios *tp; - int flags; +sttysetflags(struct termios *tp, int flags) { tcflag_t iflag = tp->c_iflag; tcflag_t oflag = tp->c_oflag; @@ -243,9 +240,7 @@ sttysetflags(tp, flags) } void -sttyclearlflags(tp, flags) - struct termios *tp; - int flags; +sttyclearlflags(struct termios *tp, int flags) { tcflag_t iflag = tp->c_iflag; tcflag_t oflag = tp->c_oflag; @@ -280,9 +275,7 @@ sttyclearlflags(tp, flags) } void -sttysetlflags(tp, flags) - struct termios *tp; - int flags; +sttysetlflags(struct termios *tp, int flags) { tcflag_t iflag = tp->c_iflag; tcflag_t oflag = tp->c_oflag; diff --git a/usr.sbin/lpr/lpq/Makefile b/usr.sbin/lpr/lpq/Makefile index b8227017f7a..79e229243dd 100644 --- a/usr.sbin/lpr/lpq/Makefile +++ b/usr.sbin/lpr/lpq/Makefile @@ -1,9 +1,9 @@ # from: @(#)Makefile 8.1 (Berkeley) 6/6/93 -# $OpenBSD: Makefile,v 1.2 1997/01/17 16:12:44 millert Exp $ +# $OpenBSD: Makefile,v 1.3 2002/05/20 23:13:50 millert Exp $ PROG= lpq CFLAGS+=-I${.CURDIR}/../common_source -SRCS= lpq.c displayq.c common.c +SRCS= lpq.c displayq.c common.c common_vars.c BINOWN= root BINGRP= daemon BINMODE=6555 diff --git a/usr.sbin/lpr/lpq/lpq.1 b/usr.sbin/lpr/lpq/lpq.1 index 331d52b9ff6..5ad81b9df7d 100644 --- a/usr.sbin/lpr/lpq/lpq.1 +++ b/usr.sbin/lpr/lpq/lpq.1 @@ -1,4 +1,5 @@ -.\" $OpenBSD: lpq.1,v 1.6 2000/03/19 17:57:06 aaron Exp $ +.\" $OpenBSD: lpq.1,v 1.7 2002/05/20 23:13:50 millert Exp $ +.\" $NetBSD: lpq.1,v 1.11 2002/01/19 03:23:11 wiz Exp $ .\" .\" Copyright (c) 1983, 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -41,8 +42,7 @@ .Nd spool queue examination program .Sh SYNOPSIS .Nm lpq -.Op Fl a -.Op Fl l +.Op Fl al .Op Fl P Ns Ar printer .Op Ar job# Ar ... .Op Ar user Ar ... @@ -52,7 +52,7 @@ examines the spooling area used by .Xr lpd 8 for printing files on the line printer, and reports the status of the specified jobs or all jobs associated with a user. -.Nm lpq +.Nm invoked without any arguments reports on any jobs currently in the queue. .Pp @@ -77,7 +77,7 @@ rather than just the specified printer. .Pp For each job submitted (i.e., invocation of .Xr lpr 1 ) -.Nm lpq +.Nm reports the user's name, current rank in the queue, the names of files comprising the job, the job identifier (a number which may be supplied to @@ -91,14 +91,12 @@ to be File names comprising a job may be unavailable (when .Xr lpr 1 -is used as a sink in a pipeline) in which case the file -is indicated as +is used as a sink in a pipeline) in which case the file is indicated as .Dq (standard input) . .Pp If -.Nm lpq -warns that there is no daemon present (i.e., due to some malfunction), -the +.Nm +warns that there is no daemon present (i.e., due to some malfunction), the .Xr lpc 8 command can be used to restart the printer daemon. .Sh ENVIRONMENT @@ -109,16 +107,21 @@ If the following environment variable exists, it is used by Specifies an alternate default printer. .El .Sh FILES -.Bl -tag -width "/var/spool/*/lock" -compact +.Bl -tag -width "/var/spool/output/*/lock" -compact .It Pa /etc/printcap -for determining printer characteristics +To determine printer characteristics. .It Pa /var/spool/* -spooling directory, as determined from printcap -.It Pa /var/spool/*/cf* -control files specifying jobs -.It Pa /var/spool/*/lock -lock file to obtain the currently active job +The spooling directory, as determined from printcap. +.It Pa /var/spool/output/*/cf* +Control files specifying jobs. +.It Pa /var/spool/output/*/lock +The lock file to obtain the currently active job. .El +.Sh DIAGNOSTICS +Unable to open various files. +The lock file being malformed. +Garbage files when there is no daemon active, but files in the +spooling directory. .Sh SEE ALSO .Xr lpr 1 , .Xr lprm 1 , @@ -130,12 +133,7 @@ appeared in .Bx 3 . .Sh BUGS Due to the dynamic nature of the information in the spooling directory, -.Nm lpq +.Nm may report unreliably. Output formatting is sensitive to the line length of the terminal; this can result in widely spaced columns. -.Sh DIAGNOSTICS -Unable to open various files. -The lock file being malformed. -Garbage -files when there is no daemon active, but files in the spooling directory. diff --git a/usr.sbin/lpr/lpq/lpq.c b/usr.sbin/lpr/lpq/lpq.c index 7d578382b3e..bc90790276d 100644 --- a/usr.sbin/lpr/lpq/lpq.c +++ b/usr.sbin/lpr/lpq/lpq.c @@ -1,4 +1,5 @@ -/* $OpenBSD: lpq.c,v 1.11 2002/02/16 21:28:04 millert Exp $ */ +/* $OpenBSD: lpq.c,v 1.12 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: lpq.c,v 1.9 1999/12/07 14:54:47 mrg Exp $ */ /* * Copyright (c) 1983, 1993 @@ -44,7 +45,7 @@ static const char copyright[] = #if 0 static const char sccsid[] = "@(#)lpq.c 8.3 (Berkeley) 5/10/95"; #else -static const char rcsid[] = "$OpenBSD: lpq.c,v 1.11 2002/02/16 21:28:04 millert Exp $"; +static const char rcsid[] = "$OpenBSD: lpq.c,v 1.12 2002/05/20 23:13:50 millert Exp $"; #endif #endif /* not lint */ @@ -60,12 +61,14 @@ static const char rcsid[] = "$OpenBSD: lpq.c,v 1.11 2002/02/16 21:28:04 millert #include <sys/param.h> -#include <syslog.h> +#include <ctype.h> #include <dirent.h> +#include <err.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> -#include <ctype.h> +#include <syslog.h> + #include "lp.h" #include "lp.local.h" #include "pathnames.h" @@ -75,36 +78,29 @@ int requests; /* # of spool requests */ char *user[MAXUSERS]; /* users to process */ int users; /* # of users in user array */ -uid_t uid, euid; - volatile sig_atomic_t gotintr; static int ckqueue(char *); -void usage(void); +static __dead void usage(void); int -main(argc, argv) - int argc; - char **argv; +main(int argc, char **argv) { - extern char *optarg; - extern int optind; int ch, aflag, lflag; char *buf, *cp; + long l; euid = geteuid(); uid = getuid(); seteuid(uid); - if (gethostname(host, sizeof(host))) { - perror("lpq: gethostname"); - exit(1); - } - openlog("lpd", 0, LOG_LPR); + if (gethostname(host, sizeof(host)) != 0) + err(1, "gethostname"); + openlog("lpq", 0, LOG_LPR); aflag = lflag = 0; - while ((ch = getopt(argc, argv, "alP:")) != -1) - switch((char)ch) { + while ((ch = getopt(argc, argv, "alP:w:")) != -1) { + switch(ch) { case 'a': ++aflag; break; @@ -114,18 +110,23 @@ main(argc, argv) case 'P': /* printer name */ printer = optarg; break; + case 'w': + l = strtol(optarg, &cp, 10); + if (*cp != '\0' || l < 0 || l >= INT_MAX) + errx(1, "wait time must be postive integer: %s", + optarg); + wait_time = (u_int)l; + if (wait_time < 30) + warnx("warning: wait time less than 30 seconds"); + break; case '?': default: usage(); } + } - if (!aflag && printer == NULL) { - char *p; - + if (!aflag && printer == NULL && (printer = getenv("PRINTER")) == NULL) printer = DEFLP; - if ((p = getenv("PRINTER")) != NULL) - printer = p; - } for (argc -= optind, argv += optind; argc; --argc, ++argv) if (isdigit(argv[0][0])) { @@ -162,8 +163,7 @@ main(argc, argv) } static int -ckqueue(cap) - char *cap; +ckqueue(char *cap) { struct dirent *d; DIR *dirp; @@ -183,9 +183,13 @@ ckqueue(cap) return (0); } -void -usage() +static __dead void +usage(void) { - puts("usage: lpq [-a] [-l] [-Pprinter] [user ...] [job ...]"); + extern char *__progname; + + fprintf(stderr, + "usage: %s [-a] [-l] [-Pprinter] [user ...] [job ...]\n", + __progname); exit(1); } diff --git a/usr.sbin/lpr/lpr/Makefile b/usr.sbin/lpr/lpr/Makefile index dcb20b0a30b..c53d3fcfed2 100644 --- a/usr.sbin/lpr/lpr/Makefile +++ b/usr.sbin/lpr/lpr/Makefile @@ -1,9 +1,9 @@ # from: @(#)Makefile 8.1 (Berkeley) 6/6/93 -# $OpenBSD: Makefile,v 1.2 1997/01/17 16:12:45 millert Exp $ +# $OpenBSD: Makefile,v 1.3 2002/05/20 23:13:50 millert Exp $ PROG= lpr CFLAGS+=-I${.CURDIR}/../common_source -SRCS= lpr.c startdaemon.c common.c +SRCS= lpr.c startdaemon.c common.c common_vars.c BINOWN= root BINGRP= daemon BINMODE=6555 diff --git a/usr.sbin/lpr/lpr/lpr.1 b/usr.sbin/lpr/lpr/lpr.1 index 11978334edf..3daf8fcc978 100644 --- a/usr.sbin/lpr/lpr/lpr.1 +++ b/usr.sbin/lpr/lpr/lpr.1 @@ -1,4 +1,5 @@ -.\" $OpenBSD: lpr.1,v 1.4 2002/02/13 08:33:47 mpech Exp $ +.\" $OpenBSD: lpr.1,v 1.5 2002/05/20 23:13:50 millert Exp $ +.\" $NetBSD: lpr.1,v 1.10 2002/01/19 03:23:26 wiz Exp $ .\" .\" Copyright (c) 1980, 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -41,16 +42,34 @@ .Nd off line print .Sh SYNOPSIS .Nm lpr +.Op Fl cdfghlnmprstv +.Bk -words .Op Fl P Ns Ar printer +.Ek +.Bk -words .Op Fl \&# Ns Ar num +.Ek +.Bk -words .Op Fl C Ar class +.Ek +.Bk -words .Op Fl J Ar job +.Ek +.Bk -words .Op Fl T Ar title +.Ek +.Bk -words .Op Fl U Ar user +.Ek +.Bk -words .Op Fl i Op Ar numcols +.Ek +.Bk -words .Op Fl 1234 Ar font +.Ek +.Bk -words .Op Fl w Ns Ar num -.Op Fl cdfghlnmprstv +.Ek .Op Ar name ... .Sh DESCRIPTION .Nm lpr @@ -65,7 +84,7 @@ use the appropriate filters to print the data accordingly. .Bl -tag -width indent .It Fl c The files are assumed to contain data produced by -.Xr cifplot 1 . +.Ic cifplot . .It Fl d The files are assumed to contain data from .Em tex @@ -78,7 +97,7 @@ standard carriage control character. .It Fl g The files are assumed to contain standard plot data as produced by the -.Xr plot +.Ic plot routines (see also .Xr plot for the filters used by the printer spooler). @@ -92,8 +111,7 @@ The files are assumed to contain data from .It Fl p Use .Xr pr 1 -to format the files (equivalent to -.Xr print ) . +to format the files. .It Fl t The files are assumed to contain data from .Xr troff 1 @@ -199,7 +217,7 @@ If the next argument is numeric .Pq Ar numcols , it is used as the number of blanks to be printed before each line; otherwise, 8 characters are printed. -.It Fl w Ns Ar num +.It Fl w Ar num Uses .Ar num as the page width for @@ -215,7 +233,7 @@ Specifies an alternate default printer. .Sh FILES .Bl -tag -width /var/spool/output/*/tf* -compact .It Pa /etc/passwd -personal identification +local users database .It Pa /etc/printcap printer capabilities database .It Pa /usr/sbin/lpd* @@ -233,38 +251,38 @@ temporary copies of .Dq cf files .El -.Sh SEE ALSO -.Xr lpq 1 , -.Xr lprm 1 , -.Xr pr 1 , -.Xr symlink 2 , -.Xr printcap 5 , -.Xr lpc 8 , -.Xr lpd 8 -.Sh HISTORY -The -.Nm lpr -command appeared in -.Bx 3 . .Sh DIAGNOSTICS If you try to spool too large a file, it will be truncated. .Nm lpr will object to printing binary files. If a user other than root prints a file and spooling is disabled, -.Nm lpr +.Nm will print a message saying so and will not put jobs in the queue. If a connection to -.Xr lpd 1 +.Xr lpd 8 on the local machine cannot be made, -.Nm lpr +.Nm will say that the daemon cannot be started. Diagnostics may be printed in the daemon's log file regarding missing spool files by -.Xr lpd 1 . +.Xr lpd 8 . .Sh BUGS Fonts for .Xr troff 1 and -.Xr tex +.Ic tex reside on the host with the printer. It is currently not possible to use local font libraries. +.Sh SEE ALSO +.Xr lpq 1 , +.Xr lprm 1 , +.Xr pr 1 , +.Xr symlink 2 , +.Xr printcap 5 , +.Xr lpc 8 , +.Xr lpd 8 +.Sh HISTORY +The +.Nm +command appeared in +.Bx 3 . diff --git a/usr.sbin/lpr/lpr/lpr.c b/usr.sbin/lpr/lpr/lpr.c index 99c84378bc8..348a38b94d9 100644 --- a/usr.sbin/lpr/lpr/lpr.c +++ b/usr.sbin/lpr/lpr/lpr.c @@ -1,5 +1,5 @@ -/* $OpenBSD: lpr.c,v 1.24 2002/02/16 21:28:04 millert Exp $ */ -/* $NetBSD: lpr.c,v 1.10 1996/03/21 18:12:25 jtc Exp $ */ +/* $OpenBSD: lpr.c,v 1.25 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: lpr.c,v 1.19 2000/10/11 20:23:52 is Exp $ */ /* * Copyright (c) 1983, 1989, 1993 @@ -50,7 +50,7 @@ static const char copyright[] = #if 0 static const char sccsid[] = "@(#)lpr.c 8.4 (Berkeley) 4/28/95"; #else -static const char rcsid[] = "$OpenBSD: lpr.c,v 1.24 2002/02/16 21:28:04 millert Exp $"; +static const char rcsid[] = "$OpenBSD: lpr.c,v 1.25 2002/05/20 23:13:50 millert Exp $"; #endif #endif /* not lint */ @@ -77,6 +77,8 @@ static const char rcsid[] = "$OpenBSD: lpr.c,v 1.24 2002/02/16 21:28:04 millert #include <stdio.h> #include <ctype.h> #include <string.h> +#include <err.h> + #include "lp.h" #include "lp.local.h" #include "pathnames.h" @@ -94,7 +96,7 @@ static char *jobname; /* job name on header page */ static int mailflg; /* send mail */ static int nact; /* number of jobs to act on */ static int ncopies = 1; /* # of copies to make */ -static char *person; /* user name */ +static const char *person; /* user name */ static int qflag; /* q job, but don't exec daemon */ static int rflag; /* remove files upon completion */ static int sflag; /* symbolic link flag */ @@ -108,34 +110,32 @@ static struct stat statb; volatile sig_atomic_t gotintr; -static void card(int, char *); +static void card(int, const char *); static void chkprinter(char *); static void cleanup(int); static void copy(int, char []); +static char *itoa(int); static char *linked(char *); static char *lmktemp(char *, int, int); static void mktemps(void); static int nfile(char *); static int test(char *); -static char *itoa(int); - -uid_t uid, euid; +static void usage(void); int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char **argv) { struct passwd *pw; struct group *gptr; char *arg, *cp; - char buf[BUFSIZ]; - int i, f; + char buf[MAXPATHLEN]; + int i, f, ch; struct stat stb; euid = geteuid(); uid = getuid(); seteuid(uid); + if (signal(SIGHUP, SIG_IGN) != SIG_IGN) signal(SIGHUP, cleanup); if (signal(SIGINT, SIG_IGN) != SIG_IGN) @@ -146,136 +146,116 @@ main(argc, argv) signal(SIGTERM, cleanup); gethostname(host, sizeof (host)); - openlog("lpd", 0, LOG_LPR); + openlog("lpr", 0, LOG_LPR); - while (argc > 1 && argv[1][0] == '-') { - argc--; - arg = *++argv; - switch (arg[1]) { + while ((ch = getopt(argc, argv, + ":#:1:2:3:4:C:J:P:T:U:cdfghi:lnmprstvw:")) != -1) { + switch (ch) { - case 'P': /* specifiy printer name */ - if (arg[2]) - printer = &arg[2]; - else if (argc > 1) { - argc--; - printer = *++argv; + case '#': /* n copies */ + if (isdigit(*optarg)) { + i = atoi(optarg); + if (i > 0) + ncopies = i; } + + case '4': /* troff fonts */ + case '3': + case '2': + case '1': + fonts[optopt - '1'] = optarg; break; case 'C': /* classification spec */ hdr++; - if (arg[2]) - class = &arg[2]; - else if (argc > 1) { - argc--; - class = *++argv; - } + class = optarg; break; - case 'U': /* user name */ + case 'J': /* job name */ hdr++; - if (arg[2]) - person = &arg[2]; - else if (argc > 1) { - argc--; - person = *++argv; - } + jobname = optarg; break; - case 'J': /* job name */ - hdr++; - if (arg[2]) - jobname = &arg[2]; - else if (argc > 1) { - argc--; - jobname = *++argv; - } + case 'P': /* specifiy printer name */ + printer = optarg; break; case 'T': /* pr's title line */ - if (arg[2]) - title = &arg[2]; - else if (argc > 1) { - argc--; - title = *++argv; - } + title = optarg; + break; + + case 'U': /* user name */ + hdr++; + person = optarg; break; + case 'c': /* print cifplot output */ + case 'd': /* print tex output (dvi files) */ + case 'g': /* print graph(1G) output */ case 'l': /* literal output */ + case 'n': /* print ditroff output */ case 'p': /* print using ``pr'' */ case 't': /* print troff output (cat files) */ - case 'n': /* print ditroff output */ - case 'd': /* print tex output (dvi files) */ - case 'g': /* print graph(1G) output */ - case 'c': /* print cifplot output */ case 'v': /* print vplot output */ - format = arg[1]; + format = optopt; break; case 'f': /* print fortran output */ format = 'r'; break; - case '4': /* troff fonts */ - case '3': - case '2': - case '1': - if (argc > 1) { - argc--; - fonts[arg[1] - '1'] = *++argv; - } - break; - - case 'w': /* versatec page width */ - width = arg+2; + case 'h': /* toggle want of header page */ + hdr = !hdr; break; - case 'r': /* remove file when done */ - rflag++; + case 'i': /* indent output */ + iflag++; + indent = atoi(optarg); + if (indent < 0) + indent = 8; break; case 'm': /* send mail when done */ mailflg++; break; - case 'h': /* toggle want of header page */ - hdr = !hdr; + case 'q': /* just q job */ + qflag++; + break; + + case 'r': /* remove file when done */ + rflag++; break; case 's': /* try to link files */ sflag++; break; - case 'q': /* just q job */ - qflag++; + case 'w': /* versatec page width */ + width = optarg; break; - case 'i': /* indent output */ - iflag++; - indent = arg[2] ? atoi(&arg[2]) : 8; + case ':': /* catch "missing argument" error */ + if (optopt == 'i') { + iflag++; /* -i without args is valid */ + indent = 8; + } else + usage(); break; - case '#': /* n copies */ - if (isdigit(arg[2])) { - i = atoi(&arg[2]); - if (i > 0) - ncopies = i; - } + default: + usage(); } } - - if (printer == NULL) { - char *p; - + argc -= optind; + argv += optind; + if (printer == NULL && (printer = getenv("PRINTER")) == NULL) printer = DEFLP; - if ((p = getenv("PRINTER")) != NULL) - printer = p; - } chkprinter(printer); if (SC && ncopies > 1) errx(1, "multiple copies are not allowed"); if (MC > 0 && ncopies > MC) - errx(1, "only %d copies are allowed", MC); + errx(1, "only %ld copies are allowed", MC); /* * Get the identity of the person doing the lpr using the same * algorithm as lprm. @@ -305,7 +285,7 @@ main(argc, argv) /* * Check to make sure queuing is enabled if userid is not root. */ - (void) snprintf(buf, sizeof(buf), "%s/%s", SD, LO); + (void)snprintf(buf, sizeof(buf), "%s/%s", SD, LO); if (userid && stat(buf, &stb) == 0 && (stb.st_mode & 010)) errx(1, "Printer queue is disabled"); /* @@ -314,16 +294,17 @@ main(argc, argv) mktemps(); tfd = nfile(tfname); seteuid(euid); - (void) fchown(tfd, DU, -1); /* owned by daemon for protection */ + (void)fchown(tfd, DU, -1); /* owned by daemon for protection */ seteuid(uid); card('H', host); card('P', person); if (hdr) { if (jobname == NULL) { - if (argc == 1) + if (argc == 0) jobname = "stdin"; else - jobname = (arg = strrchr(argv[1], '/')) ? arg+1 : argv[1]; + jobname = (arg = strrchr(argv[0], '/')) ? + arg + 1 : argv[0]; } card('J', jobname); card('C', class); @@ -343,15 +324,21 @@ main(argc, argv) /* * Read the files and spool them. */ - if (argc == 1) + if (argc == 0) copy(0, " "); - else while (--argc) { - if ((f = test(arg = *++argv)) < 0) + else while (argc--) { + if (argv[0][0] == '-' && argv[0][1] == '\0') { + /* use stdin */ + copy(0, " "); + argv++; + continue; + } + if ((f = test(arg = *argv++)) < 0) continue; /* file unreasonable */ if (sflag && (cp = linked(arg)) != NULL) { - (void) snprintf(buf, sizeof(buf), "%d %d", statb.st_dev, - statb.st_ino); + (void)snprintf(buf, sizeof(buf), "%d %d", + statb.st_dev, statb.st_ino); card('S', buf); if (format == 'p') card('T', title ? title : arg); @@ -371,14 +358,14 @@ main(argc, argv) warn("%s", arg); else { copy(i, arg); - (void) close(i); + (void)close(i); if (f && unlink(arg) < 0) warnx("%s: not removed", arg); } } if (nact) { - (void) close(tfd); + (void)close(tfd); tfname[inchar]--; /* * Touch the control file to fix position in the queue. @@ -394,7 +381,7 @@ main(argc, argv) tfname[inchar]++; cleanup(0); } - (void) close(tfd); + (void)close(tfd); } if (link(tfname, cfname) < 0) { warn("cannot rename %s", cfname); @@ -433,14 +420,14 @@ copy(f, n) card('N', n); fd = nfile(dfname); nr = nc = 0; - while ((i = read(f, buf, BUFSIZ)) > 0) { + while ((i = read(f, buf, sizeof(buf))) > 0) { if (write(fd, buf, i) != i) { warn("%s", n); break; } nc += i; - if (nc >= BUFSIZ) { - nc -= BUFSIZ; + if (nc >= sizeof(buf)) { + nc -= sizeof(buf); nr++; if (MX > 0 && nr > MX) { warnx("%s: copy file is too large", n); @@ -448,7 +435,7 @@ copy(f, n) } } } - (void) close(fd); + (void)close(fd); if (nc==0 && nr==0) warnx("%s: empty input file", f ? n : "stdin"); else @@ -464,11 +451,11 @@ linked(file) char *file; { char *cp; - static char nfile[MAXPATHLEN]; + static char buf[MAXPATHLEN]; int ret; if (*file != '/') { - if (getcwd(nfile, sizeof(nfile)) == NULL) + if (getcwd(buf, sizeof(buf)) == NULL) return(NULL); while (file[0] == '.') { @@ -478,7 +465,7 @@ linked(file) continue; case '.': if (file[2] == '/') { - if ((cp = strrchr(nfile, '/')) != NULL) + if ((cp = strrchr(buf, '/')) != NULL) *cp = '\0'; file += 3; continue; @@ -486,9 +473,10 @@ linked(file) } break; } - strncat(nfile, "/", sizeof(nfile) - strlen(nfile) - 1); - strncat(nfile, file, sizeof(nfile) - strlen(nfile) - 1); - file = nfile; + if (strlcat(buf, "/", sizeof(buf)) >= sizeof(buf) || + strlcat(buf, file, sizeof(buf)) >= sizeof(buf)) + return(NULL); + file = buf; } seteuid(euid); ret = symlink(file, dfname); @@ -502,12 +490,16 @@ linked(file) static void card(c, p2) int c; - char *p2; + const char *p2; { char buf[BUFSIZ]; char *p1 = buf; int len = 2; + if (strlen(p2) > sizeof(buf) - 2) + errx(1, "Internal error: String longer than %ld", + (long)sizeof(buf)); + *p1++ = c; while ((c = *p2++) != '\0' && len < sizeof(buf)) { *p1++ = (c == '\n') ? ' ' : c; @@ -529,7 +521,7 @@ nfile(n) seteuid(euid); f = open(n, O_WRONLY | O_EXCL | O_CREAT, FILMOD); - (void) umask(oldumask); + (void)umask(oldumask); if (f < 0) { warn("%s", n); cleanup(0); @@ -604,7 +596,7 @@ test(file) warn("cannot stat %s\n", file); goto bad; } - if ((statb.st_mode & S_IFMT) == S_IFDIR) { + if (S_ISDIR(statb.st_mode)) { warnx("%s is a directory\n", file); goto bad; } @@ -616,10 +608,10 @@ test(file) !N_BADMAG(execb)) { warnx("%s is an executable program and is unprintable", file); - (void) close(fd); + (void)close(fd); goto bad; } - (void) close(fd); + (void)close(fd); if (rflag) { if ((cp = strrchr(file, '/')) == NULL) { if (access(".", 2) == 0) @@ -695,9 +687,8 @@ mktemps() int len, fd, n; char *cp; char buf[BUFSIZ]; - char *lmktemp(); - (void) snprintf(buf, sizeof(buf), "%s/.seq", SD); + (void)snprintf(buf, sizeof(buf), "%s/.seq", SD); seteuid(euid); if ((fd = open(buf, O_RDWR|O_CREAT, 0661)) < 0) err(1, "cannot create %s", buf); @@ -718,10 +709,10 @@ mktemps() dfname = lmktemp("df", n, len); inchar = strlen(SD) + 3; n = (n + 1) % 1000; - (void) lseek(fd, (off_t)0, 0); + (void)lseek(fd, (off_t)0, 0); snprintf(buf, sizeof(buf), "%03d\n", n); - (void) write(fd, buf, strlen(buf)); - (void) close(fd); /* unlocks as well */ + (void)write(fd, buf, strlen(buf)); + (void)close(fd); /* unlocks as well */ } /* @@ -736,6 +727,18 @@ lmktemp(id, num, len) if ((s = malloc(len)) == NULL) err(1, NULL); - (void) snprintf(s, len, "%s/%sA%03d%s", SD, id, num, host); + (void)snprintf(s, len, "%s/%sA%03d%s", SD, id, num, host); return(s); } + +static void +usage() +{ + extern char *__progname; + + fprintf(stderr, + "usage: %s [-cdfghlnmprstv] [-Pprinter] [-#num] [-C class] " + "[-J job] [-T title]\n [-U user] [-i [numcols]] " + "[-1234 font] [-wnum] [name ...]\n", __progname); + exit(1); +} diff --git a/usr.sbin/lpr/lprm/Makefile b/usr.sbin/lpr/lprm/Makefile index ab6b4f3133f..968e100e65d 100644 --- a/usr.sbin/lpr/lprm/Makefile +++ b/usr.sbin/lpr/lprm/Makefile @@ -1,9 +1,9 @@ # @(#)Makefile 8.1 (Berkeley) 6/6/93 -# $OpenBSD: Makefile,v 1.2 1997/01/17 16:12:47 millert Exp $ +# $OpenBSD: Makefile,v 1.3 2002/05/20 23:13:50 millert Exp $ PROG= lprm CFLAGS+=-I${.CURDIR}/../common_source -SRCS= lprm.c rmjob.c startdaemon.c common.c +SRCS= lprm.c rmjob.c startdaemon.c common.c common_vars.c BINOWN= root BINGRP= daemon BINMODE=6555 diff --git a/usr.sbin/lpr/lprm/lprm.1 b/usr.sbin/lpr/lprm/lprm.1 index 6b629e924dc..0662163b272 100644 --- a/usr.sbin/lpr/lprm/lprm.1 +++ b/usr.sbin/lpr/lprm/lprm.1 @@ -1,4 +1,5 @@ -.\" $OpenBSD: lprm.1,v 1.6 2000/03/19 17:57:07 aaron Exp $ +.\" $OpenBSD: lprm.1,v 1.7 2002/05/20 23:13:50 millert Exp $ +.\" $NetBSD: lprm.1,v 1.10 2002/01/19 03:23:47 wiz Exp $ .\" .\" Copyright (c) 1983, 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -41,15 +42,17 @@ .Nd remove jobs from the line printer spooling queue .Sh SYNOPSIS .Nm lprm -.Op Fl P Ns Ar printer .Op Fl -.Op Ar job# Ar ... -.Op Ar user Ar ... +.Bk -words +.Op Fl P Ns Ar printer +.Ek +.Oo Op Ar job# Ar ... +.Op Ar user Ar ... Oc .Sh DESCRIPTION .Nm lprm will remove a job, or jobs, from a printer's spool queue. Since the spooling directory is protected from users, using -.Nm lprm +.Nm is normally the only method by which a user may remove a job. The owner of a job is determined by the user's login name and host name on the machine where the @@ -66,18 +69,17 @@ Specify the queue associated with a specific If a single .Dq Fl is given, -.Nm lprm +.Nm will remove all jobs which a user owns. If the superuser employs this flag, the spool queue will be emptied entirely. .It Ar user Causes -.Nm lprm -to attempt to remove any jobs queued belonging to that user -(or users). +.Nm +to attempt to remove any jobs queued belonging to that user (or users). This form of invoking -.Nm lprm +.Nm is useful only to the superuser. .It Ar job\ \&# A user may dequeue an individual job by specifying its job number. @@ -95,7 +97,7 @@ program, e.g., .El .Pp If neither arguments or options are given, -.Nm lprm +.Nm will delete the currently active job if it is owned by the user who invoked .Nm lprm . @@ -104,7 +106,7 @@ owned by the user who invoked announces the names of any files it removes and is silent if there are no jobs in the queue which match the request list. .Pp -.Nm lprm +.Nm will kill off an active daemon, if necessary, before removing any spooling files. If a daemon is killed, a new one is @@ -124,29 +126,29 @@ the default printer is assumed from .Ev PRINTER . .El .Sh FILES -.Bl -tag -width /var/spool/*/lock/ -compact +.Bl -tag -width /var/spool/output/*/lock/ -compact .It Pa /etc/printcap -printer characteristics file -.It Pa /var/spool/* -spooling directories -.It Pa /var/spool/*/lock -lock file used to obtain the PID of the current -daemon and the job number of the currently active job +Printer characteristics file. +.It Pa /var/spool/output/* +Spooling directories. +.It Pa /var/spool/output/*/lock +Lock file used to obtain the PID of the current +daemon and the job number of the currently active job. .El -.Sh SEE ALSO -.Xr lpq 1 , -.Xr lpr 1 , -.Xr lpd 8 .Sh DIAGNOSTICS .Bl -tag -width Ds .It Sy Permission denied Printed if the user tries to remove files other than his own. .El -.Sh BUGS -Since there are race conditions possible in the update of the lock file, -the currently active job may be incorrectly identified. +.Sh SEE ALSO +.Xr lpq 1 , +.Xr lpr 1 , +.Xr lpd 8 .Sh HISTORY The .Nm lprm command appeared in .Bx 3.0 . +.Sh BUGS +Since there are race conditions possible in the update of the lock file, +the currently active job may be incorrectly identified. diff --git a/usr.sbin/lpr/lprm/lprm.c b/usr.sbin/lpr/lprm/lprm.c index 226730c6302..4c7c0d949a9 100644 --- a/usr.sbin/lpr/lprm/lprm.c +++ b/usr.sbin/lpr/lprm/lprm.c @@ -1,4 +1,5 @@ -/* $OpenBSD: lprm.c,v 1.10 2002/02/16 21:28:04 millert Exp $ */ +/* $OpenBSD: lprm.c,v 1.11 2002/05/20 23:13:50 millert Exp $ */ +/* $$NetBSD: lprm.c,v 1.9 1999/08/16 03:12:32 simonb Exp $ */ /* * Copyright (c) 1983, 1993 @@ -44,7 +45,7 @@ static const char copyright[] = #if 0 static const char sccsid[] = "@(#)lprm.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: lprm.c,v 1.10 2002/02/16 21:28:04 millert Exp $"; +static const char rcsid[] = "$OpenBSD: lprm.c,v 1.11 2002/05/20 23:13:50 millert Exp $"; #endif #endif /* not lint */ @@ -55,20 +56,22 @@ static const char rcsid[] = "$OpenBSD: lprm.c,v 1.10 2002/02/16 21:28:04 millert * * Using information in the lock file, lprm will kill the * currently active daemon (if necessary), remove the associated files, - * and startup a new daemon. Priviledged users may remove anyone's spool + * and startup a new daemon. Privileged users may remove anyone's spool * entries, otherwise one can only remove their own. */ #include <sys/param.h> -#include <syslog.h> +#include <ctype.h> #include <dirent.h> +#include <err.h> #include <pwd.h> -#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> -#include <ctype.h> +#include <syslog.h> +#include <unistd.h> + #include "lp.h" #include "lp.local.h" @@ -80,82 +83,83 @@ int requ[MAXREQUESTS]; /* job number of spool entries */ int requests; /* # of spool requests */ char *user[MAXUSERS]; /* users to process */ int users; /* # of users in user array */ -uid_t uid, euid; /* real and effective user id's */ - -static char luser[MAXLOGNAME]; /* buffer for person */ - -volatile sig_atomic_t gotintr; +volatile sig_atomic_t gotintr; /* set when we receive SIGINT */ +static char luser[MAXLOGNAME]; /* buffer for person */ -void usage(void); +static __dead void usage(void); int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char **argv) { - char *arg; struct passwd *p; + char *cp; + long l; + int ch; uid = getuid(); euid = geteuid(); seteuid(uid); /* be safe */ gethostname(host, sizeof(host)); - openlog("lpd", 0, LOG_LPR); + openlog("lprm", 0, LOG_LPR); if ((p = getpwuid(getuid())) == NULL) fatal("Who are you?"); if (strlen(p->pw_name) >= sizeof(luser)) fatal("Your name is too long"); - strcpy(luser, p->pw_name); + strlcpy(luser, p->pw_name, sizeof(luser)); person = luser; - while (--argc) { - if ((arg = *++argv)[0] == '-') - switch (arg[1]) { - case 'P': - if (arg[2]) - printer = &arg[2]; - else if (argc > 1) { - argc--; - printer = *++argv; - } - break; - case '\0': - if (!users) { - users = -1; - break; - } - default: - usage(); - } - else { - if (users < 0) - usage(); - if (isdigit(arg[0])) { - if (requests >= MAXREQUESTS) - fatal("Too many requests"); - requ[requests++] = atoi(arg); - } else { - if (users >= MAXUSERS) - fatal("Too many users"); - user[users++] = arg; - } + while ((ch = getopt(argc, argv, "-P:w:")) != -1) { + switch (ch) { + case '-': + users = -1; + break; + case 'P': + printer = optarg; + break; + case 'w': + l = strtol(optarg, &cp, 10); + if (*cp != '\0' || l < 0 || l >= INT_MAX) + errx(1, "wait time must be postive integer: %s", + optarg); + wait_time = (u_int)l; + if (wait_time < 30) + warnx("warning: wait time less than 30 seconds"); + break; + default: + usage(); } } - if (printer == NULL) { - char *p; + argc -= optind; + argv += optind; + if (printer == NULL && (printer = getenv("PRINTER")) == NULL) printer = DEFLP; - if ((p = getenv("PRINTER")) != NULL) - printer = p; + if (users < 0 && argc != 0) + usage(); + while (argc > 0) { + if (isdigit(*argv[0])) { + if (requests >= MAXREQUESTS) + fatal("Too many requests"); + requ[requests++] = atoi(argv[0]); + } else { + if (users >= MAXUSERS) + fatal("Too many users"); + user[users++] = argv[0]; + } + argc--; + argv++; } rmjob(); exit(0); } -void -usage() +static __dead void +usage(void) { - fprintf(stderr, "usage: lprm [-] [-Pprinter] [[job #] [user] ...]\n"); + extern char *__progname; + + fprintf(stderr, "usage: %s [-] [-Pprinter] [[job #] [user] ...]\n", + __progname); exit(2); } diff --git a/usr.sbin/lpr/lptest/lptest.1 b/usr.sbin/lpr/lptest/lptest.1 index b466ea0de0f..247fae2a01b 100644 --- a/usr.sbin/lpr/lptest/lptest.1 +++ b/usr.sbin/lpr/lptest/lptest.1 @@ -1,4 +1,5 @@ -.\" $OpenBSD: lptest.1,v 1.3 2000/03/19 17:57:07 aaron Exp $ +.\" $OpenBSD: lptest.1,v 1.4 2002/05/20 23:13:50 millert Exp $ +.\" $NetBSD: lptest.1,v 1.7 1999/03/22 18:44:00 garbled Exp $ .\" .\" Copyright (c) 1985, 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -73,6 +74,6 @@ is to be specified, .Ar length must be also be specified. .Sh HISTORY -.Nm lptest +.Nm appeared in .Bx 4.3 . diff --git a/usr.sbin/lpr/lptest/lptest.c b/usr.sbin/lpr/lptest/lptest.c index 5ac3477c0f6..d8806c9d984 100644 --- a/usr.sbin/lpr/lptest/lptest.c +++ b/usr.sbin/lpr/lptest/lptest.c @@ -1,5 +1,5 @@ -/* $OpenBSD: lptest.c,v 1.4 2001/08/30 17:38:13 millert Exp $ */ -/* $NetBSD: lptest.c,v 1.5 1996/03/21 18:13:20 jtc Exp $ */ +/* $OpenBSD: lptest.c,v 1.5 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: lptest.c,v 1.6 1996/12/09 09:57:50 mrg Exp $ */ /* * Copyright (c) 1983, 1993 @@ -45,7 +45,7 @@ static const char copyright[] = #if 0 static const char sccsid[] = "@(#)lptest.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: lptest.c,v 1.4 2001/08/30 17:38:13 millert Exp $"; +static const char rcsid[] = "$OpenBSD: lptest.c,v 1.5 2002/05/20 23:13:50 millert Exp $"; #endif #endif /* not lint */ @@ -85,6 +85,6 @@ main(argc, argv) } putchar('\n'); } - (void) fflush(stdout); + (void)fflush(stdout); exit(0); } diff --git a/usr.sbin/lpr/pac/Makefile b/usr.sbin/lpr/pac/Makefile index b986b559419..41fd7878bb1 100644 --- a/usr.sbin/lpr/pac/Makefile +++ b/usr.sbin/lpr/pac/Makefile @@ -1,10 +1,10 @@ # from: @(#)Makefile 8.1 (Berkeley) 6/6/93 -# $OpenBSD: Makefile,v 1.2 1997/01/17 16:12:49 millert Exp $ +# $OpenBSD: Makefile,v 1.3 2002/05/20 23:13:50 millert Exp $ PROG= pac CFLAGS+=-I${.CURDIR}/../common_source MAN= pac.8 -SRCS= pac.c common.c +SRCS= pac.c common.c common_vars.c .PATH: ${.CURDIR}/../common_source .include "../../Makefile.inc" diff --git a/usr.sbin/lpr/pac/pac.8 b/usr.sbin/lpr/pac/pac.8 index fa630726a8b..333e7fad80a 100644 --- a/usr.sbin/lpr/pac/pac.8 +++ b/usr.sbin/lpr/pac/pac.8 @@ -1,4 +1,5 @@ -.\" $OpenBSD: pac.8,v 1.5 2000/11/09 17:53:15 aaron Exp $ +.\" $OpenBSD: pac.8,v 1.6 2002/05/20 23:13:50 millert Exp $ +.\" $NetBSD: pac.8,v 1.9 2002/01/19 03:24:14 wiz Exp $ .\" .\" Copyright (c) 1983, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -41,12 +42,13 @@ .Nd printer/plotter accounting information .Sh SYNOPSIS .Nm pac +.Op Fl cmrs +.Bk -words .Op Fl P Ns Ar printer -.Op Fl c -.Op Fl m +.Ek +.Bk -words .Op Fl p Ns Ar price -.Op Fl s -.Op Fl r +.Ek .Op Ar user ... .Sh DESCRIPTION .Nm pac @@ -54,8 +56,7 @@ reads the printer/plotter accounting files, accumulating the number of pages (the usual case) or feet (for raster devices) of paper consumed by each named .Ar user , -and prints out -how much each user consumed in pages or feet and dollars. +and prints out how much each user consumed in pages or feet and dollars. .Pp When no .Ar user @@ -90,6 +91,28 @@ Accounting information is summarized on the summary accounting file; this summarization is necessary since on a busy system, the accounting file can grow by several lines per day. .El +.Sh OUTPUT FORMAT +.Nm +formats the output into simple table, using four columns: +.Bl -enum +.It +The host name followed by the user's login name (column "Login"). +If the +.Fl m +option was specified, the host name will be omitted. +.It +The number of pages or feet printed (column "pages/feet"). +.It +The number of copies made (column "runs"). +.It +The total price for the user (column "price"). +.El +.Pp +If no +.Ar user +argument was specified, +.Nm +will print a summary line with print totals. .Sh FILES .Bl -tag -width /var/account/?_sum -compact .It Pa /var/account/?acct @@ -101,11 +124,11 @@ printer capability database .El .Sh SEE ALSO .Xr printcap 5 -.Sh BUGS -The relationship between the computed price and reality is -as yet unknown. .Sh HISTORY The .Nm command appeared in .Bx 4.0 . +.Sh BUGS +The relationship between the computed price and reality is +as yet unknown. diff --git a/usr.sbin/lpr/pac/pac.c b/usr.sbin/lpr/pac/pac.c index f355056a4e8..3da340f36cd 100644 --- a/usr.sbin/lpr/pac/pac.c +++ b/usr.sbin/lpr/pac/pac.c @@ -1,5 +1,5 @@ -/* $OpenBSD: pac.c,v 1.12 2002/02/16 21:28:04 millert Exp $ */ -/* $NetBSD: pac.c,v 1.7 1996/03/21 18:21:20 jtc Exp $ */ +/* $OpenBSD: pac.c,v 1.13 2002/05/20 23:13:50 millert Exp $ */ +/* $NetBSD: pac.c,v 1.14 2000/04/27 13:40:18 msaitoh Exp $ */ /* * Copyright (c) 1983, 1993 @@ -45,7 +45,7 @@ static const char copyright[] = #if 0 static const char sccsid[] = "@(#)pac.c 8.1 (Berkeley) 6/6/93"; #else -static const char rcsid[] = "$OpenBSD: pac.c,v 1.12 2002/02/16 21:28:04 millert Exp $"; +static const char rcsid[] = "$OpenBSD: pac.c,v 1.13 2002/05/20 23:13:50 millert Exp $"; #endif #endif /* not lint */ @@ -58,11 +58,16 @@ static const char rcsid[] = "$OpenBSD: pac.c,v 1.12 2002/02/16 21:28:04 millert #include <sys/param.h> +#include <ctype.h> #include <dirent.h> +#include <err.h> +#include <errno.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> + #include "lp.h" #include "lp.local.h" @@ -79,8 +84,6 @@ static int sort; /* Sort by cost */ static char *sumfile; /* summary file */ static int summarize; /* Compress accounting file */ -uid_t uid, euid; - volatile sig_atomic_t gotintr; /* @@ -101,97 +104,93 @@ struct hent { static struct hent *hashtab[HSHSIZE]; /* Hash table proper */ static void account(FILE *); -static int any(int, char []); -static int chkprinter(char *); +static int chkprinter(const char *); static void dumpit(void); -static int hash(char []); -static struct hent *enter(char []); -static struct hent *lookup(char []); +static int hash(const char *); +static struct hent *enter(const char *); +static struct hent *lookup(const char *); static int qucmp(const void *, const void *); static void rewrite(void); +__dead void usage(void); int -main(argc, argv) - int argc; - char **argv; +main(int argc, char **argv) { FILE *acct; - char *cp; + int ch; euid = geteuid(); /* these aren't used in pac(1) */ uid = getuid(); - while (--argc) { - cp = *++argv; - if (*cp++ == '-') { - switch(*cp++) { - case 'P': - /* - * Printer name. - */ - printer = cp; - continue; - - case 'p': - /* - * get the price. - */ - price = atof(cp); - pflag = 1; - continue; - - case 's': - /* - * Summarize and compress accounting file. - */ - summarize++; - continue; - - case 'c': - /* - * Sort by cost. - */ - sort++; - continue; - - case 'm': - /* - * disregard machine names for each user - */ - mflag = 1; - continue; - - case 'r': - /* - * Reverse sorting order. - */ - reverse++; - continue; - - default: -fprintf(stderr, - "usage: pac [-Pprinter] [-pprice] [-s] [-c] [-r] [-m] [user ...]\n"); - exit(1); - } + while ((ch = getopt(argc, argv, "P:p:scmr")) != -1) { + switch (ch) { + case 'P': + /* + * Printer name. + */ + printer = optarg; + continue; + + case 'p': + /* + * get the price. + */ + price = atof(optarg); + pflag = 1; + continue; + + case 's': + /* + * Summarize and compress accounting file. + */ + summarize++; + continue; + + case 'c': + /* + * Sort by cost. + */ + sort++; + continue; + + case 'm': + /* + * disregard machine names for each user + */ + mflag = 1; + continue; + + case 'r': + /* + * Reverse sorting order. + */ + reverse++; + continue; + + default: + usage(); + /* NOTREACHED */ } - (void) enter(--cp); + } + argc -= optind; + argv += optind; + + /* + * If there are any arguments left, they're names of users + * we want to print info for. In that case, put them in the hash + * table and unset allflag. + */ + for( ; argc > 0; argc--, argv++) { + (void)enter(*argv); allflag = 0; } - if (printer == NULL) { - char *p; + if (printer == NULL && (printer = getenv("PRINTER")) == NULL) printer = DEFLP; - if ((p = getenv("PRINTER")) != NULL) - printer = p; - } - if (!chkprinter(printer)) { - printf("pac: unknown printer %s\n", printer); - exit(2); - } + if (!chkprinter(printer)) + errx(2, "unknown printer: %s", printer); - if ((acct = fopen(acctfile, "r")) == NULL) { - perror(acctfile); - exit(1); - } + if ((acct = fopen(acctfile, "r")) == NULL) + err(1, "%s", acctfile); account(acct); fclose(acct); if ((acct = fopen(sumfile, "r")) != NULL) { @@ -211,33 +210,54 @@ fprintf(stderr, * is set, then just gather the facts on everyone. * Note that we must accomodate both the active and summary file * formats here. + * The Format of the accounting file is: + * feet_per_page [runs_count] [hostname:]username + * Some software relies on whitespace between runs_count and hostname:username + * being optional (such as Ghostscript's unix-lpr.sh). + * * Host names are ignored if the -m flag is present. */ static void -account(acct) - FILE *acct; +account(FILE *acct) { char linebuf[BUFSIZ]; double t; - char *cp, *cp2; + long l; + char *cp, *cp2, *ep; struct hent *hp; int ic; - while (fgets(linebuf, BUFSIZ, acct) != NULL) { + while (fgets(linebuf, sizeof(linebuf), acct) != NULL) { cp = linebuf; - while (any(*cp, " \t")) - cp++; - t = atof(cp); - while (any(*cp, ".0123456789")) + while (isspace(*cp)) cp++; - while (any(*cp, " \t")) + + /* get t, feet_per_page */ + errno = 0; + t = strtod(cp, &ep); + if (!isspace(*ep) || errno == ERANGE) + continue; + + /* get ic, runs_count (optional) */ + for (cp = ep + 1; isspace(*cp); ) cp++; - for (cp2 = cp; !any(*cp2, " \t\n"); cp2++) + l = strtol(cp, &ep, 10); + if (cp == ep) + l = 0; /* runs_count not specified */ + else if (l < 0 || l >= INT_MAX) + continue; + ic = (int)l; + + /* get [hostname:]username */ + for (cp = ep; isspace(*cp); cp++) + ; + for (cp2 = cp; *cp2 && !isspace(*cp2); cp2++) ; - ic = atoi(cp2); *cp2 = '\0'; - if (mflag && strchr(cp, ':')) - cp = strchr(cp, ':') + 1; + /* if -m was specified, don't use the hostname part */ + if (mflag && (cp2 = strchr(cp, ':')) != NULL) + cp = cp2 + 1; + hp = lookup(cp); if (hp == NULL) { if (!allflag) @@ -257,7 +277,7 @@ account(acct) * and print it all out. */ static void -dumpit() +dumpit(void) { struct hent **base; struct hent *hp, **ap; @@ -266,7 +286,9 @@ dumpit() hp = hashtab[0]; hno = 1; - base = (struct hent **) calloc(sizeof hp, hcount); + base = (struct hent **) malloc(hcount * sizeof(hp)); + if (base == NULL) + err(1, NULL); for (ap = base, c = hcount; c--; ap++) { while (hp == NULL) hp = hashtab[hno++]; @@ -295,14 +317,14 @@ dumpit() * Rewrite the summary file with the summary information we have accumulated. */ static void -rewrite() +rewrite(void) { struct hent *hp; int i; FILE *acctf; if ((acctf = fopen(sumfile, "w")) == NULL) { - perror(sumfile); + warn("%s", sumfile); errs++; return; } @@ -316,12 +338,12 @@ rewrite() } fflush(acctf); if (ferror(acctf)) { - perror(sumfile); + warn("%s", sumfile); errs++; } fclose(acctf); if ((acctf = fopen(acctfile, "w")) == NULL) - perror(acctfile); + warn("%s", acctfile); else fclose(acctf); } @@ -335,8 +357,7 @@ rewrite() */ static struct hent * -enter(name) - char name[]; +enter(const char *name) { struct hent *hp; int h; @@ -345,9 +366,12 @@ enter(name) return(hp); h = hash(name); hcount++; - hp = (struct hent *) calloc(sizeof *hp, 1); - hp->h_name = (char *) calloc(sizeof(char), strlen(name)+1); - strcpy(hp->h_name, name); + hp = (struct hent *) malloc(sizeof *hp); + if (hp == NULL) + err(1, NULL); + hp->h_name = strdup(name); + if (hp->h_name == NULL) + err(1, NULL); hp->h_feetpages = 0.0; hp->h_count = 0; hp->h_link = hashtab[h]; @@ -361,8 +385,7 @@ enter(name) */ static struct hent * -lookup(name) - char name[]; +lookup(const char *name) { int h; struct hent *hp; @@ -379,11 +402,10 @@ lookup(name) * the hash table to begin the search. */ static int -hash(name) - char name[]; +hash(const char *name) { int h; - char *cp; + const char *cp; for (cp = name, h = 0; *cp; h = (h << 2) + *cp++) ; @@ -391,30 +413,12 @@ hash(name) } /* - * Other stuff - */ -static int -any(ch, str) - int ch; - char str[]; -{ - int c = ch; - char *cp = str; - - while (*cp) - if (*cp++ == c) - return(1); - return(0); -} - -/* * The qsort comparison routine. * The comparison is ascii collating order * or by feet of typesetter film, according to sort. */ static int -qucmp(a, b) - const void *a, *b; +qucmp(const void *a, const void *b) { struct hent *h1, *h2; int r; @@ -433,8 +437,7 @@ qucmp(a, b) * Perform lookup for printer name or abbreviation -- */ static int -chkprinter(s) - char *s; +chkprinter(const char *s) { int stat; @@ -452,12 +455,20 @@ chkprinter(s) } if (!pflag && (cgetnum(bp, "pc", &price100) == 0)) price = price100/10000.0; - sumfile = (char *) calloc(sizeof(char), strlen(acctfile)+5); - if (sumfile == NULL) { - perror("pac"); - exit(1); - } - strcpy(sumfile, acctfile); - strcat(sumfile, "_sum"); + sumfile = (char *) malloc(strlen(acctfile) + 5); + if (sumfile == NULL) + err(1, "pac"); + strcpy(sumfile, acctfile); /* safe */ + strcat(sumfile, "_sum"); /* safe */ return(1); } + +__dead void +usage(void) +{ + extern char *__progname; + + fprintf(stderr, "usage: %s [-cmrs] [-Pprinter] [-pprice] [user ...]\n", + __progname); + exit(1); +} |