xref: /csrg-svn/usr.sbin/lpr/lpc/cmds.c (revision 22424)
1*22424Sdist /*
2*22424Sdist  * Copyright (c) 1983 Regents of the University of California.
3*22424Sdist  * All rights reserved.  The Berkeley software License Agreement
4*22424Sdist  * specifies the terms and conditions for redistribution.
5*22424Sdist  */
6*22424Sdist 
712382Sralph #ifndef lint
8*22424Sdist static char sccsid[] = "@(#)cmds.c	5.1 (Berkeley) 06/06/85";
9*22424Sdist #endif not lint
1012382Sralph 
1112382Sralph /*
1215719Sralph  * lpc -- line printer control program -- commands:
1312382Sralph  */
1412382Sralph 
1512382Sralph #include "lp.h"
1615719Sralph #include <sys/time.h>
1712382Sralph 
1812382Sralph /*
1912382Sralph  * kill an existing daemon and disable printing.
2012382Sralph  */
2112382Sralph abort(argc, argv)
2212382Sralph 	char *argv[];
2312382Sralph {
2412382Sralph 	register int c, status;
2512382Sralph 	register char *cp1, *cp2;
2612382Sralph 	char prbuf[100];
2712382Sralph 
2812382Sralph 	if (argc == 1) {
2912382Sralph 		printf("Usage: abort {all | printer ...}\n");
3012382Sralph 		return;
3112382Sralph 	}
3212382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
3312382Sralph 		printer = prbuf;
3412382Sralph 		while (getprent(line) > 0) {
3512382Sralph 			cp1 = prbuf;
3612382Sralph 			cp2 = line;
3712382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
3812382Sralph 				*cp1++ = c;
3912382Sralph 			*cp1 = '\0';
4016755Sralph 			abortpr(1);
4112382Sralph 		}
4212382Sralph 		return;
4312382Sralph 	}
4412382Sralph 	while (--argc) {
4512382Sralph 		printer = *++argv;
4612382Sralph 		if ((status = pgetent(line, printer)) < 0) {
4712514Sralph 			printf("cannot open printer description file\n");
4812382Sralph 			continue;
4912382Sralph 		} else if (status == 0) {
5012514Sralph 			printf("unknown printer %s\n", printer);
5112382Sralph 			continue;
5212382Sralph 		}
5316755Sralph 		abortpr(1);
5412382Sralph 	}
5512382Sralph }
5612382Sralph 
5716755Sralph abortpr(dis)
5812382Sralph {
5912382Sralph 	register FILE *fp;
6012382Sralph 	struct stat stbuf;
6112382Sralph 	int pid, fd;
6212382Sralph 
6312382Sralph 	bp = pbuf;
6412382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
6512382Sralph 		SD = DEFSPOOL;
6612382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
6712382Sralph 		LO = DEFLOCK;
6812382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
6912382Sralph 	printf("%s:\n", printer);
7012382Sralph 
7112382Sralph 	/*
7212382Sralph 	 * Turn on the owner execute bit of the lock file to disable printing.
7312382Sralph 	 */
7416755Sralph 	if (dis) {
7516755Sralph 		if (stat(line, &stbuf) >= 0) {
7616755Sralph 			if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
7716755Sralph 				printf("\tcannot disable printing\n");
7816755Sralph 			else
7916755Sralph 				printf("\tprinting disabled\n");
8016755Sralph 		} else if (errno == ENOENT) {
8116755Sralph 			if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
8216755Sralph 				printf("\tcannot create lock file\n");
8316755Sralph 			else {
8416755Sralph 				(void) close(fd);
8516755Sralph 				printf("\tprinting disabled\n");
8616755Sralph 				printf("\tno daemon to abort\n");
8716755Sralph 			}
8816755Sralph 			return;
8916755Sralph 		} else {
9016755Sralph 			printf("\tcannot stat lock file\n");
9116755Sralph 			return;
9212382Sralph 		}
9312382Sralph 	}
9412382Sralph 	/*
9512382Sralph 	 * Kill the current daemon to stop printing now.
9612382Sralph 	 */
9712382Sralph 	if ((fp = fopen(line, "r")) == NULL) {
9812382Sralph 		printf("\tcannot open lock file\n");
9912382Sralph 		return;
10012382Sralph 	}
10113146Ssam 	if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) {
10213168Sralph 		(void) fclose(fp);	/* unlocks as well */
10312382Sralph 		printf("\tno daemon to abort\n");
10412382Sralph 		return;
10512382Sralph 	}
10612382Sralph 	(void) fclose(fp);
10716755Sralph 	if (kill(pid = atoi(line), SIGTERM) < 0)
10812382Sralph 		printf("\tWarning: daemon (pid %d) not killed\n", pid);
10912382Sralph 	else
11012382Sralph 		printf("\tdaemon (pid %d) killed\n", pid);
11112382Sralph }
11212382Sralph 
11312382Sralph /*
11412382Sralph  * Remove all spool files and temporaries from the spooling area.
11512382Sralph  */
11612382Sralph clean(argc, argv)
11712382Sralph 	char *argv[];
11812382Sralph {
11912382Sralph 	register int c, status;
12012382Sralph 	register char *cp1, *cp2;
12112382Sralph 	char prbuf[100];
12212382Sralph 
12312382Sralph 	if (argc == 1) {
12412382Sralph 		printf("Usage: clean {all | printer ...}\n");
12512382Sralph 		return;
12612382Sralph 	}
12712382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
12812382Sralph 		printer = prbuf;
12912382Sralph 		while (getprent(line) > 0) {
13012382Sralph 			cp1 = prbuf;
13112382Sralph 			cp2 = line;
13212382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
13312382Sralph 				*cp1++ = c;
13412382Sralph 			*cp1 = '\0';
13512382Sralph 			cleanpr();
13612382Sralph 		}
13712382Sralph 		return;
13812382Sralph 	}
13912382Sralph 	while (--argc) {
14012382Sralph 		printer = *++argv;
14112382Sralph 		if ((status = pgetent(line, printer)) < 0) {
14212514Sralph 			printf("cannot open printer description file\n");
14312382Sralph 			continue;
14412382Sralph 		} else if (status == 0) {
14512514Sralph 			printf("unknown printer %s\n", printer);
14612382Sralph 			continue;
14712382Sralph 		}
14812382Sralph 		cleanpr();
14912382Sralph 	}
15012382Sralph }
15112382Sralph 
15215719Sralph select(d)
15315719Sralph struct direct *d;
15415719Sralph {
15515719Sralph 	int c = d->d_name[0];
15615719Sralph 
15715719Sralph 	if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f')
15815719Sralph 		return(1);
15915719Sralph 	return(0);
16015719Sralph }
16115719Sralph 
16215719Sralph /*
16315719Sralph  * Comparison routine for scandir. Sort by job number and machine, then
16415719Sralph  * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z.
16515719Sralph  */
16615719Sralph sortq(d1, d2)
16715719Sralph struct direct **d1, **d2;
16815719Sralph {
16915719Sralph 	int c1, c2;
17015719Sralph 
17115719Sralph 	if (c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3))
17215719Sralph 		return(c1);
17315719Sralph 	c1 = (*d1)->d_name[0];
17415719Sralph 	c2 = (*d2)->d_name[0];
17515719Sralph 	if (c1 == c2)
17615719Sralph 		return((*d1)->d_name[2] - (*d2)->d_name[2]);
17715719Sralph 	if (c1 == 'c')
17815719Sralph 		return(-1);
17915719Sralph 	if (c1 == 'd' || c2 == 'c')
18015719Sralph 		return(1);
18115719Sralph 	return(-1);
18215719Sralph }
18315719Sralph 
18415719Sralph /*
18515719Sralph  * Remove incomplete jobs from spooling area.
18615719Sralph  */
18712382Sralph cleanpr()
18812382Sralph {
18915719Sralph 	register int i, n;
19015719Sralph 	register char *cp, *cp1, *lp;
19115719Sralph 	struct direct **queue;
19215719Sralph 	int nitems;
19312382Sralph 
19412382Sralph 	bp = pbuf;
19512382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
19612382Sralph 		SD = DEFSPOOL;
19712382Sralph 	printf("%s:\n", printer);
19812382Sralph 
19915719Sralph 	for (lp = line, cp = SD; *lp++ = *cp++; )
20015719Sralph 		;
20115719Sralph 	lp[-1] = '/';
20215719Sralph 
20315719Sralph 	nitems = scandir(SD, &queue, select, sortq);
20415719Sralph 	if (nitems < 0) {
20512382Sralph 		printf("\tcannot examine spool directory\n");
20612382Sralph 		return;
20712382Sralph 	}
20815719Sralph 	if (nitems == 0)
20915719Sralph 		return;
21015719Sralph 	i = 0;
21115719Sralph 	do {
21215719Sralph 		cp = queue[i]->d_name;
21315719Sralph 		if (*cp == 'c') {
21415719Sralph 			n = 0;
21515719Sralph 			while (i + 1 < nitems) {
21615719Sralph 				cp1 = queue[i + 1]->d_name;
21715719Sralph 				if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3))
21815719Sralph 					break;
21915719Sralph 				i++;
22015719Sralph 				n++;
22115719Sralph 			}
22215719Sralph 			if (n == 0) {
22315719Sralph 				strcpy(lp, cp);
22415719Sralph 				unlinkf(line);
22515719Sralph 			}
22615719Sralph 		} else {
22715719Sralph 			/*
22815719Sralph 			 * Must be a df with no cf (otherwise, it would have
22915719Sralph 			 * been skipped above) or a tf file (which can always
23015719Sralph 			 * be removed).
23115719Sralph 			 */
23215719Sralph 			strcpy(lp, cp);
23315719Sralph 			unlinkf(line);
23412382Sralph 		}
23515719Sralph      	} while (++i < nitems);
23612382Sralph }
23715719Sralph 
23815719Sralph unlinkf(name)
23915719Sralph 	char	*name;
24015719Sralph {
24115719Sralph 	if (unlink(name) < 0)
24215719Sralph 		printf("\tcannot remove %s\n", name);
24315719Sralph 	else
24415719Sralph 		printf("\tremoved %s\n", name);
24515719Sralph }
24612382Sralph 
24712382Sralph /*
24812382Sralph  * Enable queuing to the printer (allow lpr's).
24912382Sralph  */
25012382Sralph enable(argc, argv)
25112382Sralph 	char *argv[];
25212382Sralph {
25312382Sralph 	register int c, status;
25412382Sralph 	register char *cp1, *cp2;
25512382Sralph 	char prbuf[100];
25612382Sralph 
25712382Sralph 	if (argc == 1) {
25812382Sralph 		printf("Usage: enable {all | printer ...}\n");
25912382Sralph 		return;
26012382Sralph 	}
26112382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
26212382Sralph 		printer = prbuf;
26312382Sralph 		while (getprent(line) > 0) {
26412382Sralph 			cp1 = prbuf;
26512382Sralph 			cp2 = line;
26612382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
26712382Sralph 				*cp1++ = c;
26812382Sralph 			*cp1 = '\0';
26912382Sralph 			enablepr();
27012382Sralph 		}
27112382Sralph 		return;
27212382Sralph 	}
27312382Sralph 	while (--argc) {
27412382Sralph 		printer = *++argv;
27512382Sralph 		if ((status = pgetent(line, printer)) < 0) {
27612514Sralph 			printf("cannot open printer description file\n");
27712382Sralph 			continue;
27812382Sralph 		} else if (status == 0) {
27912514Sralph 			printf("unknown printer %s\n", printer);
28012382Sralph 			continue;
28112382Sralph 		}
28212382Sralph 		enablepr();
28312382Sralph 	}
28412382Sralph }
28512382Sralph 
28612382Sralph enablepr()
28712382Sralph {
28812382Sralph 	struct stat stbuf;
28912382Sralph 
29012382Sralph 	bp = pbuf;
29112382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
29212382Sralph 		SD = DEFSPOOL;
29312382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
29412382Sralph 		LO = DEFLOCK;
29512382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
29612382Sralph 	printf("%s:\n", printer);
29712382Sralph 
29812382Sralph 	/*
29912382Sralph 	 * Turn off the group execute bit of the lock file to enable queuing.
30012382Sralph 	 */
30112382Sralph 	if (stat(line, &stbuf) >= 0) {
30212382Sralph 		if (chmod(line, stbuf.st_mode & 0767) < 0)
30312514Sralph 			printf("\tcannot enable queuing\n");
30412382Sralph 		else
30512382Sralph 			printf("\tqueuing enabled\n");
30612382Sralph 	}
30712382Sralph }
30812382Sralph 
30912382Sralph /*
31012382Sralph  * Disable queuing.
31112382Sralph  */
31212382Sralph disable(argc, argv)
31312382Sralph 	char *argv[];
31412382Sralph {
31512382Sralph 	register int c, status;
31612382Sralph 	register char *cp1, *cp2;
31712382Sralph 	char prbuf[100];
31812382Sralph 
31912382Sralph 	if (argc == 1) {
32012382Sralph 		printf("Usage: disable {all | printer ...}\n");
32112382Sralph 		return;
32212382Sralph 	}
32312382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
32412382Sralph 		printer = prbuf;
32512382Sralph 		while (getprent(line) > 0) {
32612382Sralph 			cp1 = prbuf;
32712382Sralph 			cp2 = line;
32812382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
32912382Sralph 				*cp1++ = c;
33012382Sralph 			*cp1 = '\0';
33112382Sralph 			disablepr();
33212382Sralph 		}
33312382Sralph 		return;
33412382Sralph 	}
33512382Sralph 	while (--argc) {
33612382Sralph 		printer = *++argv;
33712382Sralph 		if ((status = pgetent(line, printer)) < 0) {
33812514Sralph 			printf("cannot open printer description file\n");
33912382Sralph 			continue;
34012382Sralph 		} else if (status == 0) {
34112514Sralph 			printf("unknown printer %s\n", printer);
34212382Sralph 			continue;
34312382Sralph 		}
34412382Sralph 		disablepr();
34512382Sralph 	}
34612382Sralph }
34712382Sralph 
34812382Sralph disablepr()
34912382Sralph {
35012382Sralph 	register int fd;
35112382Sralph 	struct stat stbuf;
35212382Sralph 
35312382Sralph 	bp = pbuf;
35412382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
35512382Sralph 		SD = DEFSPOOL;
35612382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
35712382Sralph 		LO = DEFLOCK;
35812382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
35912382Sralph 	printf("%s:\n", printer);
36012382Sralph 	/*
36112382Sralph 	 * Turn on the group execute bit of the lock file to disable queuing.
36212382Sralph 	 */
36312382Sralph 	if (stat(line, &stbuf) >= 0) {
36412382Sralph 		if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0)
36512382Sralph 			printf("\tcannot disable queuing\n");
36612382Sralph 		else
36712382Sralph 			printf("\tqueuing disabled\n");
36812382Sralph 	} else if (errno == ENOENT) {
36913146Ssam 		if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0)
37012382Sralph 			printf("\tcannot create lock file\n");
37112382Sralph 		else {
37212382Sralph 			(void) close(fd);
37312382Sralph 			printf("\tqueuing disabled\n");
37412382Sralph 		}
37512382Sralph 		return;
37612382Sralph 	} else
37712382Sralph 		printf("\tcannot stat lock file\n");
37812382Sralph }
37912382Sralph 
38012382Sralph /*
38115907Sralph  * Disable queuing and printing and put a message into the status file
38215907Sralph  * (reason for being down).
38315907Sralph  */
38415907Sralph down(argc, argv)
38515907Sralph 	char *argv[];
38615907Sralph {
38715907Sralph 	register int c, status;
38815907Sralph 	register char *cp1, *cp2;
38915907Sralph 	char prbuf[100];
39015907Sralph 
39115907Sralph 	if (argc == 1) {
39216204Sralph 		printf("Usage: down {all | printer} [message ...]\n");
39315907Sralph 		return;
39415907Sralph 	}
39515907Sralph 	if (!strcmp(argv[1], "all")) {
39615907Sralph 		printer = prbuf;
39715907Sralph 		while (getprent(line) > 0) {
39815907Sralph 			cp1 = prbuf;
39915907Sralph 			cp2 = line;
40015907Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
40115907Sralph 				*cp1++ = c;
40215907Sralph 			*cp1 = '\0';
40315907Sralph 			putmsg(argc - 2, argv + 2);
40415907Sralph 		}
40515907Sralph 		return;
40615907Sralph 	}
40715907Sralph 	printer = argv[1];
40815907Sralph 	if ((status = pgetent(line, printer)) < 0) {
40915907Sralph 		printf("cannot open printer description file\n");
41015907Sralph 		return;
41115907Sralph 	} else if (status == 0) {
41215907Sralph 		printf("unknown printer %s\n", printer);
41315907Sralph 		return;
41415907Sralph 	}
41515907Sralph 	putmsg(argc - 2, argv + 2);
41615907Sralph }
41715907Sralph 
41815907Sralph putmsg(argc, argv)
41915907Sralph 	char **argv;
42015907Sralph {
42115907Sralph 	register int fd;
42215907Sralph 	register char *cp1, *cp2;
42315907Sralph 	char buf[1024];
42415907Sralph 	struct stat stbuf;
42515907Sralph 
42615907Sralph 	bp = pbuf;
42715907Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
42815907Sralph 		SD = DEFSPOOL;
42915907Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
43015907Sralph 		LO = DEFLOCK;
43115907Sralph 	if ((ST = pgetstr("st", &bp)) == NULL)
43215907Sralph 		ST = DEFSTAT;
43315907Sralph 	printf("%s:\n", printer);
43415907Sralph 	/*
43515907Sralph 	 * Turn on the group execute bit of the lock file to disable queuing and
43615907Sralph 	 * turn on the owner execute bit of the lock file to disable printing.
43715907Sralph 	 */
43815907Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
43915907Sralph 	if (stat(line, &stbuf) >= 0) {
44015907Sralph 		if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0)
44115907Sralph 			printf("\tcannot disable queuing\n");
44215907Sralph 		else
44315907Sralph 			printf("\tprinter and queuing disabled\n");
44415907Sralph 	} else if (errno == ENOENT) {
44515907Sralph 		if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0)
44615907Sralph 			printf("\tcannot create lock file\n");
44715907Sralph 		else {
44815907Sralph 			(void) close(fd);
44915907Sralph 			printf("\tprinter and queuing disabled\n");
45015907Sralph 		}
45115907Sralph 		return;
45215907Sralph 	} else
45315907Sralph 		printf("\tcannot stat lock file\n");
45415907Sralph 	/*
45515907Sralph 	 * Write the message into the status file.
45615907Sralph 	 */
45715907Sralph 	(void) sprintf(line, "%s/%s", SD, ST);
45815907Sralph 	fd = open(line, O_WRONLY|O_CREAT, 0664);
45915907Sralph 	if (fd < 0 || flock(fd, LOCK_EX) < 0) {
46015907Sralph 		printf("\tcannot create status file\n");
46115907Sralph 		return;
46215907Sralph 	}
46315907Sralph 	(void) ftruncate(fd, 0);
46416204Sralph 	if (argc <= 0) {
46516204Sralph 		(void) write(fd, "\n", 1);
46616204Sralph 		(void) close(fd);
46716204Sralph 		return;
46816204Sralph 	}
46915907Sralph 	cp1 = buf;
47015907Sralph 	while (--argc >= 0) {
47115907Sralph 		cp2 = *argv++;
47215907Sralph 		while (*cp1++ = *cp2++)
47315907Sralph 			;
47415907Sralph 		cp1[-1] = ' ';
47515907Sralph 	}
47615907Sralph 	cp1[-1] = '\n';
47715907Sralph 	*cp1 = '\0';
47815907Sralph 	(void) write(fd, buf, strlen(buf));
47915907Sralph 	(void) close(fd);
48015907Sralph }
48115907Sralph 
48215907Sralph /*
48312382Sralph  * Exit lpc
48412382Sralph  */
48512382Sralph quit(argc, argv)
48612382Sralph 	char *argv[];
48712382Sralph {
48812382Sralph 	exit(0);
48912382Sralph }
49012382Sralph 
49112382Sralph /*
49216755Sralph  * Kill and restart the daemon.
49312382Sralph  */
49412382Sralph restart(argc, argv)
49512382Sralph 	char *argv[];
49612382Sralph {
49712382Sralph 	register int c, status;
49812382Sralph 	register char *cp1, *cp2;
49912382Sralph 	char prbuf[100];
50012382Sralph 
50112382Sralph 	if (argc == 1) {
50212382Sralph 		printf("Usage: restart {all | printer ...}\n");
50312382Sralph 		return;
50412382Sralph 	}
50512382Sralph 	gethostname(host, sizeof(host));
50612382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
50712382Sralph 		printer = prbuf;
50812382Sralph 		while (getprent(line) > 0) {
50912382Sralph 			cp1 = prbuf;
51012382Sralph 			cp2 = line;
51112382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
51212382Sralph 				*cp1++ = c;
51312382Sralph 			*cp1 = '\0';
51416755Sralph 			abortpr(0);
51512382Sralph 			startpr(0);
51612382Sralph 		}
51712382Sralph 		return;
51812382Sralph 	}
51912382Sralph 	while (--argc) {
52012382Sralph 		printer = *++argv;
52112382Sralph 		if ((status = pgetent(line, printer)) < 0) {
52212514Sralph 			printf("cannot open printer description file\n");
52312382Sralph 			continue;
52412382Sralph 		} else if (status == 0) {
52512514Sralph 			printf("unknown printer %s\n", printer);
52612382Sralph 			continue;
52712382Sralph 		}
52816755Sralph 		abortpr(0);
52912382Sralph 		startpr(0);
53012382Sralph 	}
53112382Sralph }
53212382Sralph 
53312382Sralph /*
53412382Sralph  * Enable printing on the specified printer and startup the daemon.
53512382Sralph  */
53612382Sralph start(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: start {all | printer ...}\n");
54512382Sralph 		return;
54612382Sralph 	}
54712382Sralph 	gethostname(host, sizeof(host));
54812382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
54912382Sralph 		printer = prbuf;
55012382Sralph 		while (getprent(line) > 0) {
55112382Sralph 			cp1 = prbuf;
55212382Sralph 			cp2 = line;
55312382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
55412382Sralph 				*cp1++ = c;
55512382Sralph 			*cp1 = '\0';
55612382Sralph 			startpr(1);
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 		}
56912382Sralph 		startpr(1);
57012382Sralph 	}
57112382Sralph }
57212382Sralph 
57312382Sralph startpr(enable)
57412382Sralph {
57512382Sralph 	struct stat stbuf;
57612382Sralph 
57712382Sralph 	bp = pbuf;
57812382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
57912382Sralph 		SD = DEFSPOOL;
58012382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
58112382Sralph 		LO = DEFLOCK;
58212382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
58312382Sralph 	printf("%s:\n", printer);
58412382Sralph 
58512382Sralph 	/*
58612382Sralph 	 * Turn off the owner execute bit of the lock file to enable printing.
58712382Sralph 	 */
58812382Sralph 	if (enable && stat(line, &stbuf) >= 0) {
58916771Sralph 		if (chmod(line, stbuf.st_mode & (enable==2 ? 0666 : 0677)) < 0)
59012382Sralph 			printf("\tcannot enable printing\n");
59112382Sralph 		else
59212382Sralph 			printf("\tprinting enabled\n");
59312382Sralph 	}
59413727Sroot 	if (!startdaemon(printer))
59512382Sralph 		printf("\tcouldn't start daemon\n");
59612382Sralph 	else
59712382Sralph 		printf("\tdaemon started\n");
59812382Sralph }
59912382Sralph 
60012382Sralph /*
60112382Sralph  * Print the status of each queue listed or all the queues.
60212382Sralph  */
60312382Sralph status(argc, argv)
60412382Sralph 	char *argv[];
60512382Sralph {
60612382Sralph 	register int c, status;
60712382Sralph 	register char *cp1, *cp2;
60812382Sralph 	char prbuf[100];
60912382Sralph 
61012382Sralph 	if (argc == 1) {
61112382Sralph 		printer = prbuf;
61212382Sralph 		while (getprent(line) > 0) {
61312382Sralph 			cp1 = prbuf;
61412382Sralph 			cp2 = line;
61512382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
61612382Sralph 				*cp1++ = c;
61712382Sralph 			*cp1 = '\0';
61812382Sralph 			prstat();
61912382Sralph 		}
62012382Sralph 		return;
62112382Sralph 	}
62212382Sralph 	while (--argc) {
62312382Sralph 		printer = *++argv;
62412382Sralph 		if ((status = pgetent(line, printer)) < 0) {
62512514Sralph 			printf("cannot open printer description file\n");
62612382Sralph 			continue;
62712382Sralph 		} else if (status == 0) {
62812514Sralph 			printf("unknown printer %s\n", printer);
62912382Sralph 			continue;
63012382Sralph 		}
63112382Sralph 		prstat();
63212382Sralph 	}
63312382Sralph }
63412382Sralph 
63512382Sralph /*
63612382Sralph  * Print the status of the printer queue.
63712382Sralph  */
63812382Sralph prstat()
63912382Sralph {
64012382Sralph 	struct stat stbuf;
64112382Sralph 	register int fd, i;
64212382Sralph 	register struct direct *dp;
64312382Sralph 	DIR *dirp;
64412382Sralph 
64512382Sralph 	bp = pbuf;
64612382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
64712382Sralph 		SD = DEFSPOOL;
64812382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
64912382Sralph 		LO = DEFLOCK;
65012382Sralph 	if ((ST = pgetstr("st", &bp)) == NULL)
65112382Sralph 		ST = DEFSTAT;
65212382Sralph 	printf("%s:\n", printer);
65312382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
65412382Sralph 	if (stat(line, &stbuf) >= 0) {
65512382Sralph 		printf("\tqueuing is %s\n",
65612382Sralph 			(stbuf.st_mode & 010) ? "disabled" : "enabled");
65712382Sralph 		printf("\tprinting is %s\n",
65812382Sralph 			(stbuf.st_mode & 0100) ? "disabled" : "enabled");
65912382Sralph 	} else {
66012382Sralph 		printf("\tqueuing is enabled\n");
66112382Sralph 		printf("\tprinting is enabled\n");
66212382Sralph 	}
66312382Sralph 	if ((dirp = opendir(SD)) == NULL) {
66412382Sralph 		printf("\tcannot examine spool directory\n");
66512382Sralph 		return;
66612382Sralph 	}
66712382Sralph 	i = 0;
66812382Sralph 	while ((dp = readdir(dirp)) != NULL) {
66912382Sralph 		if (*dp->d_name == 'c' && dp->d_name[1] == 'f')
67012382Sralph 			i++;
67112382Sralph 	}
67212382Sralph 	closedir(dirp);
67312382Sralph 	if (i == 0)
67412382Sralph 		printf("\tno entries\n");
67512382Sralph 	else if (i == 1)
67612382Sralph 		printf("\t1 entry in spool area\n");
67712382Sralph 	else
67812382Sralph 		printf("\t%d entries in spool area\n", i);
67913146Ssam 	fd = open(line, O_RDONLY);
68013146Ssam 	if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) {
68113168Sralph 		(void) close(fd);	/* unlocks as well */
68212382Sralph 		printf("\tno daemon present\n");
68312382Sralph 		return;
68412382Sralph 	}
68512382Sralph 	(void) close(fd);
68612382Sralph 	putchar('\t');
68712382Sralph 	(void) sprintf(line, "%s/%s", SD, ST);
68813146Ssam 	fd = open(line, O_RDONLY);
68913146Ssam 	if (fd >= 0) {
69013146Ssam 		(void) flock(fd, LOCK_SH);
69112382Sralph 		while ((i = read(fd, line, sizeof(line))) > 0)
69212382Sralph 			(void) fwrite(line, 1, i, stdout);
69313168Sralph 		(void) close(fd);	/* unlocks as well */
69412382Sralph 	}
69512382Sralph }
69612382Sralph 
69712382Sralph /*
69812382Sralph  * Stop the specified daemon after completing the current job and disable
69912382Sralph  * printing.
70012382Sralph  */
70112382Sralph stop(argc, argv)
70212382Sralph 	char *argv[];
70312382Sralph {
70412382Sralph 	register int c, status;
70512382Sralph 	register char *cp1, *cp2;
70612382Sralph 	char prbuf[100];
70712382Sralph 
70812382Sralph 	if (argc == 1) {
70912382Sralph 		printf("Usage: stop {all | printer ...}\n");
71012382Sralph 		return;
71112382Sralph 	}
71212382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
71312382Sralph 		printer = prbuf;
71412382Sralph 		while (getprent(line) > 0) {
71512382Sralph 			cp1 = prbuf;
71612382Sralph 			cp2 = line;
71712382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
71812382Sralph 				*cp1++ = c;
71912382Sralph 			*cp1 = '\0';
72012382Sralph 			stoppr();
72112382Sralph 		}
72212382Sralph 		return;
72312382Sralph 	}
72412382Sralph 	while (--argc) {
72512382Sralph 		printer = *++argv;
72612382Sralph 		if ((status = pgetent(line, printer)) < 0) {
72712514Sralph 			printf("cannot open printer description file\n");
72812382Sralph 			continue;
72912382Sralph 		} else if (status == 0) {
73012514Sralph 			printf("unknown printer %s\n", printer);
73112382Sralph 			continue;
73212382Sralph 		}
73312382Sralph 		stoppr();
73412382Sralph 	}
73512382Sralph }
73612382Sralph 
73712382Sralph stoppr()
73812382Sralph {
73912382Sralph 	register int fd;
74012382Sralph 	struct stat stbuf;
74112382Sralph 
74212382Sralph 	bp = pbuf;
74312382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
74412382Sralph 		SD = DEFSPOOL;
74512382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
74612382Sralph 		LO = DEFLOCK;
74712382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
74812382Sralph 	printf("%s:\n", printer);
74912382Sralph 
75012382Sralph 	/*
75112382Sralph 	 * Turn on the owner execute bit of the lock file to disable printing.
75212382Sralph 	 */
75312382Sralph 	if (stat(line, &stbuf) >= 0) {
75412382Sralph 		if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
75512382Sralph 			printf("\tcannot disable printing\n");
75612382Sralph 		else
75712382Sralph 			printf("\tprinting disabled\n");
75812382Sralph 	} else if (errno == ENOENT) {
75913146Ssam 		if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
76012382Sralph 			printf("\tcannot create lock file\n");
76112382Sralph 		else {
76212382Sralph 			(void) close(fd);
76312382Sralph 			printf("\tprinting disabled\n");
76412382Sralph 		}
76512382Sralph 	} else
76612382Sralph 		printf("\tcannot stat lock file\n");
76712382Sralph }
76813727Sroot 
76915719Sralph struct	queue **queue;
77015719Sralph int	nitems;
77115719Sralph time_t	mtime;
77215719Sralph 
77313727Sroot /*
77413727Sroot  * Put the specified jobs at the top of printer queue.
77513727Sroot  */
77613727Sroot topq(argc, argv)
77713727Sroot 	char *argv[];
77813727Sroot {
77915719Sralph 	register int n, i;
78013727Sroot 	struct stat stbuf;
78113727Sroot 	register char *cfname;
78215719Sralph 	int status, changed;
78313727Sroot 
78415719Sralph 	if (argc < 3) {
78513727Sroot 		printf("Usage: topq printer [jobnum ...] [user ...]\n");
78613727Sroot 		return;
78713727Sroot 	}
78813727Sroot 
78913727Sroot 	--argc;
79013727Sroot 	printer = *++argv;
79113727Sroot 	status = pgetent(line, printer);
79213727Sroot 	if (status < 0) {
79313727Sroot 		printf("cannot open printer description file\n");
79413727Sroot 		return;
79514151Sralph 	} else if (status == 0) {
79613727Sroot 		printf("%s: unknown printer\n", printer);
79713727Sroot 		return;
79813727Sroot 	}
79913727Sroot 	bp = pbuf;
80013727Sroot 	if ((SD = pgetstr("sd", &bp)) == NULL)
80113727Sroot 		SD = DEFSPOOL;
80213727Sroot 	if ((LO = pgetstr("lo", &bp)) == NULL)
80313727Sroot 		LO = DEFLOCK;
80413727Sroot 	printf("%s:\n", printer);
80513727Sroot 
80613727Sroot 	if (chdir(SD) < 0) {
80713727Sroot 		printf("\tcannot chdir to %s\n", SD);
80813727Sroot 		return;
80913727Sroot 	}
81013727Sroot 	nitems = getq(&queue);
81115719Sralph 	if (nitems == 0)
81215719Sralph 		return;
81315719Sralph 	changed = 0;
81415719Sralph 	mtime = queue[0]->q_time;
81515719Sralph 	for (i = argc; --i; ) {
81615719Sralph 		if (doarg(argv[i]) == 0) {
81715719Sralph 			printf("\tjob %s is not in the queue\n", argv[i]);
81813727Sroot 			continue;
81915719Sralph 		} else
82014151Sralph 			changed++;
82113727Sroot 	}
82215719Sralph 	for (i = 0; i < nitems; i++)
82315719Sralph 		free(queue[i]);
82415719Sralph 	free(queue);
82515719Sralph 	if (!changed) {
82615719Sralph 		printf("\tqueue order unchanged\n");
82715719Sralph 		return;
82813727Sroot 	}
82913727Sroot 	/*
83013727Sroot 	 * Turn on the public execute bit of the lock file to
83113727Sroot 	 * get lpd to rebuild the queue after the current job.
83213727Sroot 	 */
83314151Sralph 	if (changed && stat(LO, &stbuf) >= 0)
83414151Sralph 		(void) chmod(LO, (stbuf.st_mode & 0777) | 01);
83513727Sroot }
83613727Sroot 
83715719Sralph /*
83815719Sralph  * Reposition the job by changing the modification time of
83915719Sralph  * the control file.
84013727Sroot  */
84115719Sralph touch(q)
84215719Sralph 	struct queue *q;
84313727Sroot {
84415719Sralph 	struct timeval tvp[2];
84513727Sroot 
84615719Sralph 	tvp[0].tv_sec = tvp[1].tv_sec = --mtime;
84715719Sralph 	tvp[0].tv_usec = tvp[1].tv_usec = 0;
84815719Sralph 	return(utimes(q->q_name, tvp));
84913727Sroot }
85013727Sroot 
85113727Sroot /*
85213727Sroot  * Checks if specified job name is in the printer's queue.
85313727Sroot  * Returns:  negative (-1) if argument name is not in the queue.
85413727Sroot  */
85515719Sralph doarg(job)
85613727Sroot 	char *job;
85713727Sroot {
85815719Sralph 	register struct queue **qq;
85915719Sralph 	register int jobnum, n;
86015719Sralph 	register char *cp, *machine;
86115719Sralph 	int cnt = 0;
86214151Sralph 	FILE *fp;
86313727Sroot 
86415719Sralph 	/*
86515719Sralph 	 * Look for a job item consisting of system name, colon, number
86615719Sralph 	 * (example: ucbarpa:114)
86715719Sralph 	 */
86815719Sralph 	if ((cp = index(job, ':')) != NULL) {
86915719Sralph 		machine = job;
87015719Sralph 		*cp++ = '\0';
87115719Sralph 		job = cp;
87215719Sralph 	} else
87315719Sralph 		machine = NULL;
87415719Sralph 
87515719Sralph 	/*
87615719Sralph 	 * Check for job specified by number (example: 112 or 235ucbarpa).
87715719Sralph 	 */
87813727Sroot 	if (isdigit(*job)) {
87913727Sroot 		jobnum = 0;
88013727Sroot 		do
88113727Sroot 			jobnum = jobnum * 10 + (*job++ - '0');
88213727Sroot 		while (isdigit(*job));
88315719Sralph 		for (qq = queue + nitems; --qq >= queue; ) {
88413727Sroot 			n = 0;
88515719Sralph 			for (cp = (*qq)->q_name+3; isdigit(*cp); )
88614151Sralph 				n = n * 10 + (*cp++ - '0');
88715719Sralph 			if (jobnum != n)
88815719Sralph 				continue;
88915719Sralph 			if (*job && strcmp(job, cp) != 0)
89015719Sralph 				continue;
89115719Sralph 			if (machine != NULL && strcmp(machine, cp) != 0)
89215719Sralph 				continue;
89315719Sralph 			if (touch(*qq) == 0) {
89415719Sralph 				printf("\tmoved %s\n", (*qq)->q_name);
89515719Sralph 				cnt++;
89615719Sralph 			}
89713727Sroot 		}
89815719Sralph 		return(cnt);
89915719Sralph 	}
90015719Sralph 	/*
90115719Sralph 	 * Process item consisting of owner's name (example: henry).
90215719Sralph 	 */
90315719Sralph 	for (qq = queue + nitems; --qq >= queue; ) {
90415719Sralph 		if ((fp = fopen((*qq)->q_name, "r")) == NULL)
90513727Sroot 			continue;
90615719Sralph 		while (getline(fp) > 0)
90715719Sralph 			if (line[0] == 'P')
90815719Sralph 				break;
90915719Sralph 		(void) fclose(fp);
91015719Sralph 		if (line[0] != 'P' || strcmp(job, line+1) != 0)
91115719Sralph 			continue;
91215719Sralph 		if (touch(*qq) == 0) {
91315719Sralph 			printf("\tmoved %s\n", (*qq)->q_name);
91415719Sralph 			cnt++;
91513727Sroot 		}
91613727Sroot 	}
91715719Sralph 	return(cnt);
91813727Sroot }
91916755Sralph 
92016755Sralph /*
92116755Sralph  * Enable everything and start printer (undo `down').
92216755Sralph  */
92316755Sralph up(argc, argv)
92416755Sralph 	char *argv[];
92516755Sralph {
92616755Sralph 	register int c, status;
92716755Sralph 	register char *cp1, *cp2;
92816755Sralph 	char prbuf[100];
92916755Sralph 
93016755Sralph 	if (argc == 1) {
93116755Sralph 		printf("Usage: up {all | printer ...}\n");
93216755Sralph 		return;
93316755Sralph 	}
93416755Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
93516755Sralph 		printer = prbuf;
93616755Sralph 		while (getprent(line) > 0) {
93716755Sralph 			cp1 = prbuf;
93816755Sralph 			cp2 = line;
93916755Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
94016755Sralph 				*cp1++ = c;
94116755Sralph 			*cp1 = '\0';
94216755Sralph 			startpr(2);
94316755Sralph 		}
94416755Sralph 		return;
94516755Sralph 	}
94616755Sralph 	while (--argc) {
94716755Sralph 		printer = *++argv;
94816755Sralph 		if ((status = pgetent(line, printer)) < 0) {
94916755Sralph 			printf("cannot open printer description file\n");
95016755Sralph 			continue;
95116755Sralph 		} else if (status == 0) {
95216755Sralph 			printf("unknown printer %s\n", printer);
95316755Sralph 			continue;
95416755Sralph 		}
95516755Sralph 		startpr(2);
95616755Sralph 	}
95716755Sralph }
958