xref: /csrg-svn/usr.sbin/lpr/lpc/cmds.c (revision 16771)
112382Sralph #ifndef lint
2*16771Sralph static char sccsid[] = "@(#)cmds.c	4.13 (Berkeley) 07/26/84";
312382Sralph #endif
412382Sralph 
512382Sralph /*
615719Sralph  * lpc -- line printer control program -- commands:
712382Sralph  */
812382Sralph 
912382Sralph #include "lp.h"
1015719Sralph #include <sys/time.h>
1112382Sralph 
1212382Sralph /*
1312382Sralph  * kill an existing daemon and disable printing.
1412382Sralph  */
1512382Sralph abort(argc, argv)
1612382Sralph 	char *argv[];
1712382Sralph {
1812382Sralph 	register int c, status;
1912382Sralph 	register char *cp1, *cp2;
2012382Sralph 	char prbuf[100];
2112382Sralph 
2212382Sralph 	if (argc == 1) {
2312382Sralph 		printf("Usage: abort {all | printer ...}\n");
2412382Sralph 		return;
2512382Sralph 	}
2612382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
2712382Sralph 		printer = prbuf;
2812382Sralph 		while (getprent(line) > 0) {
2912382Sralph 			cp1 = prbuf;
3012382Sralph 			cp2 = line;
3112382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
3212382Sralph 				*cp1++ = c;
3312382Sralph 			*cp1 = '\0';
3416755Sralph 			abortpr(1);
3512382Sralph 		}
3612382Sralph 		return;
3712382Sralph 	}
3812382Sralph 	while (--argc) {
3912382Sralph 		printer = *++argv;
4012382Sralph 		if ((status = pgetent(line, printer)) < 0) {
4112514Sralph 			printf("cannot open printer description file\n");
4212382Sralph 			continue;
4312382Sralph 		} else if (status == 0) {
4412514Sralph 			printf("unknown printer %s\n", printer);
4512382Sralph 			continue;
4612382Sralph 		}
4716755Sralph 		abortpr(1);
4812382Sralph 	}
4912382Sralph }
5012382Sralph 
5116755Sralph abortpr(dis)
5212382Sralph {
5312382Sralph 	register FILE *fp;
5412382Sralph 	struct stat stbuf;
5512382Sralph 	int pid, fd;
5612382Sralph 
5712382Sralph 	bp = pbuf;
5812382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
5912382Sralph 		SD = DEFSPOOL;
6012382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
6112382Sralph 		LO = DEFLOCK;
6212382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
6312382Sralph 	printf("%s:\n", printer);
6412382Sralph 
6512382Sralph 	/*
6612382Sralph 	 * Turn on the owner execute bit of the lock file to disable printing.
6712382Sralph 	 */
6816755Sralph 	if (dis) {
6916755Sralph 		if (stat(line, &stbuf) >= 0) {
7016755Sralph 			if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
7116755Sralph 				printf("\tcannot disable printing\n");
7216755Sralph 			else
7316755Sralph 				printf("\tprinting disabled\n");
7416755Sralph 		} else if (errno == ENOENT) {
7516755Sralph 			if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
7616755Sralph 				printf("\tcannot create lock file\n");
7716755Sralph 			else {
7816755Sralph 				(void) close(fd);
7916755Sralph 				printf("\tprinting disabled\n");
8016755Sralph 				printf("\tno daemon to abort\n");
8116755Sralph 			}
8216755Sralph 			return;
8316755Sralph 		} else {
8416755Sralph 			printf("\tcannot stat lock file\n");
8516755Sralph 			return;
8612382Sralph 		}
8712382Sralph 	}
8812382Sralph 	/*
8912382Sralph 	 * Kill the current daemon to stop printing now.
9012382Sralph 	 */
9112382Sralph 	if ((fp = fopen(line, "r")) == NULL) {
9212382Sralph 		printf("\tcannot open lock file\n");
9312382Sralph 		return;
9412382Sralph 	}
9513146Ssam 	if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) {
9613168Sralph 		(void) fclose(fp);	/* unlocks as well */
9712382Sralph 		printf("\tno daemon to abort\n");
9812382Sralph 		return;
9912382Sralph 	}
10012382Sralph 	(void) fclose(fp);
10116755Sralph 	if (kill(pid = atoi(line), SIGTERM) < 0)
10212382Sralph 		printf("\tWarning: daemon (pid %d) not killed\n", pid);
10312382Sralph 	else
10412382Sralph 		printf("\tdaemon (pid %d) killed\n", pid);
10512382Sralph }
10612382Sralph 
10712382Sralph /*
10812382Sralph  * Remove all spool files and temporaries from the spooling area.
10912382Sralph  */
11012382Sralph clean(argc, argv)
11112382Sralph 	char *argv[];
11212382Sralph {
11312382Sralph 	register int c, status;
11412382Sralph 	register char *cp1, *cp2;
11512382Sralph 	char prbuf[100];
11612382Sralph 
11712382Sralph 	if (argc == 1) {
11812382Sralph 		printf("Usage: clean {all | printer ...}\n");
11912382Sralph 		return;
12012382Sralph 	}
12112382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
12212382Sralph 		printer = prbuf;
12312382Sralph 		while (getprent(line) > 0) {
12412382Sralph 			cp1 = prbuf;
12512382Sralph 			cp2 = line;
12612382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
12712382Sralph 				*cp1++ = c;
12812382Sralph 			*cp1 = '\0';
12912382Sralph 			cleanpr();
13012382Sralph 		}
13112382Sralph 		return;
13212382Sralph 	}
13312382Sralph 	while (--argc) {
13412382Sralph 		printer = *++argv;
13512382Sralph 		if ((status = pgetent(line, printer)) < 0) {
13612514Sralph 			printf("cannot open printer description file\n");
13712382Sralph 			continue;
13812382Sralph 		} else if (status == 0) {
13912514Sralph 			printf("unknown printer %s\n", printer);
14012382Sralph 			continue;
14112382Sralph 		}
14212382Sralph 		cleanpr();
14312382Sralph 	}
14412382Sralph }
14512382Sralph 
14615719Sralph select(d)
14715719Sralph struct direct *d;
14815719Sralph {
14915719Sralph 	int c = d->d_name[0];
15015719Sralph 
15115719Sralph 	if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f')
15215719Sralph 		return(1);
15315719Sralph 	return(0);
15415719Sralph }
15515719Sralph 
15615719Sralph /*
15715719Sralph  * Comparison routine for scandir. Sort by job number and machine, then
15815719Sralph  * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z.
15915719Sralph  */
16015719Sralph sortq(d1, d2)
16115719Sralph struct direct **d1, **d2;
16215719Sralph {
16315719Sralph 	int c1, c2;
16415719Sralph 
16515719Sralph 	if (c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3))
16615719Sralph 		return(c1);
16715719Sralph 	c1 = (*d1)->d_name[0];
16815719Sralph 	c2 = (*d2)->d_name[0];
16915719Sralph 	if (c1 == c2)
17015719Sralph 		return((*d1)->d_name[2] - (*d2)->d_name[2]);
17115719Sralph 	if (c1 == 'c')
17215719Sralph 		return(-1);
17315719Sralph 	if (c1 == 'd' || c2 == 'c')
17415719Sralph 		return(1);
17515719Sralph 	return(-1);
17615719Sralph }
17715719Sralph 
17815719Sralph /*
17915719Sralph  * Remove incomplete jobs from spooling area.
18015719Sralph  */
18112382Sralph cleanpr()
18212382Sralph {
18315719Sralph 	register int i, n;
18415719Sralph 	register char *cp, *cp1, *lp;
18515719Sralph 	struct direct **queue;
18615719Sralph 	int nitems;
18712382Sralph 
18812382Sralph 	bp = pbuf;
18912382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
19012382Sralph 		SD = DEFSPOOL;
19112382Sralph 	printf("%s:\n", printer);
19212382Sralph 
19315719Sralph 	for (lp = line, cp = SD; *lp++ = *cp++; )
19415719Sralph 		;
19515719Sralph 	lp[-1] = '/';
19615719Sralph 
19715719Sralph 	nitems = scandir(SD, &queue, select, sortq);
19815719Sralph 	if (nitems < 0) {
19912382Sralph 		printf("\tcannot examine spool directory\n");
20012382Sralph 		return;
20112382Sralph 	}
20215719Sralph 	if (nitems == 0)
20315719Sralph 		return;
20415719Sralph 	i = 0;
20515719Sralph 	do {
20615719Sralph 		cp = queue[i]->d_name;
20715719Sralph 		if (*cp == 'c') {
20815719Sralph 			n = 0;
20915719Sralph 			while (i + 1 < nitems) {
21015719Sralph 				cp1 = queue[i + 1]->d_name;
21115719Sralph 				if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3))
21215719Sralph 					break;
21315719Sralph 				i++;
21415719Sralph 				n++;
21515719Sralph 			}
21615719Sralph 			if (n == 0) {
21715719Sralph 				strcpy(lp, cp);
21815719Sralph 				unlinkf(line);
21915719Sralph 			}
22015719Sralph 		} else {
22115719Sralph 			/*
22215719Sralph 			 * Must be a df with no cf (otherwise, it would have
22315719Sralph 			 * been skipped above) or a tf file (which can always
22415719Sralph 			 * be removed).
22515719Sralph 			 */
22615719Sralph 			strcpy(lp, cp);
22715719Sralph 			unlinkf(line);
22812382Sralph 		}
22915719Sralph      	} while (++i < nitems);
23012382Sralph }
23115719Sralph 
23215719Sralph unlinkf(name)
23315719Sralph 	char	*name;
23415719Sralph {
23515719Sralph 	if (unlink(name) < 0)
23615719Sralph 		printf("\tcannot remove %s\n", name);
23715719Sralph 	else
23815719Sralph 		printf("\tremoved %s\n", name);
23915719Sralph }
24012382Sralph 
24112382Sralph /*
24212382Sralph  * Enable queuing to the printer (allow lpr's).
24312382Sralph  */
24412382Sralph enable(argc, argv)
24512382Sralph 	char *argv[];
24612382Sralph {
24712382Sralph 	register int c, status;
24812382Sralph 	register char *cp1, *cp2;
24912382Sralph 	char prbuf[100];
25012382Sralph 
25112382Sralph 	if (argc == 1) {
25212382Sralph 		printf("Usage: enable {all | printer ...}\n");
25312382Sralph 		return;
25412382Sralph 	}
25512382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
25612382Sralph 		printer = prbuf;
25712382Sralph 		while (getprent(line) > 0) {
25812382Sralph 			cp1 = prbuf;
25912382Sralph 			cp2 = line;
26012382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
26112382Sralph 				*cp1++ = c;
26212382Sralph 			*cp1 = '\0';
26312382Sralph 			enablepr();
26412382Sralph 		}
26512382Sralph 		return;
26612382Sralph 	}
26712382Sralph 	while (--argc) {
26812382Sralph 		printer = *++argv;
26912382Sralph 		if ((status = pgetent(line, printer)) < 0) {
27012514Sralph 			printf("cannot open printer description file\n");
27112382Sralph 			continue;
27212382Sralph 		} else if (status == 0) {
27312514Sralph 			printf("unknown printer %s\n", printer);
27412382Sralph 			continue;
27512382Sralph 		}
27612382Sralph 		enablepr();
27712382Sralph 	}
27812382Sralph }
27912382Sralph 
28012382Sralph enablepr()
28112382Sralph {
28212382Sralph 	struct stat stbuf;
28312382Sralph 
28412382Sralph 	bp = pbuf;
28512382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
28612382Sralph 		SD = DEFSPOOL;
28712382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
28812382Sralph 		LO = DEFLOCK;
28912382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
29012382Sralph 	printf("%s:\n", printer);
29112382Sralph 
29212382Sralph 	/*
29312382Sralph 	 * Turn off the group execute bit of the lock file to enable queuing.
29412382Sralph 	 */
29512382Sralph 	if (stat(line, &stbuf) >= 0) {
29612382Sralph 		if (chmod(line, stbuf.st_mode & 0767) < 0)
29712514Sralph 			printf("\tcannot enable queuing\n");
29812382Sralph 		else
29912382Sralph 			printf("\tqueuing enabled\n");
30012382Sralph 	}
30112382Sralph }
30212382Sralph 
30312382Sralph /*
30412382Sralph  * Disable queuing.
30512382Sralph  */
30612382Sralph disable(argc, argv)
30712382Sralph 	char *argv[];
30812382Sralph {
30912382Sralph 	register int c, status;
31012382Sralph 	register char *cp1, *cp2;
31112382Sralph 	char prbuf[100];
31212382Sralph 
31312382Sralph 	if (argc == 1) {
31412382Sralph 		printf("Usage: disable {all | printer ...}\n");
31512382Sralph 		return;
31612382Sralph 	}
31712382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
31812382Sralph 		printer = prbuf;
31912382Sralph 		while (getprent(line) > 0) {
32012382Sralph 			cp1 = prbuf;
32112382Sralph 			cp2 = line;
32212382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
32312382Sralph 				*cp1++ = c;
32412382Sralph 			*cp1 = '\0';
32512382Sralph 			disablepr();
32612382Sralph 		}
32712382Sralph 		return;
32812382Sralph 	}
32912382Sralph 	while (--argc) {
33012382Sralph 		printer = *++argv;
33112382Sralph 		if ((status = pgetent(line, printer)) < 0) {
33212514Sralph 			printf("cannot open printer description file\n");
33312382Sralph 			continue;
33412382Sralph 		} else if (status == 0) {
33512514Sralph 			printf("unknown printer %s\n", printer);
33612382Sralph 			continue;
33712382Sralph 		}
33812382Sralph 		disablepr();
33912382Sralph 	}
34012382Sralph }
34112382Sralph 
34212382Sralph disablepr()
34312382Sralph {
34412382Sralph 	register int fd;
34512382Sralph 	struct stat stbuf;
34612382Sralph 
34712382Sralph 	bp = pbuf;
34812382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
34912382Sralph 		SD = DEFSPOOL;
35012382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
35112382Sralph 		LO = DEFLOCK;
35212382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
35312382Sralph 	printf("%s:\n", printer);
35412382Sralph 	/*
35512382Sralph 	 * Turn on the group execute bit of the lock file to disable queuing.
35612382Sralph 	 */
35712382Sralph 	if (stat(line, &stbuf) >= 0) {
35812382Sralph 		if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0)
35912382Sralph 			printf("\tcannot disable queuing\n");
36012382Sralph 		else
36112382Sralph 			printf("\tqueuing disabled\n");
36212382Sralph 	} else if (errno == ENOENT) {
36313146Ssam 		if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0)
36412382Sralph 			printf("\tcannot create lock file\n");
36512382Sralph 		else {
36612382Sralph 			(void) close(fd);
36712382Sralph 			printf("\tqueuing disabled\n");
36812382Sralph 		}
36912382Sralph 		return;
37012382Sralph 	} else
37112382Sralph 		printf("\tcannot stat lock file\n");
37212382Sralph }
37312382Sralph 
37412382Sralph /*
37515907Sralph  * Disable queuing and printing and put a message into the status file
37615907Sralph  * (reason for being down).
37715907Sralph  */
37815907Sralph down(argc, argv)
37915907Sralph 	char *argv[];
38015907Sralph {
38115907Sralph 	register int c, status;
38215907Sralph 	register char *cp1, *cp2;
38315907Sralph 	char prbuf[100];
38415907Sralph 
38515907Sralph 	if (argc == 1) {
38616204Sralph 		printf("Usage: down {all | printer} [message ...]\n");
38715907Sralph 		return;
38815907Sralph 	}
38915907Sralph 	if (!strcmp(argv[1], "all")) {
39015907Sralph 		printer = prbuf;
39115907Sralph 		while (getprent(line) > 0) {
39215907Sralph 			cp1 = prbuf;
39315907Sralph 			cp2 = line;
39415907Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
39515907Sralph 				*cp1++ = c;
39615907Sralph 			*cp1 = '\0';
39715907Sralph 			putmsg(argc - 2, argv + 2);
39815907Sralph 		}
39915907Sralph 		return;
40015907Sralph 	}
40115907Sralph 	printer = argv[1];
40215907Sralph 	if ((status = pgetent(line, printer)) < 0) {
40315907Sralph 		printf("cannot open printer description file\n");
40415907Sralph 		return;
40515907Sralph 	} else if (status == 0) {
40615907Sralph 		printf("unknown printer %s\n", printer);
40715907Sralph 		return;
40815907Sralph 	}
40915907Sralph 	putmsg(argc - 2, argv + 2);
41015907Sralph }
41115907Sralph 
41215907Sralph putmsg(argc, argv)
41315907Sralph 	char **argv;
41415907Sralph {
41515907Sralph 	register int fd;
41615907Sralph 	register char *cp1, *cp2;
41715907Sralph 	char buf[1024];
41815907Sralph 	struct stat stbuf;
41915907Sralph 
42015907Sralph 	bp = pbuf;
42115907Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
42215907Sralph 		SD = DEFSPOOL;
42315907Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
42415907Sralph 		LO = DEFLOCK;
42515907Sralph 	if ((ST = pgetstr("st", &bp)) == NULL)
42615907Sralph 		ST = DEFSTAT;
42715907Sralph 	printf("%s:\n", printer);
42815907Sralph 	/*
42915907Sralph 	 * Turn on the group execute bit of the lock file to disable queuing and
43015907Sralph 	 * turn on the owner execute bit of the lock file to disable printing.
43115907Sralph 	 */
43215907Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
43315907Sralph 	if (stat(line, &stbuf) >= 0) {
43415907Sralph 		if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0)
43515907Sralph 			printf("\tcannot disable queuing\n");
43615907Sralph 		else
43715907Sralph 			printf("\tprinter and queuing disabled\n");
43815907Sralph 	} else if (errno == ENOENT) {
43915907Sralph 		if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0)
44015907Sralph 			printf("\tcannot create lock file\n");
44115907Sralph 		else {
44215907Sralph 			(void) close(fd);
44315907Sralph 			printf("\tprinter and queuing disabled\n");
44415907Sralph 		}
44515907Sralph 		return;
44615907Sralph 	} else
44715907Sralph 		printf("\tcannot stat lock file\n");
44815907Sralph 	/*
44915907Sralph 	 * Write the message into the status file.
45015907Sralph 	 */
45115907Sralph 	(void) sprintf(line, "%s/%s", SD, ST);
45215907Sralph 	fd = open(line, O_WRONLY|O_CREAT, 0664);
45315907Sralph 	if (fd < 0 || flock(fd, LOCK_EX) < 0) {
45415907Sralph 		printf("\tcannot create status file\n");
45515907Sralph 		return;
45615907Sralph 	}
45715907Sralph 	(void) ftruncate(fd, 0);
45816204Sralph 	if (argc <= 0) {
45916204Sralph 		(void) write(fd, "\n", 1);
46016204Sralph 		(void) close(fd);
46116204Sralph 		return;
46216204Sralph 	}
46315907Sralph 	cp1 = buf;
46415907Sralph 	while (--argc >= 0) {
46515907Sralph 		cp2 = *argv++;
46615907Sralph 		while (*cp1++ = *cp2++)
46715907Sralph 			;
46815907Sralph 		cp1[-1] = ' ';
46915907Sralph 	}
47015907Sralph 	cp1[-1] = '\n';
47115907Sralph 	*cp1 = '\0';
47215907Sralph 	(void) write(fd, buf, strlen(buf));
47315907Sralph 	(void) close(fd);
47415907Sralph }
47515907Sralph 
47615907Sralph /*
47712382Sralph  * Exit lpc
47812382Sralph  */
47912382Sralph quit(argc, argv)
48012382Sralph 	char *argv[];
48112382Sralph {
48212382Sralph 	exit(0);
48312382Sralph }
48412382Sralph 
48512382Sralph /*
48616755Sralph  * Kill and restart the daemon.
48712382Sralph  */
48812382Sralph restart(argc, argv)
48912382Sralph 	char *argv[];
49012382Sralph {
49112382Sralph 	register int c, status;
49212382Sralph 	register char *cp1, *cp2;
49312382Sralph 	char prbuf[100];
49412382Sralph 
49512382Sralph 	if (argc == 1) {
49612382Sralph 		printf("Usage: restart {all | printer ...}\n");
49712382Sralph 		return;
49812382Sralph 	}
49912382Sralph 	gethostname(host, sizeof(host));
50012382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
50112382Sralph 		printer = prbuf;
50212382Sralph 		while (getprent(line) > 0) {
50312382Sralph 			cp1 = prbuf;
50412382Sralph 			cp2 = line;
50512382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
50612382Sralph 				*cp1++ = c;
50712382Sralph 			*cp1 = '\0';
50816755Sralph 			abortpr(0);
50912382Sralph 			startpr(0);
51012382Sralph 		}
51112382Sralph 		return;
51212382Sralph 	}
51312382Sralph 	while (--argc) {
51412382Sralph 		printer = *++argv;
51512382Sralph 		if ((status = pgetent(line, printer)) < 0) {
51612514Sralph 			printf("cannot open printer description file\n");
51712382Sralph 			continue;
51812382Sralph 		} else if (status == 0) {
51912514Sralph 			printf("unknown printer %s\n", printer);
52012382Sralph 			continue;
52112382Sralph 		}
52216755Sralph 		abortpr(0);
52312382Sralph 		startpr(0);
52412382Sralph 	}
52512382Sralph }
52612382Sralph 
52712382Sralph /*
52812382Sralph  * Enable printing on the specified printer and startup the daemon.
52912382Sralph  */
53012382Sralph start(argc, argv)
53112382Sralph 	char *argv[];
53212382Sralph {
53312382Sralph 	register int c, status;
53412382Sralph 	register char *cp1, *cp2;
53512382Sralph 	char prbuf[100];
53612382Sralph 
53712382Sralph 	if (argc == 1) {
53812382Sralph 		printf("Usage: start {all | printer ...}\n");
53912382Sralph 		return;
54012382Sralph 	}
54112382Sralph 	gethostname(host, sizeof(host));
54212382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
54312382Sralph 		printer = prbuf;
54412382Sralph 		while (getprent(line) > 0) {
54512382Sralph 			cp1 = prbuf;
54612382Sralph 			cp2 = line;
54712382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
54812382Sralph 				*cp1++ = c;
54912382Sralph 			*cp1 = '\0';
55012382Sralph 			startpr(1);
55112382Sralph 		}
55212382Sralph 		return;
55312382Sralph 	}
55412382Sralph 	while (--argc) {
55512382Sralph 		printer = *++argv;
55612382Sralph 		if ((status = pgetent(line, printer)) < 0) {
55712514Sralph 			printf("cannot open printer description file\n");
55812382Sralph 			continue;
55912382Sralph 		} else if (status == 0) {
56012514Sralph 			printf("unknown printer %s\n", printer);
56112382Sralph 			continue;
56212382Sralph 		}
56312382Sralph 		startpr(1);
56412382Sralph 	}
56512382Sralph }
56612382Sralph 
56712382Sralph startpr(enable)
56812382Sralph {
56912382Sralph 	struct stat stbuf;
57012382Sralph 
57112382Sralph 	bp = pbuf;
57212382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
57312382Sralph 		SD = DEFSPOOL;
57412382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
57512382Sralph 		LO = DEFLOCK;
57612382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
57712382Sralph 	printf("%s:\n", printer);
57812382Sralph 
57912382Sralph 	/*
58012382Sralph 	 * Turn off the owner execute bit of the lock file to enable printing.
58112382Sralph 	 */
58212382Sralph 	if (enable && stat(line, &stbuf) >= 0) {
583*16771Sralph 		if (chmod(line, stbuf.st_mode & (enable==2 ? 0666 : 0677)) < 0)
58412382Sralph 			printf("\tcannot enable printing\n");
58512382Sralph 		else
58612382Sralph 			printf("\tprinting enabled\n");
58712382Sralph 	}
58813727Sroot 	if (!startdaemon(printer))
58912382Sralph 		printf("\tcouldn't start daemon\n");
59012382Sralph 	else
59112382Sralph 		printf("\tdaemon started\n");
59212382Sralph }
59312382Sralph 
59412382Sralph /*
59512382Sralph  * Print the status of each queue listed or all the queues.
59612382Sralph  */
59712382Sralph status(argc, argv)
59812382Sralph 	char *argv[];
59912382Sralph {
60012382Sralph 	register int c, status;
60112382Sralph 	register char *cp1, *cp2;
60212382Sralph 	char prbuf[100];
60312382Sralph 
60412382Sralph 	if (argc == 1) {
60512382Sralph 		printer = prbuf;
60612382Sralph 		while (getprent(line) > 0) {
60712382Sralph 			cp1 = prbuf;
60812382Sralph 			cp2 = line;
60912382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
61012382Sralph 				*cp1++ = c;
61112382Sralph 			*cp1 = '\0';
61212382Sralph 			prstat();
61312382Sralph 		}
61412382Sralph 		return;
61512382Sralph 	}
61612382Sralph 	while (--argc) {
61712382Sralph 		printer = *++argv;
61812382Sralph 		if ((status = pgetent(line, printer)) < 0) {
61912514Sralph 			printf("cannot open printer description file\n");
62012382Sralph 			continue;
62112382Sralph 		} else if (status == 0) {
62212514Sralph 			printf("unknown printer %s\n", printer);
62312382Sralph 			continue;
62412382Sralph 		}
62512382Sralph 		prstat();
62612382Sralph 	}
62712382Sralph }
62812382Sralph 
62912382Sralph /*
63012382Sralph  * Print the status of the printer queue.
63112382Sralph  */
63212382Sralph prstat()
63312382Sralph {
63412382Sralph 	struct stat stbuf;
63512382Sralph 	register int fd, i;
63612382Sralph 	register struct direct *dp;
63712382Sralph 	DIR *dirp;
63812382Sralph 
63912382Sralph 	bp = pbuf;
64012382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
64112382Sralph 		SD = DEFSPOOL;
64212382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
64312382Sralph 		LO = DEFLOCK;
64412382Sralph 	if ((ST = pgetstr("st", &bp)) == NULL)
64512382Sralph 		ST = DEFSTAT;
64612382Sralph 	printf("%s:\n", printer);
64712382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
64812382Sralph 	if (stat(line, &stbuf) >= 0) {
64912382Sralph 		printf("\tqueuing is %s\n",
65012382Sralph 			(stbuf.st_mode & 010) ? "disabled" : "enabled");
65112382Sralph 		printf("\tprinting is %s\n",
65212382Sralph 			(stbuf.st_mode & 0100) ? "disabled" : "enabled");
65312382Sralph 	} else {
65412382Sralph 		printf("\tqueuing is enabled\n");
65512382Sralph 		printf("\tprinting is enabled\n");
65612382Sralph 	}
65712382Sralph 	if ((dirp = opendir(SD)) == NULL) {
65812382Sralph 		printf("\tcannot examine spool directory\n");
65912382Sralph 		return;
66012382Sralph 	}
66112382Sralph 	i = 0;
66212382Sralph 	while ((dp = readdir(dirp)) != NULL) {
66312382Sralph 		if (*dp->d_name == 'c' && dp->d_name[1] == 'f')
66412382Sralph 			i++;
66512382Sralph 	}
66612382Sralph 	closedir(dirp);
66712382Sralph 	if (i == 0)
66812382Sralph 		printf("\tno entries\n");
66912382Sralph 	else if (i == 1)
67012382Sralph 		printf("\t1 entry in spool area\n");
67112382Sralph 	else
67212382Sralph 		printf("\t%d entries in spool area\n", i);
67313146Ssam 	fd = open(line, O_RDONLY);
67413146Ssam 	if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) {
67513168Sralph 		(void) close(fd);	/* unlocks as well */
67612382Sralph 		printf("\tno daemon present\n");
67712382Sralph 		return;
67812382Sralph 	}
67912382Sralph 	(void) close(fd);
68012382Sralph 	putchar('\t');
68112382Sralph 	(void) sprintf(line, "%s/%s", SD, ST);
68213146Ssam 	fd = open(line, O_RDONLY);
68313146Ssam 	if (fd >= 0) {
68413146Ssam 		(void) flock(fd, LOCK_SH);
68512382Sralph 		while ((i = read(fd, line, sizeof(line))) > 0)
68612382Sralph 			(void) fwrite(line, 1, i, stdout);
68713168Sralph 		(void) close(fd);	/* unlocks as well */
68812382Sralph 	}
68912382Sralph }
69012382Sralph 
69112382Sralph /*
69212382Sralph  * Stop the specified daemon after completing the current job and disable
69312382Sralph  * printing.
69412382Sralph  */
69512382Sralph stop(argc, argv)
69612382Sralph 	char *argv[];
69712382Sralph {
69812382Sralph 	register int c, status;
69912382Sralph 	register char *cp1, *cp2;
70012382Sralph 	char prbuf[100];
70112382Sralph 
70212382Sralph 	if (argc == 1) {
70312382Sralph 		printf("Usage: stop {all | printer ...}\n");
70412382Sralph 		return;
70512382Sralph 	}
70612382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
70712382Sralph 		printer = prbuf;
70812382Sralph 		while (getprent(line) > 0) {
70912382Sralph 			cp1 = prbuf;
71012382Sralph 			cp2 = line;
71112382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
71212382Sralph 				*cp1++ = c;
71312382Sralph 			*cp1 = '\0';
71412382Sralph 			stoppr();
71512382Sralph 		}
71612382Sralph 		return;
71712382Sralph 	}
71812382Sralph 	while (--argc) {
71912382Sralph 		printer = *++argv;
72012382Sralph 		if ((status = pgetent(line, printer)) < 0) {
72112514Sralph 			printf("cannot open printer description file\n");
72212382Sralph 			continue;
72312382Sralph 		} else if (status == 0) {
72412514Sralph 			printf("unknown printer %s\n", printer);
72512382Sralph 			continue;
72612382Sralph 		}
72712382Sralph 		stoppr();
72812382Sralph 	}
72912382Sralph }
73012382Sralph 
73112382Sralph stoppr()
73212382Sralph {
73312382Sralph 	register int fd;
73412382Sralph 	struct stat stbuf;
73512382Sralph 
73612382Sralph 	bp = pbuf;
73712382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
73812382Sralph 		SD = DEFSPOOL;
73912382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
74012382Sralph 		LO = DEFLOCK;
74112382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
74212382Sralph 	printf("%s:\n", printer);
74312382Sralph 
74412382Sralph 	/*
74512382Sralph 	 * Turn on the owner execute bit of the lock file to disable printing.
74612382Sralph 	 */
74712382Sralph 	if (stat(line, &stbuf) >= 0) {
74812382Sralph 		if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
74912382Sralph 			printf("\tcannot disable printing\n");
75012382Sralph 		else
75112382Sralph 			printf("\tprinting disabled\n");
75212382Sralph 	} else if (errno == ENOENT) {
75313146Ssam 		if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
75412382Sralph 			printf("\tcannot create lock file\n");
75512382Sralph 		else {
75612382Sralph 			(void) close(fd);
75712382Sralph 			printf("\tprinting disabled\n");
75812382Sralph 		}
75912382Sralph 	} else
76012382Sralph 		printf("\tcannot stat lock file\n");
76112382Sralph }
76213727Sroot 
76315719Sralph struct	queue **queue;
76415719Sralph int	nitems;
76515719Sralph time_t	mtime;
76615719Sralph 
76713727Sroot /*
76813727Sroot  * Put the specified jobs at the top of printer queue.
76913727Sroot  */
77013727Sroot topq(argc, argv)
77113727Sroot 	char *argv[];
77213727Sroot {
77315719Sralph 	register int n, i;
77413727Sroot 	struct stat stbuf;
77513727Sroot 	register char *cfname;
77615719Sralph 	int status, changed;
77713727Sroot 
77815719Sralph 	if (argc < 3) {
77913727Sroot 		printf("Usage: topq printer [jobnum ...] [user ...]\n");
78013727Sroot 		return;
78113727Sroot 	}
78213727Sroot 
78313727Sroot 	--argc;
78413727Sroot 	printer = *++argv;
78513727Sroot 	status = pgetent(line, printer);
78613727Sroot 	if (status < 0) {
78713727Sroot 		printf("cannot open printer description file\n");
78813727Sroot 		return;
78914151Sralph 	} else if (status == 0) {
79013727Sroot 		printf("%s: unknown printer\n", printer);
79113727Sroot 		return;
79213727Sroot 	}
79313727Sroot 	bp = pbuf;
79413727Sroot 	if ((SD = pgetstr("sd", &bp)) == NULL)
79513727Sroot 		SD = DEFSPOOL;
79613727Sroot 	if ((LO = pgetstr("lo", &bp)) == NULL)
79713727Sroot 		LO = DEFLOCK;
79813727Sroot 	printf("%s:\n", printer);
79913727Sroot 
80013727Sroot 	if (chdir(SD) < 0) {
80113727Sroot 		printf("\tcannot chdir to %s\n", SD);
80213727Sroot 		return;
80313727Sroot 	}
80413727Sroot 	nitems = getq(&queue);
80515719Sralph 	if (nitems == 0)
80615719Sralph 		return;
80715719Sralph 	changed = 0;
80815719Sralph 	mtime = queue[0]->q_time;
80915719Sralph 	for (i = argc; --i; ) {
81015719Sralph 		if (doarg(argv[i]) == 0) {
81115719Sralph 			printf("\tjob %s is not in the queue\n", argv[i]);
81213727Sroot 			continue;
81315719Sralph 		} else
81414151Sralph 			changed++;
81513727Sroot 	}
81615719Sralph 	for (i = 0; i < nitems; i++)
81715719Sralph 		free(queue[i]);
81815719Sralph 	free(queue);
81915719Sralph 	if (!changed) {
82015719Sralph 		printf("\tqueue order unchanged\n");
82115719Sralph 		return;
82213727Sroot 	}
82313727Sroot 	/*
82413727Sroot 	 * Turn on the public execute bit of the lock file to
82513727Sroot 	 * get lpd to rebuild the queue after the current job.
82613727Sroot 	 */
82714151Sralph 	if (changed && stat(LO, &stbuf) >= 0)
82814151Sralph 		(void) chmod(LO, (stbuf.st_mode & 0777) | 01);
82913727Sroot }
83013727Sroot 
83115719Sralph /*
83215719Sralph  * Reposition the job by changing the modification time of
83315719Sralph  * the control file.
83413727Sroot  */
83515719Sralph touch(q)
83615719Sralph 	struct queue *q;
83713727Sroot {
83815719Sralph 	struct timeval tvp[2];
83913727Sroot 
84015719Sralph 	tvp[0].tv_sec = tvp[1].tv_sec = --mtime;
84115719Sralph 	tvp[0].tv_usec = tvp[1].tv_usec = 0;
84215719Sralph 	return(utimes(q->q_name, tvp));
84313727Sroot }
84413727Sroot 
84513727Sroot /*
84613727Sroot  * Checks if specified job name is in the printer's queue.
84713727Sroot  * Returns:  negative (-1) if argument name is not in the queue.
84813727Sroot  */
84915719Sralph doarg(job)
85013727Sroot 	char *job;
85113727Sroot {
85215719Sralph 	register struct queue **qq;
85315719Sralph 	register int jobnum, n;
85415719Sralph 	register char *cp, *machine;
85515719Sralph 	int cnt = 0;
85614151Sralph 	FILE *fp;
85713727Sroot 
85815719Sralph 	/*
85915719Sralph 	 * Look for a job item consisting of system name, colon, number
86015719Sralph 	 * (example: ucbarpa:114)
86115719Sralph 	 */
86215719Sralph 	if ((cp = index(job, ':')) != NULL) {
86315719Sralph 		machine = job;
86415719Sralph 		*cp++ = '\0';
86515719Sralph 		job = cp;
86615719Sralph 	} else
86715719Sralph 		machine = NULL;
86815719Sralph 
86915719Sralph 	/*
87015719Sralph 	 * Check for job specified by number (example: 112 or 235ucbarpa).
87115719Sralph 	 */
87213727Sroot 	if (isdigit(*job)) {
87313727Sroot 		jobnum = 0;
87413727Sroot 		do
87513727Sroot 			jobnum = jobnum * 10 + (*job++ - '0');
87613727Sroot 		while (isdigit(*job));
87715719Sralph 		for (qq = queue + nitems; --qq >= queue; ) {
87813727Sroot 			n = 0;
87915719Sralph 			for (cp = (*qq)->q_name+3; isdigit(*cp); )
88014151Sralph 				n = n * 10 + (*cp++ - '0');
88115719Sralph 			if (jobnum != n)
88215719Sralph 				continue;
88315719Sralph 			if (*job && strcmp(job, cp) != 0)
88415719Sralph 				continue;
88515719Sralph 			if (machine != NULL && strcmp(machine, cp) != 0)
88615719Sralph 				continue;
88715719Sralph 			if (touch(*qq) == 0) {
88815719Sralph 				printf("\tmoved %s\n", (*qq)->q_name);
88915719Sralph 				cnt++;
89015719Sralph 			}
89113727Sroot 		}
89215719Sralph 		return(cnt);
89315719Sralph 	}
89415719Sralph 	/*
89515719Sralph 	 * Process item consisting of owner's name (example: henry).
89615719Sralph 	 */
89715719Sralph 	for (qq = queue + nitems; --qq >= queue; ) {
89815719Sralph 		if ((fp = fopen((*qq)->q_name, "r")) == NULL)
89913727Sroot 			continue;
90015719Sralph 		while (getline(fp) > 0)
90115719Sralph 			if (line[0] == 'P')
90215719Sralph 				break;
90315719Sralph 		(void) fclose(fp);
90415719Sralph 		if (line[0] != 'P' || strcmp(job, line+1) != 0)
90515719Sralph 			continue;
90615719Sralph 		if (touch(*qq) == 0) {
90715719Sralph 			printf("\tmoved %s\n", (*qq)->q_name);
90815719Sralph 			cnt++;
90913727Sroot 		}
91013727Sroot 	}
91115719Sralph 	return(cnt);
91213727Sroot }
91316755Sralph 
91416755Sralph /*
91516755Sralph  * Enable everything and start printer (undo `down').
91616755Sralph  */
91716755Sralph up(argc, argv)
91816755Sralph 	char *argv[];
91916755Sralph {
92016755Sralph 	register int c, status;
92116755Sralph 	register char *cp1, *cp2;
92216755Sralph 	char prbuf[100];
92316755Sralph 
92416755Sralph 	if (argc == 1) {
92516755Sralph 		printf("Usage: up {all | printer ...}\n");
92616755Sralph 		return;
92716755Sralph 	}
92816755Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
92916755Sralph 		printer = prbuf;
93016755Sralph 		while (getprent(line) > 0) {
93116755Sralph 			cp1 = prbuf;
93216755Sralph 			cp2 = line;
93316755Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
93416755Sralph 				*cp1++ = c;
93516755Sralph 			*cp1 = '\0';
93616755Sralph 			startpr(2);
93716755Sralph 		}
93816755Sralph 		return;
93916755Sralph 	}
94016755Sralph 	while (--argc) {
94116755Sralph 		printer = *++argv;
94216755Sralph 		if ((status = pgetent(line, printer)) < 0) {
94316755Sralph 			printf("cannot open printer description file\n");
94416755Sralph 			continue;
94516755Sralph 		} else if (status == 0) {
94616755Sralph 			printf("unknown printer %s\n", printer);
94716755Sralph 			continue;
94816755Sralph 		}
94916755Sralph 		startpr(2);
95016755Sralph 	}
95116755Sralph }
952