xref: /csrg-svn/usr.sbin/lpr/lpc/cmds.c (revision 38735)
122424Sdist /*
222424Sdist  * Copyright (c) 1983 Regents of the University of California.
334203Sbostic  * All rights reserved.
434203Sbostic  *
534203Sbostic  * Redistribution and use in source and binary forms are permitted
634936Sbostic  * provided that the above copyright notice and this paragraph are
734936Sbostic  * duplicated in all such forms and that any documentation,
834936Sbostic  * advertising materials, and other materials related to such
934936Sbostic  * distribution and use acknowledge that the software was developed
1034936Sbostic  * by the University of California, Berkeley.  The name of the
1134936Sbostic  * University may not be used to endorse or promote products derived
1234936Sbostic  * from this software without specific prior written permission.
1334936Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1434936Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1534936Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1622424Sdist  */
1722424Sdist 
1812382Sralph #ifndef lint
19*38735Stef static char sccsid[] = "@(#)cmds.c	5.6 (Berkeley) 08/22/89";
2034203Sbostic #endif /* not lint */
2112382Sralph 
2212382Sralph /*
2315719Sralph  * lpc -- line printer control program -- commands:
2412382Sralph  */
2512382Sralph 
2612382Sralph #include "lp.h"
2715719Sralph #include <sys/time.h>
2837968Sbostic #include "pathnames.h"
2912382Sralph 
3012382Sralph /*
3112382Sralph  * kill an existing daemon and disable printing.
3212382Sralph  */
3312382Sralph abort(argc, argv)
3412382Sralph 	char *argv[];
3512382Sralph {
3612382Sralph 	register int c, status;
3712382Sralph 	register char *cp1, *cp2;
3812382Sralph 	char prbuf[100];
3912382Sralph 
4012382Sralph 	if (argc == 1) {
4112382Sralph 		printf("Usage: abort {all | printer ...}\n");
4212382Sralph 		return;
4312382Sralph 	}
4412382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
4512382Sralph 		printer = prbuf;
4612382Sralph 		while (getprent(line) > 0) {
4712382Sralph 			cp1 = prbuf;
4812382Sralph 			cp2 = line;
4912382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
5012382Sralph 				*cp1++ = c;
5112382Sralph 			*cp1 = '\0';
5216755Sralph 			abortpr(1);
5312382Sralph 		}
5412382Sralph 		return;
5512382Sralph 	}
5612382Sralph 	while (--argc) {
5712382Sralph 		printer = *++argv;
5812382Sralph 		if ((status = pgetent(line, printer)) < 0) {
5912514Sralph 			printf("cannot open printer description file\n");
6012382Sralph 			continue;
6112382Sralph 		} else if (status == 0) {
6212514Sralph 			printf("unknown printer %s\n", printer);
6312382Sralph 			continue;
6412382Sralph 		}
6516755Sralph 		abortpr(1);
6612382Sralph 	}
6712382Sralph }
6812382Sralph 
6916755Sralph abortpr(dis)
7012382Sralph {
7112382Sralph 	register FILE *fp;
7212382Sralph 	struct stat stbuf;
7312382Sralph 	int pid, fd;
7412382Sralph 
7512382Sralph 	bp = pbuf;
7612382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
7737968Sbostic 		SD = _PATH_DEFSPOOL;
7812382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
7912382Sralph 		LO = DEFLOCK;
8012382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
8112382Sralph 	printf("%s:\n", printer);
8212382Sralph 
8312382Sralph 	/*
8412382Sralph 	 * Turn on the owner execute bit of the lock file to disable printing.
8512382Sralph 	 */
8616755Sralph 	if (dis) {
8716755Sralph 		if (stat(line, &stbuf) >= 0) {
8816755Sralph 			if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
8916755Sralph 				printf("\tcannot disable printing\n");
90*38735Stef 			else {
91*38735Stef 				upstat("printing disabled\n");
9216755Sralph 				printf("\tprinting disabled\n");
93*38735Stef 			}
9416755Sralph 		} else if (errno == ENOENT) {
9516755Sralph 			if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
9616755Sralph 				printf("\tcannot create lock file\n");
9716755Sralph 			else {
9816755Sralph 				(void) close(fd);
99*38735Stef 				upstat("printing disabled\n");
10016755Sralph 				printf("\tprinting disabled\n");
10116755Sralph 				printf("\tno daemon to abort\n");
10216755Sralph 			}
10316755Sralph 			return;
10416755Sralph 		} else {
10516755Sralph 			printf("\tcannot stat lock file\n");
10616755Sralph 			return;
10712382Sralph 		}
10812382Sralph 	}
10912382Sralph 	/*
11012382Sralph 	 * Kill the current daemon to stop printing now.
11112382Sralph 	 */
11212382Sralph 	if ((fp = fopen(line, "r")) == NULL) {
11312382Sralph 		printf("\tcannot open lock file\n");
11412382Sralph 		return;
11512382Sralph 	}
11613146Ssam 	if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) {
11713168Sralph 		(void) fclose(fp);	/* unlocks as well */
11812382Sralph 		printf("\tno daemon to abort\n");
11912382Sralph 		return;
12012382Sralph 	}
12112382Sralph 	(void) fclose(fp);
12216755Sralph 	if (kill(pid = atoi(line), SIGTERM) < 0)
12312382Sralph 		printf("\tWarning: daemon (pid %d) not killed\n", pid);
12412382Sralph 	else
12512382Sralph 		printf("\tdaemon (pid %d) killed\n", pid);
12612382Sralph }
12712382Sralph 
12812382Sralph /*
129*38735Stef  * Write a message into the status file.
130*38735Stef  */
131*38735Stef upstat(msg)
132*38735Stef 	char *msg;
133*38735Stef {
134*38735Stef 	register int fd;
135*38735Stef 	char statfile[BUFSIZ];
136*38735Stef 
137*38735Stef 	bp = pbuf;
138*38735Stef 	if ((ST = pgetstr("st", &bp)) == NULL)
139*38735Stef 		ST = DEFSTAT;
140*38735Stef 	(void) sprintf(statfile, "%s/%s", SD, ST);
141*38735Stef 	umask(0);
142*38735Stef 	fd = open(statfile, O_WRONLY|O_CREAT, 0664);
143*38735Stef 	if (fd < 0 || flock(fd, LOCK_EX) < 0) {
144*38735Stef 		printf("\tcannot create status file\n");
145*38735Stef 		return;
146*38735Stef 	}
147*38735Stef 	(void) ftruncate(fd, 0);
148*38735Stef 	if (msg == (char *)NULL)
149*38735Stef 		(void) write(fd, "\n", 1);
150*38735Stef 	else
151*38735Stef 		(void) write(fd, msg, strlen(msg));
152*38735Stef 	(void) close(fd);
153*38735Stef }
154*38735Stef 
155*38735Stef /*
15612382Sralph  * Remove all spool files and temporaries from the spooling area.
15712382Sralph  */
15812382Sralph clean(argc, argv)
15912382Sralph 	char *argv[];
16012382Sralph {
16112382Sralph 	register int c, status;
16212382Sralph 	register char *cp1, *cp2;
16312382Sralph 	char prbuf[100];
16412382Sralph 
16512382Sralph 	if (argc == 1) {
16612382Sralph 		printf("Usage: clean {all | printer ...}\n");
16712382Sralph 		return;
16812382Sralph 	}
16912382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
17012382Sralph 		printer = prbuf;
17112382Sralph 		while (getprent(line) > 0) {
17212382Sralph 			cp1 = prbuf;
17312382Sralph 			cp2 = line;
17412382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
17512382Sralph 				*cp1++ = c;
17612382Sralph 			*cp1 = '\0';
17712382Sralph 			cleanpr();
17812382Sralph 		}
17912382Sralph 		return;
18012382Sralph 	}
18112382Sralph 	while (--argc) {
18212382Sralph 		printer = *++argv;
18312382Sralph 		if ((status = pgetent(line, printer)) < 0) {
18412514Sralph 			printf("cannot open printer description file\n");
18512382Sralph 			continue;
18612382Sralph 		} else if (status == 0) {
18712514Sralph 			printf("unknown printer %s\n", printer);
18812382Sralph 			continue;
18912382Sralph 		}
19012382Sralph 		cleanpr();
19112382Sralph 	}
19212382Sralph }
19312382Sralph 
19415719Sralph select(d)
19515719Sralph struct direct *d;
19615719Sralph {
19715719Sralph 	int c = d->d_name[0];
19815719Sralph 
19915719Sralph 	if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f')
20015719Sralph 		return(1);
20115719Sralph 	return(0);
20215719Sralph }
20315719Sralph 
20415719Sralph /*
20515719Sralph  * Comparison routine for scandir. Sort by job number and machine, then
20615719Sralph  * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z.
20715719Sralph  */
20815719Sralph sortq(d1, d2)
20915719Sralph struct direct **d1, **d2;
21015719Sralph {
21115719Sralph 	int c1, c2;
21215719Sralph 
21315719Sralph 	if (c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3))
21415719Sralph 		return(c1);
21515719Sralph 	c1 = (*d1)->d_name[0];
21615719Sralph 	c2 = (*d2)->d_name[0];
21715719Sralph 	if (c1 == c2)
21815719Sralph 		return((*d1)->d_name[2] - (*d2)->d_name[2]);
21915719Sralph 	if (c1 == 'c')
22015719Sralph 		return(-1);
22115719Sralph 	if (c1 == 'd' || c2 == 'c')
22215719Sralph 		return(1);
22315719Sralph 	return(-1);
22415719Sralph }
22515719Sralph 
22615719Sralph /*
22715719Sralph  * Remove incomplete jobs from spooling area.
22815719Sralph  */
22912382Sralph cleanpr()
23012382Sralph {
23115719Sralph 	register int i, n;
23215719Sralph 	register char *cp, *cp1, *lp;
23315719Sralph 	struct direct **queue;
23415719Sralph 	int nitems;
23512382Sralph 
23612382Sralph 	bp = pbuf;
23712382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
23837968Sbostic 		SD = _PATH_DEFSPOOL;
23912382Sralph 	printf("%s:\n", printer);
24012382Sralph 
24115719Sralph 	for (lp = line, cp = SD; *lp++ = *cp++; )
24215719Sralph 		;
24315719Sralph 	lp[-1] = '/';
24415719Sralph 
24515719Sralph 	nitems = scandir(SD, &queue, select, sortq);
24615719Sralph 	if (nitems < 0) {
24712382Sralph 		printf("\tcannot examine spool directory\n");
24812382Sralph 		return;
24912382Sralph 	}
25015719Sralph 	if (nitems == 0)
25115719Sralph 		return;
25215719Sralph 	i = 0;
25315719Sralph 	do {
25415719Sralph 		cp = queue[i]->d_name;
25515719Sralph 		if (*cp == 'c') {
25615719Sralph 			n = 0;
25715719Sralph 			while (i + 1 < nitems) {
25815719Sralph 				cp1 = queue[i + 1]->d_name;
25915719Sralph 				if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3))
26015719Sralph 					break;
26115719Sralph 				i++;
26215719Sralph 				n++;
26315719Sralph 			}
26415719Sralph 			if (n == 0) {
26515719Sralph 				strcpy(lp, cp);
26615719Sralph 				unlinkf(line);
26715719Sralph 			}
26815719Sralph 		} else {
26915719Sralph 			/*
27015719Sralph 			 * Must be a df with no cf (otherwise, it would have
27115719Sralph 			 * been skipped above) or a tf file (which can always
27215719Sralph 			 * be removed).
27315719Sralph 			 */
27415719Sralph 			strcpy(lp, cp);
27515719Sralph 			unlinkf(line);
27612382Sralph 		}
27715719Sralph      	} while (++i < nitems);
27812382Sralph }
27915719Sralph 
28015719Sralph unlinkf(name)
28115719Sralph 	char	*name;
28215719Sralph {
28315719Sralph 	if (unlink(name) < 0)
28415719Sralph 		printf("\tcannot remove %s\n", name);
28515719Sralph 	else
28615719Sralph 		printf("\tremoved %s\n", name);
28715719Sralph }
28812382Sralph 
28912382Sralph /*
29012382Sralph  * Enable queuing to the printer (allow lpr's).
29112382Sralph  */
29212382Sralph enable(argc, argv)
29312382Sralph 	char *argv[];
29412382Sralph {
29512382Sralph 	register int c, status;
29612382Sralph 	register char *cp1, *cp2;
29712382Sralph 	char prbuf[100];
29812382Sralph 
29912382Sralph 	if (argc == 1) {
30012382Sralph 		printf("Usage: enable {all | printer ...}\n");
30112382Sralph 		return;
30212382Sralph 	}
30312382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
30412382Sralph 		printer = prbuf;
30512382Sralph 		while (getprent(line) > 0) {
30612382Sralph 			cp1 = prbuf;
30712382Sralph 			cp2 = line;
30812382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
30912382Sralph 				*cp1++ = c;
31012382Sralph 			*cp1 = '\0';
31112382Sralph 			enablepr();
31212382Sralph 		}
31312382Sralph 		return;
31412382Sralph 	}
31512382Sralph 	while (--argc) {
31612382Sralph 		printer = *++argv;
31712382Sralph 		if ((status = pgetent(line, printer)) < 0) {
31812514Sralph 			printf("cannot open printer description file\n");
31912382Sralph 			continue;
32012382Sralph 		} else if (status == 0) {
32112514Sralph 			printf("unknown printer %s\n", printer);
32212382Sralph 			continue;
32312382Sralph 		}
32412382Sralph 		enablepr();
32512382Sralph 	}
32612382Sralph }
32712382Sralph 
32812382Sralph enablepr()
32912382Sralph {
33012382Sralph 	struct stat stbuf;
33112382Sralph 
33212382Sralph 	bp = pbuf;
33312382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
33437968Sbostic 		SD = _PATH_DEFSPOOL;
33512382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
33612382Sralph 		LO = DEFLOCK;
33712382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
33812382Sralph 	printf("%s:\n", printer);
33912382Sralph 
34012382Sralph 	/*
34112382Sralph 	 * Turn off the group execute bit of the lock file to enable queuing.
34212382Sralph 	 */
34312382Sralph 	if (stat(line, &stbuf) >= 0) {
34412382Sralph 		if (chmod(line, stbuf.st_mode & 0767) < 0)
34512514Sralph 			printf("\tcannot enable queuing\n");
34612382Sralph 		else
34712382Sralph 			printf("\tqueuing enabled\n");
34812382Sralph 	}
34912382Sralph }
35012382Sralph 
35112382Sralph /*
35212382Sralph  * Disable queuing.
35312382Sralph  */
35412382Sralph disable(argc, argv)
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: disable {all | printer ...}\n");
36312382Sralph 		return;
36412382Sralph 	}
36512382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
36612382Sralph 		printer = prbuf;
36712382Sralph 		while (getprent(line) > 0) {
36812382Sralph 			cp1 = prbuf;
36912382Sralph 			cp2 = line;
37012382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
37112382Sralph 				*cp1++ = c;
37212382Sralph 			*cp1 = '\0';
37312382Sralph 			disablepr();
37412382Sralph 		}
37512382Sralph 		return;
37612382Sralph 	}
37712382Sralph 	while (--argc) {
37812382Sralph 		printer = *++argv;
37912382Sralph 		if ((status = pgetent(line, printer)) < 0) {
38012514Sralph 			printf("cannot open printer description file\n");
38112382Sralph 			continue;
38212382Sralph 		} else if (status == 0) {
38312514Sralph 			printf("unknown printer %s\n", printer);
38412382Sralph 			continue;
38512382Sralph 		}
38612382Sralph 		disablepr();
38712382Sralph 	}
38812382Sralph }
38912382Sralph 
39012382Sralph disablepr()
39112382Sralph {
39212382Sralph 	register int fd;
39312382Sralph 	struct stat stbuf;
39412382Sralph 
39512382Sralph 	bp = pbuf;
39612382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
39737968Sbostic 		SD = _PATH_DEFSPOOL;
39812382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
39912382Sralph 		LO = DEFLOCK;
40012382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
40112382Sralph 	printf("%s:\n", printer);
40212382Sralph 	/*
40312382Sralph 	 * Turn on the group execute bit of the lock file to disable queuing.
40412382Sralph 	 */
40512382Sralph 	if (stat(line, &stbuf) >= 0) {
40612382Sralph 		if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0)
40712382Sralph 			printf("\tcannot disable queuing\n");
40812382Sralph 		else
40912382Sralph 			printf("\tqueuing disabled\n");
41012382Sralph 	} else if (errno == ENOENT) {
41113146Ssam 		if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0)
41212382Sralph 			printf("\tcannot create lock file\n");
41312382Sralph 		else {
41412382Sralph 			(void) close(fd);
41512382Sralph 			printf("\tqueuing disabled\n");
41612382Sralph 		}
41712382Sralph 		return;
41812382Sralph 	} else
41912382Sralph 		printf("\tcannot stat lock file\n");
42012382Sralph }
42112382Sralph 
42212382Sralph /*
42315907Sralph  * Disable queuing and printing and put a message into the status file
42415907Sralph  * (reason for being down).
42515907Sralph  */
42615907Sralph down(argc, argv)
42715907Sralph 	char *argv[];
42815907Sralph {
42915907Sralph 	register int c, status;
43015907Sralph 	register char *cp1, *cp2;
43115907Sralph 	char prbuf[100];
43215907Sralph 
43315907Sralph 	if (argc == 1) {
43416204Sralph 		printf("Usage: down {all | printer} [message ...]\n");
43515907Sralph 		return;
43615907Sralph 	}
43715907Sralph 	if (!strcmp(argv[1], "all")) {
43815907Sralph 		printer = prbuf;
43915907Sralph 		while (getprent(line) > 0) {
44015907Sralph 			cp1 = prbuf;
44115907Sralph 			cp2 = line;
44215907Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
44315907Sralph 				*cp1++ = c;
44415907Sralph 			*cp1 = '\0';
44515907Sralph 			putmsg(argc - 2, argv + 2);
44615907Sralph 		}
44715907Sralph 		return;
44815907Sralph 	}
44915907Sralph 	printer = argv[1];
45015907Sralph 	if ((status = pgetent(line, printer)) < 0) {
45115907Sralph 		printf("cannot open printer description file\n");
45215907Sralph 		return;
45315907Sralph 	} else if (status == 0) {
45415907Sralph 		printf("unknown printer %s\n", printer);
45515907Sralph 		return;
45615907Sralph 	}
45715907Sralph 	putmsg(argc - 2, argv + 2);
45815907Sralph }
45915907Sralph 
46015907Sralph putmsg(argc, argv)
46115907Sralph 	char **argv;
46215907Sralph {
46315907Sralph 	register int fd;
46415907Sralph 	register char *cp1, *cp2;
46515907Sralph 	char buf[1024];
46615907Sralph 	struct stat stbuf;
46715907Sralph 
46815907Sralph 	bp = pbuf;
46915907Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
47037968Sbostic 		SD = _PATH_DEFSPOOL;
47115907Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
47215907Sralph 		LO = DEFLOCK;
47315907Sralph 	if ((ST = pgetstr("st", &bp)) == NULL)
47415907Sralph 		ST = DEFSTAT;
47515907Sralph 	printf("%s:\n", printer);
47615907Sralph 	/*
47715907Sralph 	 * Turn on the group execute bit of the lock file to disable queuing and
47815907Sralph 	 * turn on the owner execute bit of the lock file to disable printing.
47915907Sralph 	 */
48015907Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
48115907Sralph 	if (stat(line, &stbuf) >= 0) {
48215907Sralph 		if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0)
48315907Sralph 			printf("\tcannot disable queuing\n");
48415907Sralph 		else
48515907Sralph 			printf("\tprinter and queuing disabled\n");
48615907Sralph 	} else if (errno == ENOENT) {
48715907Sralph 		if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0)
48815907Sralph 			printf("\tcannot create lock file\n");
48915907Sralph 		else {
49015907Sralph 			(void) close(fd);
49115907Sralph 			printf("\tprinter and queuing disabled\n");
49215907Sralph 		}
49315907Sralph 		return;
49415907Sralph 	} else
49515907Sralph 		printf("\tcannot stat lock file\n");
49615907Sralph 	/*
49715907Sralph 	 * Write the message into the status file.
49815907Sralph 	 */
49915907Sralph 	(void) sprintf(line, "%s/%s", SD, ST);
50015907Sralph 	fd = open(line, O_WRONLY|O_CREAT, 0664);
50115907Sralph 	if (fd < 0 || flock(fd, LOCK_EX) < 0) {
50215907Sralph 		printf("\tcannot create status file\n");
50315907Sralph 		return;
50415907Sralph 	}
50515907Sralph 	(void) ftruncate(fd, 0);
50616204Sralph 	if (argc <= 0) {
50716204Sralph 		(void) write(fd, "\n", 1);
50816204Sralph 		(void) close(fd);
50916204Sralph 		return;
51016204Sralph 	}
51115907Sralph 	cp1 = buf;
51215907Sralph 	while (--argc >= 0) {
51315907Sralph 		cp2 = *argv++;
51415907Sralph 		while (*cp1++ = *cp2++)
51515907Sralph 			;
51615907Sralph 		cp1[-1] = ' ';
51715907Sralph 	}
51815907Sralph 	cp1[-1] = '\n';
51915907Sralph 	*cp1 = '\0';
52015907Sralph 	(void) write(fd, buf, strlen(buf));
52115907Sralph 	(void) close(fd);
52215907Sralph }
52315907Sralph 
52415907Sralph /*
52512382Sralph  * Exit lpc
52612382Sralph  */
52712382Sralph quit(argc, argv)
52812382Sralph 	char *argv[];
52912382Sralph {
53012382Sralph 	exit(0);
53112382Sralph }
53212382Sralph 
53312382Sralph /*
53416755Sralph  * Kill and restart the daemon.
53512382Sralph  */
53612382Sralph restart(argc, argv)
53712382Sralph 	char *argv[];
53812382Sralph {
53912382Sralph 	register int c, status;
54012382Sralph 	register char *cp1, *cp2;
54112382Sralph 	char prbuf[100];
54212382Sralph 
54312382Sralph 	if (argc == 1) {
54412382Sralph 		printf("Usage: restart {all | printer ...}\n");
54512382Sralph 		return;
54612382Sralph 	}
54712382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
54812382Sralph 		printer = prbuf;
54912382Sralph 		while (getprent(line) > 0) {
55012382Sralph 			cp1 = prbuf;
55112382Sralph 			cp2 = line;
55212382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
55312382Sralph 				*cp1++ = c;
55412382Sralph 			*cp1 = '\0';
55516755Sralph 			abortpr(0);
55612382Sralph 			startpr(0);
55712382Sralph 		}
55812382Sralph 		return;
55912382Sralph 	}
56012382Sralph 	while (--argc) {
56112382Sralph 		printer = *++argv;
56212382Sralph 		if ((status = pgetent(line, printer)) < 0) {
56312514Sralph 			printf("cannot open printer description file\n");
56412382Sralph 			continue;
56512382Sralph 		} else if (status == 0) {
56612514Sralph 			printf("unknown printer %s\n", printer);
56712382Sralph 			continue;
56812382Sralph 		}
56916755Sralph 		abortpr(0);
57012382Sralph 		startpr(0);
57112382Sralph 	}
57212382Sralph }
57312382Sralph 
57412382Sralph /*
57512382Sralph  * Enable printing on the specified printer and startup the daemon.
57612382Sralph  */
57712382Sralph start(argc, argv)
57812382Sralph 	char *argv[];
57912382Sralph {
58012382Sralph 	register int c, status;
58112382Sralph 	register char *cp1, *cp2;
58212382Sralph 	char prbuf[100];
58312382Sralph 
58412382Sralph 	if (argc == 1) {
58512382Sralph 		printf("Usage: start {all | printer ...}\n");
58612382Sralph 		return;
58712382Sralph 	}
58812382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
58912382Sralph 		printer = prbuf;
59012382Sralph 		while (getprent(line) > 0) {
59112382Sralph 			cp1 = prbuf;
59212382Sralph 			cp2 = line;
59312382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
59412382Sralph 				*cp1++ = c;
59512382Sralph 			*cp1 = '\0';
59612382Sralph 			startpr(1);
59712382Sralph 		}
59812382Sralph 		return;
59912382Sralph 	}
60012382Sralph 	while (--argc) {
60112382Sralph 		printer = *++argv;
60212382Sralph 		if ((status = pgetent(line, printer)) < 0) {
60312514Sralph 			printf("cannot open printer description file\n");
60412382Sralph 			continue;
60512382Sralph 		} else if (status == 0) {
60612514Sralph 			printf("unknown printer %s\n", printer);
60712382Sralph 			continue;
60812382Sralph 		}
60912382Sralph 		startpr(1);
61012382Sralph 	}
61112382Sralph }
61212382Sralph 
61312382Sralph startpr(enable)
61412382Sralph {
61512382Sralph 	struct stat stbuf;
61612382Sralph 
61712382Sralph 	bp = pbuf;
61812382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
61937968Sbostic 		SD = _PATH_DEFSPOOL;
62012382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
62112382Sralph 		LO = DEFLOCK;
62212382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
62312382Sralph 	printf("%s:\n", printer);
62412382Sralph 
62512382Sralph 	/*
62612382Sralph 	 * Turn off the owner execute bit of the lock file to enable printing.
62712382Sralph 	 */
62812382Sralph 	if (enable && stat(line, &stbuf) >= 0) {
62916771Sralph 		if (chmod(line, stbuf.st_mode & (enable==2 ? 0666 : 0677)) < 0)
63012382Sralph 			printf("\tcannot enable printing\n");
63112382Sralph 		else
63212382Sralph 			printf("\tprinting enabled\n");
63312382Sralph 	}
63413727Sroot 	if (!startdaemon(printer))
63512382Sralph 		printf("\tcouldn't start daemon\n");
63612382Sralph 	else
63712382Sralph 		printf("\tdaemon started\n");
63812382Sralph }
63912382Sralph 
64012382Sralph /*
64112382Sralph  * Print the status of each queue listed or all the queues.
64212382Sralph  */
64312382Sralph status(argc, argv)
64412382Sralph 	char *argv[];
64512382Sralph {
64612382Sralph 	register int c, status;
64712382Sralph 	register char *cp1, *cp2;
64812382Sralph 	char prbuf[100];
64912382Sralph 
65012382Sralph 	if (argc == 1) {
65112382Sralph 		printer = prbuf;
65212382Sralph 		while (getprent(line) > 0) {
65312382Sralph 			cp1 = prbuf;
65412382Sralph 			cp2 = line;
65512382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
65612382Sralph 				*cp1++ = c;
65712382Sralph 			*cp1 = '\0';
65812382Sralph 			prstat();
65912382Sralph 		}
66012382Sralph 		return;
66112382Sralph 	}
66212382Sralph 	while (--argc) {
66312382Sralph 		printer = *++argv;
66412382Sralph 		if ((status = pgetent(line, printer)) < 0) {
66512514Sralph 			printf("cannot open printer description file\n");
66612382Sralph 			continue;
66712382Sralph 		} else if (status == 0) {
66812514Sralph 			printf("unknown printer %s\n", printer);
66912382Sralph 			continue;
67012382Sralph 		}
67112382Sralph 		prstat();
67212382Sralph 	}
67312382Sralph }
67412382Sralph 
67512382Sralph /*
67612382Sralph  * Print the status of the printer queue.
67712382Sralph  */
67812382Sralph prstat()
67912382Sralph {
68012382Sralph 	struct stat stbuf;
68112382Sralph 	register int fd, i;
68212382Sralph 	register struct direct *dp;
68312382Sralph 	DIR *dirp;
68412382Sralph 
68512382Sralph 	bp = pbuf;
68612382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
68737968Sbostic 		SD = _PATH_DEFSPOOL;
68812382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
68912382Sralph 		LO = DEFLOCK;
69012382Sralph 	if ((ST = pgetstr("st", &bp)) == NULL)
69112382Sralph 		ST = DEFSTAT;
69212382Sralph 	printf("%s:\n", printer);
69312382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
69412382Sralph 	if (stat(line, &stbuf) >= 0) {
69512382Sralph 		printf("\tqueuing is %s\n",
69612382Sralph 			(stbuf.st_mode & 010) ? "disabled" : "enabled");
69712382Sralph 		printf("\tprinting is %s\n",
69812382Sralph 			(stbuf.st_mode & 0100) ? "disabled" : "enabled");
69912382Sralph 	} else {
70012382Sralph 		printf("\tqueuing is enabled\n");
70112382Sralph 		printf("\tprinting is enabled\n");
70212382Sralph 	}
70312382Sralph 	if ((dirp = opendir(SD)) == NULL) {
70412382Sralph 		printf("\tcannot examine spool directory\n");
70512382Sralph 		return;
70612382Sralph 	}
70712382Sralph 	i = 0;
70812382Sralph 	while ((dp = readdir(dirp)) != NULL) {
70912382Sralph 		if (*dp->d_name == 'c' && dp->d_name[1] == 'f')
71012382Sralph 			i++;
71112382Sralph 	}
71212382Sralph 	closedir(dirp);
71312382Sralph 	if (i == 0)
71412382Sralph 		printf("\tno entries\n");
71512382Sralph 	else if (i == 1)
71612382Sralph 		printf("\t1 entry in spool area\n");
71712382Sralph 	else
71812382Sralph 		printf("\t%d entries in spool area\n", i);
71913146Ssam 	fd = open(line, O_RDONLY);
72013146Ssam 	if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) {
72113168Sralph 		(void) close(fd);	/* unlocks as well */
72212382Sralph 		printf("\tno daemon present\n");
72312382Sralph 		return;
72412382Sralph 	}
72512382Sralph 	(void) close(fd);
72612382Sralph 	putchar('\t');
72712382Sralph 	(void) sprintf(line, "%s/%s", SD, ST);
72813146Ssam 	fd = open(line, O_RDONLY);
72913146Ssam 	if (fd >= 0) {
73013146Ssam 		(void) flock(fd, LOCK_SH);
73112382Sralph 		while ((i = read(fd, line, sizeof(line))) > 0)
73212382Sralph 			(void) fwrite(line, 1, i, stdout);
73313168Sralph 		(void) close(fd);	/* unlocks as well */
73412382Sralph 	}
73512382Sralph }
73612382Sralph 
73712382Sralph /*
73812382Sralph  * Stop the specified daemon after completing the current job and disable
73912382Sralph  * printing.
74012382Sralph  */
74112382Sralph stop(argc, argv)
74212382Sralph 	char *argv[];
74312382Sralph {
74412382Sralph 	register int c, status;
74512382Sralph 	register char *cp1, *cp2;
74612382Sralph 	char prbuf[100];
74712382Sralph 
74812382Sralph 	if (argc == 1) {
74912382Sralph 		printf("Usage: stop {all | printer ...}\n");
75012382Sralph 		return;
75112382Sralph 	}
75212382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
75312382Sralph 		printer = prbuf;
75412382Sralph 		while (getprent(line) > 0) {
75512382Sralph 			cp1 = prbuf;
75612382Sralph 			cp2 = line;
75712382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
75812382Sralph 				*cp1++ = c;
75912382Sralph 			*cp1 = '\0';
76012382Sralph 			stoppr();
76112382Sralph 		}
76212382Sralph 		return;
76312382Sralph 	}
76412382Sralph 	while (--argc) {
76512382Sralph 		printer = *++argv;
76612382Sralph 		if ((status = pgetent(line, printer)) < 0) {
76712514Sralph 			printf("cannot open printer description file\n");
76812382Sralph 			continue;
76912382Sralph 		} else if (status == 0) {
77012514Sralph 			printf("unknown printer %s\n", printer);
77112382Sralph 			continue;
77212382Sralph 		}
77312382Sralph 		stoppr();
77412382Sralph 	}
77512382Sralph }
77612382Sralph 
77712382Sralph stoppr()
77812382Sralph {
77912382Sralph 	register int fd;
78012382Sralph 	struct stat stbuf;
78112382Sralph 
78212382Sralph 	bp = pbuf;
78312382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
78437968Sbostic 		SD = _PATH_DEFSPOOL;
78512382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
78612382Sralph 		LO = DEFLOCK;
78712382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
78812382Sralph 	printf("%s:\n", printer);
78912382Sralph 
79012382Sralph 	/*
79112382Sralph 	 * Turn on the owner execute bit of the lock file to disable printing.
79212382Sralph 	 */
79312382Sralph 	if (stat(line, &stbuf) >= 0) {
79412382Sralph 		if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
79512382Sralph 			printf("\tcannot disable printing\n");
796*38735Stef 		else {
797*38735Stef 			upstat("printing disabled\n");
79812382Sralph 			printf("\tprinting disabled\n");
799*38735Stef 		}
80012382Sralph 	} else if (errno == ENOENT) {
80113146Ssam 		if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
80212382Sralph 			printf("\tcannot create lock file\n");
80312382Sralph 		else {
80412382Sralph 			(void) close(fd);
805*38735Stef 			upstat("printing disabled\n");
80612382Sralph 			printf("\tprinting disabled\n");
80712382Sralph 		}
80812382Sralph 	} else
80912382Sralph 		printf("\tcannot stat lock file\n");
81012382Sralph }
81113727Sroot 
81215719Sralph struct	queue **queue;
81315719Sralph int	nitems;
81415719Sralph time_t	mtime;
81515719Sralph 
81613727Sroot /*
81713727Sroot  * Put the specified jobs at the top of printer queue.
81813727Sroot  */
81913727Sroot topq(argc, argv)
82013727Sroot 	char *argv[];
82113727Sroot {
82215719Sralph 	register int n, i;
82313727Sroot 	struct stat stbuf;
82413727Sroot 	register char *cfname;
82515719Sralph 	int status, changed;
82613727Sroot 
82715719Sralph 	if (argc < 3) {
82813727Sroot 		printf("Usage: topq printer [jobnum ...] [user ...]\n");
82913727Sroot 		return;
83013727Sroot 	}
83113727Sroot 
83213727Sroot 	--argc;
83313727Sroot 	printer = *++argv;
83413727Sroot 	status = pgetent(line, printer);
83513727Sroot 	if (status < 0) {
83613727Sroot 		printf("cannot open printer description file\n");
83713727Sroot 		return;
83814151Sralph 	} else if (status == 0) {
83913727Sroot 		printf("%s: unknown printer\n", printer);
84013727Sroot 		return;
84113727Sroot 	}
84213727Sroot 	bp = pbuf;
84313727Sroot 	if ((SD = pgetstr("sd", &bp)) == NULL)
84437968Sbostic 		SD = _PATH_DEFSPOOL;
84513727Sroot 	if ((LO = pgetstr("lo", &bp)) == NULL)
84613727Sroot 		LO = DEFLOCK;
84713727Sroot 	printf("%s:\n", printer);
84813727Sroot 
84913727Sroot 	if (chdir(SD) < 0) {
85013727Sroot 		printf("\tcannot chdir to %s\n", SD);
85113727Sroot 		return;
85213727Sroot 	}
85313727Sroot 	nitems = getq(&queue);
85415719Sralph 	if (nitems == 0)
85515719Sralph 		return;
85615719Sralph 	changed = 0;
85715719Sralph 	mtime = queue[0]->q_time;
85815719Sralph 	for (i = argc; --i; ) {
85915719Sralph 		if (doarg(argv[i]) == 0) {
86015719Sralph 			printf("\tjob %s is not in the queue\n", argv[i]);
86113727Sroot 			continue;
86215719Sralph 		} else
86314151Sralph 			changed++;
86413727Sroot 	}
86515719Sralph 	for (i = 0; i < nitems; i++)
86615719Sralph 		free(queue[i]);
86715719Sralph 	free(queue);
86815719Sralph 	if (!changed) {
86915719Sralph 		printf("\tqueue order unchanged\n");
87015719Sralph 		return;
87113727Sroot 	}
87213727Sroot 	/*
87313727Sroot 	 * Turn on the public execute bit of the lock file to
87413727Sroot 	 * get lpd to rebuild the queue after the current job.
87513727Sroot 	 */
87614151Sralph 	if (changed && stat(LO, &stbuf) >= 0)
87714151Sralph 		(void) chmod(LO, (stbuf.st_mode & 0777) | 01);
87813727Sroot }
87913727Sroot 
88015719Sralph /*
88115719Sralph  * Reposition the job by changing the modification time of
88215719Sralph  * the control file.
88313727Sroot  */
88415719Sralph touch(q)
88515719Sralph 	struct queue *q;
88613727Sroot {
88715719Sralph 	struct timeval tvp[2];
88813727Sroot 
88915719Sralph 	tvp[0].tv_sec = tvp[1].tv_sec = --mtime;
89015719Sralph 	tvp[0].tv_usec = tvp[1].tv_usec = 0;
89115719Sralph 	return(utimes(q->q_name, tvp));
89213727Sroot }
89313727Sroot 
89413727Sroot /*
89513727Sroot  * Checks if specified job name is in the printer's queue.
89613727Sroot  * Returns:  negative (-1) if argument name is not in the queue.
89713727Sroot  */
89815719Sralph doarg(job)
89913727Sroot 	char *job;
90013727Sroot {
90115719Sralph 	register struct queue **qq;
90215719Sralph 	register int jobnum, n;
90315719Sralph 	register char *cp, *machine;
90415719Sralph 	int cnt = 0;
90514151Sralph 	FILE *fp;
90613727Sroot 
90715719Sralph 	/*
90815719Sralph 	 * Look for a job item consisting of system name, colon, number
90915719Sralph 	 * (example: ucbarpa:114)
91015719Sralph 	 */
91115719Sralph 	if ((cp = index(job, ':')) != NULL) {
91215719Sralph 		machine = job;
91315719Sralph 		*cp++ = '\0';
91415719Sralph 		job = cp;
91515719Sralph 	} else
91615719Sralph 		machine = NULL;
91715719Sralph 
91815719Sralph 	/*
91915719Sralph 	 * Check for job specified by number (example: 112 or 235ucbarpa).
92015719Sralph 	 */
92113727Sroot 	if (isdigit(*job)) {
92213727Sroot 		jobnum = 0;
92313727Sroot 		do
92413727Sroot 			jobnum = jobnum * 10 + (*job++ - '0');
92513727Sroot 		while (isdigit(*job));
92615719Sralph 		for (qq = queue + nitems; --qq >= queue; ) {
92713727Sroot 			n = 0;
92815719Sralph 			for (cp = (*qq)->q_name+3; isdigit(*cp); )
92914151Sralph 				n = n * 10 + (*cp++ - '0');
93015719Sralph 			if (jobnum != n)
93115719Sralph 				continue;
93215719Sralph 			if (*job && strcmp(job, cp) != 0)
93315719Sralph 				continue;
93415719Sralph 			if (machine != NULL && strcmp(machine, cp) != 0)
93515719Sralph 				continue;
93615719Sralph 			if (touch(*qq) == 0) {
93715719Sralph 				printf("\tmoved %s\n", (*qq)->q_name);
93815719Sralph 				cnt++;
93915719Sralph 			}
94013727Sroot 		}
94115719Sralph 		return(cnt);
94215719Sralph 	}
94315719Sralph 	/*
94415719Sralph 	 * Process item consisting of owner's name (example: henry).
94515719Sralph 	 */
94615719Sralph 	for (qq = queue + nitems; --qq >= queue; ) {
94715719Sralph 		if ((fp = fopen((*qq)->q_name, "r")) == NULL)
94813727Sroot 			continue;
94915719Sralph 		while (getline(fp) > 0)
95015719Sralph 			if (line[0] == 'P')
95115719Sralph 				break;
95215719Sralph 		(void) fclose(fp);
95315719Sralph 		if (line[0] != 'P' || strcmp(job, line+1) != 0)
95415719Sralph 			continue;
95515719Sralph 		if (touch(*qq) == 0) {
95615719Sralph 			printf("\tmoved %s\n", (*qq)->q_name);
95715719Sralph 			cnt++;
95813727Sroot 		}
95913727Sroot 	}
96015719Sralph 	return(cnt);
96113727Sroot }
96216755Sralph 
96316755Sralph /*
96416755Sralph  * Enable everything and start printer (undo `down').
96516755Sralph  */
96616755Sralph up(argc, argv)
96716755Sralph 	char *argv[];
96816755Sralph {
96916755Sralph 	register int c, status;
97016755Sralph 	register char *cp1, *cp2;
97116755Sralph 	char prbuf[100];
97216755Sralph 
97316755Sralph 	if (argc == 1) {
97416755Sralph 		printf("Usage: up {all | printer ...}\n");
97516755Sralph 		return;
97616755Sralph 	}
97716755Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
97816755Sralph 		printer = prbuf;
97916755Sralph 		while (getprent(line) > 0) {
98016755Sralph 			cp1 = prbuf;
98116755Sralph 			cp2 = line;
98216755Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
98316755Sralph 				*cp1++ = c;
98416755Sralph 			*cp1 = '\0';
98516755Sralph 			startpr(2);
98616755Sralph 		}
98716755Sralph 		return;
98816755Sralph 	}
98916755Sralph 	while (--argc) {
99016755Sralph 		printer = *++argv;
99116755Sralph 		if ((status = pgetent(line, printer)) < 0) {
99216755Sralph 			printf("cannot open printer description file\n");
99316755Sralph 			continue;
99416755Sralph 		} else if (status == 0) {
99516755Sralph 			printf("unknown printer %s\n", printer);
99616755Sralph 			continue;
99716755Sralph 		}
99816755Sralph 		startpr(2);
99916755Sralph 	}
100016755Sralph }
1001