xref: /csrg-svn/usr.sbin/lpr/lpc/cmds.c (revision 37968)
122424Sdist /*
222424Sdist  * Copyright (c) 1983 Regents of the University of California.
334203Sbostic  * All rights reserved.
434203Sbostic  *
534203Sbostic  * Redistribution and use in source and binary forms are permitted
634936Sbostic  * provided that the above copyright notice and this paragraph are
734936Sbostic  * duplicated in all such forms and that any documentation,
834936Sbostic  * advertising materials, and other materials related to such
934936Sbostic  * distribution and use acknowledge that the software was developed
1034936Sbostic  * by the University of California, Berkeley.  The name of the
1134936Sbostic  * University may not be used to endorse or promote products derived
1234936Sbostic  * from this software without specific prior written permission.
1334936Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1434936Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1534936Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1622424Sdist  */
1722424Sdist 
1812382Sralph #ifndef lint
19*37968Sbostic static char sccsid[] = "@(#)cmds.c	5.5 (Berkeley) 05/11/89";
2034203Sbostic #endif /* not lint */
2112382Sralph 
2212382Sralph /*
2315719Sralph  * lpc -- line printer control program -- commands:
2412382Sralph  */
2512382Sralph 
2612382Sralph #include "lp.h"
2715719Sralph #include <sys/time.h>
28*37968Sbostic #include "pathnames.h"
2912382Sralph 
3012382Sralph /*
3112382Sralph  * kill an existing daemon and disable printing.
3212382Sralph  */
3312382Sralph abort(argc, argv)
3412382Sralph 	char *argv[];
3512382Sralph {
3612382Sralph 	register int c, status;
3712382Sralph 	register char *cp1, *cp2;
3812382Sralph 	char prbuf[100];
3912382Sralph 
4012382Sralph 	if (argc == 1) {
4112382Sralph 		printf("Usage: abort {all | printer ...}\n");
4212382Sralph 		return;
4312382Sralph 	}
4412382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
4512382Sralph 		printer = prbuf;
4612382Sralph 		while (getprent(line) > 0) {
4712382Sralph 			cp1 = prbuf;
4812382Sralph 			cp2 = line;
4912382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
5012382Sralph 				*cp1++ = c;
5112382Sralph 			*cp1 = '\0';
5216755Sralph 			abortpr(1);
5312382Sralph 		}
5412382Sralph 		return;
5512382Sralph 	}
5612382Sralph 	while (--argc) {
5712382Sralph 		printer = *++argv;
5812382Sralph 		if ((status = pgetent(line, printer)) < 0) {
5912514Sralph 			printf("cannot open printer description file\n");
6012382Sralph 			continue;
6112382Sralph 		} else if (status == 0) {
6212514Sralph 			printf("unknown printer %s\n", printer);
6312382Sralph 			continue;
6412382Sralph 		}
6516755Sralph 		abortpr(1);
6612382Sralph 	}
6712382Sralph }
6812382Sralph 
6916755Sralph abortpr(dis)
7012382Sralph {
7112382Sralph 	register FILE *fp;
7212382Sralph 	struct stat stbuf;
7312382Sralph 	int pid, fd;
7412382Sralph 
7512382Sralph 	bp = pbuf;
7612382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
77*37968Sbostic 		SD = _PATH_DEFSPOOL;
7812382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
7912382Sralph 		LO = DEFLOCK;
8012382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
8112382Sralph 	printf("%s:\n", printer);
8212382Sralph 
8312382Sralph 	/*
8412382Sralph 	 * Turn on the owner execute bit of the lock file to disable printing.
8512382Sralph 	 */
8616755Sralph 	if (dis) {
8716755Sralph 		if (stat(line, &stbuf) >= 0) {
8816755Sralph 			if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
8916755Sralph 				printf("\tcannot disable printing\n");
9016755Sralph 			else
9116755Sralph 				printf("\tprinting disabled\n");
9216755Sralph 		} else if (errno == ENOENT) {
9316755Sralph 			if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
9416755Sralph 				printf("\tcannot create lock file\n");
9516755Sralph 			else {
9616755Sralph 				(void) close(fd);
9716755Sralph 				printf("\tprinting disabled\n");
9816755Sralph 				printf("\tno daemon to abort\n");
9916755Sralph 			}
10016755Sralph 			return;
10116755Sralph 		} else {
10216755Sralph 			printf("\tcannot stat lock file\n");
10316755Sralph 			return;
10412382Sralph 		}
10512382Sralph 	}
10612382Sralph 	/*
10712382Sralph 	 * Kill the current daemon to stop printing now.
10812382Sralph 	 */
10912382Sralph 	if ((fp = fopen(line, "r")) == NULL) {
11012382Sralph 		printf("\tcannot open lock file\n");
11112382Sralph 		return;
11212382Sralph 	}
11313146Ssam 	if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) {
11413168Sralph 		(void) fclose(fp);	/* unlocks as well */
11512382Sralph 		printf("\tno daemon to abort\n");
11612382Sralph 		return;
11712382Sralph 	}
11812382Sralph 	(void) fclose(fp);
11916755Sralph 	if (kill(pid = atoi(line), SIGTERM) < 0)
12012382Sralph 		printf("\tWarning: daemon (pid %d) not killed\n", pid);
12112382Sralph 	else
12212382Sralph 		printf("\tdaemon (pid %d) killed\n", pid);
12312382Sralph }
12412382Sralph 
12512382Sralph /*
12612382Sralph  * Remove all spool files and temporaries from the spooling area.
12712382Sralph  */
12812382Sralph clean(argc, argv)
12912382Sralph 	char *argv[];
13012382Sralph {
13112382Sralph 	register int c, status;
13212382Sralph 	register char *cp1, *cp2;
13312382Sralph 	char prbuf[100];
13412382Sralph 
13512382Sralph 	if (argc == 1) {
13612382Sralph 		printf("Usage: clean {all | printer ...}\n");
13712382Sralph 		return;
13812382Sralph 	}
13912382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
14012382Sralph 		printer = prbuf;
14112382Sralph 		while (getprent(line) > 0) {
14212382Sralph 			cp1 = prbuf;
14312382Sralph 			cp2 = line;
14412382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
14512382Sralph 				*cp1++ = c;
14612382Sralph 			*cp1 = '\0';
14712382Sralph 			cleanpr();
14812382Sralph 		}
14912382Sralph 		return;
15012382Sralph 	}
15112382Sralph 	while (--argc) {
15212382Sralph 		printer = *++argv;
15312382Sralph 		if ((status = pgetent(line, printer)) < 0) {
15412514Sralph 			printf("cannot open printer description file\n");
15512382Sralph 			continue;
15612382Sralph 		} else if (status == 0) {
15712514Sralph 			printf("unknown printer %s\n", printer);
15812382Sralph 			continue;
15912382Sralph 		}
16012382Sralph 		cleanpr();
16112382Sralph 	}
16212382Sralph }
16312382Sralph 
16415719Sralph select(d)
16515719Sralph struct direct *d;
16615719Sralph {
16715719Sralph 	int c = d->d_name[0];
16815719Sralph 
16915719Sralph 	if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f')
17015719Sralph 		return(1);
17115719Sralph 	return(0);
17215719Sralph }
17315719Sralph 
17415719Sralph /*
17515719Sralph  * Comparison routine for scandir. Sort by job number and machine, then
17615719Sralph  * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z.
17715719Sralph  */
17815719Sralph sortq(d1, d2)
17915719Sralph struct direct **d1, **d2;
18015719Sralph {
18115719Sralph 	int c1, c2;
18215719Sralph 
18315719Sralph 	if (c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3))
18415719Sralph 		return(c1);
18515719Sralph 	c1 = (*d1)->d_name[0];
18615719Sralph 	c2 = (*d2)->d_name[0];
18715719Sralph 	if (c1 == c2)
18815719Sralph 		return((*d1)->d_name[2] - (*d2)->d_name[2]);
18915719Sralph 	if (c1 == 'c')
19015719Sralph 		return(-1);
19115719Sralph 	if (c1 == 'd' || c2 == 'c')
19215719Sralph 		return(1);
19315719Sralph 	return(-1);
19415719Sralph }
19515719Sralph 
19615719Sralph /*
19715719Sralph  * Remove incomplete jobs from spooling area.
19815719Sralph  */
19912382Sralph cleanpr()
20012382Sralph {
20115719Sralph 	register int i, n;
20215719Sralph 	register char *cp, *cp1, *lp;
20315719Sralph 	struct direct **queue;
20415719Sralph 	int nitems;
20512382Sralph 
20612382Sralph 	bp = pbuf;
20712382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
208*37968Sbostic 		SD = _PATH_DEFSPOOL;
20912382Sralph 	printf("%s:\n", printer);
21012382Sralph 
21115719Sralph 	for (lp = line, cp = SD; *lp++ = *cp++; )
21215719Sralph 		;
21315719Sralph 	lp[-1] = '/';
21415719Sralph 
21515719Sralph 	nitems = scandir(SD, &queue, select, sortq);
21615719Sralph 	if (nitems < 0) {
21712382Sralph 		printf("\tcannot examine spool directory\n");
21812382Sralph 		return;
21912382Sralph 	}
22015719Sralph 	if (nitems == 0)
22115719Sralph 		return;
22215719Sralph 	i = 0;
22315719Sralph 	do {
22415719Sralph 		cp = queue[i]->d_name;
22515719Sralph 		if (*cp == 'c') {
22615719Sralph 			n = 0;
22715719Sralph 			while (i + 1 < nitems) {
22815719Sralph 				cp1 = queue[i + 1]->d_name;
22915719Sralph 				if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3))
23015719Sralph 					break;
23115719Sralph 				i++;
23215719Sralph 				n++;
23315719Sralph 			}
23415719Sralph 			if (n == 0) {
23515719Sralph 				strcpy(lp, cp);
23615719Sralph 				unlinkf(line);
23715719Sralph 			}
23815719Sralph 		} else {
23915719Sralph 			/*
24015719Sralph 			 * Must be a df with no cf (otherwise, it would have
24115719Sralph 			 * been skipped above) or a tf file (which can always
24215719Sralph 			 * be removed).
24315719Sralph 			 */
24415719Sralph 			strcpy(lp, cp);
24515719Sralph 			unlinkf(line);
24612382Sralph 		}
24715719Sralph      	} while (++i < nitems);
24812382Sralph }
24915719Sralph 
25015719Sralph unlinkf(name)
25115719Sralph 	char	*name;
25215719Sralph {
25315719Sralph 	if (unlink(name) < 0)
25415719Sralph 		printf("\tcannot remove %s\n", name);
25515719Sralph 	else
25615719Sralph 		printf("\tremoved %s\n", name);
25715719Sralph }
25812382Sralph 
25912382Sralph /*
26012382Sralph  * Enable queuing to the printer (allow lpr's).
26112382Sralph  */
26212382Sralph enable(argc, argv)
26312382Sralph 	char *argv[];
26412382Sralph {
26512382Sralph 	register int c, status;
26612382Sralph 	register char *cp1, *cp2;
26712382Sralph 	char prbuf[100];
26812382Sralph 
26912382Sralph 	if (argc == 1) {
27012382Sralph 		printf("Usage: enable {all | printer ...}\n");
27112382Sralph 		return;
27212382Sralph 	}
27312382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
27412382Sralph 		printer = prbuf;
27512382Sralph 		while (getprent(line) > 0) {
27612382Sralph 			cp1 = prbuf;
27712382Sralph 			cp2 = line;
27812382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
27912382Sralph 				*cp1++ = c;
28012382Sralph 			*cp1 = '\0';
28112382Sralph 			enablepr();
28212382Sralph 		}
28312382Sralph 		return;
28412382Sralph 	}
28512382Sralph 	while (--argc) {
28612382Sralph 		printer = *++argv;
28712382Sralph 		if ((status = pgetent(line, printer)) < 0) {
28812514Sralph 			printf("cannot open printer description file\n");
28912382Sralph 			continue;
29012382Sralph 		} else if (status == 0) {
29112514Sralph 			printf("unknown printer %s\n", printer);
29212382Sralph 			continue;
29312382Sralph 		}
29412382Sralph 		enablepr();
29512382Sralph 	}
29612382Sralph }
29712382Sralph 
29812382Sralph enablepr()
29912382Sralph {
30012382Sralph 	struct stat stbuf;
30112382Sralph 
30212382Sralph 	bp = pbuf;
30312382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
304*37968Sbostic 		SD = _PATH_DEFSPOOL;
30512382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
30612382Sralph 		LO = DEFLOCK;
30712382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
30812382Sralph 	printf("%s:\n", printer);
30912382Sralph 
31012382Sralph 	/*
31112382Sralph 	 * Turn off the group execute bit of the lock file to enable queuing.
31212382Sralph 	 */
31312382Sralph 	if (stat(line, &stbuf) >= 0) {
31412382Sralph 		if (chmod(line, stbuf.st_mode & 0767) < 0)
31512514Sralph 			printf("\tcannot enable queuing\n");
31612382Sralph 		else
31712382Sralph 			printf("\tqueuing enabled\n");
31812382Sralph 	}
31912382Sralph }
32012382Sralph 
32112382Sralph /*
32212382Sralph  * Disable queuing.
32312382Sralph  */
32412382Sralph disable(argc, argv)
32512382Sralph 	char *argv[];
32612382Sralph {
32712382Sralph 	register int c, status;
32812382Sralph 	register char *cp1, *cp2;
32912382Sralph 	char prbuf[100];
33012382Sralph 
33112382Sralph 	if (argc == 1) {
33212382Sralph 		printf("Usage: disable {all | printer ...}\n");
33312382Sralph 		return;
33412382Sralph 	}
33512382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
33612382Sralph 		printer = prbuf;
33712382Sralph 		while (getprent(line) > 0) {
33812382Sralph 			cp1 = prbuf;
33912382Sralph 			cp2 = line;
34012382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
34112382Sralph 				*cp1++ = c;
34212382Sralph 			*cp1 = '\0';
34312382Sralph 			disablepr();
34412382Sralph 		}
34512382Sralph 		return;
34612382Sralph 	}
34712382Sralph 	while (--argc) {
34812382Sralph 		printer = *++argv;
34912382Sralph 		if ((status = pgetent(line, printer)) < 0) {
35012514Sralph 			printf("cannot open printer description file\n");
35112382Sralph 			continue;
35212382Sralph 		} else if (status == 0) {
35312514Sralph 			printf("unknown printer %s\n", printer);
35412382Sralph 			continue;
35512382Sralph 		}
35612382Sralph 		disablepr();
35712382Sralph 	}
35812382Sralph }
35912382Sralph 
36012382Sralph disablepr()
36112382Sralph {
36212382Sralph 	register int fd;
36312382Sralph 	struct stat stbuf;
36412382Sralph 
36512382Sralph 	bp = pbuf;
36612382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
367*37968Sbostic 		SD = _PATH_DEFSPOOL;
36812382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
36912382Sralph 		LO = DEFLOCK;
37012382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
37112382Sralph 	printf("%s:\n", printer);
37212382Sralph 	/*
37312382Sralph 	 * Turn on the group execute bit of the lock file to disable queuing.
37412382Sralph 	 */
37512382Sralph 	if (stat(line, &stbuf) >= 0) {
37612382Sralph 		if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0)
37712382Sralph 			printf("\tcannot disable queuing\n");
37812382Sralph 		else
37912382Sralph 			printf("\tqueuing disabled\n");
38012382Sralph 	} else if (errno == ENOENT) {
38113146Ssam 		if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0)
38212382Sralph 			printf("\tcannot create lock file\n");
38312382Sralph 		else {
38412382Sralph 			(void) close(fd);
38512382Sralph 			printf("\tqueuing disabled\n");
38612382Sralph 		}
38712382Sralph 		return;
38812382Sralph 	} else
38912382Sralph 		printf("\tcannot stat lock file\n");
39012382Sralph }
39112382Sralph 
39212382Sralph /*
39315907Sralph  * Disable queuing and printing and put a message into the status file
39415907Sralph  * (reason for being down).
39515907Sralph  */
39615907Sralph down(argc, argv)
39715907Sralph 	char *argv[];
39815907Sralph {
39915907Sralph 	register int c, status;
40015907Sralph 	register char *cp1, *cp2;
40115907Sralph 	char prbuf[100];
40215907Sralph 
40315907Sralph 	if (argc == 1) {
40416204Sralph 		printf("Usage: down {all | printer} [message ...]\n");
40515907Sralph 		return;
40615907Sralph 	}
40715907Sralph 	if (!strcmp(argv[1], "all")) {
40815907Sralph 		printer = prbuf;
40915907Sralph 		while (getprent(line) > 0) {
41015907Sralph 			cp1 = prbuf;
41115907Sralph 			cp2 = line;
41215907Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
41315907Sralph 				*cp1++ = c;
41415907Sralph 			*cp1 = '\0';
41515907Sralph 			putmsg(argc - 2, argv + 2);
41615907Sralph 		}
41715907Sralph 		return;
41815907Sralph 	}
41915907Sralph 	printer = argv[1];
42015907Sralph 	if ((status = pgetent(line, printer)) < 0) {
42115907Sralph 		printf("cannot open printer description file\n");
42215907Sralph 		return;
42315907Sralph 	} else if (status == 0) {
42415907Sralph 		printf("unknown printer %s\n", printer);
42515907Sralph 		return;
42615907Sralph 	}
42715907Sralph 	putmsg(argc - 2, argv + 2);
42815907Sralph }
42915907Sralph 
43015907Sralph putmsg(argc, argv)
43115907Sralph 	char **argv;
43215907Sralph {
43315907Sralph 	register int fd;
43415907Sralph 	register char *cp1, *cp2;
43515907Sralph 	char buf[1024];
43615907Sralph 	struct stat stbuf;
43715907Sralph 
43815907Sralph 	bp = pbuf;
43915907Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
440*37968Sbostic 		SD = _PATH_DEFSPOOL;
44115907Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
44215907Sralph 		LO = DEFLOCK;
44315907Sralph 	if ((ST = pgetstr("st", &bp)) == NULL)
44415907Sralph 		ST = DEFSTAT;
44515907Sralph 	printf("%s:\n", printer);
44615907Sralph 	/*
44715907Sralph 	 * Turn on the group execute bit of the lock file to disable queuing and
44815907Sralph 	 * turn on the owner execute bit of the lock file to disable printing.
44915907Sralph 	 */
45015907Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
45115907Sralph 	if (stat(line, &stbuf) >= 0) {
45215907Sralph 		if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0)
45315907Sralph 			printf("\tcannot disable queuing\n");
45415907Sralph 		else
45515907Sralph 			printf("\tprinter and queuing disabled\n");
45615907Sralph 	} else if (errno == ENOENT) {
45715907Sralph 		if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0)
45815907Sralph 			printf("\tcannot create lock file\n");
45915907Sralph 		else {
46015907Sralph 			(void) close(fd);
46115907Sralph 			printf("\tprinter and queuing disabled\n");
46215907Sralph 		}
46315907Sralph 		return;
46415907Sralph 	} else
46515907Sralph 		printf("\tcannot stat lock file\n");
46615907Sralph 	/*
46715907Sralph 	 * Write the message into the status file.
46815907Sralph 	 */
46915907Sralph 	(void) sprintf(line, "%s/%s", SD, ST);
47015907Sralph 	fd = open(line, O_WRONLY|O_CREAT, 0664);
47115907Sralph 	if (fd < 0 || flock(fd, LOCK_EX) < 0) {
47215907Sralph 		printf("\tcannot create status file\n");
47315907Sralph 		return;
47415907Sralph 	}
47515907Sralph 	(void) ftruncate(fd, 0);
47616204Sralph 	if (argc <= 0) {
47716204Sralph 		(void) write(fd, "\n", 1);
47816204Sralph 		(void) close(fd);
47916204Sralph 		return;
48016204Sralph 	}
48115907Sralph 	cp1 = buf;
48215907Sralph 	while (--argc >= 0) {
48315907Sralph 		cp2 = *argv++;
48415907Sralph 		while (*cp1++ = *cp2++)
48515907Sralph 			;
48615907Sralph 		cp1[-1] = ' ';
48715907Sralph 	}
48815907Sralph 	cp1[-1] = '\n';
48915907Sralph 	*cp1 = '\0';
49015907Sralph 	(void) write(fd, buf, strlen(buf));
49115907Sralph 	(void) close(fd);
49215907Sralph }
49315907Sralph 
49415907Sralph /*
49512382Sralph  * Exit lpc
49612382Sralph  */
49712382Sralph quit(argc, argv)
49812382Sralph 	char *argv[];
49912382Sralph {
50012382Sralph 	exit(0);
50112382Sralph }
50212382Sralph 
50312382Sralph /*
50416755Sralph  * Kill and restart the daemon.
50512382Sralph  */
50612382Sralph restart(argc, argv)
50712382Sralph 	char *argv[];
50812382Sralph {
50912382Sralph 	register int c, status;
51012382Sralph 	register char *cp1, *cp2;
51112382Sralph 	char prbuf[100];
51212382Sralph 
51312382Sralph 	if (argc == 1) {
51412382Sralph 		printf("Usage: restart {all | printer ...}\n");
51512382Sralph 		return;
51612382Sralph 	}
51712382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
51812382Sralph 		printer = prbuf;
51912382Sralph 		while (getprent(line) > 0) {
52012382Sralph 			cp1 = prbuf;
52112382Sralph 			cp2 = line;
52212382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
52312382Sralph 				*cp1++ = c;
52412382Sralph 			*cp1 = '\0';
52516755Sralph 			abortpr(0);
52612382Sralph 			startpr(0);
52712382Sralph 		}
52812382Sralph 		return;
52912382Sralph 	}
53012382Sralph 	while (--argc) {
53112382Sralph 		printer = *++argv;
53212382Sralph 		if ((status = pgetent(line, printer)) < 0) {
53312514Sralph 			printf("cannot open printer description file\n");
53412382Sralph 			continue;
53512382Sralph 		} else if (status == 0) {
53612514Sralph 			printf("unknown printer %s\n", printer);
53712382Sralph 			continue;
53812382Sralph 		}
53916755Sralph 		abortpr(0);
54012382Sralph 		startpr(0);
54112382Sralph 	}
54212382Sralph }
54312382Sralph 
54412382Sralph /*
54512382Sralph  * Enable printing on the specified printer and startup the daemon.
54612382Sralph  */
54712382Sralph start(argc, argv)
54812382Sralph 	char *argv[];
54912382Sralph {
55012382Sralph 	register int c, status;
55112382Sralph 	register char *cp1, *cp2;
55212382Sralph 	char prbuf[100];
55312382Sralph 
55412382Sralph 	if (argc == 1) {
55512382Sralph 		printf("Usage: start {all | printer ...}\n");
55612382Sralph 		return;
55712382Sralph 	}
55812382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
55912382Sralph 		printer = prbuf;
56012382Sralph 		while (getprent(line) > 0) {
56112382Sralph 			cp1 = prbuf;
56212382Sralph 			cp2 = line;
56312382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
56412382Sralph 				*cp1++ = c;
56512382Sralph 			*cp1 = '\0';
56612382Sralph 			startpr(1);
56712382Sralph 		}
56812382Sralph 		return;
56912382Sralph 	}
57012382Sralph 	while (--argc) {
57112382Sralph 		printer = *++argv;
57212382Sralph 		if ((status = pgetent(line, printer)) < 0) {
57312514Sralph 			printf("cannot open printer description file\n");
57412382Sralph 			continue;
57512382Sralph 		} else if (status == 0) {
57612514Sralph 			printf("unknown printer %s\n", printer);
57712382Sralph 			continue;
57812382Sralph 		}
57912382Sralph 		startpr(1);
58012382Sralph 	}
58112382Sralph }
58212382Sralph 
58312382Sralph startpr(enable)
58412382Sralph {
58512382Sralph 	struct stat stbuf;
58612382Sralph 
58712382Sralph 	bp = pbuf;
58812382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
589*37968Sbostic 		SD = _PATH_DEFSPOOL;
59012382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
59112382Sralph 		LO = DEFLOCK;
59212382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
59312382Sralph 	printf("%s:\n", printer);
59412382Sralph 
59512382Sralph 	/*
59612382Sralph 	 * Turn off the owner execute bit of the lock file to enable printing.
59712382Sralph 	 */
59812382Sralph 	if (enable && stat(line, &stbuf) >= 0) {
59916771Sralph 		if (chmod(line, stbuf.st_mode & (enable==2 ? 0666 : 0677)) < 0)
60012382Sralph 			printf("\tcannot enable printing\n");
60112382Sralph 		else
60212382Sralph 			printf("\tprinting enabled\n");
60312382Sralph 	}
60413727Sroot 	if (!startdaemon(printer))
60512382Sralph 		printf("\tcouldn't start daemon\n");
60612382Sralph 	else
60712382Sralph 		printf("\tdaemon started\n");
60812382Sralph }
60912382Sralph 
61012382Sralph /*
61112382Sralph  * Print the status of each queue listed or all the queues.
61212382Sralph  */
61312382Sralph status(argc, argv)
61412382Sralph 	char *argv[];
61512382Sralph {
61612382Sralph 	register int c, status;
61712382Sralph 	register char *cp1, *cp2;
61812382Sralph 	char prbuf[100];
61912382Sralph 
62012382Sralph 	if (argc == 1) {
62112382Sralph 		printer = prbuf;
62212382Sralph 		while (getprent(line) > 0) {
62312382Sralph 			cp1 = prbuf;
62412382Sralph 			cp2 = line;
62512382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
62612382Sralph 				*cp1++ = c;
62712382Sralph 			*cp1 = '\0';
62812382Sralph 			prstat();
62912382Sralph 		}
63012382Sralph 		return;
63112382Sralph 	}
63212382Sralph 	while (--argc) {
63312382Sralph 		printer = *++argv;
63412382Sralph 		if ((status = pgetent(line, printer)) < 0) {
63512514Sralph 			printf("cannot open printer description file\n");
63612382Sralph 			continue;
63712382Sralph 		} else if (status == 0) {
63812514Sralph 			printf("unknown printer %s\n", printer);
63912382Sralph 			continue;
64012382Sralph 		}
64112382Sralph 		prstat();
64212382Sralph 	}
64312382Sralph }
64412382Sralph 
64512382Sralph /*
64612382Sralph  * Print the status of the printer queue.
64712382Sralph  */
64812382Sralph prstat()
64912382Sralph {
65012382Sralph 	struct stat stbuf;
65112382Sralph 	register int fd, i;
65212382Sralph 	register struct direct *dp;
65312382Sralph 	DIR *dirp;
65412382Sralph 
65512382Sralph 	bp = pbuf;
65612382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
657*37968Sbostic 		SD = _PATH_DEFSPOOL;
65812382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
65912382Sralph 		LO = DEFLOCK;
66012382Sralph 	if ((ST = pgetstr("st", &bp)) == NULL)
66112382Sralph 		ST = DEFSTAT;
66212382Sralph 	printf("%s:\n", printer);
66312382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
66412382Sralph 	if (stat(line, &stbuf) >= 0) {
66512382Sralph 		printf("\tqueuing is %s\n",
66612382Sralph 			(stbuf.st_mode & 010) ? "disabled" : "enabled");
66712382Sralph 		printf("\tprinting is %s\n",
66812382Sralph 			(stbuf.st_mode & 0100) ? "disabled" : "enabled");
66912382Sralph 	} else {
67012382Sralph 		printf("\tqueuing is enabled\n");
67112382Sralph 		printf("\tprinting is enabled\n");
67212382Sralph 	}
67312382Sralph 	if ((dirp = opendir(SD)) == NULL) {
67412382Sralph 		printf("\tcannot examine spool directory\n");
67512382Sralph 		return;
67612382Sralph 	}
67712382Sralph 	i = 0;
67812382Sralph 	while ((dp = readdir(dirp)) != NULL) {
67912382Sralph 		if (*dp->d_name == 'c' && dp->d_name[1] == 'f')
68012382Sralph 			i++;
68112382Sralph 	}
68212382Sralph 	closedir(dirp);
68312382Sralph 	if (i == 0)
68412382Sralph 		printf("\tno entries\n");
68512382Sralph 	else if (i == 1)
68612382Sralph 		printf("\t1 entry in spool area\n");
68712382Sralph 	else
68812382Sralph 		printf("\t%d entries in spool area\n", i);
68913146Ssam 	fd = open(line, O_RDONLY);
69013146Ssam 	if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) {
69113168Sralph 		(void) close(fd);	/* unlocks as well */
69212382Sralph 		printf("\tno daemon present\n");
69312382Sralph 		return;
69412382Sralph 	}
69512382Sralph 	(void) close(fd);
69612382Sralph 	putchar('\t');
69712382Sralph 	(void) sprintf(line, "%s/%s", SD, ST);
69813146Ssam 	fd = open(line, O_RDONLY);
69913146Ssam 	if (fd >= 0) {
70013146Ssam 		(void) flock(fd, LOCK_SH);
70112382Sralph 		while ((i = read(fd, line, sizeof(line))) > 0)
70212382Sralph 			(void) fwrite(line, 1, i, stdout);
70313168Sralph 		(void) close(fd);	/* unlocks as well */
70412382Sralph 	}
70512382Sralph }
70612382Sralph 
70712382Sralph /*
70812382Sralph  * Stop the specified daemon after completing the current job and disable
70912382Sralph  * printing.
71012382Sralph  */
71112382Sralph stop(argc, argv)
71212382Sralph 	char *argv[];
71312382Sralph {
71412382Sralph 	register int c, status;
71512382Sralph 	register char *cp1, *cp2;
71612382Sralph 	char prbuf[100];
71712382Sralph 
71812382Sralph 	if (argc == 1) {
71912382Sralph 		printf("Usage: stop {all | printer ...}\n");
72012382Sralph 		return;
72112382Sralph 	}
72212382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
72312382Sralph 		printer = prbuf;
72412382Sralph 		while (getprent(line) > 0) {
72512382Sralph 			cp1 = prbuf;
72612382Sralph 			cp2 = line;
72712382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
72812382Sralph 				*cp1++ = c;
72912382Sralph 			*cp1 = '\0';
73012382Sralph 			stoppr();
73112382Sralph 		}
73212382Sralph 		return;
73312382Sralph 	}
73412382Sralph 	while (--argc) {
73512382Sralph 		printer = *++argv;
73612382Sralph 		if ((status = pgetent(line, printer)) < 0) {
73712514Sralph 			printf("cannot open printer description file\n");
73812382Sralph 			continue;
73912382Sralph 		} else if (status == 0) {
74012514Sralph 			printf("unknown printer %s\n", printer);
74112382Sralph 			continue;
74212382Sralph 		}
74312382Sralph 		stoppr();
74412382Sralph 	}
74512382Sralph }
74612382Sralph 
74712382Sralph stoppr()
74812382Sralph {
74912382Sralph 	register int fd;
75012382Sralph 	struct stat stbuf;
75112382Sralph 
75212382Sralph 	bp = pbuf;
75312382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
754*37968Sbostic 		SD = _PATH_DEFSPOOL;
75512382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
75612382Sralph 		LO = DEFLOCK;
75712382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
75812382Sralph 	printf("%s:\n", printer);
75912382Sralph 
76012382Sralph 	/*
76112382Sralph 	 * Turn on the owner execute bit of the lock file to disable printing.
76212382Sralph 	 */
76312382Sralph 	if (stat(line, &stbuf) >= 0) {
76412382Sralph 		if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
76512382Sralph 			printf("\tcannot disable printing\n");
76612382Sralph 		else
76712382Sralph 			printf("\tprinting disabled\n");
76812382Sralph 	} else if (errno == ENOENT) {
76913146Ssam 		if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
77012382Sralph 			printf("\tcannot create lock file\n");
77112382Sralph 		else {
77212382Sralph 			(void) close(fd);
77312382Sralph 			printf("\tprinting disabled\n");
77412382Sralph 		}
77512382Sralph 	} else
77612382Sralph 		printf("\tcannot stat lock file\n");
77712382Sralph }
77813727Sroot 
77915719Sralph struct	queue **queue;
78015719Sralph int	nitems;
78115719Sralph time_t	mtime;
78215719Sralph 
78313727Sroot /*
78413727Sroot  * Put the specified jobs at the top of printer queue.
78513727Sroot  */
78613727Sroot topq(argc, argv)
78713727Sroot 	char *argv[];
78813727Sroot {
78915719Sralph 	register int n, i;
79013727Sroot 	struct stat stbuf;
79113727Sroot 	register char *cfname;
79215719Sralph 	int status, changed;
79313727Sroot 
79415719Sralph 	if (argc < 3) {
79513727Sroot 		printf("Usage: topq printer [jobnum ...] [user ...]\n");
79613727Sroot 		return;
79713727Sroot 	}
79813727Sroot 
79913727Sroot 	--argc;
80013727Sroot 	printer = *++argv;
80113727Sroot 	status = pgetent(line, printer);
80213727Sroot 	if (status < 0) {
80313727Sroot 		printf("cannot open printer description file\n");
80413727Sroot 		return;
80514151Sralph 	} else if (status == 0) {
80613727Sroot 		printf("%s: unknown printer\n", printer);
80713727Sroot 		return;
80813727Sroot 	}
80913727Sroot 	bp = pbuf;
81013727Sroot 	if ((SD = pgetstr("sd", &bp)) == NULL)
811*37968Sbostic 		SD = _PATH_DEFSPOOL;
81213727Sroot 	if ((LO = pgetstr("lo", &bp)) == NULL)
81313727Sroot 		LO = DEFLOCK;
81413727Sroot 	printf("%s:\n", printer);
81513727Sroot 
81613727Sroot 	if (chdir(SD) < 0) {
81713727Sroot 		printf("\tcannot chdir to %s\n", SD);
81813727Sroot 		return;
81913727Sroot 	}
82013727Sroot 	nitems = getq(&queue);
82115719Sralph 	if (nitems == 0)
82215719Sralph 		return;
82315719Sralph 	changed = 0;
82415719Sralph 	mtime = queue[0]->q_time;
82515719Sralph 	for (i = argc; --i; ) {
82615719Sralph 		if (doarg(argv[i]) == 0) {
82715719Sralph 			printf("\tjob %s is not in the queue\n", argv[i]);
82813727Sroot 			continue;
82915719Sralph 		} else
83014151Sralph 			changed++;
83113727Sroot 	}
83215719Sralph 	for (i = 0; i < nitems; i++)
83315719Sralph 		free(queue[i]);
83415719Sralph 	free(queue);
83515719Sralph 	if (!changed) {
83615719Sralph 		printf("\tqueue order unchanged\n");
83715719Sralph 		return;
83813727Sroot 	}
83913727Sroot 	/*
84013727Sroot 	 * Turn on the public execute bit of the lock file to
84113727Sroot 	 * get lpd to rebuild the queue after the current job.
84213727Sroot 	 */
84314151Sralph 	if (changed && stat(LO, &stbuf) >= 0)
84414151Sralph 		(void) chmod(LO, (stbuf.st_mode & 0777) | 01);
84513727Sroot }
84613727Sroot 
84715719Sralph /*
84815719Sralph  * Reposition the job by changing the modification time of
84915719Sralph  * the control file.
85013727Sroot  */
85115719Sralph touch(q)
85215719Sralph 	struct queue *q;
85313727Sroot {
85415719Sralph 	struct timeval tvp[2];
85513727Sroot 
85615719Sralph 	tvp[0].tv_sec = tvp[1].tv_sec = --mtime;
85715719Sralph 	tvp[0].tv_usec = tvp[1].tv_usec = 0;
85815719Sralph 	return(utimes(q->q_name, tvp));
85913727Sroot }
86013727Sroot 
86113727Sroot /*
86213727Sroot  * Checks if specified job name is in the printer's queue.
86313727Sroot  * Returns:  negative (-1) if argument name is not in the queue.
86413727Sroot  */
86515719Sralph doarg(job)
86613727Sroot 	char *job;
86713727Sroot {
86815719Sralph 	register struct queue **qq;
86915719Sralph 	register int jobnum, n;
87015719Sralph 	register char *cp, *machine;
87115719Sralph 	int cnt = 0;
87214151Sralph 	FILE *fp;
87313727Sroot 
87415719Sralph 	/*
87515719Sralph 	 * Look for a job item consisting of system name, colon, number
87615719Sralph 	 * (example: ucbarpa:114)
87715719Sralph 	 */
87815719Sralph 	if ((cp = index(job, ':')) != NULL) {
87915719Sralph 		machine = job;
88015719Sralph 		*cp++ = '\0';
88115719Sralph 		job = cp;
88215719Sralph 	} else
88315719Sralph 		machine = NULL;
88415719Sralph 
88515719Sralph 	/*
88615719Sralph 	 * Check for job specified by number (example: 112 or 235ucbarpa).
88715719Sralph 	 */
88813727Sroot 	if (isdigit(*job)) {
88913727Sroot 		jobnum = 0;
89013727Sroot 		do
89113727Sroot 			jobnum = jobnum * 10 + (*job++ - '0');
89213727Sroot 		while (isdigit(*job));
89315719Sralph 		for (qq = queue + nitems; --qq >= queue; ) {
89413727Sroot 			n = 0;
89515719Sralph 			for (cp = (*qq)->q_name+3; isdigit(*cp); )
89614151Sralph 				n = n * 10 + (*cp++ - '0');
89715719Sralph 			if (jobnum != n)
89815719Sralph 				continue;
89915719Sralph 			if (*job && strcmp(job, cp) != 0)
90015719Sralph 				continue;
90115719Sralph 			if (machine != NULL && strcmp(machine, cp) != 0)
90215719Sralph 				continue;
90315719Sralph 			if (touch(*qq) == 0) {
90415719Sralph 				printf("\tmoved %s\n", (*qq)->q_name);
90515719Sralph 				cnt++;
90615719Sralph 			}
90713727Sroot 		}
90815719Sralph 		return(cnt);
90915719Sralph 	}
91015719Sralph 	/*
91115719Sralph 	 * Process item consisting of owner's name (example: henry).
91215719Sralph 	 */
91315719Sralph 	for (qq = queue + nitems; --qq >= queue; ) {
91415719Sralph 		if ((fp = fopen((*qq)->q_name, "r")) == NULL)
91513727Sroot 			continue;
91615719Sralph 		while (getline(fp) > 0)
91715719Sralph 			if (line[0] == 'P')
91815719Sralph 				break;
91915719Sralph 		(void) fclose(fp);
92015719Sralph 		if (line[0] != 'P' || strcmp(job, line+1) != 0)
92115719Sralph 			continue;
92215719Sralph 		if (touch(*qq) == 0) {
92315719Sralph 			printf("\tmoved %s\n", (*qq)->q_name);
92415719Sralph 			cnt++;
92513727Sroot 		}
92613727Sroot 	}
92715719Sralph 	return(cnt);
92813727Sroot }
92916755Sralph 
93016755Sralph /*
93116755Sralph  * Enable everything and start printer (undo `down').
93216755Sralph  */
93316755Sralph up(argc, argv)
93416755Sralph 	char *argv[];
93516755Sralph {
93616755Sralph 	register int c, status;
93716755Sralph 	register char *cp1, *cp2;
93816755Sralph 	char prbuf[100];
93916755Sralph 
94016755Sralph 	if (argc == 1) {
94116755Sralph 		printf("Usage: up {all | printer ...}\n");
94216755Sralph 		return;
94316755Sralph 	}
94416755Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
94516755Sralph 		printer = prbuf;
94616755Sralph 		while (getprent(line) > 0) {
94716755Sralph 			cp1 = prbuf;
94816755Sralph 			cp2 = line;
94916755Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
95016755Sralph 				*cp1++ = c;
95116755Sralph 			*cp1 = '\0';
95216755Sralph 			startpr(2);
95316755Sralph 		}
95416755Sralph 		return;
95516755Sralph 	}
95616755Sralph 	while (--argc) {
95716755Sralph 		printer = *++argv;
95816755Sralph 		if ((status = pgetent(line, printer)) < 0) {
95916755Sralph 			printf("cannot open printer description file\n");
96016755Sralph 			continue;
96116755Sralph 		} else if (status == 0) {
96216755Sralph 			printf("unknown printer %s\n", printer);
96316755Sralph 			continue;
96416755Sralph 		}
96516755Sralph 		startpr(2);
96616755Sralph 	}
96716755Sralph }
968