xref: /csrg-svn/usr.sbin/lpr/lpc/cmds.c (revision 56121)
122424Sdist /*
222424Sdist  * Copyright (c) 1983 Regents of the University of California.
334203Sbostic  * All rights reserved.
434203Sbostic  *
5*56121Selan  * Redistribution and use in source and binary forms, with or without
6*56121Selan  * modification, are permitted provided that the following conditions
7*56121Selan  * are met:
8*56121Selan  * 1. Redistributions of source code must retain the above copyright
9*56121Selan  *    notice, this list of conditions and the following disclaimer.
10*56121Selan  * 2. Redistributions in binary form must reproduce the above copyright
11*56121Selan  *    notice, this list of conditions and the following disclaimer in the
12*56121Selan  *    documentation and/or other materials provided with the distribution.
13*56121Selan  * 3. All advertising materials mentioning features or use of this software
14*56121Selan  *    must display the following acknowledgement:
15*56121Selan  *	This product includes software developed by the University of
16*56121Selan  *	California, Berkeley and its contributors.
17*56121Selan  * 4. Neither the name of the University nor the names of its contributors
18*56121Selan  *    may be used to endorse or promote products derived from this software
19*56121Selan  *    without specific prior written permission.
20*56121Selan  *
21*56121Selan  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22*56121Selan  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23*56121Selan  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24*56121Selan  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25*56121Selan  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26*56121Selan  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27*56121Selan  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28*56121Selan  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29*56121Selan  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30*56121Selan  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*56121Selan  * SUCH DAMAGE.
3222424Sdist  */
3322424Sdist 
3412382Sralph #ifndef lint
35*56121Selan static char sccsid[] = "@(#)cmds.c	5.10 (Berkeley) 8/31/92";
3634203Sbostic #endif /* not lint */
3712382Sralph 
3812382Sralph /*
3915719Sralph  * lpc -- line printer control program -- commands:
4012382Sralph  */
4112382Sralph 
4255472Sbostic #include <sys/param.h>
4355472Sbostic #include <sys/time.h>
4455472Sbostic #include <sys/stat.h>
4555472Sbostic 
4655472Sbostic #include <signal.h>
4755472Sbostic #include <fcntl.h>
4855472Sbostic #include <errno.h>
4955472Sbostic #include <dirent.h>
5055472Sbostic #include <unistd.h>
5155472Sbostic #include <stdlib.h>
5255472Sbostic #include <stdio.h>
5355472Sbostic #include <ctype.h>
5455472Sbostic #include <string.h>
5512382Sralph #include "lp.h"
5655472Sbostic #include "lp.local.h"
5755472Sbostic #include "lpc.h"
5855472Sbostic #include "extern.h"
5937968Sbostic #include "pathnames.h"
6012382Sralph 
6155472Sbostic static void	abortpr __P((int));
6255472Sbostic static void	cleanpr __P((void));
63*56121Selan static void	disablepr __P((void));
64*56121Selan static int	doarg __P((char *));
6555472Sbostic static int	doselect __P((struct dirent *));
66*56121Selan static void	enablepr __P((void));
67*56121Selan static void	prstat __P((void));
68*56121Selan static void	putmsg __P((int, char **));
6955472Sbostic static int	sortq __P((const void *, const void *));
70*56121Selan static void	startpr __P((int));
71*56121Selan static void	stoppr __P((void));
72*56121Selan static int	touch __P((struct queue *));
7355472Sbostic static void	unlinkf __P((char *));
74*56121Selan static void	upstat __P((char *));
7555472Sbostic 
7612382Sralph /*
7712382Sralph  * kill an existing daemon and disable printing.
7812382Sralph  */
7955472Sbostic void
8055472Sbostic doabort(argc, argv)
8155472Sbostic 	int argc;
8212382Sralph 	char *argv[];
8312382Sralph {
8412382Sralph 	register int c, status;
8512382Sralph 	register char *cp1, *cp2;
8612382Sralph 	char prbuf[100];
8712382Sralph 
8812382Sralph 	if (argc == 1) {
8912382Sralph 		printf("Usage: abort {all | printer ...}\n");
9012382Sralph 		return;
9112382Sralph 	}
9212382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
9312382Sralph 		printer = prbuf;
94*56121Selan 		while (cgetnext(&bp, printcapdb) > 0) {
9512382Sralph 			cp1 = prbuf;
96*56121Selan 			cp2 = bp;
9712382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
9812382Sralph 				*cp1++ = c;
9912382Sralph 			*cp1 = '\0';
10016755Sralph 			abortpr(1);
10112382Sralph 		}
10212382Sralph 		return;
10312382Sralph 	}
10412382Sralph 	while (--argc) {
10512382Sralph 		printer = *++argv;
106*56121Selan 		if ((status = cgetent(&bp, printcapdb, printer)) == -2) {
10712514Sralph 			printf("cannot open printer description file\n");
10812382Sralph 			continue;
109*56121Selan 		} else if (status == -1) {
11012514Sralph 			printf("unknown printer %s\n", printer);
11112382Sralph 			continue;
112*56121Selan 		} else if (status == -3)
113*56121Selan 			fatal("potential reference loop detected in printcap file");
11416755Sralph 		abortpr(1);
11512382Sralph 	}
11612382Sralph }
11712382Sralph 
11855472Sbostic static void
11916755Sralph abortpr(dis)
12055472Sbostic 	int dis;
12112382Sralph {
12212382Sralph 	register FILE *fp;
12312382Sralph 	struct stat stbuf;
12412382Sralph 	int pid, fd;
12512382Sralph 
126*56121Selan 	if (cgetstr(bp, "sd", &SD) == -1)
12737968Sbostic 		SD = _PATH_DEFSPOOL;
128*56121Selan 	if (cgetstr(bp, "lo", &LO) == -1)
12912382Sralph 		LO = DEFLOCK;
13012382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
13112382Sralph 	printf("%s:\n", printer);
13212382Sralph 
13312382Sralph 	/*
13412382Sralph 	 * Turn on the owner execute bit of the lock file to disable printing.
13512382Sralph 	 */
13616755Sralph 	if (dis) {
13716755Sralph 		if (stat(line, &stbuf) >= 0) {
13816755Sralph 			if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
13916755Sralph 				printf("\tcannot disable printing\n");
14038735Stef 			else {
14138735Stef 				upstat("printing disabled\n");
14216755Sralph 				printf("\tprinting disabled\n");
14338735Stef 			}
14416755Sralph 		} else if (errno == ENOENT) {
14516755Sralph 			if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
14616755Sralph 				printf("\tcannot create lock file\n");
14716755Sralph 			else {
14816755Sralph 				(void) close(fd);
14938735Stef 				upstat("printing disabled\n");
15016755Sralph 				printf("\tprinting disabled\n");
15116755Sralph 				printf("\tno daemon to abort\n");
15216755Sralph 			}
15316755Sralph 			return;
15416755Sralph 		} else {
15516755Sralph 			printf("\tcannot stat lock file\n");
15616755Sralph 			return;
15712382Sralph 		}
15812382Sralph 	}
15912382Sralph 	/*
16012382Sralph 	 * Kill the current daemon to stop printing now.
16112382Sralph 	 */
16212382Sralph 	if ((fp = fopen(line, "r")) == NULL) {
16312382Sralph 		printf("\tcannot open lock file\n");
16412382Sralph 		return;
16512382Sralph 	}
16613146Ssam 	if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) {
16713168Sralph 		(void) fclose(fp);	/* unlocks as well */
16812382Sralph 		printf("\tno daemon to abort\n");
16912382Sralph 		return;
17012382Sralph 	}
17112382Sralph 	(void) fclose(fp);
17216755Sralph 	if (kill(pid = atoi(line), SIGTERM) < 0)
17312382Sralph 		printf("\tWarning: daemon (pid %d) not killed\n", pid);
17412382Sralph 	else
17512382Sralph 		printf("\tdaemon (pid %d) killed\n", pid);
17612382Sralph }
17712382Sralph 
17812382Sralph /*
17938735Stef  * Write a message into the status file.
18038735Stef  */
18155472Sbostic static void
18238735Stef upstat(msg)
18338735Stef 	char *msg;
18438735Stef {
18538735Stef 	register int fd;
18638735Stef 	char statfile[BUFSIZ];
18738735Stef 
188*56121Selan 	if (cgetstr(bp, "st", &ST) == -1)
18938735Stef 		ST = DEFSTAT;
19038735Stef 	(void) sprintf(statfile, "%s/%s", SD, ST);
19138735Stef 	umask(0);
19238735Stef 	fd = open(statfile, O_WRONLY|O_CREAT, 0664);
19338735Stef 	if (fd < 0 || flock(fd, LOCK_EX) < 0) {
19438735Stef 		printf("\tcannot create status file\n");
19538735Stef 		return;
19638735Stef 	}
19738735Stef 	(void) ftruncate(fd, 0);
19838735Stef 	if (msg == (char *)NULL)
19938735Stef 		(void) write(fd, "\n", 1);
20038735Stef 	else
20138735Stef 		(void) write(fd, msg, strlen(msg));
20238735Stef 	(void) close(fd);
20338735Stef }
20438735Stef 
20538735Stef /*
20612382Sralph  * Remove all spool files and temporaries from the spooling area.
20712382Sralph  */
20855472Sbostic void
20912382Sralph clean(argc, argv)
21055472Sbostic 	int argc;
21112382Sralph 	char *argv[];
21212382Sralph {
21312382Sralph 	register int c, status;
21412382Sralph 	register char *cp1, *cp2;
21512382Sralph 	char prbuf[100];
21612382Sralph 
21712382Sralph 	if (argc == 1) {
21812382Sralph 		printf("Usage: clean {all | printer ...}\n");
21912382Sralph 		return;
22012382Sralph 	}
22112382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
22212382Sralph 		printer = prbuf;
223*56121Selan 		while (cgetnext(&bp, printcapdb) > 0) {
22412382Sralph 			cp1 = prbuf;
225*56121Selan 			cp2 = bp;
22612382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
22712382Sralph 				*cp1++ = c;
22812382Sralph 			*cp1 = '\0';
22912382Sralph 			cleanpr();
23012382Sralph 		}
23112382Sralph 		return;
23212382Sralph 	}
23312382Sralph 	while (--argc) {
23412382Sralph 		printer = *++argv;
235*56121Selan 		if ((status = cgetent(&bp, printcapdb, printer)) == -2) {
23612514Sralph 			printf("cannot open printer description file\n");
23712382Sralph 			continue;
238*56121Selan 		} else if (status == -1) {
23912514Sralph 			printf("unknown printer %s\n", printer);
24012382Sralph 			continue;
241*56121Selan 		} else if (status == -3)
242*56121Selan 			fatal("potential reference loop detected in printcap file");
243*56121Selan 
24412382Sralph 		cleanpr();
24512382Sralph 	}
24612382Sralph }
24712382Sralph 
24855472Sbostic static int
24955472Sbostic doselect(d)
25055472Sbostic 	struct dirent *d;
25115719Sralph {
25215719Sralph 	int c = d->d_name[0];
25315719Sralph 
25415719Sralph 	if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f')
25515719Sralph 		return(1);
25615719Sralph 	return(0);
25715719Sralph }
25815719Sralph 
25915719Sralph /*
26015719Sralph  * Comparison routine for scandir. Sort by job number and machine, then
26115719Sralph  * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z.
26215719Sralph  */
26355472Sbostic static int
26455472Sbostic sortq(a, b)
26555472Sbostic 	const void *a, *b;
26615719Sralph {
26755472Sbostic 	struct dirent **d1, **d2;
26815719Sralph 	int c1, c2;
26915719Sralph 
27055472Sbostic 	d1 = (struct dirent **)a;
27155472Sbostic 	d2 = (struct dirent **)b;
27215719Sralph 	if (c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3))
27315719Sralph 		return(c1);
27415719Sralph 	c1 = (*d1)->d_name[0];
27515719Sralph 	c2 = (*d2)->d_name[0];
27615719Sralph 	if (c1 == c2)
27715719Sralph 		return((*d1)->d_name[2] - (*d2)->d_name[2]);
27815719Sralph 	if (c1 == 'c')
27915719Sralph 		return(-1);
28015719Sralph 	if (c1 == 'd' || c2 == 'c')
28115719Sralph 		return(1);
28215719Sralph 	return(-1);
28315719Sralph }
28415719Sralph 
28515719Sralph /*
28615719Sralph  * Remove incomplete jobs from spooling area.
28715719Sralph  */
28855472Sbostic static void
28912382Sralph cleanpr()
29012382Sralph {
29115719Sralph 	register int i, n;
29215719Sralph 	register char *cp, *cp1, *lp;
29355472Sbostic 	struct dirent **queue;
29415719Sralph 	int nitems;
29512382Sralph 
296*56121Selan 	if (cgetstr(bp, "sd", &SD) == -1)
29737968Sbostic 		SD = _PATH_DEFSPOOL;
29812382Sralph 	printf("%s:\n", printer);
29912382Sralph 
30015719Sralph 	for (lp = line, cp = SD; *lp++ = *cp++; )
30115719Sralph 		;
30215719Sralph 	lp[-1] = '/';
30315719Sralph 
30455472Sbostic 	nitems = scandir(SD, &queue, doselect, sortq);
30515719Sralph 	if (nitems < 0) {
30612382Sralph 		printf("\tcannot examine spool directory\n");
30712382Sralph 		return;
30812382Sralph 	}
30915719Sralph 	if (nitems == 0)
31015719Sralph 		return;
31115719Sralph 	i = 0;
31215719Sralph 	do {
31315719Sralph 		cp = queue[i]->d_name;
31415719Sralph 		if (*cp == 'c') {
31515719Sralph 			n = 0;
31615719Sralph 			while (i + 1 < nitems) {
31715719Sralph 				cp1 = queue[i + 1]->d_name;
31815719Sralph 				if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3))
31915719Sralph 					break;
32015719Sralph 				i++;
32115719Sralph 				n++;
32215719Sralph 			}
32315719Sralph 			if (n == 0) {
32415719Sralph 				strcpy(lp, cp);
32515719Sralph 				unlinkf(line);
32615719Sralph 			}
32715719Sralph 		} else {
32815719Sralph 			/*
32915719Sralph 			 * Must be a df with no cf (otherwise, it would have
33015719Sralph 			 * been skipped above) or a tf file (which can always
33115719Sralph 			 * be removed).
33215719Sralph 			 */
33315719Sralph 			strcpy(lp, cp);
33415719Sralph 			unlinkf(line);
33512382Sralph 		}
33615719Sralph      	} while (++i < nitems);
33712382Sralph }
33815719Sralph 
33955472Sbostic static void
34015719Sralph unlinkf(name)
34115719Sralph 	char	*name;
34215719Sralph {
34315719Sralph 	if (unlink(name) < 0)
34415719Sralph 		printf("\tcannot remove %s\n", name);
34515719Sralph 	else
34615719Sralph 		printf("\tremoved %s\n", name);
34715719Sralph }
34812382Sralph 
34912382Sralph /*
35012382Sralph  * Enable queuing to the printer (allow lpr's).
35112382Sralph  */
35255472Sbostic void
35312382Sralph enable(argc, argv)
35455472Sbostic 	int argc;
35512382Sralph 	char *argv[];
35612382Sralph {
35712382Sralph 	register int c, status;
35812382Sralph 	register char *cp1, *cp2;
35912382Sralph 	char prbuf[100];
36012382Sralph 
36112382Sralph 	if (argc == 1) {
36212382Sralph 		printf("Usage: enable {all | printer ...}\n");
36312382Sralph 		return;
36412382Sralph 	}
36512382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
36612382Sralph 		printer = prbuf;
367*56121Selan 		while (cgetnext(&bp, printcapdb) > 0) {
36812382Sralph 			cp1 = prbuf;
369*56121Selan 			cp2 = bp;
37012382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
37112382Sralph 				*cp1++ = c;
37212382Sralph 			*cp1 = '\0';
37312382Sralph 			enablepr();
37412382Sralph 		}
37512382Sralph 		return;
37612382Sralph 	}
37712382Sralph 	while (--argc) {
37812382Sralph 		printer = *++argv;
379*56121Selan 		if ((status = cgetent(&bp, printcapdb, printer)) == -2) {
38012514Sralph 			printf("cannot open printer description file\n");
38112382Sralph 			continue;
382*56121Selan 		} else if (status == -1) {
38312514Sralph 			printf("unknown printer %s\n", printer);
38412382Sralph 			continue;
385*56121Selan 		} else if (status == -3)
386*56121Selan 			fatal("potential reference loop detected in printcap file");
387*56121Selan 
38812382Sralph 		enablepr();
38912382Sralph 	}
39012382Sralph }
39112382Sralph 
39255472Sbostic static void
39312382Sralph enablepr()
39412382Sralph {
39512382Sralph 	struct stat stbuf;
39612382Sralph 
397*56121Selan 	if (cgetstr(bp, "sd", &SD) == -1)
39837968Sbostic 		SD = _PATH_DEFSPOOL;
399*56121Selan 	if (cgetstr(bp, "lo", &LO) == -1)
40012382Sralph 		LO = DEFLOCK;
40112382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
40212382Sralph 	printf("%s:\n", printer);
40312382Sralph 
40412382Sralph 	/*
40512382Sralph 	 * Turn off the group execute bit of the lock file to enable queuing.
40612382Sralph 	 */
40712382Sralph 	if (stat(line, &stbuf) >= 0) {
40812382Sralph 		if (chmod(line, stbuf.st_mode & 0767) < 0)
40912514Sralph 			printf("\tcannot enable queuing\n");
41012382Sralph 		else
41112382Sralph 			printf("\tqueuing enabled\n");
41212382Sralph 	}
41312382Sralph }
41412382Sralph 
41512382Sralph /*
41612382Sralph  * Disable queuing.
41712382Sralph  */
41855472Sbostic void
41912382Sralph disable(argc, argv)
42055472Sbostic 	int argc;
42112382Sralph 	char *argv[];
42212382Sralph {
42312382Sralph 	register int c, status;
42412382Sralph 	register char *cp1, *cp2;
42512382Sralph 	char prbuf[100];
42612382Sralph 
42712382Sralph 	if (argc == 1) {
42812382Sralph 		printf("Usage: disable {all | printer ...}\n");
42912382Sralph 		return;
43012382Sralph 	}
43112382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
43212382Sralph 		printer = prbuf;
433*56121Selan 		while (cgetnext(&bp, printcapdb) > 0) {
43412382Sralph 			cp1 = prbuf;
435*56121Selan 			cp2 = bp;
43612382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
43712382Sralph 				*cp1++ = c;
43812382Sralph 			*cp1 = '\0';
43912382Sralph 			disablepr();
44012382Sralph 		}
44112382Sralph 		return;
44212382Sralph 	}
44312382Sralph 	while (--argc) {
44412382Sralph 		printer = *++argv;
445*56121Selan 		if ((status = cgetent(&bp, printcapdb, printer)) == -2) {
44612514Sralph 			printf("cannot open printer description file\n");
44712382Sralph 			continue;
448*56121Selan 		} else if (status == -1) {
44912514Sralph 			printf("unknown printer %s\n", printer);
45012382Sralph 			continue;
451*56121Selan 		} else if (status == -3)
452*56121Selan 			fatal("potential reference loop detected in printcap file");
453*56121Selan 
45412382Sralph 		disablepr();
45512382Sralph 	}
45612382Sralph }
45712382Sralph 
45855472Sbostic static void
45912382Sralph disablepr()
46012382Sralph {
46112382Sralph 	register int fd;
46212382Sralph 	struct stat stbuf;
46312382Sralph 
464*56121Selan 	if (cgetstr(bp, "sd", &SD) == -1)
46537968Sbostic 		SD = _PATH_DEFSPOOL;
466*56121Selan 	if (cgetstr(bp, "lo", &LO) == -1)
46712382Sralph 		LO = DEFLOCK;
46812382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
46912382Sralph 	printf("%s:\n", printer);
47012382Sralph 	/*
47112382Sralph 	 * Turn on the group execute bit of the lock file to disable queuing.
47212382Sralph 	 */
47312382Sralph 	if (stat(line, &stbuf) >= 0) {
47412382Sralph 		if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0)
47512382Sralph 			printf("\tcannot disable queuing\n");
47612382Sralph 		else
47712382Sralph 			printf("\tqueuing disabled\n");
47812382Sralph 	} else if (errno == ENOENT) {
47913146Ssam 		if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0)
48012382Sralph 			printf("\tcannot create lock file\n");
48112382Sralph 		else {
48212382Sralph 			(void) close(fd);
48312382Sralph 			printf("\tqueuing disabled\n");
48412382Sralph 		}
48512382Sralph 		return;
48612382Sralph 	} else
48712382Sralph 		printf("\tcannot stat lock file\n");
48812382Sralph }
48912382Sralph 
49012382Sralph /*
49115907Sralph  * Disable queuing and printing and put a message into the status file
49215907Sralph  * (reason for being down).
49315907Sralph  */
49455472Sbostic void
49515907Sralph down(argc, argv)
49655472Sbostic 	int argc;
49715907Sralph 	char *argv[];
49815907Sralph {
49915907Sralph 	register int c, status;
50015907Sralph 	register char *cp1, *cp2;
50115907Sralph 	char prbuf[100];
50215907Sralph 
50315907Sralph 	if (argc == 1) {
50416204Sralph 		printf("Usage: down {all | printer} [message ...]\n");
50515907Sralph 		return;
50615907Sralph 	}
50715907Sralph 	if (!strcmp(argv[1], "all")) {
50815907Sralph 		printer = prbuf;
509*56121Selan 		while (cgetnext(&bp, printcapdb) > 0) {
51015907Sralph 			cp1 = prbuf;
511*56121Selan 			cp2 = bp;
51215907Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
51315907Sralph 				*cp1++ = c;
51415907Sralph 			*cp1 = '\0';
51515907Sralph 			putmsg(argc - 2, argv + 2);
51615907Sralph 		}
51715907Sralph 		return;
51815907Sralph 	}
51915907Sralph 	printer = argv[1];
520*56121Selan 	if ((status = cgetent(&bp, printcapdb, printer)) == -2) {
52115907Sralph 		printf("cannot open printer description file\n");
52215907Sralph 		return;
523*56121Selan 	} else if (status == -1) {
52415907Sralph 		printf("unknown printer %s\n", printer);
52515907Sralph 		return;
526*56121Selan 	} else if (status == -3)
527*56121Selan 			fatal("potential reference loop detected in printcap file");
528*56121Selan 
52915907Sralph 	putmsg(argc - 2, argv + 2);
53015907Sralph }
53115907Sralph 
53255472Sbostic static void
53315907Sralph putmsg(argc, argv)
53455472Sbostic 	int argc;
53515907Sralph 	char **argv;
53615907Sralph {
53715907Sralph 	register int fd;
53815907Sralph 	register char *cp1, *cp2;
53915907Sralph 	char buf[1024];
54015907Sralph 	struct stat stbuf;
54115907Sralph 
542*56121Selan 	if (cgetstr(bp, "sd", &SD) == -1)
54337968Sbostic 		SD = _PATH_DEFSPOOL;
544*56121Selan 	if (cgetstr(bp, "lo", &LO) == -1)
54515907Sralph 		LO = DEFLOCK;
546*56121Selan 	if (cgetstr(bp, "st", &ST) == -1)
54715907Sralph 		ST = DEFSTAT;
54815907Sralph 	printf("%s:\n", printer);
54915907Sralph 	/*
55015907Sralph 	 * Turn on the group execute bit of the lock file to disable queuing and
55115907Sralph 	 * turn on the owner execute bit of the lock file to disable printing.
55215907Sralph 	 */
55315907Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
55415907Sralph 	if (stat(line, &stbuf) >= 0) {
55515907Sralph 		if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0)
55615907Sralph 			printf("\tcannot disable queuing\n");
55715907Sralph 		else
55815907Sralph 			printf("\tprinter and queuing disabled\n");
55915907Sralph 	} else if (errno == ENOENT) {
56015907Sralph 		if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0)
56115907Sralph 			printf("\tcannot create lock file\n");
56215907Sralph 		else {
56315907Sralph 			(void) close(fd);
56415907Sralph 			printf("\tprinter and queuing disabled\n");
56515907Sralph 		}
56615907Sralph 		return;
56715907Sralph 	} else
56815907Sralph 		printf("\tcannot stat lock file\n");
56915907Sralph 	/*
57015907Sralph 	 * Write the message into the status file.
57115907Sralph 	 */
57215907Sralph 	(void) sprintf(line, "%s/%s", SD, ST);
57315907Sralph 	fd = open(line, O_WRONLY|O_CREAT, 0664);
57415907Sralph 	if (fd < 0 || flock(fd, LOCK_EX) < 0) {
57515907Sralph 		printf("\tcannot create status file\n");
57615907Sralph 		return;
57715907Sralph 	}
57815907Sralph 	(void) ftruncate(fd, 0);
57916204Sralph 	if (argc <= 0) {
58016204Sralph 		(void) write(fd, "\n", 1);
58116204Sralph 		(void) close(fd);
58216204Sralph 		return;
58316204Sralph 	}
58415907Sralph 	cp1 = buf;
58515907Sralph 	while (--argc >= 0) {
58615907Sralph 		cp2 = *argv++;
58715907Sralph 		while (*cp1++ = *cp2++)
58815907Sralph 			;
58915907Sralph 		cp1[-1] = ' ';
59015907Sralph 	}
59115907Sralph 	cp1[-1] = '\n';
59215907Sralph 	*cp1 = '\0';
59315907Sralph 	(void) write(fd, buf, strlen(buf));
59415907Sralph 	(void) close(fd);
59515907Sralph }
59615907Sralph 
59715907Sralph /*
59812382Sralph  * Exit lpc
59912382Sralph  */
60055472Sbostic void
60112382Sralph quit(argc, argv)
60255472Sbostic 	int argc;
60312382Sralph 	char *argv[];
60412382Sralph {
60512382Sralph 	exit(0);
60612382Sralph }
60712382Sralph 
60812382Sralph /*
60916755Sralph  * Kill and restart the daemon.
61012382Sralph  */
61155472Sbostic void
61212382Sralph restart(argc, argv)
61355472Sbostic 	int argc;
61412382Sralph 	char *argv[];
61512382Sralph {
61612382Sralph 	register int c, status;
61712382Sralph 	register char *cp1, *cp2;
61812382Sralph 	char prbuf[100];
61912382Sralph 
62012382Sralph 	if (argc == 1) {
62112382Sralph 		printf("Usage: restart {all | printer ...}\n");
62212382Sralph 		return;
62312382Sralph 	}
62412382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
62512382Sralph 		printer = prbuf;
626*56121Selan 		while (cgetnext(&bp, printcapdb) > 0) {
62712382Sralph 			cp1 = prbuf;
628*56121Selan 			cp2 = bp;
62912382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
63012382Sralph 				*cp1++ = c;
63112382Sralph 			*cp1 = '\0';
63216755Sralph 			abortpr(0);
63312382Sralph 			startpr(0);
63412382Sralph 		}
63512382Sralph 		return;
63612382Sralph 	}
63712382Sralph 	while (--argc) {
63812382Sralph 		printer = *++argv;
639*56121Selan 		if ((status = cgetent(&bp, printcapdb, printer)) == -2) {
64012514Sralph 			printf("cannot open printer description file\n");
64112382Sralph 			continue;
642*56121Selan 		} else if (status == -1) {
64312514Sralph 			printf("unknown printer %s\n", printer);
64412382Sralph 			continue;
645*56121Selan 		} else if (status == -3)
646*56121Selan 			fatal("potential reference loop detected in printcap file");
647*56121Selan 
64816755Sralph 		abortpr(0);
64912382Sralph 		startpr(0);
65012382Sralph 	}
65112382Sralph }
65212382Sralph 
65312382Sralph /*
65412382Sralph  * Enable printing on the specified printer and startup the daemon.
65512382Sralph  */
65655472Sbostic void
65712382Sralph start(argc, argv)
65855472Sbostic 	int argc;
65912382Sralph 	char *argv[];
66012382Sralph {
66112382Sralph 	register int c, status;
66212382Sralph 	register char *cp1, *cp2;
66312382Sralph 	char prbuf[100];
66412382Sralph 
66512382Sralph 	if (argc == 1) {
66612382Sralph 		printf("Usage: start {all | printer ...}\n");
66712382Sralph 		return;
66812382Sralph 	}
66912382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
67012382Sralph 		printer = prbuf;
671*56121Selan 		while (cgetnext(&bp, printcapdb) > 0) {
67212382Sralph 			cp1 = prbuf;
673*56121Selan 			cp2 = bp;
67412382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
67512382Sralph 				*cp1++ = c;
67612382Sralph 			*cp1 = '\0';
67712382Sralph 			startpr(1);
67812382Sralph 		}
67912382Sralph 		return;
68012382Sralph 	}
68112382Sralph 	while (--argc) {
68212382Sralph 		printer = *++argv;
683*56121Selan 		if ((status = cgetent(&bp, printcapdb, printer)) == -2) {
68412514Sralph 			printf("cannot open printer description file\n");
68512382Sralph 			continue;
686*56121Selan 		} else if (status == -1) {
68712514Sralph 			printf("unknown printer %s\n", printer);
68812382Sralph 			continue;
689*56121Selan 		} else if (status == -3)
690*56121Selan 			fatal("potential reference loop detected in printcap file");
691*56121Selan 
69212382Sralph 		startpr(1);
69312382Sralph 	}
69412382Sralph }
69512382Sralph 
69655472Sbostic static void
69712382Sralph startpr(enable)
69855472Sbostic 	int enable;
69912382Sralph {
70012382Sralph 	struct stat stbuf;
70112382Sralph 
702*56121Selan 	if (cgetstr(bp, "sd", &SD) == -1)
70337968Sbostic 		SD = _PATH_DEFSPOOL;
704*56121Selan 	if (cgetstr(bp, "lo", &LO) == -1)
70512382Sralph 		LO = DEFLOCK;
70612382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
70712382Sralph 	printf("%s:\n", printer);
70812382Sralph 
70912382Sralph 	/*
71012382Sralph 	 * Turn off the owner execute bit of the lock file to enable printing.
71112382Sralph 	 */
71212382Sralph 	if (enable && stat(line, &stbuf) >= 0) {
71316771Sralph 		if (chmod(line, stbuf.st_mode & (enable==2 ? 0666 : 0677)) < 0)
71412382Sralph 			printf("\tcannot enable printing\n");
71512382Sralph 		else
71612382Sralph 			printf("\tprinting enabled\n");
71712382Sralph 	}
71813727Sroot 	if (!startdaemon(printer))
71912382Sralph 		printf("\tcouldn't start daemon\n");
72012382Sralph 	else
72112382Sralph 		printf("\tdaemon started\n");
72212382Sralph }
72312382Sralph 
72412382Sralph /*
72512382Sralph  * Print the status of each queue listed or all the queues.
72612382Sralph  */
72755472Sbostic void
72812382Sralph status(argc, argv)
72955472Sbostic 	int argc;
73012382Sralph 	char *argv[];
73112382Sralph {
73212382Sralph 	register int c, status;
73312382Sralph 	register char *cp1, *cp2;
73412382Sralph 	char prbuf[100];
73512382Sralph 
73612382Sralph 	if (argc == 1) {
73712382Sralph 		printer = prbuf;
738*56121Selan 		while (cgetnext(&bp, printcapdb) > 0) {
73912382Sralph 			cp1 = prbuf;
740*56121Selan 			cp2 = bp;
74112382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
74212382Sralph 				*cp1++ = c;
74312382Sralph 			*cp1 = '\0';
74412382Sralph 			prstat();
74512382Sralph 		}
74612382Sralph 		return;
74712382Sralph 	}
74812382Sralph 	while (--argc) {
74912382Sralph 		printer = *++argv;
750*56121Selan 		if ((status = cgetent(&bp, printcapdb, printer)) == -2) {
75112514Sralph 			printf("cannot open printer description file\n");
75212382Sralph 			continue;
753*56121Selan 		} else if (status == -1) {
75412514Sralph 			printf("unknown printer %s\n", printer);
75512382Sralph 			continue;
756*56121Selan 		} else if (status == -3)
757*56121Selan 			fatal("potential reference loop detected in printcap file");
758*56121Selan 
75912382Sralph 		prstat();
76012382Sralph 	}
76112382Sralph }
76212382Sralph 
76312382Sralph /*
76412382Sralph  * Print the status of the printer queue.
76512382Sralph  */
76655472Sbostic static void
76712382Sralph prstat()
76812382Sralph {
76912382Sralph 	struct stat stbuf;
77012382Sralph 	register int fd, i;
77155472Sbostic 	register struct dirent *dp;
77212382Sralph 	DIR *dirp;
77312382Sralph 
774*56121Selan 	if (cgetstr(bp, "sd", &SD) == -1)
77537968Sbostic 		SD = _PATH_DEFSPOOL;
776*56121Selan 	if (cgetstr(bp, "lo", &LO) == -1)
77712382Sralph 		LO = DEFLOCK;
778*56121Selan 	if (cgetstr(bp, "st", &ST) == -1)
77912382Sralph 		ST = DEFSTAT;
78012382Sralph 	printf("%s:\n", printer);
78112382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
78212382Sralph 	if (stat(line, &stbuf) >= 0) {
78312382Sralph 		printf("\tqueuing is %s\n",
78412382Sralph 			(stbuf.st_mode & 010) ? "disabled" : "enabled");
78512382Sralph 		printf("\tprinting is %s\n",
78612382Sralph 			(stbuf.st_mode & 0100) ? "disabled" : "enabled");
78712382Sralph 	} else {
78812382Sralph 		printf("\tqueuing is enabled\n");
78912382Sralph 		printf("\tprinting is enabled\n");
79012382Sralph 	}
79112382Sralph 	if ((dirp = opendir(SD)) == NULL) {
79212382Sralph 		printf("\tcannot examine spool directory\n");
79312382Sralph 		return;
79412382Sralph 	}
79512382Sralph 	i = 0;
79612382Sralph 	while ((dp = readdir(dirp)) != NULL) {
79712382Sralph 		if (*dp->d_name == 'c' && dp->d_name[1] == 'f')
79812382Sralph 			i++;
79912382Sralph 	}
80012382Sralph 	closedir(dirp);
80112382Sralph 	if (i == 0)
80212382Sralph 		printf("\tno entries\n");
80312382Sralph 	else if (i == 1)
80412382Sralph 		printf("\t1 entry in spool area\n");
80512382Sralph 	else
80612382Sralph 		printf("\t%d entries in spool area\n", i);
80713146Ssam 	fd = open(line, O_RDONLY);
80813146Ssam 	if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) {
80913168Sralph 		(void) close(fd);	/* unlocks as well */
81012382Sralph 		printf("\tno daemon present\n");
81112382Sralph 		return;
81212382Sralph 	}
81312382Sralph 	(void) close(fd);
81412382Sralph 	putchar('\t');
81512382Sralph 	(void) sprintf(line, "%s/%s", SD, ST);
81613146Ssam 	fd = open(line, O_RDONLY);
81713146Ssam 	if (fd >= 0) {
81813146Ssam 		(void) flock(fd, LOCK_SH);
81912382Sralph 		while ((i = read(fd, line, sizeof(line))) > 0)
82012382Sralph 			(void) fwrite(line, 1, i, stdout);
82113168Sralph 		(void) close(fd);	/* unlocks as well */
82212382Sralph 	}
82312382Sralph }
82412382Sralph 
82512382Sralph /*
82612382Sralph  * Stop the specified daemon after completing the current job and disable
82712382Sralph  * printing.
82812382Sralph  */
82955472Sbostic void
83012382Sralph stop(argc, argv)
83155472Sbostic 	int argc;
83212382Sralph 	char *argv[];
83312382Sralph {
83412382Sralph 	register int c, status;
83512382Sralph 	register char *cp1, *cp2;
83612382Sralph 	char prbuf[100];
83712382Sralph 
83812382Sralph 	if (argc == 1) {
83912382Sralph 		printf("Usage: stop {all | printer ...}\n");
84012382Sralph 		return;
84112382Sralph 	}
84212382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
84312382Sralph 		printer = prbuf;
844*56121Selan 		while (cgetnext(&bp, printcapdb) > 0) {
84512382Sralph 			cp1 = prbuf;
846*56121Selan 			cp2 = bp;
84712382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
84812382Sralph 				*cp1++ = c;
84912382Sralph 			*cp1 = '\0';
85012382Sralph 			stoppr();
85112382Sralph 		}
85212382Sralph 		return;
85312382Sralph 	}
85412382Sralph 	while (--argc) {
85512382Sralph 		printer = *++argv;
856*56121Selan 		if ((status = cgetent(&bp, printcapdb, printer)) == -2) {
85712514Sralph 			printf("cannot open printer description file\n");
85812382Sralph 			continue;
859*56121Selan 		} else if (status == -1) {
86012514Sralph 			printf("unknown printer %s\n", printer);
86112382Sralph 			continue;
862*56121Selan 		} else if (status == -3)
863*56121Selan 			fatal("potential reference loop detected in printcap file");
864*56121Selan 
86512382Sralph 		stoppr();
86612382Sralph 	}
86712382Sralph }
86812382Sralph 
86955472Sbostic static void
87012382Sralph stoppr()
87112382Sralph {
87212382Sralph 	register int fd;
87312382Sralph 	struct stat stbuf;
87412382Sralph 
875*56121Selan 	if (cgetstr(bp, "sd", &SD) == -1)
87637968Sbostic 		SD = _PATH_DEFSPOOL;
877*56121Selan 	if (cgetstr(bp, "lo", &LO) == -1)
87812382Sralph 		LO = DEFLOCK;
87912382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
88012382Sralph 	printf("%s:\n", printer);
88112382Sralph 
88212382Sralph 	/*
88312382Sralph 	 * Turn on the owner execute bit of the lock file to disable printing.
88412382Sralph 	 */
88512382Sralph 	if (stat(line, &stbuf) >= 0) {
88612382Sralph 		if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
88712382Sralph 			printf("\tcannot disable printing\n");
88838735Stef 		else {
88938735Stef 			upstat("printing disabled\n");
89012382Sralph 			printf("\tprinting disabled\n");
89138735Stef 		}
89212382Sralph 	} else if (errno == ENOENT) {
89313146Ssam 		if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
89412382Sralph 			printf("\tcannot create lock file\n");
89512382Sralph 		else {
89612382Sralph 			(void) close(fd);
89738735Stef 			upstat("printing disabled\n");
89812382Sralph 			printf("\tprinting disabled\n");
89912382Sralph 		}
90012382Sralph 	} else
90112382Sralph 		printf("\tcannot stat lock file\n");
90212382Sralph }
90313727Sroot 
90415719Sralph struct	queue **queue;
90515719Sralph int	nitems;
90615719Sralph time_t	mtime;
90715719Sralph 
90813727Sroot /*
90913727Sroot  * Put the specified jobs at the top of printer queue.
91013727Sroot  */
91155472Sbostic void
91213727Sroot topq(argc, argv)
91355472Sbostic 	int argc;
91413727Sroot 	char *argv[];
91513727Sroot {
91655472Sbostic 	register int i;
91713727Sroot 	struct stat stbuf;
91815719Sralph 	int status, changed;
91913727Sroot 
92015719Sralph 	if (argc < 3) {
92113727Sroot 		printf("Usage: topq printer [jobnum ...] [user ...]\n");
92213727Sroot 		return;
92313727Sroot 	}
92413727Sroot 
92513727Sroot 	--argc;
92613727Sroot 	printer = *++argv;
927*56121Selan 	status = cgetent(&bp, printcapdb, printer);
928*56121Selan 	if (status == -2) {
92913727Sroot 		printf("cannot open printer description file\n");
93013727Sroot 		return;
931*56121Selan 	} else if (status == -1) {
93213727Sroot 		printf("%s: unknown printer\n", printer);
93313727Sroot 		return;
934*56121Selan 	} else if (status == -3)
935*56121Selan 		fatal("potential reference loop detected in printcap file");
936*56121Selan 
937*56121Selan 	if (cgetstr(bp, "sd", &SD) == -1)
93837968Sbostic 		SD = _PATH_DEFSPOOL;
939*56121Selan 	if (cgetstr(bp, "lo", &LO) == -1)
94013727Sroot 		LO = DEFLOCK;
94113727Sroot 	printf("%s:\n", printer);
94213727Sroot 
94313727Sroot 	if (chdir(SD) < 0) {
94413727Sroot 		printf("\tcannot chdir to %s\n", SD);
94513727Sroot 		return;
94613727Sroot 	}
94713727Sroot 	nitems = getq(&queue);
94815719Sralph 	if (nitems == 0)
94915719Sralph 		return;
95015719Sralph 	changed = 0;
95115719Sralph 	mtime = queue[0]->q_time;
95215719Sralph 	for (i = argc; --i; ) {
95315719Sralph 		if (doarg(argv[i]) == 0) {
95415719Sralph 			printf("\tjob %s is not in the queue\n", argv[i]);
95513727Sroot 			continue;
95615719Sralph 		} else
95714151Sralph 			changed++;
95813727Sroot 	}
95915719Sralph 	for (i = 0; i < nitems; i++)
96015719Sralph 		free(queue[i]);
96115719Sralph 	free(queue);
96215719Sralph 	if (!changed) {
96315719Sralph 		printf("\tqueue order unchanged\n");
96415719Sralph 		return;
96513727Sroot 	}
96613727Sroot 	/*
96713727Sroot 	 * Turn on the public execute bit of the lock file to
96813727Sroot 	 * get lpd to rebuild the queue after the current job.
96913727Sroot 	 */
97014151Sralph 	if (changed && stat(LO, &stbuf) >= 0)
97114151Sralph 		(void) chmod(LO, (stbuf.st_mode & 0777) | 01);
97213727Sroot }
97313727Sroot 
97415719Sralph /*
97515719Sralph  * Reposition the job by changing the modification time of
97615719Sralph  * the control file.
97713727Sroot  */
97855472Sbostic static int
97915719Sralph touch(q)
98015719Sralph 	struct queue *q;
98113727Sroot {
98215719Sralph 	struct timeval tvp[2];
98313727Sroot 
98415719Sralph 	tvp[0].tv_sec = tvp[1].tv_sec = --mtime;
98515719Sralph 	tvp[0].tv_usec = tvp[1].tv_usec = 0;
98615719Sralph 	return(utimes(q->q_name, tvp));
98713727Sroot }
98813727Sroot 
98913727Sroot /*
99013727Sroot  * Checks if specified job name is in the printer's queue.
99113727Sroot  * Returns:  negative (-1) if argument name is not in the queue.
99213727Sroot  */
99355472Sbostic static int
99415719Sralph doarg(job)
99513727Sroot 	char *job;
99613727Sroot {
99715719Sralph 	register struct queue **qq;
99815719Sralph 	register int jobnum, n;
99915719Sralph 	register char *cp, *machine;
100015719Sralph 	int cnt = 0;
100114151Sralph 	FILE *fp;
100213727Sroot 
100315719Sralph 	/*
100415719Sralph 	 * Look for a job item consisting of system name, colon, number
100515719Sralph 	 * (example: ucbarpa:114)
100615719Sralph 	 */
100715719Sralph 	if ((cp = index(job, ':')) != NULL) {
100815719Sralph 		machine = job;
100915719Sralph 		*cp++ = '\0';
101015719Sralph 		job = cp;
101115719Sralph 	} else
101215719Sralph 		machine = NULL;
101315719Sralph 
101415719Sralph 	/*
101515719Sralph 	 * Check for job specified by number (example: 112 or 235ucbarpa).
101615719Sralph 	 */
101713727Sroot 	if (isdigit(*job)) {
101813727Sroot 		jobnum = 0;
101913727Sroot 		do
102013727Sroot 			jobnum = jobnum * 10 + (*job++ - '0');
102113727Sroot 		while (isdigit(*job));
102215719Sralph 		for (qq = queue + nitems; --qq >= queue; ) {
102313727Sroot 			n = 0;
102415719Sralph 			for (cp = (*qq)->q_name+3; isdigit(*cp); )
102514151Sralph 				n = n * 10 + (*cp++ - '0');
102615719Sralph 			if (jobnum != n)
102715719Sralph 				continue;
102815719Sralph 			if (*job && strcmp(job, cp) != 0)
102915719Sralph 				continue;
103015719Sralph 			if (machine != NULL && strcmp(machine, cp) != 0)
103115719Sralph 				continue;
103215719Sralph 			if (touch(*qq) == 0) {
103315719Sralph 				printf("\tmoved %s\n", (*qq)->q_name);
103415719Sralph 				cnt++;
103515719Sralph 			}
103613727Sroot 		}
103715719Sralph 		return(cnt);
103815719Sralph 	}
103915719Sralph 	/*
104015719Sralph 	 * Process item consisting of owner's name (example: henry).
104115719Sralph 	 */
104215719Sralph 	for (qq = queue + nitems; --qq >= queue; ) {
104315719Sralph 		if ((fp = fopen((*qq)->q_name, "r")) == NULL)
104413727Sroot 			continue;
104515719Sralph 		while (getline(fp) > 0)
104615719Sralph 			if (line[0] == 'P')
104715719Sralph 				break;
104815719Sralph 		(void) fclose(fp);
104915719Sralph 		if (line[0] != 'P' || strcmp(job, line+1) != 0)
105015719Sralph 			continue;
105115719Sralph 		if (touch(*qq) == 0) {
105215719Sralph 			printf("\tmoved %s\n", (*qq)->q_name);
105315719Sralph 			cnt++;
105413727Sroot 		}
105513727Sroot 	}
105615719Sralph 	return(cnt);
105713727Sroot }
105816755Sralph 
105916755Sralph /*
106016755Sralph  * Enable everything and start printer (undo `down').
106116755Sralph  */
106255472Sbostic void
106316755Sralph up(argc, argv)
106455472Sbostic 	int argc;
106516755Sralph 	char *argv[];
106616755Sralph {
106716755Sralph 	register int c, status;
106816755Sralph 	register char *cp1, *cp2;
106916755Sralph 	char prbuf[100];
107016755Sralph 
107116755Sralph 	if (argc == 1) {
107216755Sralph 		printf("Usage: up {all | printer ...}\n");
107316755Sralph 		return;
107416755Sralph 	}
107516755Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
107616755Sralph 		printer = prbuf;
1077*56121Selan 		while (cgetnext(&bp, printcapdb) > 0) {
107816755Sralph 			cp1 = prbuf;
1079*56121Selan 			cp2 = bp;
108016755Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
108116755Sralph 				*cp1++ = c;
108216755Sralph 			*cp1 = '\0';
108316755Sralph 			startpr(2);
108416755Sralph 		}
108516755Sralph 		return;
108616755Sralph 	}
108716755Sralph 	while (--argc) {
108816755Sralph 		printer = *++argv;
1089*56121Selan 		if ((status = cgetent(&bp, printcapdb, printer)) == -2) {
109016755Sralph 			printf("cannot open printer description file\n");
109116755Sralph 			continue;
1092*56121Selan 		} else if (status == -1) {
109316755Sralph 			printf("unknown printer %s\n", printer);
109416755Sralph 			continue;
1095*56121Selan 		} else if (status == -3)
1096*56121Selan 			fatal("potential reference loop detected in printcap file");
1097*56121Selan 
109816755Sralph 		startpr(2);
109916755Sralph 	}
110016755Sralph }
1101