summaryrefslogtreecommitdiffstats
path: root/usr.sbin/lpr
diff options
context:
space:
mode:
authorjoerg <joerg@FreeBSD.org>1996-05-05 14:04:33 +0000
committerjoerg <joerg@FreeBSD.org>1996-05-05 14:04:33 +0000
commit0291e848bc787305335af649ac14bc8fe5a19a49 (patch)
treef679484620675241701b875cbab6124b83dc1136 /usr.sbin/lpr
parent825cd02612729df0559ca26d13d946c625215900 (diff)
downloadFreeBSD-src-0291e848bc787305335af649ac14bc8fe5a19a49.zip
FreeBSD-src-0291e848bc787305335af649ac14bc8fe5a19a49.tar.gz
Vendor-branch import of the 4.4BSD-Lite2 code for lpr. There are
several bugfixes in it that are worth considering. Don't be alarmed about the import conflicts... Obtained from: 4.4BSD-Lite2
Diffstat (limited to 'usr.sbin/lpr')
-rw-r--r--usr.sbin/lpr/common_source/aux.c400
-rw-r--r--usr.sbin/lpr/common_source/aux.h67
-rw-r--r--usr.sbin/lpr/common_source/common.c63
-rw-r--r--usr.sbin/lpr/common_source/displayq.c27
-rw-r--r--usr.sbin/lpr/common_source/lp.h7
-rw-r--r--usr.sbin/lpr/common_source/printcap.c117
-rw-r--r--usr.sbin/lpr/common_source/rmjob.c6
-rw-r--r--usr.sbin/lpr/lpc/cmds.c3
-rw-r--r--usr.sbin/lpr/lpc/lpc.87
-rw-r--r--usr.sbin/lpr/lpc/lpc.c45
-rw-r--r--usr.sbin/lpr/lpd/lpd.c37
-rw-r--r--usr.sbin/lpr/lpd/printjob.c240
-rw-r--r--usr.sbin/lpr/lpd/recvjob.c4
-rw-r--r--usr.sbin/lpr/lpq/lpq.112
-rw-r--r--usr.sbin/lpr/lpq/lpq.c63
-rw-r--r--usr.sbin/lpr/lpr/lpr.c3
16 files changed, 964 insertions, 137 deletions
diff --git a/usr.sbin/lpr/common_source/aux.c b/usr.sbin/lpr/common_source/aux.c
new file mode 100644
index 0000000..8d7a936
--- /dev/null
+++ b/usr.sbin/lpr/common_source/aux.c
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 1995
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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.
+ */
+
+/*
+ * Auxillary functions to aid portability to other systems.
+ * These are 4.4BSD routines that are often not found on other systems.
+ *
+ * !!!USE THIS FILE ONLY IF YOU ARE NOT RUNNING 4.4BSD!!!
+ */
+
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#ifdef NO_SNPRINTF
+#if __STDC__
+snprintf(char *str, size_t n, const char *fmt, ...)
+#else
+snprintf(str, n, fmt, va_alist)
+ char *str;
+ size_t n;
+ char *fmt;
+ va_dcl
+#endif
+{
+ int ret;
+ va_list ap;
+
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ ret = vsprintf(str, fmt, ap);
+ va_end(ap);
+ if (strlen(str) > n)
+ fatal("memory corrupted");
+ return (ret);
+}
+
+vsnprintf(str, n, fmt, ap)
+ char *str;
+ size_t n;
+ char *fmt;
+ va_list ap;
+{
+ int ret;
+
+ ret = vsprintf(str, fmt, ap);
+ if (strlen(str) > n)
+ fatal("memory corrupted");
+ return (ret);
+}
+#endif
+
+#ifdef NO_STRERROR
+char *
+strerror(num)
+ int num;
+{
+ extern int sys_nerr;
+ extern char *sys_errlist[];
+#define UPREFIX "Unknown error: "
+ static char ebuf[40] = UPREFIX; /* 64-bit number + slop */
+ register unsigned int errnum;
+ register char *p, *t;
+ char tmp[40];
+
+ errnum = num; /* convert to unsigned */
+ if (errnum < sys_nerr)
+ return(sys_errlist[errnum]);
+
+ /* Do this by hand, so we don't include stdio(3). */
+ t = tmp;
+ do {
+ *t++ = "0123456789"[errnum % 10];
+ } while (errnum /= 10);
+ for (p = ebuf + sizeof(UPREFIX) - 1;;) {
+ *p++ = *--t;
+ if (t <= tmp)
+ break;
+ }
+ return(ebuf);
+}
+#endif
+
+#ifdef NO_STRDUP
+char *
+strdup(str)
+ char *str;
+{
+ int n;
+ char *sp;
+
+ n = strlen(str) + 1;
+ if (sp = (char *) malloc(n))
+ memcpy(sp, str, n);
+ return (sp);
+}
+#endif
+
+#ifdef NO_DAEMON
+#include <fcntl.h>
+#include <paths.h>
+#include <unistd.h>
+#include <sgtty.h>
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+
+int
+daemon(nochdir, noclose)
+ int nochdir, noclose;
+{
+ int fd;
+
+ switch (fork()) {
+ case -1:
+ return (-1);
+ case 0:
+ break;
+ default:
+ _exit(0);
+ }
+
+ if (setsid() == -1)
+ return (-1);
+
+ if (!nochdir)
+ (void)chdir("/");
+
+ if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
+ (void)dup2(fd, STDIN_FILENO);
+ (void)dup2(fd, STDOUT_FILENO);
+ (void)dup2(fd, STDERR_FILENO);
+ if (fd > 2)
+ (void)close (fd);
+ }
+ return (0);
+}
+#endif
+
+
+#ifdef NO_SETSID
+int
+setsid()
+{
+ int f;
+
+ f = open("/dev/tty", O_RDWR);
+ if (f > 0) {
+ ioctl(f, TIOCNOTTY, 0);
+ (void) close(f);
+ }
+ return f;
+}
+#endif
+
+
+#ifdef NO_VSYSLOG
+#include <stdio.h>
+#include <errno.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+vsyslog(pri, fmt, ap)
+ int pri;
+ const char *fmt;
+ va_list ap;
+{
+ char buf[2048], fmt_cpy[1024];
+
+ /* substitute error message for %m */
+ {
+ register char ch, *t1, *t2;
+ char *strerror();
+
+ for (t1 = fmt_cpy; ch = *fmt; ++fmt)
+ if (ch == '%' && fmt[1] == 'm') {
+ ++fmt;
+ for (t2 = strerror(errno);
+ *t1 = *t2++; ++t1);
+ }
+ else
+ *t1++ = ch;
+ *t1 = '\0';
+ }
+ vsprintf(buf, fmt_cpy, ap);
+ syslog(pri, "%s", buf);
+}
+#endif
+
+
+#ifdef NO_IVALIDUSER
+#include <stdio.h>
+#include <ctype.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include "pathnames.h"
+
+/*
+ * Returns 0 if ok, -1 if not ok.
+ */
+int
+__ivaliduser(hostf, raddr, luser, ruser)
+ FILE *hostf;
+ struct in_addr raddr;
+ const char *luser, *ruser;
+{
+ register char *user, *p;
+ int ch;
+ char buf[MAXHOSTNAMELEN + 128]; /* host + login */
+
+ while (fgets(buf, sizeof(buf), hostf)) {
+ p = buf;
+ /* Skip lines that are too long. */
+ if (strchr(p, '\n') == NULL) {
+ while ((ch = getc(hostf)) != '\n' && ch != EOF);
+ continue;
+ }
+ while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') {
+ *p = isupper(*p) ? tolower(*p) : *p;
+ p++;
+ }
+ if (*p == ' ' || *p == '\t') {
+ *p++ = '\0';
+ while (*p == ' ' || *p == '\t')
+ p++;
+ user = p;
+ while (*p != '\n' && *p != ' ' &&
+ *p != '\t' && *p != '\0')
+ p++;
+ } else
+ user = p;
+ *p = '\0';
+ if (__icheckhost(raddr, buf) &&
+ strcmp(ruser, *user ? user : luser) == 0) {
+ return (0);
+ }
+ }
+ return (-1);
+}
+
+/*
+ * Returns "true" if match, 0 if no match.
+ */
+__icheckhost(raddr, lhost)
+ struct in_addr raddr;
+ register char *lhost;
+{
+ register struct hostent *hp;
+ struct in_addr laddr;
+ register char **pp;
+
+ /* Try for raw ip address first. */
+ if (isdigit(*lhost) && (laddr.s_addr = inet_addr(lhost)) != INADDR_NONE)
+ return (raddr.s_addr == laddr.s_addr);
+
+ /* Better be a hostname. */
+ if ((hp = gethostbyname(lhost)) == NULL)
+ return (0);
+
+ /* Spin through ip addresses. */
+ for (pp = hp->h_addr_list; *pp; ++pp)
+ if (!bcmp(&raddr, *pp, sizeof(struct in_addr)))
+ return (1);
+
+ /* No match. */
+ return (0);
+}
+#endif /* NO_IVALIDUSER */
+
+
+#ifdef NO_STATFS
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/dir.h>
+#include <sys/param.h>
+#include <ufs/fs.h>
+
+/*
+ * Check to see if there is enough space on the disk for size bytes.
+ * 1 == OK, 0 == Not OK.
+ */
+static int
+chksize(size)
+ int size;
+{
+ struct stat stb;
+ int spacefree;
+ struct fs fs;
+ static int dfd;
+ static char *find_dev();
+
+#ifndef SBOFF
+#define SBOFF ((off_t)(BBSIZE))
+#endif
+ if (dfd <= 0) {
+ char *ddev;
+
+ if (stat(".", &stb) < 0) {
+ syslog(LOG_ERR, "%s: %m", "statfs(\".\")");
+ return (1);
+ }
+ ddev = find_dev(stb.st_dev, S_IFBLK);
+ if ((dfd = open(ddev, O_RDONLY)) < 0) {
+ syslog(LOG_WARNING, "%s: %s: %m", printer, ddev);
+ return (1);
+ }
+ }
+ if (lseek(dfd, (off_t)(SBOFF), 0) < 0)
+ return(1);
+ if (read(dfd, (char *)&fs, sizeof fs) != sizeof fs
+ || fs.fs_magic != FS_MAGIC) {
+ syslog(LOG_ERR, "Can't calculate free space on spool device");
+ return(1);
+ }
+ spacefree = freespace(&fs, fs.fs_minfree) * fs.fs_fsize / 512;
+ size = (size + 511) / 512;
+ if (minfree + size > spacefree)
+ return(0);
+ return(1);
+}
+
+static char *
+find_dev(dev, type)
+ register dev_t dev;
+ register int type;
+{
+ register DIR *dfd;
+ struct direct *dir;
+ struct stat stb;
+ char devname[MAXNAMLEN+6];
+ char *dp;
+ int n;
+
+ strcpy(devname, "/dev/dsk");
+ if ((dfd = opendir(devname)) == NULL) {
+ strcpy(devname, "/dev");
+ dfd = opendir(devname);
+ }
+ strcat(devname, "/");
+ n = strlen(devname);
+
+ while ((dir = readdir(dfd))) {
+ strcpy(devname + n, dir->d_name);
+ if (stat(devname, &stb))
+ continue;
+ if ((stb.st_mode & S_IFMT) != type)
+ continue;
+ if (dev == stb.st_rdev) {
+ closedir(dfd);
+ dp = (char *)malloc(strlen(devname)+1);
+ strcpy(dp, devname);
+ return(dp);
+ }
+ }
+ closedir(dfd);
+ frecverr("cannot find device %d, %d", major(dev), minor(dev));
+ /*NOTREACHED*/
+}
+#endif /* NOSTATFS */
diff --git a/usr.sbin/lpr/common_source/aux.h b/usr.sbin/lpr/common_source/aux.h
new file mode 100644
index 0000000..d9bb0bf
--- /dev/null
+++ b/usr.sbin/lpr/common_source/aux.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1995
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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.
+ */
+
+/*
+ * Auxillary functions to aid portability to other systems.
+ * These are 4.4BSD routines that are often not found on other systems.
+ *
+ * !!!USE THIS FILE ONLY IF YOU ARE NOT RUNNING 4.4BSD!!!
+ */
+
+#ifdef PREPOSIX
+#define dirent direct
+extern int errno;
+#endif
+
+#ifdef NO_RINDEX
+#define index strchr
+#define rindex strrchr
+#endif
+
+#ifdef BSDWAIT
+#define WAITARG_T(a) ((int *)(a))
+#else
+#define WAITARG_T(a) (a)
+#endif
+
+#ifdef SETPGID
+#define setpgrp(a, b) setpgid((pid_t)(a), (pid_t)(b))
+#endif
+
+#ifndef FD_COPY
+#define FD_COPY(f, t) memcpy((char *)t, (char *)f, sizeof(*(f)))
+#endif
+
+#ifdef NO_SNPRINTF
+int snprintf __P((char *str, size_t n, const char *fmt, ...));
+#endif
diff --git a/usr.sbin/lpr/common_source/common.c b/usr.sbin/lpr/common_source/common.c
index 49f7939..8be8c8d 100644
--- a/usr.sbin/lpr/common_source/common.c
+++ b/usr.sbin/lpr/common_source/common.c
@@ -37,11 +37,12 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)common.c 8.2 (Berkeley) 1/21/94";
+static char sccsid[] = "@(#)common.c 8.5 (Berkeley) 4/28/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/stat.h>
+#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -108,18 +109,20 @@ char *printer; /* printer name */
/* host machine name */
char host[MAXHOSTNAMELEN];
char *from = host; /* client's machine name */
-int sendtorem; /* are we sending to a remote? */
+int remote; /* true if sending files to a remote host */
char *printcapdb[2] = { _PATH_PRINTCAP, 0 };
static int compar __P((const void *, const void *));
/*
- * Create a connection to the remote printer server.
+ * Create a TCP connection to host "rhost" at port "rport".
+ * If rport == 0, then use the printer service port.
* Most of this code comes from rcmd.c.
*/
int
-getport(rhost)
+getport(rhost, rport)
char *rhost;
+ int rport;
{
struct hostent *hp;
struct servent *sp;
@@ -132,16 +135,24 @@ getport(rhost)
*/
if (rhost == NULL)
fatal("no remote host to connect to");
- hp = gethostbyname(rhost);
- if (hp == NULL)
- fatal("unknown host %s", rhost);
- sp = getservbyname("printer", "tcp");
- if (sp == NULL)
- fatal("printer/tcp: unknown service");
bzero((char *)&sin, sizeof(sin));
- bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
- sin.sin_family = hp->h_addrtype;
- sin.sin_port = sp->s_port;
+ sin.sin_addr.s_addr = inet_addr(rhost);
+ if (sin.sin_addr.s_addr != INADDR_NONE)
+ sin.sin_family = AF_INET;
+ else {
+ hp = gethostbyname(rhost);
+ if (hp == NULL)
+ fatal("unknown host %s", rhost);
+ bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
+ sin.sin_family = hp->h_addrtype;
+ }
+ if (rport == 0) {
+ sp = getservbyname("printer", "tcp");
+ if (sp == NULL)
+ fatal("printer/tcp: unknown service");
+ sin.sin_port = sp->s_port;
+ } else
+ sin.sin_port = htons(rport);
/*
* Try connecting to the server.
@@ -244,8 +255,9 @@ getq(namelist)
* realloc the maximum size.
*/
if (++nitems > arraysz) {
+ arraysz *= 2;
queue = (struct queue **)realloc((char *)queue,
- (stbuf.st_size/12) * sizeof(struct queue *));
+ arraysz * sizeof(struct queue *));
if (queue == NULL)
goto errdone;
}
@@ -287,8 +299,8 @@ checkremote()
register struct hostent *hp;
static char errbuf[128];
- sendtorem = 0; /* assume printer is local */
- if (RM != (char *)NULL) {
+ remote = 0; /* assume printer is local */
+ if (RM != NULL) {
/* get the official name of the local host */
gethostname(name, sizeof(name));
name[sizeof(name)-1] = '\0';
@@ -313,10 +325,23 @@ checkremote()
* if the two hosts are not the same,
* then the printer must be remote.
*/
- if (strcmp(name, hp->h_name) != 0)
- sendtorem = 1;
+ if (strcasecmp(name, hp->h_name) != 0)
+ remote = 1;
}
- return (char *)0;
+ return NULL;
+}
+
+/* sleep n milliseconds */
+void
+delay(n)
+{
+ struct timeval tdelay;
+
+ if (n <= 0 || n > 10000)
+ fatal("unreasonable delay period (%d)", n);
+ tdelay.tv_sec = n / 1000;
+ tdelay.tv_usec = n * 1000 % 1000000;
+ (void) select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tdelay);
}
#if __STDC__
diff --git a/usr.sbin/lpr/common_source/displayq.c b/usr.sbin/lpr/common_source/displayq.c
index 59d3cc9..34ca840 100644
--- a/usr.sbin/lpr/common_source/displayq.c
+++ b/usr.sbin/lpr/common_source/displayq.c
@@ -32,11 +32,12 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)displayq.c 8.1 (Berkeley) 6/6/93";
+static char sccsid[] = "@(#)displayq.c 8.4 (Berkeley) 4/28/95";
#endif /* not lint */
#include <sys/param.h>
#include <sys/stat.h>
+#include <sys/file.h>
#include <signal.h>
#include <fcntl.h>
@@ -124,7 +125,7 @@ displayq(format)
fatal("cannot examine spooling area\n");
if (stat(LO, &statb) >= 0) {
if (statb.st_mode & 0100) {
- if (sendtorem)
+ if (remote)
printf("%s: ", host);
printf("Warning: %s is down: ", printer);
fd = open(ST, O_RDONLY);
@@ -137,7 +138,7 @@ displayq(format)
putchar('\n');
}
if (statb.st_mode & 010) {
- if (sendtorem)
+ if (remote)
printf("%s: ", host);
printf("Warning: %s queue is turned off\n", printer);
}
@@ -150,8 +151,8 @@ displayq(format)
else {
/* get daemon pid */
cp = current;
- while ((*cp = getc(fp)) != EOF && *cp != '\n')
- cp++;
+ while ((i = getc(fp)) != EOF && i != '\n')
+ *cp++ = i;
*cp = '\0';
i = atoi(current);
if (i <= 0 || kill(i, 0) < 0)
@@ -159,13 +160,13 @@ displayq(format)
else {
/* read current file name */
cp = current;
- while ((*cp = getc(fp)) != EOF && *cp != '\n')
- cp++;
+ while ((i = getc(fp)) != EOF && i != '\n')
+ *cp++ = i;
*cp = '\0';
/*
* Print the status file.
*/
- if (sendtorem)
+ if (remote)
printf("%s: ", host);
fd = open(ST, O_RDONLY);
if (fd >= 0) {
@@ -191,7 +192,7 @@ displayq(format)
}
free(queue);
}
- if (!sendtorem) {
+ if (!remote) {
if (nitems == 0)
puts("no entries");
return;
@@ -215,7 +216,7 @@ displayq(format)
(void) strcpy(cp, user[i]);
}
strcat(line, "\n");
- fd = getport(RM);
+ fd = getport(RM, 0);
if (fd < 0) {
if (from != host)
printf("%s: ", host);
@@ -237,7 +238,7 @@ displayq(format)
void
warn()
{
- if (sendtorem)
+ if (remote)
printf("\n%s: ", host);
puts("Warning: no daemon present");
current[0] = '\0';
@@ -271,7 +272,7 @@ inform(cf)
if (rank < 0)
rank = 0;
- if (sendtorem || garbage || strcmp(cf, current))
+ if (remote || garbage || strcmp(cf, current))
rank++;
j = 0;
while (getline(cfp)) {
@@ -416,7 +417,7 @@ ldump(nfile, file, copies)
else
printf("%-32s", nfile);
if (*file && !stat(file, &lbuf))
- printf(" %qd bytes", lbuf.st_size);
+ printf(" %ld bytes", (long)lbuf.st_size);
else
printf(" ??? bytes");
putchar('\n');
diff --git a/usr.sbin/lpr/common_source/lp.h b/usr.sbin/lpr/common_source/lp.h
index 6dd1bf0..ffe42d2 100644
--- a/usr.sbin/lpr/common_source/lp.h
+++ b/usr.sbin/lpr/common_source/lp.h
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)lp.h 8.1 (Berkeley) 6/6/93
+ * @(#)lp.h 8.2 (Berkeley) 4/28/95
*/
@@ -85,7 +85,7 @@ extern char *printer; /* printer name */
/* host machine name */
extern char host[MAXHOSTNAMELEN];
extern char *from; /* client's machine name */
-extern int sendtorem; /* are we sending to a remote? */
+extern int remote; /* true if sending files to a remote host */
extern char *printcapdb[]; /* printcap database array */
/*
* Structure used for building a sorted list of control files.
@@ -107,7 +107,7 @@ void displayq __P((int));
void dump __P((char *, char *, int));
void fatal __P((const char *, ...));
int getline __P((FILE *));
-int getport __P((char *));
+int getport __P((char *, int));
int getq __P((struct queue *(*[])));
void header __P((void));
void inform __P((char *));
@@ -123,4 +123,5 @@ void rmremote __P((void));
void show __P((char *, char *, int));
int startdaemon __P((char *));
void warn __P((void));
+void delay __P((int));
__END_DECLS
diff --git a/usr.sbin/lpr/common_source/printcap.c b/usr.sbin/lpr/common_source/printcap.c
index 627d2ce..cbbaef1 100644
--- a/usr.sbin/lpr/common_source/printcap.c
+++ b/usr.sbin/lpr/common_source/printcap.c
@@ -32,7 +32,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)printcap.c 8.1 (Berkeley) 6/6/93";
+static char sccsid[] = "@(#)printcap.c 8.2 (Berkeley) 4/28/95";
#endif /* not lint */
#include <sys/param.h>
@@ -52,6 +52,87 @@ static char sccsid[] = "@(#)printcap.c 8.1 (Berkeley) 6/6/93";
#define MAXHOP 32 /* max number of tc= indirections */
/*
+ * getcap-style interface for the old printcap routines.
+ *
+ * !!!USE THIS INTERFACE ONLY IF YOU DON'T HAVE THE REAL GETCAP!!!
+ */
+
+static char *pbp; /* pointer into pbuf for pgetstr() */
+static char pbuf[BUFSIZ]; /* buffer for capability strings */
+extern char line[]; /* buffer for printcap entries */
+
+int
+cgetnext(bp, db_array)
+ register char **bp;
+ char **db_array;
+{
+ int ret;
+ char *strdup();
+
+ pbp = pbuf;
+ ret = getprent(line);
+ *bp = strdup(line);
+ return (ret);
+}
+
+int
+cgetent(bp, db_array, name)
+ char **bp, **db_array, *name;
+{
+ int i;
+
+ *bp = line;
+ pbp = pbuf;
+ i = pgetent(*bp, name);
+ if (i < 0)
+ return (-2);
+ else if (i == 0)
+ return (-1);
+ else
+ return (0);
+}
+
+char *
+cgetcap(buf, cap, type)
+ char *buf, *cap;
+ int type;
+{
+ return ((char *) pgetflag(cap));
+}
+
+int
+cgetstr(buf, cap, str)
+ char *buf, *cap;
+ char **str;
+{
+ char *pgetstr __P((char *, char **));
+
+ if (pbp >= pbuf+BUFSIZ) {
+ write(2, "Capability string buffer overflow\n", 34);
+ return (-1);
+ }
+ return ((*str = pgetstr(cap, &pbp)) == NULL ? -1 : 0);
+}
+
+int
+cgetnum(buf, cap, num)
+ char *buf, *cap;
+ long *num;
+{
+ return ((*num = pgetnum(cap)) < 0 ? -1 : 0);
+}
+
+int
+cgetclose()
+{
+ void endprent __P((void));
+
+ endprent();
+ return (0);
+}
+
+
+/*
* termcap - routines for dealing with the terminal capability data base
*
* BUG: Should use a "last" pointer in tbuf, so that searching
@@ -83,9 +164,10 @@ static char sccsid[] = "@(#)printcap.c 8.1 (Berkeley) 6/6/93";
static FILE *pfp = NULL; /* printcap data base file pointer */
static char *tbuf;
static int hopcount; /* detect infinite loops in termcap, init 0 */
+static int tf;
+char *tgetstr __P((char *, char **));
static char *tskip __P((char *));
-static char *tskip __P((char *bp));
static char *tdecode __P((char *, char **));
/*
@@ -137,8 +219,18 @@ getprent(bp)
void
endprent()
{
- if (pfp != NULL)
- fclose(pfp);
+ if (pfp != NULL) {
+ /*
+ * Can't use fclose here because on POSIX-compliant
+ * systems, fclose() causes the file pointer of the
+ * underlying file descriptor (which is possibly shared
+ * with a parent process) to be adjusted, and this
+ * reeks havoc in the parent because it doesn't know
+ * the file pointer has changed.
+ */
+ (void) close(fileno(pfp));
+ pfp = NULL;
+ }
}
/*
@@ -154,10 +246,8 @@ tgetent(bp, name)
register int c;
register int i = 0, cnt = 0;
char ibuf[BUFSIZ];
- int tf;
tbuf = bp;
- tf = 0;
#ifndef V6
cp = getenv("TERMCAP");
/*
@@ -179,11 +269,9 @@ tgetent(bp, name)
} else
tf = open(cp, 0);
}
+#endif
if (tf==0)
tf = open(_PATH_PRINTCAP, 0);
-#else
- tf = open(_PATH_PRINTCAP, 0);
-#endif
if (tf < 0)
return (-1);
for (;;) {
@@ -193,6 +281,7 @@ tgetent(bp, name)
cnt = read(tf, ibuf, BUFSIZ);
if (cnt <= 0) {
close(tf);
+ tf = 0;
return (0);
}
i = 0;
@@ -217,8 +306,13 @@ tgetent(bp, name)
* The real work for the match.
*/
if (tnamatch(name)) {
- close(tf);
- return(tnchktc());
+ lseek(tf, 0L, 0);
+ i = tnchktc();
+ if (tf) {
+ close(tf);
+ tf = 0;
+ }
+ return(i);
}
}
}
@@ -455,4 +549,3 @@ nextc:
*area = cp;
return (str);
}
-
diff --git a/usr.sbin/lpr/common_source/rmjob.c b/usr.sbin/lpr/common_source/rmjob.c
index 74a94d8..bdfe853 100644
--- a/usr.sbin/lpr/common_source/rmjob.c
+++ b/usr.sbin/lpr/common_source/rmjob.c
@@ -32,7 +32,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)rmjob.c 8.1 (Berkeley) 6/6/93";
+static char sccsid[] = "@(#)rmjob.c 8.2 (Berkeley) 4/28/95";
#endif /* not lint */
#include <sys/param.h>
@@ -292,7 +292,7 @@ rmremote()
register int i, rem;
char buf[BUFSIZ];
- if (!sendtorem)
+ if (!remote)
return; /* not sending to a remote machine */
/*
@@ -313,7 +313,7 @@ rmremote()
(void) sprintf(cp, " %d", requ[i]);
}
strcat(cp, "\n");
- rem = getport(RM);
+ rem = getport(RM, 0);
if (rem < 0) {
if (from != host)
printf("%s: ", host);
diff --git a/usr.sbin/lpr/lpc/cmds.c b/usr.sbin/lpr/lpc/cmds.c
index 7c2b6fe..937fc08 100644
--- a/usr.sbin/lpr/lpc/cmds.c
+++ b/usr.sbin/lpr/lpc/cmds.c
@@ -39,7 +39,7 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)cmds.c 8.1 (Berkeley) 6/6/93";
+static char sccsid[] = "@(#)cmds.c 8.2 (Berkeley) 4/28/95";
#endif /* not lint */
/*
@@ -49,6 +49,7 @@ static char sccsid[] = "@(#)cmds.c 8.1 (Berkeley) 6/6/93";
#include <sys/param.h>
#include <sys/time.h>
#include <sys/stat.h>
+#include <sys/file.h>
#include <signal.h>
#include <fcntl.h>
diff --git a/usr.sbin/lpr/lpc/lpc.8 b/usr.sbin/lpr/lpc/lpc.8
index a786adc..280a8b2 100644
--- a/usr.sbin/lpr/lpc/lpc.8
+++ b/usr.sbin/lpr/lpc/lpc.8
@@ -29,9 +29,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)lpc.8 8.3 (Berkeley) 4/19/94
+.\" @(#)lpc.8 8.5 (Berkeley) 4/28/95
.\"
-.Dd April 19, 1994
+.Dd April 28, 1995
.Dt LPC 8
.Os BSD 4.2
.Sh NAME
@@ -117,6 +117,7 @@ to put new jobs in the spool queue.
.It Ic exit
.It Ic quit
Exit from lpc.
+.ne 1i
.Pp
.It Ic restart No {\ all\ |\ printer\ }
Attempt to start a new printer daemon.
@@ -165,7 +166,7 @@ abbreviation matches more than one command
.It Sy "?Invalid command"
no match was found
.It Sy "?Privileged command"
-command can be executed by root only
+you must be a member of group "operator" or root to execute this command
.El
.Sh HISTORY
The
diff --git a/usr.sbin/lpr/lpc/lpc.c b/usr.sbin/lpr/lpc/lpc.c
index 01cfc12..64432b2 100644
--- a/usr.sbin/lpr/lpc/lpc.c
+++ b/usr.sbin/lpr/lpc/lpc.c
@@ -39,7 +39,7 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)lpc.c 8.1 (Berkeley) 6/6/93";
+static char sccsid[] = "@(#)lpc.c 8.3 (Berkeley) 4/28/95";
#endif /* not lint */
#include <sys/param.h>
@@ -53,10 +53,16 @@ static char sccsid[] = "@(#)lpc.c 8.1 (Berkeley) 6/6/93";
#include <stdio.h>
#include <ctype.h>
#include <string.h>
+#include <grp.h>
+#include <sys/param.h>
#include "lp.h"
#include "lpc.h"
#include "extern.h"
+#ifndef LPR_OPER
+#define LPR_OPER "operator" /* group name of lpr operators */
+#endif
+
/*
* lpc -- line printer control program
*/
@@ -74,6 +80,7 @@ static void cmdscanner __P((int));
static struct cmd *getcmd __P((char *));
static void intr __P((int));
static void makeargv __P((void));
+static int ingroup __P((char *));
int
main(argc, argv)
@@ -95,7 +102,7 @@ main(argc, argv)
printf("?Invalid command\n");
exit(1);
}
- if (c->c_priv && getuid()) {
+ if (c->c_priv && getuid() && ingroup(LPR_OPER) == 0) {
printf("?Privileged command\n");
exit(1);
}
@@ -151,7 +158,7 @@ cmdscanner(top)
printf("?Invalid command\n");
continue;
}
- if (c->c_priv && getuid()) {
+ if (c->c_priv && getuid() && ingroup(LPR_OPER) == 0) {
printf("?Privileged command\n");
continue;
}
@@ -160,7 +167,7 @@ cmdscanner(top)
longjmp(toplevel, 0);
}
-struct cmd *
+static struct cmd *
getcmd(name)
register char *name;
{
@@ -275,3 +282,33 @@ help(argc, argv)
c->c_name, c->c_help);
}
}
+
+/*
+ * return non-zero if the user is a member of the given group
+ */
+static int
+ingroup(grname)
+ char *grname;
+{
+ static struct group *gptr=NULL;
+ static gid_t groups[NGROUPS];
+ register gid_t gid;
+ register int i;
+
+ if (gptr == NULL) {
+ if ((gptr = getgrnam(grname)) == NULL) {
+ fprintf(stderr, "Warning: unknown group '%s'\n",
+ grname);
+ return(0);
+ }
+ if (getgroups(NGROUPS, groups) < 0) {
+ perror("getgroups");
+ exit(1);
+ }
+ }
+ gid = gptr->gr_gid;
+ for (i = 0; i < NGROUPS; i++)
+ if (gid == groups[i])
+ return(1);
+ return(0);
+}
diff --git a/usr.sbin/lpr/lpd/lpd.c b/usr.sbin/lpr/lpd/lpd.c
index aaf72b7..3b23359 100644
--- a/usr.sbin/lpr/lpd/lpd.c
+++ b/usr.sbin/lpr/lpd/lpd.c
@@ -39,7 +39,7 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)lpd.c 8.4 (Berkeley) 4/17/94";
+static char sccsid[] = "@(#)lpd.c 8.7 (Berkeley) 5/10/95";
#endif /* not lint */
/*
@@ -77,6 +77,7 @@ static char sccsid[] = "@(#)lpd.c 8.4 (Berkeley) 4/17/94";
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/stat.h>
+#include <sys/file.h>
#include <netinet/in.h>
#include <netdb.h>
@@ -103,6 +104,7 @@ static void mcleanup __P((int));
static void doit __P((void));
static void startup __P((void));
static void chkhost __P((struct sockaddr_in *));
+static int ckqueue __P((char *));
int
main(argc, argv)
@@ -429,11 +431,17 @@ startup()
* Restart the daemons.
*/
while (cgetnext(&buf, printcapdb) > 0) {
+ if (ckqueue(buf) <= 0) {
+ free(buf);
+ continue; /* no work to do for this printer */
+ }
for (cp = buf; *cp; cp++)
if (*cp == '|' || *cp == ':') {
*cp = '\0';
break;
}
+ if (lflag)
+ syslog(LOG_INFO, "work for %s", buf);
if ((pid = fork()) < 0) {
syslog(LOG_WARNING, "startup: cannot fork");
mcleanup(0);
@@ -442,8 +450,35 @@ startup()
printer = buf;
cgetclose();
printjob();
+ /* NOTREACHED */
}
+ else free(buf);
+ }
+}
+
+/*
+ * Make sure there's some work to do before forking off a child
+ */
+static int
+ckqueue(cap)
+ char *cap;
+{
+ register struct dirent *d;
+ DIR *dirp;
+ char *spooldir;
+
+ if (cgetstr(cap, "sd", &spooldir) == -1)
+ spooldir = _PATH_DEFSPOOL;
+ if ((dirp = opendir(spooldir)) == NULL)
+ return (-1);
+ while ((d = readdir(dirp)) != NULL) {
+ if (d->d_name[0] != 'c' || d->d_name[1] != 'f')
+ continue; /* daemon control files only */
+ closedir(dirp);
+ return (1); /* found something */
}
+ closedir(dirp);
+ return (0);
}
#define DUMMY ":nobody::"
diff --git a/usr.sbin/lpr/lpd/printjob.c b/usr.sbin/lpr/lpd/printjob.c
index 87c9352..2d17619 100644
--- a/usr.sbin/lpr/lpd/printjob.c
+++ b/usr.sbin/lpr/lpd/printjob.c
@@ -39,7 +39,7 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)printjob.c 8.2 (Berkeley) 4/16/94";
+static char sccsid[] = "@(#)printjob.c 8.7 (Berkeley) 5/10/95";
#endif /* not lint */
@@ -54,6 +54,7 @@ static char sccsid[] = "@(#)printjob.c 8.2 (Berkeley) 4/16/94";
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <sys/file.h>
#include <pwd.h>
#include <unistd.h>
@@ -95,7 +96,6 @@ static int ofilter; /* id of output filter, if any */
static int pfd; /* prstatic inter file descriptor */
static int pid; /* pid of lpd process */
static int prchild; /* id of pr process */
-static int remote; /* true if sending files to remote */
static char title[80]; /* ``pr'' title */
static int tof; /* true if at top of form */
@@ -117,6 +117,9 @@ static int dofork __P((int));
static int dropit __P((int));
static void init __P((void));
static void openpr __P((void));
+static void opennet __P((char *));
+static void opentty __P((void));
+static void openrem __P((void));
static int print __P((int, char *));
static int printit __P((char *));
static void pstatus __P((const char *, ...));
@@ -135,8 +138,8 @@ printjob()
register struct queue *q, **qp;
struct queue **queue;
register int i, nitems;
- long pidoff;
- int count = 0;
+ off_t pidoff;
+ int errcnt, count = 0;
init(); /* set up capabilities */
(void) write(1, "", 1); /* ack that daemon is started */
@@ -209,8 +212,9 @@ again:
q = *qp++;
if (stat(q->q_name, &stb) < 0)
continue;
+ errcnt = 0;
restart:
- (void) lseek(lfd, (off_t)pidoff, 0);
+ (void) lseek(lfd, pidoff, 0);
(void) sprintf(line, "%s\n", q->q_name);
i = strlen(line);
if (write(lfd, line, i) != i)
@@ -239,12 +243,13 @@ again:
}
if (i == OK) /* file ok and printed */
count++;
- else if (i == REPRINT) { /* try reprinting the job */
+ else if (i == REPRINT && ++errcnt < 5) {
+ /* try reprinting the job */
syslog(LOG_INFO, "restarting %s", printer);
if (ofilter > 0) {
kill(ofilter, SIGCONT); /* to be sure */
(void) close(ofd);
- while ((i = wait(0)) > 0 && i != ofilter)
+ while ((i = wait(NULL)) > 0 && i != ofilter)
;
ofilter = 0;
}
@@ -253,6 +258,17 @@ again:
syslog(LOG_WARNING, "%s: %s: %m", printer, LO);
openpr(); /* try to reopen printer */
goto restart;
+ } else {
+ syslog(LOG_WARNING, "%s: job could not be %s (%s)", printer,
+ remote ? "sent to remote host" : "printed", q->q_name);
+ if (i == REPRINT) {
+ /* insure we don't attempt this job again */
+ (void) unlink(q->q_name);
+ q->q_name[0] = 'd';
+ (void) unlink(q->q_name);
+ if (logname[0])
+ sendmail(logname, FATALERR);
+ }
}
}
free((char *) queue);
@@ -328,6 +344,7 @@ printit(file)
* H -- "host name" of machine where lpr was done
* P -- "person" user's login name
* I -- "indent" amount to indent output
+ * R -- laser dpi "resolution"
* f -- "file name" name of text file to print
* l -- "file name" text file with control chars
* p -- "file name" text file to print with pr(1)
@@ -442,6 +459,7 @@ printit(file)
case 'N':
case 'U':
case 'M':
+ case 'R':
continue;
}
@@ -537,6 +555,7 @@ print(format, file)
if ((prchild = dofork(DORETURN)) == 0) { /* child */
dup2(fi, 0); /* file is stdin */
dup2(p[1], 1); /* pipe is stdout */
+ closelog();
for (n = 3; n < NOFILE; n++)
(void) close(n);
execl(_PATH_PR, "pr", width, length,
@@ -619,6 +638,13 @@ print(format, file)
printer, format);
return(ERROR);
}
+ if (prog == NULL) {
+ (void) close(fi);
+ syslog(LOG_ERR,
+ "%s: no filter found in printcap for format character '%c'",
+ printer, format);
+ return(ERROR);
+ }
if ((av[0] = rindex(prog, '/')) != NULL)
av[0]++;
else
@@ -637,8 +663,9 @@ print(format, file)
;
if (status.w_stopval != WSTOPPED) {
(void) close(fi);
- syslog(LOG_WARNING, "%s: output filter died (%d)",
- printer, status.w_retcode);
+ syslog(LOG_WARNING,
+ "%s: output filter died (retcode=%d termsig=%d)",
+ printer, status.w_retcode, status.w_termsig);
return(REPRINT);
}
stopped++;
@@ -650,6 +677,7 @@ start:
n = open(tempfile, O_WRONLY|O_CREAT|O_TRUNC, 0664);
if (n >= 0)
dup2(n, 2);
+ closelog();
for (n = 3; n < NOFILE; n++)
(void) close(n);
execv(prog, av);
@@ -680,7 +708,7 @@ start:
}
if (!WIFEXITED(status)) {
- syslog(LOG_WARNING, "%s: Daemon filter '%c' terminated (%d)",
+ syslog(LOG_WARNING, "%s: filter '%c' terminated (termsig=%d)",
printer, format, status.w_termsig);
return(ERROR);
}
@@ -690,11 +718,12 @@ start:
return(OK);
case 1:
return(REPRINT);
- default:
- syslog(LOG_WARNING, "%s: Daemon filter '%c' exited (%d)",
- printer, format, status.w_retcode);
case 2:
return(ERROR);
+ default:
+ syslog(LOG_WARNING, "%s: filter '%c' exited (retcode=%d)",
+ printer, format, status.w_retcode);
+ return(FILTERERR);
}
}
@@ -809,7 +838,7 @@ sendfile(type, file)
if ((stb.st_mode & S_IFMT) == S_IFLNK && fstat(f, &stb) == 0 &&
(stb.st_dev != fdev || stb.st_ino != fino))
return(ACCESS);
- (void) sprintf(buf, "%c%qd %s\n", type, stb.st_size, file);
+ (void) sprintf(buf, "%c%ld %s\n", type, (long)stb.st_size, file);
amt = strlen(buf);
for (i = 0; ; i++) {
if (write(pfd, buf, amt) != amt ||
@@ -1007,6 +1036,7 @@ sendmail(user, bombed)
pipe(p);
if ((s = dofork(DORETURN)) == 0) { /* child */
dup2(p[0], 0);
+ closelog();
for (i = 3; i < NOFILE; i++)
(void) close(i);
if ((cp = rindex(_PATH_SENDMAIL, '/')) != NULL)
@@ -1019,41 +1049,50 @@ sendmail(user, bombed)
} else if (s > 0) { /* parent */
dup2(p[1], 1);
printf("To: %s@%s\n", user, fromhost);
- printf("Subject: printer job\n\n");
+ printf("Subject: %s printer job \"%s\"\n", printer,
+ *jobname ? jobname : "<unknown>");
+ printf("Reply-To: root@%s\n\n", host);
printf("Your printer job ");
if (*jobname)
printf("(%s) ", jobname);
switch (bombed) {
case OK:
printf("\ncompleted successfully\n");
+ cp = "OK";
break;
default:
case FATALERR:
printf("\ncould not be printed\n");
+ cp = "FATALERR";
break;
case NOACCT:
printf("\ncould not be printed without an account on %s\n", host);
+ cp = "NOACCT";
break;
case FILTERERR:
if (stat(tempfile, &stb) < 0 || stb.st_size == 0 ||
(fp = fopen(tempfile, "r")) == NULL) {
- printf("\nwas printed but had some errors\n");
+ printf("\nhad some errors and may not have printed\n");
break;
}
- printf("\nwas printed but had the following errors:\n");
+ printf("\nhad the following errors and may not have printed:\n");
while ((i = getc(fp)) != EOF)
putchar(i);
(void) fclose(fp);
+ cp = "FILTERERR";
break;
case ACCESS:
printf("\nwas not printed because it was not linked to the original file\n");
+ cp = "ACCESS";
}
fflush(stdout);
(void) close(1);
}
(void) close(p[0]);
(void) close(p[1]);
- wait(&s);
+ wait(NULL);
+ syslog(LOG_INFO, "mail sent to user %s about job %s on printer %s (%s)",
+ user, *jobname ? jobname : "<unknown>", printer, cp);
}
/*
@@ -1192,65 +1231,33 @@ init()
static void
openpr()
{
- register int i, n;
- int resp;
+ register int i;
+ char *cp;
- if (!sendtorem && *LP) {
- for (i = 1; ; i = i < 32 ? i << 1 : i) {
- pfd = open(LP, RW ? O_RDWR : O_WRONLY);
- if (pfd >= 0)
- break;
- if (errno == ENOENT) {
- syslog(LOG_ERR, "%s: %m", LP);
- exit(1);
- }
- if (i == 1)
- pstatus("waiting for %s to become ready (offline ?)", printer);
- sleep(i);
- }
- if (isatty(pfd))
- setty();
- pstatus("%s is ready and printing", printer);
- } else if (RM != NULL) {
- for (i = 1; ; i = i < 256 ? i << 1 : i) {
- resp = -1;
- pfd = getport(RM);
- if (pfd >= 0) {
- (void) sprintf(line, "\2%s\n", RP);
- n = strlen(line);
- if (write(pfd, line, n) == n &&
- (resp = response()) == '\0')
- break;
- (void) close(pfd);
- }
- if (i == 1) {
- if (resp < 0)
- pstatus("waiting for %s to come up", RM);
- else {
- pstatus("waiting for queue to be enabled on %s", RM);
- i = 256;
- }
- }
- sleep(i);
- }
- pstatus("sending to %s", RM);
- remote = 1;
+ if (!remote && *LP) {
+ if (cp = index(LP, '@'))
+ opennet(cp);
+ else
+ opentty();
+ } else if (remote) {
+ openrem();
} else {
syslog(LOG_ERR, "%s: no line printer device or host name",
printer);
exit(1);
}
+
/*
* Start up an output filter, if needed.
*/
if (!remote && OF) {
int p[2];
- char *cp;
pipe(p);
if ((ofilter = dofork(DOABORT)) == 0) { /* child */
dup2(p[0], 0); /* pipe is std in */
dup2(pfd, 1); /* printer is std out */
+ closelog();
for (i = 3; i < NOFILE; i++)
(void) close(i);
if ((cp = rindex(OF, '/')) == NULL)
@@ -1269,6 +1276,115 @@ openpr()
}
}
+/*
+ * Printer connected directly to the network
+ * or to a terminal server on the net
+ */
+static void
+opennet(cp)
+ char *cp;
+{
+ register int i;
+ int resp, port;
+ char save_ch;
+
+ save_ch = *cp;
+ *cp = '\0';
+ port = atoi(LP);
+ if (port <= 0) {
+ syslog(LOG_ERR, "%s: bad port number: %s", printer, LP);
+ exit(1);
+ }
+ *cp++ = save_ch;
+
+ for (i = 1; ; i = i < 256 ? i << 1 : i) {
+ resp = -1;
+ pfd = getport(cp, port);
+ if (pfd < 0 && errno == ECONNREFUSED)
+ resp = 1;
+ else if (pfd >= 0) {
+ /*
+ * need to delay a bit for rs232 lines
+ * to stabilize in case printer is
+ * connected via a terminal server
+ */
+ delay(500);
+ break;
+ }
+ if (i == 1) {
+ if (resp < 0)
+ pstatus("waiting for %s to come up", LP);
+ else
+ pstatus("waiting for access to printer on %s", LP);
+ }
+ sleep(i);
+ }
+ pstatus("sending to %s port %d", cp, port);
+}
+
+/*
+ * Printer is connected to an RS232 port on this host
+ */
+static void
+opentty()
+{
+ register int i;
+ int resp, port;
+
+ for (i = 1; ; i = i < 32 ? i << 1 : i) {
+ pfd = open(LP, RW ? O_RDWR : O_WRONLY);
+ if (pfd >= 0) {
+ delay(500);
+ break;
+ }
+ if (errno == ENOENT) {
+ syslog(LOG_ERR, "%s: %m", LP);
+ exit(1);
+ }
+ if (i == 1)
+ pstatus("waiting for %s to become ready (offline ?)",
+ printer);
+ sleep(i);
+ }
+ if (isatty(pfd))
+ setty();
+ pstatus("%s is ready and printing", printer);
+}
+
+/*
+ * Printer is on a remote host
+ */
+static void
+openrem()
+{
+ register int i, n;
+ int resp, port;
+
+ for (i = 1; ; i = i < 256 ? i << 1 : i) {
+ resp = -1;
+ pfd = getport(RM, 0);
+ if (pfd >= 0) {
+ (void) sprintf(line, "\2%s\n", RP);
+ n = strlen(line);
+ if (write(pfd, line, n) == n &&
+ (resp = response()) == '\0')
+ break;
+ (void) close(pfd);
+ }
+ if (i == 1) {
+ if (resp < 0)
+ pstatus("waiting for %s to come up", RM);
+ else {
+ pstatus("waiting for queue to be enabled on %s",
+ RM);
+ i = 256;
+ }
+ }
+ sleep(i);
+ }
+ pstatus("sending to %s", RM);
+}
+
struct bauds {
int baud;
int speed;
@@ -1344,7 +1460,7 @@ setty()
#include <varargs.h>
#endif
-void
+static void
#if __STDC__
pstatus(const char *msg, ...)
#else
diff --git a/usr.sbin/lpr/lpd/recvjob.c b/usr.sbin/lpr/lpd/recvjob.c
index 67a6183..0b4156c 100644
--- a/usr.sbin/lpr/lpd/recvjob.c
+++ b/usr.sbin/lpr/lpd/recvjob.c
@@ -39,7 +39,7 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)recvjob.c 8.1 (Berkeley) 6/6/93";
+static char sccsid[] = "@(#)recvjob.c 8.2 (Berkeley) 4/27/95";
#endif /* not lint */
/*
@@ -342,7 +342,7 @@ frecverr(msg, va_alist)
va_dcl
#endif
{
- extern char *fromb;
+ extern char fromb[];
va_list ap;
#if __STDC__
va_start(ap, msg);
diff --git a/usr.sbin/lpr/lpq/lpq.1 b/usr.sbin/lpr/lpq/lpq.1
index 50e1474..d5eadc5 100644
--- a/usr.sbin/lpr/lpq/lpq.1
+++ b/usr.sbin/lpr/lpq/lpq.1
@@ -29,9 +29,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)lpq.1 8.1 (Berkeley) 6/6/93
+.\" @(#)lpq.1 8.2 (Berkeley) 4/28/95
.\"
-.Dd June 6, 1993
+.Dd April 28, 1995
.Dt LPQ 1
.Os BSD 4.2
.Sh NAME
@@ -39,6 +39,7 @@
.Nd spool queue examination program
.Sh SYNOPSIS
.Nm lpq
+.OP Fl a
.Op Fl l
.Op Fl P Ns Ar printer
.Op job # ...
@@ -67,6 +68,9 @@ names or job numbers to filter out only those jobs of interest.
Information about each of the files comprising the job entry
is printed.
Normally, only as much information as will fit on one line is displayed.
+.It Fl a
+Report on the local queues for all printers,
+rather than just the specified printer.
.El
.Pp
For each job submitted (i.e. invocation of
@@ -102,7 +106,7 @@ If the following environment variable exists, it is used by
Specifies an alternate default printer.
.El
.Sh FILES
-.Bl -tag -width /usr/share/misc/termcap -compact
+.Bl -tag -width "/var/spool/*/lock" -compact
.It Pa /etc/printcap
To determine printer characteristics.
.It Pa /var/spool/*
@@ -111,8 +115,6 @@ The spooling directory, as determined from printcap.
Control files specifying jobs.
.It Pa /var/spool/*/lock
The lock file to obtain the currently active job.
-.It Pa /usr/share/misc/termcap
-For manipulating the screen for repeated display.
.El
.Sh SEE ALSO
.Xr lpr 1 ,
diff --git a/usr.sbin/lpr/lpq/lpq.c b/usr.sbin/lpr/lpq/lpq.c
index b091e8e..7d1b520 100644
--- a/usr.sbin/lpr/lpq/lpq.c
+++ b/usr.sbin/lpr/lpq/lpq.c
@@ -39,14 +39,15 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)lpq.c 8.1 (Berkeley) 6/6/93";
+static char sccsid[] = "@(#)lpq.c 8.3 (Berkeley) 5/10/95";
#endif /* not lint */
/*
* Spool Queue examination program
*
- * lpq [-l] [-Pprinter] [user...] [job...]
+ * lpq [-a] [-l] [-Pprinter] [user...] [job...]
*
+ * -a show all non-null queues on the local machine
* -l long output
* -P used to identify printer as per lpr/lprm
*/
@@ -61,12 +62,14 @@ static char sccsid[] = "@(#)lpq.c 8.1 (Berkeley) 6/6/93";
#include <ctype.h>
#include "lp.h"
#include "lp.local.h"
+#include "pathnames.h"
int requ[MAXREQUESTS]; /* job number of spool entries */
int requests; /* # of spool requests */
char *user[MAXUSERS]; /* users to process */
int users; /* # of users in user array */
+static int ckqueue __P((char *));
void usage __P((void));
int
@@ -76,7 +79,8 @@ main(argc, argv)
{
extern char *optarg;
extern int optind;
- int ch, lflag; /* long output option */
+ int ch, aflag, lflag;
+ char *buf, *cp;
name = *argv;
if (gethostname(host, sizeof(host))) {
@@ -85,9 +89,12 @@ main(argc, argv)
}
openlog("lpd", 0, LOG_LPR);
- lflag = 0;
- while ((ch = getopt(argc, argv, "lP:")) != EOF)
+ aflag = lflag = 0;
+ while ((ch = getopt(argc, argv, "alP:")) != EOF)
switch((char)ch) {
+ case 'a':
+ ++aflag;
+ break;
case 'l': /* long output */
++lflag;
break;
@@ -99,7 +106,7 @@ main(argc, argv)
usage();
}
- if (printer == NULL && (printer = getenv("PRINTER")) == NULL)
+ if (!aflag && printer == NULL && (printer = getenv("PRINTER")) == NULL)
printer = DEFLP;
for (argc -= optind, argv += optind; argc; --argc, ++argv)
@@ -114,13 +121,53 @@ main(argc, argv)
user[users++] = *argv;
}
- displayq(lflag);
+ if (aflag) {
+ while (cgetnext(&buf, printcapdb) > 0) {
+ if (ckqueue(buf) <= 0) {
+ free(buf);
+ continue; /* no jobs */
+ }
+ for (cp = buf; *cp; cp++)
+ if (*cp == '|' || *cp == ':') {
+ *cp = '\0';
+ break;
+ }
+ printer = buf;
+ printf("%s:\n", printer);
+ displayq(lflag);
+ free(buf);
+ printf("\n");
+ }
+ } else
+ displayq(lflag);
exit(0);
}
+static int
+ckqueue(cap)
+ char *cap;
+{
+ register struct dirent *d;
+ DIR *dirp;
+ char *spooldir;
+
+ if (cgetstr(cap, "sd", &spooldir) == -1)
+ spooldir = _PATH_DEFSPOOL;
+ if ((dirp = opendir(spooldir)) == NULL)
+ return (-1);
+ while ((d = readdir(dirp)) != NULL) {
+ if (d->d_name[0] != 'c' || d->d_name[1] != 'f')
+ continue; /* daemon control files only */
+ closedir(dirp);
+ return (1); /* found something */
+ }
+ closedir(dirp);
+ return (0);
+}
+
void
usage()
{
- puts("usage: lpq [-l] [-Pprinter] [user ...] [job ...]");
+ puts("usage: lpq [-a] [-l] [-Pprinter] [user ...] [job ...]");
exit(1);
}
diff --git a/usr.sbin/lpr/lpr/lpr.c b/usr.sbin/lpr/lpr/lpr.c
index 8e9c45f..6b79d63 100644
--- a/usr.sbin/lpr/lpr/lpr.c
+++ b/usr.sbin/lpr/lpr/lpr.c
@@ -44,7 +44,7 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)lpr.c 8.3 (Berkeley) 3/30/94";
+static char sccsid[] = "@(#)lpr.c 8.4 (Berkeley) 4/28/95";
#endif /* not lint */
/*
@@ -56,6 +56,7 @@ static char sccsid[] = "@(#)lpr.c 8.3 (Berkeley) 3/30/94";
#include <sys/param.h>
#include <sys/stat.h>
+#include <sys/file.h>
#include <dirent.h>
#include <fcntl.h>
OpenPOWER on IntegriCloud