xref: /csrg-svn/usr.sbin/lpr/lpc/cmds.c (revision 42801)
122424Sdist /*
222424Sdist  * Copyright (c) 1983 Regents of the University of California.
334203Sbostic  * All rights reserved.
434203Sbostic  *
5*42801Sbostic  * %sccs.include.redist.c%
622424Sdist  */
722424Sdist 
812382Sralph #ifndef lint
9*42801Sbostic static char sccsid[] = "@(#)cmds.c	5.7 (Berkeley) 06/01/90";
1034203Sbostic #endif /* not lint */
1112382Sralph 
1212382Sralph /*
1315719Sralph  * lpc -- line printer control program -- commands:
1412382Sralph  */
1512382Sralph 
1612382Sralph #include "lp.h"
1715719Sralph #include <sys/time.h>
1837968Sbostic #include "pathnames.h"
1912382Sralph 
2012382Sralph /*
2112382Sralph  * kill an existing daemon and disable printing.
2212382Sralph  */
2312382Sralph abort(argc, argv)
2412382Sralph 	char *argv[];
2512382Sralph {
2612382Sralph 	register int c, status;
2712382Sralph 	register char *cp1, *cp2;
2812382Sralph 	char prbuf[100];
2912382Sralph 
3012382Sralph 	if (argc == 1) {
3112382Sralph 		printf("Usage: abort {all | printer ...}\n");
3212382Sralph 		return;
3312382Sralph 	}
3412382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
3512382Sralph 		printer = prbuf;
3612382Sralph 		while (getprent(line) > 0) {
3712382Sralph 			cp1 = prbuf;
3812382Sralph 			cp2 = line;
3912382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
4012382Sralph 				*cp1++ = c;
4112382Sralph 			*cp1 = '\0';
4216755Sralph 			abortpr(1);
4312382Sralph 		}
4412382Sralph 		return;
4512382Sralph 	}
4612382Sralph 	while (--argc) {
4712382Sralph 		printer = *++argv;
4812382Sralph 		if ((status = pgetent(line, printer)) < 0) {
4912514Sralph 			printf("cannot open printer description file\n");
5012382Sralph 			continue;
5112382Sralph 		} else if (status == 0) {
5212514Sralph 			printf("unknown printer %s\n", printer);
5312382Sralph 			continue;
5412382Sralph 		}
5516755Sralph 		abortpr(1);
5612382Sralph 	}
5712382Sralph }
5812382Sralph 
5916755Sralph abortpr(dis)
6012382Sralph {
6112382Sralph 	register FILE *fp;
6212382Sralph 	struct stat stbuf;
6312382Sralph 	int pid, fd;
6412382Sralph 
6512382Sralph 	bp = pbuf;
6612382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
6737968Sbostic 		SD = _PATH_DEFSPOOL;
6812382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
6912382Sralph 		LO = DEFLOCK;
7012382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
7112382Sralph 	printf("%s:\n", printer);
7212382Sralph 
7312382Sralph 	/*
7412382Sralph 	 * Turn on the owner execute bit of the lock file to disable printing.
7512382Sralph 	 */
7616755Sralph 	if (dis) {
7716755Sralph 		if (stat(line, &stbuf) >= 0) {
7816755Sralph 			if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
7916755Sralph 				printf("\tcannot disable printing\n");
8038735Stef 			else {
8138735Stef 				upstat("printing disabled\n");
8216755Sralph 				printf("\tprinting disabled\n");
8338735Stef 			}
8416755Sralph 		} else if (errno == ENOENT) {
8516755Sralph 			if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
8616755Sralph 				printf("\tcannot create lock file\n");
8716755Sralph 			else {
8816755Sralph 				(void) close(fd);
8938735Stef 				upstat("printing disabled\n");
9016755Sralph 				printf("\tprinting disabled\n");
9116755Sralph 				printf("\tno daemon to abort\n");
9216755Sralph 			}
9316755Sralph 			return;
9416755Sralph 		} else {
9516755Sralph 			printf("\tcannot stat lock file\n");
9616755Sralph 			return;
9712382Sralph 		}
9812382Sralph 	}
9912382Sralph 	/*
10012382Sralph 	 * Kill the current daemon to stop printing now.
10112382Sralph 	 */
10212382Sralph 	if ((fp = fopen(line, "r")) == NULL) {
10312382Sralph 		printf("\tcannot open lock file\n");
10412382Sralph 		return;
10512382Sralph 	}
10613146Ssam 	if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) {
10713168Sralph 		(void) fclose(fp);	/* unlocks as well */
10812382Sralph 		printf("\tno daemon to abort\n");
10912382Sralph 		return;
11012382Sralph 	}
11112382Sralph 	(void) fclose(fp);
11216755Sralph 	if (kill(pid = atoi(line), SIGTERM) < 0)
11312382Sralph 		printf("\tWarning: daemon (pid %d) not killed\n", pid);
11412382Sralph 	else
11512382Sralph 		printf("\tdaemon (pid %d) killed\n", pid);
11612382Sralph }
11712382Sralph 
11812382Sralph /*
11938735Stef  * Write a message into the status file.
12038735Stef  */
12138735Stef upstat(msg)
12238735Stef 	char *msg;
12338735Stef {
12438735Stef 	register int fd;
12538735Stef 	char statfile[BUFSIZ];
12638735Stef 
12738735Stef 	bp = pbuf;
12838735Stef 	if ((ST = pgetstr("st", &bp)) == NULL)
12938735Stef 		ST = DEFSTAT;
13038735Stef 	(void) sprintf(statfile, "%s/%s", SD, ST);
13138735Stef 	umask(0);
13238735Stef 	fd = open(statfile, O_WRONLY|O_CREAT, 0664);
13338735Stef 	if (fd < 0 || flock(fd, LOCK_EX) < 0) {
13438735Stef 		printf("\tcannot create status file\n");
13538735Stef 		return;
13638735Stef 	}
13738735Stef 	(void) ftruncate(fd, 0);
13838735Stef 	if (msg == (char *)NULL)
13938735Stef 		(void) write(fd, "\n", 1);
14038735Stef 	else
14138735Stef 		(void) write(fd, msg, strlen(msg));
14238735Stef 	(void) close(fd);
14338735Stef }
14438735Stef 
14538735Stef /*
14612382Sralph  * Remove all spool files and temporaries from the spooling area.
14712382Sralph  */
14812382Sralph clean(argc, argv)
14912382Sralph 	char *argv[];
15012382Sralph {
15112382Sralph 	register int c, status;
15212382Sralph 	register char *cp1, *cp2;
15312382Sralph 	char prbuf[100];
15412382Sralph 
15512382Sralph 	if (argc == 1) {
15612382Sralph 		printf("Usage: clean {all | printer ...}\n");
15712382Sralph 		return;
15812382Sralph 	}
15912382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
16012382Sralph 		printer = prbuf;
16112382Sralph 		while (getprent(line) > 0) {
16212382Sralph 			cp1 = prbuf;
16312382Sralph 			cp2 = line;
16412382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
16512382Sralph 				*cp1++ = c;
16612382Sralph 			*cp1 = '\0';
16712382Sralph 			cleanpr();
16812382Sralph 		}
16912382Sralph 		return;
17012382Sralph 	}
17112382Sralph 	while (--argc) {
17212382Sralph 		printer = *++argv;
17312382Sralph 		if ((status = pgetent(line, printer)) < 0) {
17412514Sralph 			printf("cannot open printer description file\n");
17512382Sralph 			continue;
17612382Sralph 		} else if (status == 0) {
17712514Sralph 			printf("unknown printer %s\n", printer);
17812382Sralph 			continue;
17912382Sralph 		}
18012382Sralph 		cleanpr();
18112382Sralph 	}
18212382Sralph }
18312382Sralph 
18415719Sralph select(d)
18515719Sralph struct direct *d;
18615719Sralph {
18715719Sralph 	int c = d->d_name[0];
18815719Sralph 
18915719Sralph 	if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f')
19015719Sralph 		return(1);
19115719Sralph 	return(0);
19215719Sralph }
19315719Sralph 
19415719Sralph /*
19515719Sralph  * Comparison routine for scandir. Sort by job number and machine, then
19615719Sralph  * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z.
19715719Sralph  */
19815719Sralph sortq(d1, d2)
19915719Sralph struct direct **d1, **d2;
20015719Sralph {
20115719Sralph 	int c1, c2;
20215719Sralph 
20315719Sralph 	if (c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3))
20415719Sralph 		return(c1);
20515719Sralph 	c1 = (*d1)->d_name[0];
20615719Sralph 	c2 = (*d2)->d_name[0];
20715719Sralph 	if (c1 == c2)
20815719Sralph 		return((*d1)->d_name[2] - (*d2)->d_name[2]);
20915719Sralph 	if (c1 == 'c')
21015719Sralph 		return(-1);
21115719Sralph 	if (c1 == 'd' || c2 == 'c')
21215719Sralph 		return(1);
21315719Sralph 	return(-1);
21415719Sralph }
21515719Sralph 
21615719Sralph /*
21715719Sralph  * Remove incomplete jobs from spooling area.
21815719Sralph  */
21912382Sralph cleanpr()
22012382Sralph {
22115719Sralph 	register int i, n;
22215719Sralph 	register char *cp, *cp1, *lp;
22315719Sralph 	struct direct **queue;
22415719Sralph 	int nitems;
22512382Sralph 
22612382Sralph 	bp = pbuf;
22712382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
22837968Sbostic 		SD = _PATH_DEFSPOOL;
22912382Sralph 	printf("%s:\n", printer);
23012382Sralph 
23115719Sralph 	for (lp = line, cp = SD; *lp++ = *cp++; )
23215719Sralph 		;
23315719Sralph 	lp[-1] = '/';
23415719Sralph 
23515719Sralph 	nitems = scandir(SD, &queue, select, sortq);
23615719Sralph 	if (nitems < 0) {
23712382Sralph 		printf("\tcannot examine spool directory\n");
23812382Sralph 		return;
23912382Sralph 	}
24015719Sralph 	if (nitems == 0)
24115719Sralph 		return;
24215719Sralph 	i = 0;
24315719Sralph 	do {
24415719Sralph 		cp = queue[i]->d_name;
24515719Sralph 		if (*cp == 'c') {
24615719Sralph 			n = 0;
24715719Sralph 			while (i + 1 < nitems) {
24815719Sralph 				cp1 = queue[i + 1]->d_name;
24915719Sralph 				if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3))
25015719Sralph 					break;
25115719Sralph 				i++;
25215719Sralph 				n++;
25315719Sralph 			}
25415719Sralph 			if (n == 0) {
25515719Sralph 				strcpy(lp, cp);
25615719Sralph 				unlinkf(line);
25715719Sralph 			}
25815719Sralph 		} else {
25915719Sralph 			/*
26015719Sralph 			 * Must be a df with no cf (otherwise, it would have
26115719Sralph 			 * been skipped above) or a tf file (which can always
26215719Sralph 			 * be removed).
26315719Sralph 			 */
26415719Sralph 			strcpy(lp, cp);
26515719Sralph 			unlinkf(line);
26612382Sralph 		}
26715719Sralph      	} while (++i < nitems);
26812382Sralph }
26915719Sralph 
27015719Sralph unlinkf(name)
27115719Sralph 	char	*name;
27215719Sralph {
27315719Sralph 	if (unlink(name) < 0)
27415719Sralph 		printf("\tcannot remove %s\n", name);
27515719Sralph 	else
27615719Sralph 		printf("\tremoved %s\n", name);
27715719Sralph }
27812382Sralph 
27912382Sralph /*
28012382Sralph  * Enable queuing to the printer (allow lpr's).
28112382Sralph  */
28212382Sralph enable(argc, argv)
28312382Sralph 	char *argv[];
28412382Sralph {
28512382Sralph 	register int c, status;
28612382Sralph 	register char *cp1, *cp2;
28712382Sralph 	char prbuf[100];
28812382Sralph 
28912382Sralph 	if (argc == 1) {
29012382Sralph 		printf("Usage: enable {all | printer ...}\n");
29112382Sralph 		return;
29212382Sralph 	}
29312382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
29412382Sralph 		printer = prbuf;
29512382Sralph 		while (getprent(line) > 0) {
29612382Sralph 			cp1 = prbuf;
29712382Sralph 			cp2 = line;
29812382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
29912382Sralph 				*cp1++ = c;
30012382Sralph 			*cp1 = '\0';
30112382Sralph 			enablepr();
30212382Sralph 		}
30312382Sralph 		return;
30412382Sralph 	}
30512382Sralph 	while (--argc) {
30612382Sralph 		printer = *++argv;
30712382Sralph 		if ((status = pgetent(line, printer)) < 0) {
30812514Sralph 			printf("cannot open printer description file\n");
30912382Sralph 			continue;
31012382Sralph 		} else if (status == 0) {
31112514Sralph 			printf("unknown printer %s\n", printer);
31212382Sralph 			continue;
31312382Sralph 		}
31412382Sralph 		enablepr();
31512382Sralph 	}
31612382Sralph }
31712382Sralph 
31812382Sralph enablepr()
31912382Sralph {
32012382Sralph 	struct stat stbuf;
32112382Sralph 
32212382Sralph 	bp = pbuf;
32312382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
32437968Sbostic 		SD = _PATH_DEFSPOOL;
32512382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
32612382Sralph 		LO = DEFLOCK;
32712382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
32812382Sralph 	printf("%s:\n", printer);
32912382Sralph 
33012382Sralph 	/*
33112382Sralph 	 * Turn off the group execute bit of the lock file to enable queuing.
33212382Sralph 	 */
33312382Sralph 	if (stat(line, &stbuf) >= 0) {
33412382Sralph 		if (chmod(line, stbuf.st_mode & 0767) < 0)
33512514Sralph 			printf("\tcannot enable queuing\n");
33612382Sralph 		else
33712382Sralph 			printf("\tqueuing enabled\n");
33812382Sralph 	}
33912382Sralph }
34012382Sralph 
34112382Sralph /*
34212382Sralph  * Disable queuing.
34312382Sralph  */
34412382Sralph disable(argc, argv)
34512382Sralph 	char *argv[];
34612382Sralph {
34712382Sralph 	register int c, status;
34812382Sralph 	register char *cp1, *cp2;
34912382Sralph 	char prbuf[100];
35012382Sralph 
35112382Sralph 	if (argc == 1) {
35212382Sralph 		printf("Usage: disable {all | printer ...}\n");
35312382Sralph 		return;
35412382Sralph 	}
35512382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
35612382Sralph 		printer = prbuf;
35712382Sralph 		while (getprent(line) > 0) {
35812382Sralph 			cp1 = prbuf;
35912382Sralph 			cp2 = line;
36012382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
36112382Sralph 				*cp1++ = c;
36212382Sralph 			*cp1 = '\0';
36312382Sralph 			disablepr();
36412382Sralph 		}
36512382Sralph 		return;
36612382Sralph 	}
36712382Sralph 	while (--argc) {
36812382Sralph 		printer = *++argv;
36912382Sralph 		if ((status = pgetent(line, printer)) < 0) {
37012514Sralph 			printf("cannot open printer description file\n");
37112382Sralph 			continue;
37212382Sralph 		} else if (status == 0) {
37312514Sralph 			printf("unknown printer %s\n", printer);
37412382Sralph 			continue;
37512382Sralph 		}
37612382Sralph 		disablepr();
37712382Sralph 	}
37812382Sralph }
37912382Sralph 
38012382Sralph disablepr()
38112382Sralph {
38212382Sralph 	register int fd;
38312382Sralph 	struct stat stbuf;
38412382Sralph 
38512382Sralph 	bp = pbuf;
38612382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
38737968Sbostic 		SD = _PATH_DEFSPOOL;
38812382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
38912382Sralph 		LO = DEFLOCK;
39012382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
39112382Sralph 	printf("%s:\n", printer);
39212382Sralph 	/*
39312382Sralph 	 * Turn on the group execute bit of the lock file to disable queuing.
39412382Sralph 	 */
39512382Sralph 	if (stat(line, &stbuf) >= 0) {
39612382Sralph 		if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0)
39712382Sralph 			printf("\tcannot disable queuing\n");
39812382Sralph 		else
39912382Sralph 			printf("\tqueuing disabled\n");
40012382Sralph 	} else if (errno == ENOENT) {
40113146Ssam 		if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0)
40212382Sralph 			printf("\tcannot create lock file\n");
40312382Sralph 		else {
40412382Sralph 			(void) close(fd);
40512382Sralph 			printf("\tqueuing disabled\n");
40612382Sralph 		}
40712382Sralph 		return;
40812382Sralph 	} else
40912382Sralph 		printf("\tcannot stat lock file\n");
41012382Sralph }
41112382Sralph 
41212382Sralph /*
41315907Sralph  * Disable queuing and printing and put a message into the status file
41415907Sralph  * (reason for being down).
41515907Sralph  */
41615907Sralph down(argc, argv)
41715907Sralph 	char *argv[];
41815907Sralph {
41915907Sralph 	register int c, status;
42015907Sralph 	register char *cp1, *cp2;
42115907Sralph 	char prbuf[100];
42215907Sralph 
42315907Sralph 	if (argc == 1) {
42416204Sralph 		printf("Usage: down {all | printer} [message ...]\n");
42515907Sralph 		return;
42615907Sralph 	}
42715907Sralph 	if (!strcmp(argv[1], "all")) {
42815907Sralph 		printer = prbuf;
42915907Sralph 		while (getprent(line) > 0) {
43015907Sralph 			cp1 = prbuf;
43115907Sralph 			cp2 = line;
43215907Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
43315907Sralph 				*cp1++ = c;
43415907Sralph 			*cp1 = '\0';
43515907Sralph 			putmsg(argc - 2, argv + 2);
43615907Sralph 		}
43715907Sralph 		return;
43815907Sralph 	}
43915907Sralph 	printer = argv[1];
44015907Sralph 	if ((status = pgetent(line, printer)) < 0) {
44115907Sralph 		printf("cannot open printer description file\n");
44215907Sralph 		return;
44315907Sralph 	} else if (status == 0) {
44415907Sralph 		printf("unknown printer %s\n", printer);
44515907Sralph 		return;
44615907Sralph 	}
44715907Sralph 	putmsg(argc - 2, argv + 2);
44815907Sralph }
44915907Sralph 
45015907Sralph putmsg(argc, argv)
45115907Sralph 	char **argv;
45215907Sralph {
45315907Sralph 	register int fd;
45415907Sralph 	register char *cp1, *cp2;
45515907Sralph 	char buf[1024];
45615907Sralph 	struct stat stbuf;
45715907Sralph 
45815907Sralph 	bp = pbuf;
45915907Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
46037968Sbostic 		SD = _PATH_DEFSPOOL;
46115907Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
46215907Sralph 		LO = DEFLOCK;
46315907Sralph 	if ((ST = pgetstr("st", &bp)) == NULL)
46415907Sralph 		ST = DEFSTAT;
46515907Sralph 	printf("%s:\n", printer);
46615907Sralph 	/*
46715907Sralph 	 * Turn on the group execute bit of the lock file to disable queuing and
46815907Sralph 	 * turn on the owner execute bit of the lock file to disable printing.
46915907Sralph 	 */
47015907Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
47115907Sralph 	if (stat(line, &stbuf) >= 0) {
47215907Sralph 		if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0)
47315907Sralph 			printf("\tcannot disable queuing\n");
47415907Sralph 		else
47515907Sralph 			printf("\tprinter and queuing disabled\n");
47615907Sralph 	} else if (errno == ENOENT) {
47715907Sralph 		if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0)
47815907Sralph 			printf("\tcannot create lock file\n");
47915907Sralph 		else {
48015907Sralph 			(void) close(fd);
48115907Sralph 			printf("\tprinter and queuing disabled\n");
48215907Sralph 		}
48315907Sralph 		return;
48415907Sralph 	} else
48515907Sralph 		printf("\tcannot stat lock file\n");
48615907Sralph 	/*
48715907Sralph 	 * Write the message into the status file.
48815907Sralph 	 */
48915907Sralph 	(void) sprintf(line, "%s/%s", SD, ST);
49015907Sralph 	fd = open(line, O_WRONLY|O_CREAT, 0664);
49115907Sralph 	if (fd < 0 || flock(fd, LOCK_EX) < 0) {
49215907Sralph 		printf("\tcannot create status file\n");
49315907Sralph 		return;
49415907Sralph 	}
49515907Sralph 	(void) ftruncate(fd, 0);
49616204Sralph 	if (argc <= 0) {
49716204Sralph 		(void) write(fd, "\n", 1);
49816204Sralph 		(void) close(fd);
49916204Sralph 		return;
50016204Sralph 	}
50115907Sralph 	cp1 = buf;
50215907Sralph 	while (--argc >= 0) {
50315907Sralph 		cp2 = *argv++;
50415907Sralph 		while (*cp1++ = *cp2++)
50515907Sralph 			;
50615907Sralph 		cp1[-1] = ' ';
50715907Sralph 	}
50815907Sralph 	cp1[-1] = '\n';
50915907Sralph 	*cp1 = '\0';
51015907Sralph 	(void) write(fd, buf, strlen(buf));
51115907Sralph 	(void) close(fd);
51215907Sralph }
51315907Sralph 
51415907Sralph /*
51512382Sralph  * Exit lpc
51612382Sralph  */
51712382Sralph quit(argc, argv)
51812382Sralph 	char *argv[];
51912382Sralph {
52012382Sralph 	exit(0);
52112382Sralph }
52212382Sralph 
52312382Sralph /*
52416755Sralph  * Kill and restart the daemon.
52512382Sralph  */
52612382Sralph restart(argc, argv)
52712382Sralph 	char *argv[];
52812382Sralph {
52912382Sralph 	register int c, status;
53012382Sralph 	register char *cp1, *cp2;
53112382Sralph 	char prbuf[100];
53212382Sralph 
53312382Sralph 	if (argc == 1) {
53412382Sralph 		printf("Usage: restart {all | printer ...}\n");
53512382Sralph 		return;
53612382Sralph 	}
53712382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
53812382Sralph 		printer = prbuf;
53912382Sralph 		while (getprent(line) > 0) {
54012382Sralph 			cp1 = prbuf;
54112382Sralph 			cp2 = line;
54212382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
54312382Sralph 				*cp1++ = c;
54412382Sralph 			*cp1 = '\0';
54516755Sralph 			abortpr(0);
54612382Sralph 			startpr(0);
54712382Sralph 		}
54812382Sralph 		return;
54912382Sralph 	}
55012382Sralph 	while (--argc) {
55112382Sralph 		printer = *++argv;
55212382Sralph 		if ((status = pgetent(line, printer)) < 0) {
55312514Sralph 			printf("cannot open printer description file\n");
55412382Sralph 			continue;
55512382Sralph 		} else if (status == 0) {
55612514Sralph 			printf("unknown printer %s\n", printer);
55712382Sralph 			continue;
55812382Sralph 		}
55916755Sralph 		abortpr(0);
56012382Sralph 		startpr(0);
56112382Sralph 	}
56212382Sralph }
56312382Sralph 
56412382Sralph /*
56512382Sralph  * Enable printing on the specified printer and startup the daemon.
56612382Sralph  */
56712382Sralph start(argc, argv)
56812382Sralph 	char *argv[];
56912382Sralph {
57012382Sralph 	register int c, status;
57112382Sralph 	register char *cp1, *cp2;
57212382Sralph 	char prbuf[100];
57312382Sralph 
57412382Sralph 	if (argc == 1) {
57512382Sralph 		printf("Usage: start {all | printer ...}\n");
57612382Sralph 		return;
57712382Sralph 	}
57812382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
57912382Sralph 		printer = prbuf;
58012382Sralph 		while (getprent(line) > 0) {
58112382Sralph 			cp1 = prbuf;
58212382Sralph 			cp2 = line;
58312382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
58412382Sralph 				*cp1++ = c;
58512382Sralph 			*cp1 = '\0';
58612382Sralph 			startpr(1);
58712382Sralph 		}
58812382Sralph 		return;
58912382Sralph 	}
59012382Sralph 	while (--argc) {
59112382Sralph 		printer = *++argv;
59212382Sralph 		if ((status = pgetent(line, printer)) < 0) {
59312514Sralph 			printf("cannot open printer description file\n");
59412382Sralph 			continue;
59512382Sralph 		} else if (status == 0) {
59612514Sralph 			printf("unknown printer %s\n", printer);
59712382Sralph 			continue;
59812382Sralph 		}
59912382Sralph 		startpr(1);
60012382Sralph 	}
60112382Sralph }
60212382Sralph 
60312382Sralph startpr(enable)
60412382Sralph {
60512382Sralph 	struct stat stbuf;
60612382Sralph 
60712382Sralph 	bp = pbuf;
60812382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
60937968Sbostic 		SD = _PATH_DEFSPOOL;
61012382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
61112382Sralph 		LO = DEFLOCK;
61212382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
61312382Sralph 	printf("%s:\n", printer);
61412382Sralph 
61512382Sralph 	/*
61612382Sralph 	 * Turn off the owner execute bit of the lock file to enable printing.
61712382Sralph 	 */
61812382Sralph 	if (enable && stat(line, &stbuf) >= 0) {
61916771Sralph 		if (chmod(line, stbuf.st_mode & (enable==2 ? 0666 : 0677)) < 0)
62012382Sralph 			printf("\tcannot enable printing\n");
62112382Sralph 		else
62212382Sralph 			printf("\tprinting enabled\n");
62312382Sralph 	}
62413727Sroot 	if (!startdaemon(printer))
62512382Sralph 		printf("\tcouldn't start daemon\n");
62612382Sralph 	else
62712382Sralph 		printf("\tdaemon started\n");
62812382Sralph }
62912382Sralph 
63012382Sralph /*
63112382Sralph  * Print the status of each queue listed or all the queues.
63212382Sralph  */
63312382Sralph status(argc, argv)
63412382Sralph 	char *argv[];
63512382Sralph {
63612382Sralph 	register int c, status;
63712382Sralph 	register char *cp1, *cp2;
63812382Sralph 	char prbuf[100];
63912382Sralph 
64012382Sralph 	if (argc == 1) {
64112382Sralph 		printer = prbuf;
64212382Sralph 		while (getprent(line) > 0) {
64312382Sralph 			cp1 = prbuf;
64412382Sralph 			cp2 = line;
64512382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
64612382Sralph 				*cp1++ = c;
64712382Sralph 			*cp1 = '\0';
64812382Sralph 			prstat();
64912382Sralph 		}
65012382Sralph 		return;
65112382Sralph 	}
65212382Sralph 	while (--argc) {
65312382Sralph 		printer = *++argv;
65412382Sralph 		if ((status = pgetent(line, printer)) < 0) {
65512514Sralph 			printf("cannot open printer description file\n");
65612382Sralph 			continue;
65712382Sralph 		} else if (status == 0) {
65812514Sralph 			printf("unknown printer %s\n", printer);
65912382Sralph 			continue;
66012382Sralph 		}
66112382Sralph 		prstat();
66212382Sralph 	}
66312382Sralph }
66412382Sralph 
66512382Sralph /*
66612382Sralph  * Print the status of the printer queue.
66712382Sralph  */
66812382Sralph prstat()
66912382Sralph {
67012382Sralph 	struct stat stbuf;
67112382Sralph 	register int fd, i;
67212382Sralph 	register struct direct *dp;
67312382Sralph 	DIR *dirp;
67412382Sralph 
67512382Sralph 	bp = pbuf;
67612382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
67737968Sbostic 		SD = _PATH_DEFSPOOL;
67812382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
67912382Sralph 		LO = DEFLOCK;
68012382Sralph 	if ((ST = pgetstr("st", &bp)) == NULL)
68112382Sralph 		ST = DEFSTAT;
68212382Sralph 	printf("%s:\n", printer);
68312382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
68412382Sralph 	if (stat(line, &stbuf) >= 0) {
68512382Sralph 		printf("\tqueuing is %s\n",
68612382Sralph 			(stbuf.st_mode & 010) ? "disabled" : "enabled");
68712382Sralph 		printf("\tprinting is %s\n",
68812382Sralph 			(stbuf.st_mode & 0100) ? "disabled" : "enabled");
68912382Sralph 	} else {
69012382Sralph 		printf("\tqueuing is enabled\n");
69112382Sralph 		printf("\tprinting is enabled\n");
69212382Sralph 	}
69312382Sralph 	if ((dirp = opendir(SD)) == NULL) {
69412382Sralph 		printf("\tcannot examine spool directory\n");
69512382Sralph 		return;
69612382Sralph 	}
69712382Sralph 	i = 0;
69812382Sralph 	while ((dp = readdir(dirp)) != NULL) {
69912382Sralph 		if (*dp->d_name == 'c' && dp->d_name[1] == 'f')
70012382Sralph 			i++;
70112382Sralph 	}
70212382Sralph 	closedir(dirp);
70312382Sralph 	if (i == 0)
70412382Sralph 		printf("\tno entries\n");
70512382Sralph 	else if (i == 1)
70612382Sralph 		printf("\t1 entry in spool area\n");
70712382Sralph 	else
70812382Sralph 		printf("\t%d entries in spool area\n", i);
70913146Ssam 	fd = open(line, O_RDONLY);
71013146Ssam 	if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) {
71113168Sralph 		(void) close(fd);	/* unlocks as well */
71212382Sralph 		printf("\tno daemon present\n");
71312382Sralph 		return;
71412382Sralph 	}
71512382Sralph 	(void) close(fd);
71612382Sralph 	putchar('\t');
71712382Sralph 	(void) sprintf(line, "%s/%s", SD, ST);
71813146Ssam 	fd = open(line, O_RDONLY);
71913146Ssam 	if (fd >= 0) {
72013146Ssam 		(void) flock(fd, LOCK_SH);
72112382Sralph 		while ((i = read(fd, line, sizeof(line))) > 0)
72212382Sralph 			(void) fwrite(line, 1, i, stdout);
72313168Sralph 		(void) close(fd);	/* unlocks as well */
72412382Sralph 	}
72512382Sralph }
72612382Sralph 
72712382Sralph /*
72812382Sralph  * Stop the specified daemon after completing the current job and disable
72912382Sralph  * printing.
73012382Sralph  */
73112382Sralph stop(argc, argv)
73212382Sralph 	char *argv[];
73312382Sralph {
73412382Sralph 	register int c, status;
73512382Sralph 	register char *cp1, *cp2;
73612382Sralph 	char prbuf[100];
73712382Sralph 
73812382Sralph 	if (argc == 1) {
73912382Sralph 		printf("Usage: stop {all | printer ...}\n");
74012382Sralph 		return;
74112382Sralph 	}
74212382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
74312382Sralph 		printer = prbuf;
74412382Sralph 		while (getprent(line) > 0) {
74512382Sralph 			cp1 = prbuf;
74612382Sralph 			cp2 = line;
74712382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
74812382Sralph 				*cp1++ = c;
74912382Sralph 			*cp1 = '\0';
75012382Sralph 			stoppr();
75112382Sralph 		}
75212382Sralph 		return;
75312382Sralph 	}
75412382Sralph 	while (--argc) {
75512382Sralph 		printer = *++argv;
75612382Sralph 		if ((status = pgetent(line, printer)) < 0) {
75712514Sralph 			printf("cannot open printer description file\n");
75812382Sralph 			continue;
75912382Sralph 		} else if (status == 0) {
76012514Sralph 			printf("unknown printer %s\n", printer);
76112382Sralph 			continue;
76212382Sralph 		}
76312382Sralph 		stoppr();
76412382Sralph 	}
76512382Sralph }
76612382Sralph 
76712382Sralph stoppr()
76812382Sralph {
76912382Sralph 	register int fd;
77012382Sralph 	struct stat stbuf;
77112382Sralph 
77212382Sralph 	bp = pbuf;
77312382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
77437968Sbostic 		SD = _PATH_DEFSPOOL;
77512382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
77612382Sralph 		LO = DEFLOCK;
77712382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
77812382Sralph 	printf("%s:\n", printer);
77912382Sralph 
78012382Sralph 	/*
78112382Sralph 	 * Turn on the owner execute bit of the lock file to disable printing.
78212382Sralph 	 */
78312382Sralph 	if (stat(line, &stbuf) >= 0) {
78412382Sralph 		if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
78512382Sralph 			printf("\tcannot disable printing\n");
78638735Stef 		else {
78738735Stef 			upstat("printing disabled\n");
78812382Sralph 			printf("\tprinting disabled\n");
78938735Stef 		}
79012382Sralph 	} else if (errno == ENOENT) {
79113146Ssam 		if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
79212382Sralph 			printf("\tcannot create lock file\n");
79312382Sralph 		else {
79412382Sralph 			(void) close(fd);
79538735Stef 			upstat("printing disabled\n");
79612382Sralph 			printf("\tprinting disabled\n");
79712382Sralph 		}
79812382Sralph 	} else
79912382Sralph 		printf("\tcannot stat lock file\n");
80012382Sralph }
80113727Sroot 
80215719Sralph struct	queue **queue;
80315719Sralph int	nitems;
80415719Sralph time_t	mtime;
80515719Sralph 
80613727Sroot /*
80713727Sroot  * Put the specified jobs at the top of printer queue.
80813727Sroot  */
80913727Sroot topq(argc, argv)
81013727Sroot 	char *argv[];
81113727Sroot {
81215719Sralph 	register int n, i;
81313727Sroot 	struct stat stbuf;
81413727Sroot 	register char *cfname;
81515719Sralph 	int status, changed;
81613727Sroot 
81715719Sralph 	if (argc < 3) {
81813727Sroot 		printf("Usage: topq printer [jobnum ...] [user ...]\n");
81913727Sroot 		return;
82013727Sroot 	}
82113727Sroot 
82213727Sroot 	--argc;
82313727Sroot 	printer = *++argv;
82413727Sroot 	status = pgetent(line, printer);
82513727Sroot 	if (status < 0) {
82613727Sroot 		printf("cannot open printer description file\n");
82713727Sroot 		return;
82814151Sralph 	} else if (status == 0) {
82913727Sroot 		printf("%s: unknown printer\n", printer);
83013727Sroot 		return;
83113727Sroot 	}
83213727Sroot 	bp = pbuf;
83313727Sroot 	if ((SD = pgetstr("sd", &bp)) == NULL)
83437968Sbostic 		SD = _PATH_DEFSPOOL;
83513727Sroot 	if ((LO = pgetstr("lo", &bp)) == NULL)
83613727Sroot 		LO = DEFLOCK;
83713727Sroot 	printf("%s:\n", printer);
83813727Sroot 
83913727Sroot 	if (chdir(SD) < 0) {
84013727Sroot 		printf("\tcannot chdir to %s\n", SD);
84113727Sroot 		return;
84213727Sroot 	}
84313727Sroot 	nitems = getq(&queue);
84415719Sralph 	if (nitems == 0)
84515719Sralph 		return;
84615719Sralph 	changed = 0;
84715719Sralph 	mtime = queue[0]->q_time;
84815719Sralph 	for (i = argc; --i; ) {
84915719Sralph 		if (doarg(argv[i]) == 0) {
85015719Sralph 			printf("\tjob %s is not in the queue\n", argv[i]);
85113727Sroot 			continue;
85215719Sralph 		} else
85314151Sralph 			changed++;
85413727Sroot 	}
85515719Sralph 	for (i = 0; i < nitems; i++)
85615719Sralph 		free(queue[i]);
85715719Sralph 	free(queue);
85815719Sralph 	if (!changed) {
85915719Sralph 		printf("\tqueue order unchanged\n");
86015719Sralph 		return;
86113727Sroot 	}
86213727Sroot 	/*
86313727Sroot 	 * Turn on the public execute bit of the lock file to
86413727Sroot 	 * get lpd to rebuild the queue after the current job.
86513727Sroot 	 */
86614151Sralph 	if (changed && stat(LO, &stbuf) >= 0)
86714151Sralph 		(void) chmod(LO, (stbuf.st_mode & 0777) | 01);
86813727Sroot }
86913727Sroot 
87015719Sralph /*
87115719Sralph  * Reposition the job by changing the modification time of
87215719Sralph  * the control file.
87313727Sroot  */
87415719Sralph touch(q)
87515719Sralph 	struct queue *q;
87613727Sroot {
87715719Sralph 	struct timeval tvp[2];
87813727Sroot 
87915719Sralph 	tvp[0].tv_sec = tvp[1].tv_sec = --mtime;
88015719Sralph 	tvp[0].tv_usec = tvp[1].tv_usec = 0;
88115719Sralph 	return(utimes(q->q_name, tvp));
88213727Sroot }
88313727Sroot 
88413727Sroot /*
88513727Sroot  * Checks if specified job name is in the printer's queue.
88613727Sroot  * Returns:  negative (-1) if argument name is not in the queue.
88713727Sroot  */
88815719Sralph doarg(job)
88913727Sroot 	char *job;
89013727Sroot {
89115719Sralph 	register struct queue **qq;
89215719Sralph 	register int jobnum, n;
89315719Sralph 	register char *cp, *machine;
89415719Sralph 	int cnt = 0;
89514151Sralph 	FILE *fp;
89613727Sroot 
89715719Sralph 	/*
89815719Sralph 	 * Look for a job item consisting of system name, colon, number
89915719Sralph 	 * (example: ucbarpa:114)
90015719Sralph 	 */
90115719Sralph 	if ((cp = index(job, ':')) != NULL) {
90215719Sralph 		machine = job;
90315719Sralph 		*cp++ = '\0';
90415719Sralph 		job = cp;
90515719Sralph 	} else
90615719Sralph 		machine = NULL;
90715719Sralph 
90815719Sralph 	/*
90915719Sralph 	 * Check for job specified by number (example: 112 or 235ucbarpa).
91015719Sralph 	 */
91113727Sroot 	if (isdigit(*job)) {
91213727Sroot 		jobnum = 0;
91313727Sroot 		do
91413727Sroot 			jobnum = jobnum * 10 + (*job++ - '0');
91513727Sroot 		while (isdigit(*job));
91615719Sralph 		for (qq = queue + nitems; --qq >= queue; ) {
91713727Sroot 			n = 0;
91815719Sralph 			for (cp = (*qq)->q_name+3; isdigit(*cp); )
91914151Sralph 				n = n * 10 + (*cp++ - '0');
92015719Sralph 			if (jobnum != n)
92115719Sralph 				continue;
92215719Sralph 			if (*job && strcmp(job, cp) != 0)
92315719Sralph 				continue;
92415719Sralph 			if (machine != NULL && strcmp(machine, cp) != 0)
92515719Sralph 				continue;
92615719Sralph 			if (touch(*qq) == 0) {
92715719Sralph 				printf("\tmoved %s\n", (*qq)->q_name);
92815719Sralph 				cnt++;
92915719Sralph 			}
93013727Sroot 		}
93115719Sralph 		return(cnt);
93215719Sralph 	}
93315719Sralph 	/*
93415719Sralph 	 * Process item consisting of owner's name (example: henry).
93515719Sralph 	 */
93615719Sralph 	for (qq = queue + nitems; --qq >= queue; ) {
93715719Sralph 		if ((fp = fopen((*qq)->q_name, "r")) == NULL)
93813727Sroot 			continue;
93915719Sralph 		while (getline(fp) > 0)
94015719Sralph 			if (line[0] == 'P')
94115719Sralph 				break;
94215719Sralph 		(void) fclose(fp);
94315719Sralph 		if (line[0] != 'P' || strcmp(job, line+1) != 0)
94415719Sralph 			continue;
94515719Sralph 		if (touch(*qq) == 0) {
94615719Sralph 			printf("\tmoved %s\n", (*qq)->q_name);
94715719Sralph 			cnt++;
94813727Sroot 		}
94913727Sroot 	}
95015719Sralph 	return(cnt);
95113727Sroot }
95216755Sralph 
95316755Sralph /*
95416755Sralph  * Enable everything and start printer (undo `down').
95516755Sralph  */
95616755Sralph up(argc, argv)
95716755Sralph 	char *argv[];
95816755Sralph {
95916755Sralph 	register int c, status;
96016755Sralph 	register char *cp1, *cp2;
96116755Sralph 	char prbuf[100];
96216755Sralph 
96316755Sralph 	if (argc == 1) {
96416755Sralph 		printf("Usage: up {all | printer ...}\n");
96516755Sralph 		return;
96616755Sralph 	}
96716755Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
96816755Sralph 		printer = prbuf;
96916755Sralph 		while (getprent(line) > 0) {
97016755Sralph 			cp1 = prbuf;
97116755Sralph 			cp2 = line;
97216755Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
97316755Sralph 				*cp1++ = c;
97416755Sralph 			*cp1 = '\0';
97516755Sralph 			startpr(2);
97616755Sralph 		}
97716755Sralph 		return;
97816755Sralph 	}
97916755Sralph 	while (--argc) {
98016755Sralph 		printer = *++argv;
98116755Sralph 		if ((status = pgetent(line, printer)) < 0) {
98216755Sralph 			printf("cannot open printer description file\n");
98316755Sralph 			continue;
98416755Sralph 		} else if (status == 0) {
98516755Sralph 			printf("unknown printer %s\n", printer);
98616755Sralph 			continue;
98716755Sralph 		}
98816755Sralph 		startpr(2);
98916755Sralph 	}
99016755Sralph }
991