xref: /csrg-svn/usr.sbin/lpr/lpc/cmds.c (revision 15907)
112382Sralph #ifndef lint
2*15907Sralph static char sccsid[] = "@(#)cmds.c	4.10 (Berkeley) 01/30/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';
3412382Sralph 			abortpr();
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 		}
4712382Sralph 		abortpr();
4812382Sralph 	}
4912382Sralph }
5012382Sralph 
5112382Sralph abortpr()
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 	 */
6812382Sralph 	if (stat(line, &stbuf) >= 0) {
6912382Sralph 		if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
7012382Sralph 			printf("\tcannot disable printing\n");
7112382Sralph 		else
7212382Sralph 			printf("\tprinting disabled\n");
7312382Sralph 	} else if (errno == ENOENT) {
7413146Ssam 		if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
7512514Sralph 			printf("\tcannot create lock file\n");
7612382Sralph 		else {
7712382Sralph 			(void) close(fd);
7812382Sralph 			printf("\tprinting disabled\n");
7912382Sralph 			printf("\tno daemon to abort\n");
8012382Sralph 		}
8112382Sralph 		return;
8212382Sralph 	} else {
8312382Sralph 		printf("\tcannot stat lock file\n");
8412382Sralph 		return;
8512382Sralph 	}
8612382Sralph 	/*
8712382Sralph 	 * Kill the current daemon to stop printing now.
8812382Sralph 	 */
8912382Sralph 	if ((fp = fopen(line, "r")) == NULL) {
9012382Sralph 		printf("\tcannot open lock file\n");
9112382Sralph 		return;
9212382Sralph 	}
9313146Ssam 	if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) {
9413168Sralph 		(void) fclose(fp);	/* unlocks as well */
9512382Sralph 		printf("\tno daemon to abort\n");
9612382Sralph 		return;
9712382Sralph 	}
9812382Sralph 	(void) fclose(fp);
9912382Sralph 	if (kill(pid = atoi(line), SIGINT) < 0)
10012382Sralph 		printf("\tWarning: daemon (pid %d) not killed\n", pid);
10112382Sralph 	else
10212382Sralph 		printf("\tdaemon (pid %d) killed\n", pid);
10312382Sralph }
10412382Sralph 
10512382Sralph /*
10612382Sralph  * Remove all spool files and temporaries from the spooling area.
10712382Sralph  */
10812382Sralph clean(argc, argv)
10912382Sralph 	char *argv[];
11012382Sralph {
11112382Sralph 	register int c, status;
11212382Sralph 	register char *cp1, *cp2;
11312382Sralph 	char prbuf[100];
11412382Sralph 
11512382Sralph 	if (argc == 1) {
11612382Sralph 		printf("Usage: clean {all | printer ...}\n");
11712382Sralph 		return;
11812382Sralph 	}
11912382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
12012382Sralph 		printer = prbuf;
12112382Sralph 		while (getprent(line) > 0) {
12212382Sralph 			cp1 = prbuf;
12312382Sralph 			cp2 = line;
12412382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
12512382Sralph 				*cp1++ = c;
12612382Sralph 			*cp1 = '\0';
12712382Sralph 			cleanpr();
12812382Sralph 		}
12912382Sralph 		return;
13012382Sralph 	}
13112382Sralph 	while (--argc) {
13212382Sralph 		printer = *++argv;
13312382Sralph 		if ((status = pgetent(line, printer)) < 0) {
13412514Sralph 			printf("cannot open printer description file\n");
13512382Sralph 			continue;
13612382Sralph 		} else if (status == 0) {
13712514Sralph 			printf("unknown printer %s\n", printer);
13812382Sralph 			continue;
13912382Sralph 		}
14012382Sralph 		cleanpr();
14112382Sralph 	}
14212382Sralph }
14312382Sralph 
14415719Sralph select(d)
14515719Sralph struct direct *d;
14615719Sralph {
14715719Sralph 	int c = d->d_name[0];
14815719Sralph 
14915719Sralph 	if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f')
15015719Sralph 		return(1);
15115719Sralph 	return(0);
15215719Sralph }
15315719Sralph 
15415719Sralph /*
15515719Sralph  * Comparison routine for scandir. Sort by job number and machine, then
15615719Sralph  * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z.
15715719Sralph  */
15815719Sralph sortq(d1, d2)
15915719Sralph struct direct **d1, **d2;
16015719Sralph {
16115719Sralph 	int c1, c2;
16215719Sralph 
16315719Sralph 	if (c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3))
16415719Sralph 		return(c1);
16515719Sralph 	c1 = (*d1)->d_name[0];
16615719Sralph 	c2 = (*d2)->d_name[0];
16715719Sralph 	if (c1 == c2)
16815719Sralph 		return((*d1)->d_name[2] - (*d2)->d_name[2]);
16915719Sralph 	if (c1 == 'c')
17015719Sralph 		return(-1);
17115719Sralph 	if (c1 == 'd' || c2 == 'c')
17215719Sralph 		return(1);
17315719Sralph 	return(-1);
17415719Sralph }
17515719Sralph 
17615719Sralph /*
17715719Sralph  * Remove incomplete jobs from spooling area.
17815719Sralph  */
17912382Sralph cleanpr()
18012382Sralph {
18115719Sralph 	register int i, n;
18215719Sralph 	register char *cp, *cp1, *lp;
18315719Sralph 	struct direct **queue;
18415719Sralph 	int nitems;
18512382Sralph 
18612382Sralph 	bp = pbuf;
18712382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
18812382Sralph 		SD = DEFSPOOL;
18912382Sralph 	printf("%s:\n", printer);
19012382Sralph 
19115719Sralph 	for (lp = line, cp = SD; *lp++ = *cp++; )
19215719Sralph 		;
19315719Sralph 	lp[-1] = '/';
19415719Sralph 
19515719Sralph 	nitems = scandir(SD, &queue, select, sortq);
19615719Sralph 	if (nitems < 0) {
19712382Sralph 		printf("\tcannot examine spool directory\n");
19812382Sralph 		return;
19912382Sralph 	}
20015719Sralph 	if (nitems == 0)
20115719Sralph 		return;
20215719Sralph 	i = 0;
20315719Sralph 	do {
20415719Sralph 		cp = queue[i]->d_name;
20515719Sralph 		if (*cp == 'c') {
20615719Sralph 			n = 0;
20715719Sralph 			while (i + 1 < nitems) {
20815719Sralph 				cp1 = queue[i + 1]->d_name;
20915719Sralph 				if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3))
21015719Sralph 					break;
21115719Sralph 				i++;
21215719Sralph 				n++;
21315719Sralph 			}
21415719Sralph 			if (n == 0) {
21515719Sralph 				strcpy(lp, cp);
21615719Sralph 				unlinkf(line);
21715719Sralph 			}
21815719Sralph 		} else {
21915719Sralph 			/*
22015719Sralph 			 * Must be a df with no cf (otherwise, it would have
22115719Sralph 			 * been skipped above) or a tf file (which can always
22215719Sralph 			 * be removed).
22315719Sralph 			 */
22415719Sralph 			strcpy(lp, cp);
22515719Sralph 			unlinkf(line);
22612382Sralph 		}
22715719Sralph      	} while (++i < nitems);
22812382Sralph }
22915719Sralph 
23015719Sralph unlinkf(name)
23115719Sralph 	char	*name;
23215719Sralph {
23315719Sralph 	if (unlink(name) < 0)
23415719Sralph 		printf("\tcannot remove %s\n", name);
23515719Sralph 	else
23615719Sralph 		printf("\tremoved %s\n", name);
23715719Sralph }
23812382Sralph 
23912382Sralph /*
24012382Sralph  * Enable queuing to the printer (allow lpr's).
24112382Sralph  */
24212382Sralph enable(argc, argv)
24312382Sralph 	char *argv[];
24412382Sralph {
24512382Sralph 	register int c, status;
24612382Sralph 	register char *cp1, *cp2;
24712382Sralph 	char prbuf[100];
24812382Sralph 
24912382Sralph 	if (argc == 1) {
25012382Sralph 		printf("Usage: enable {all | printer ...}\n");
25112382Sralph 		return;
25212382Sralph 	}
25312382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
25412382Sralph 		printer = prbuf;
25512382Sralph 		while (getprent(line) > 0) {
25612382Sralph 			cp1 = prbuf;
25712382Sralph 			cp2 = line;
25812382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
25912382Sralph 				*cp1++ = c;
26012382Sralph 			*cp1 = '\0';
26112382Sralph 			enablepr();
26212382Sralph 		}
26312382Sralph 		return;
26412382Sralph 	}
26512382Sralph 	while (--argc) {
26612382Sralph 		printer = *++argv;
26712382Sralph 		if ((status = pgetent(line, printer)) < 0) {
26812514Sralph 			printf("cannot open printer description file\n");
26912382Sralph 			continue;
27012382Sralph 		} else if (status == 0) {
27112514Sralph 			printf("unknown printer %s\n", printer);
27212382Sralph 			continue;
27312382Sralph 		}
27412382Sralph 		enablepr();
27512382Sralph 	}
27612382Sralph }
27712382Sralph 
27812382Sralph enablepr()
27912382Sralph {
28012382Sralph 	struct stat stbuf;
28112382Sralph 
28212382Sralph 	bp = pbuf;
28312382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
28412382Sralph 		SD = DEFSPOOL;
28512382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
28612382Sralph 		LO = DEFLOCK;
28712382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
28812382Sralph 	printf("%s:\n", printer);
28912382Sralph 
29012382Sralph 	/*
29112382Sralph 	 * Turn off the group execute bit of the lock file to enable queuing.
29212382Sralph 	 */
29312382Sralph 	if (stat(line, &stbuf) >= 0) {
29412382Sralph 		if (chmod(line, stbuf.st_mode & 0767) < 0)
29512514Sralph 			printf("\tcannot enable queuing\n");
29612382Sralph 		else
29712382Sralph 			printf("\tqueuing enabled\n");
29812382Sralph 	}
29912382Sralph }
30012382Sralph 
30112382Sralph /*
30212382Sralph  * Disable queuing.
30312382Sralph  */
30412382Sralph disable(argc, argv)
30512382Sralph 	char *argv[];
30612382Sralph {
30712382Sralph 	register int c, status;
30812382Sralph 	register char *cp1, *cp2;
30912382Sralph 	char prbuf[100];
31012382Sralph 
31112382Sralph 	if (argc == 1) {
31212382Sralph 		printf("Usage: disable {all | printer ...}\n");
31312382Sralph 		return;
31412382Sralph 	}
31512382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
31612382Sralph 		printer = prbuf;
31712382Sralph 		while (getprent(line) > 0) {
31812382Sralph 			cp1 = prbuf;
31912382Sralph 			cp2 = line;
32012382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
32112382Sralph 				*cp1++ = c;
32212382Sralph 			*cp1 = '\0';
32312382Sralph 			disablepr();
32412382Sralph 		}
32512382Sralph 		return;
32612382Sralph 	}
32712382Sralph 	while (--argc) {
32812382Sralph 		printer = *++argv;
32912382Sralph 		if ((status = pgetent(line, printer)) < 0) {
33012514Sralph 			printf("cannot open printer description file\n");
33112382Sralph 			continue;
33212382Sralph 		} else if (status == 0) {
33312514Sralph 			printf("unknown printer %s\n", printer);
33412382Sralph 			continue;
33512382Sralph 		}
33612382Sralph 		disablepr();
33712382Sralph 	}
33812382Sralph }
33912382Sralph 
34012382Sralph disablepr()
34112382Sralph {
34212382Sralph 	register int fd;
34312382Sralph 	struct stat stbuf;
34412382Sralph 
34512382Sralph 	bp = pbuf;
34612382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
34712382Sralph 		SD = DEFSPOOL;
34812382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
34912382Sralph 		LO = DEFLOCK;
35012382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
35112382Sralph 	printf("%s:\n", printer);
35212382Sralph 	/*
35312382Sralph 	 * Turn on the group execute bit of the lock file to disable queuing.
35412382Sralph 	 */
35512382Sralph 	if (stat(line, &stbuf) >= 0) {
35612382Sralph 		if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0)
35712382Sralph 			printf("\tcannot disable queuing\n");
35812382Sralph 		else
35912382Sralph 			printf("\tqueuing disabled\n");
36012382Sralph 	} else if (errno == ENOENT) {
36113146Ssam 		if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0)
36212382Sralph 			printf("\tcannot create lock file\n");
36312382Sralph 		else {
36412382Sralph 			(void) close(fd);
36512382Sralph 			printf("\tqueuing disabled\n");
36612382Sralph 		}
36712382Sralph 		return;
36812382Sralph 	} else
36912382Sralph 		printf("\tcannot stat lock file\n");
37012382Sralph }
37112382Sralph 
37212382Sralph /*
373*15907Sralph  * Disable queuing and printing and put a message into the status file
374*15907Sralph  * (reason for being down).
375*15907Sralph  */
376*15907Sralph down(argc, argv)
377*15907Sralph 	char *argv[];
378*15907Sralph {
379*15907Sralph 	register int c, status;
380*15907Sralph 	register char *cp1, *cp2;
381*15907Sralph 	char prbuf[100];
382*15907Sralph 
383*15907Sralph 	if (argc == 1) {
384*15907Sralph 		printf("Usage: disable {all | printer} [message ...]\n");
385*15907Sralph 		return;
386*15907Sralph 	}
387*15907Sralph 	if (!strcmp(argv[1], "all")) {
388*15907Sralph 		printer = prbuf;
389*15907Sralph 		while (getprent(line) > 0) {
390*15907Sralph 			cp1 = prbuf;
391*15907Sralph 			cp2 = line;
392*15907Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
393*15907Sralph 				*cp1++ = c;
394*15907Sralph 			*cp1 = '\0';
395*15907Sralph 			putmsg(argc - 2, argv + 2);
396*15907Sralph 		}
397*15907Sralph 		return;
398*15907Sralph 	}
399*15907Sralph 	printer = argv[1];
400*15907Sralph 	if ((status = pgetent(line, printer)) < 0) {
401*15907Sralph 		printf("cannot open printer description file\n");
402*15907Sralph 		return;
403*15907Sralph 	} else if (status == 0) {
404*15907Sralph 		printf("unknown printer %s\n", printer);
405*15907Sralph 		return;
406*15907Sralph 	}
407*15907Sralph 	putmsg(argc - 2, argv + 2);
408*15907Sralph }
409*15907Sralph 
410*15907Sralph putmsg(argc, argv)
411*15907Sralph 	char **argv;
412*15907Sralph {
413*15907Sralph 	register int fd;
414*15907Sralph 	register char *cp1, *cp2;
415*15907Sralph 	char buf[1024];
416*15907Sralph 	struct stat stbuf;
417*15907Sralph 
418*15907Sralph 	bp = pbuf;
419*15907Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
420*15907Sralph 		SD = DEFSPOOL;
421*15907Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
422*15907Sralph 		LO = DEFLOCK;
423*15907Sralph 	if ((ST = pgetstr("st", &bp)) == NULL)
424*15907Sralph 		ST = DEFSTAT;
425*15907Sralph 	printf("%s:\n", printer);
426*15907Sralph 	/*
427*15907Sralph 	 * Turn on the group execute bit of the lock file to disable queuing and
428*15907Sralph 	 * turn on the owner execute bit of the lock file to disable printing.
429*15907Sralph 	 */
430*15907Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
431*15907Sralph 	if (stat(line, &stbuf) >= 0) {
432*15907Sralph 		if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0)
433*15907Sralph 			printf("\tcannot disable queuing\n");
434*15907Sralph 		else
435*15907Sralph 			printf("\tprinter and queuing disabled\n");
436*15907Sralph 	} else if (errno == ENOENT) {
437*15907Sralph 		if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0)
438*15907Sralph 			printf("\tcannot create lock file\n");
439*15907Sralph 		else {
440*15907Sralph 			(void) close(fd);
441*15907Sralph 			printf("\tprinter and queuing disabled\n");
442*15907Sralph 		}
443*15907Sralph 		return;
444*15907Sralph 	} else
445*15907Sralph 		printf("\tcannot stat lock file\n");
446*15907Sralph 	/*
447*15907Sralph 	 * Write the message into the status file.
448*15907Sralph 	 */
449*15907Sralph 	if (argc <= 0)
450*15907Sralph 		return;
451*15907Sralph 	(void) sprintf(line, "%s/%s", SD, ST);
452*15907Sralph 	fd = open(line, O_WRONLY|O_CREAT, 0664);
453*15907Sralph 	if (fd < 0 || flock(fd, LOCK_EX) < 0) {
454*15907Sralph 		printf("\tcannot create status file\n");
455*15907Sralph 		return;
456*15907Sralph 	}
457*15907Sralph 	(void) ftruncate(fd, 0);
458*15907Sralph 	cp1 = buf;
459*15907Sralph 	while (--argc >= 0) {
460*15907Sralph 		cp2 = *argv++;
461*15907Sralph 		while (*cp1++ = *cp2++)
462*15907Sralph 			;
463*15907Sralph 		cp1[-1] = ' ';
464*15907Sralph 	}
465*15907Sralph 	cp1[-1] = '\n';
466*15907Sralph 	*cp1 = '\0';
467*15907Sralph 	(void) write(fd, buf, strlen(buf));
468*15907Sralph 	(void) close(fd);
469*15907Sralph }
470*15907Sralph 
471*15907Sralph /*
47212382Sralph  * Exit lpc
47312382Sralph  */
47412382Sralph quit(argc, argv)
47512382Sralph 	char *argv[];
47612382Sralph {
47712382Sralph 	exit(0);
47812382Sralph }
47912382Sralph 
48012382Sralph /*
48112382Sralph  * Startup the daemon.
48212382Sralph  */
48312382Sralph restart(argc, argv)
48412382Sralph 	char *argv[];
48512382Sralph {
48612382Sralph 	register int c, status;
48712382Sralph 	register char *cp1, *cp2;
48812382Sralph 	char prbuf[100];
48912382Sralph 
49012382Sralph 	if (argc == 1) {
49112382Sralph 		printf("Usage: restart {all | printer ...}\n");
49212382Sralph 		return;
49312382Sralph 	}
49412382Sralph 	gethostname(host, sizeof(host));
49512382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
49612382Sralph 		printer = prbuf;
49712382Sralph 		while (getprent(line) > 0) {
49812382Sralph 			cp1 = prbuf;
49912382Sralph 			cp2 = line;
50012382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
50112382Sralph 				*cp1++ = c;
50212382Sralph 			*cp1 = '\0';
50312382Sralph 			startpr(0);
50412382Sralph 		}
50512382Sralph 		return;
50612382Sralph 	}
50712382Sralph 	while (--argc) {
50812382Sralph 		printer = *++argv;
50912382Sralph 		if ((status = pgetent(line, printer)) < 0) {
51012514Sralph 			printf("cannot open printer description file\n");
51112382Sralph 			continue;
51212382Sralph 		} else if (status == 0) {
51312514Sralph 			printf("unknown printer %s\n", printer);
51412382Sralph 			continue;
51512382Sralph 		}
51612382Sralph 		startpr(0);
51712382Sralph 	}
51812382Sralph }
51912382Sralph 
52012382Sralph /*
52112382Sralph  * Enable printing on the specified printer and startup the daemon.
52212382Sralph  */
52312382Sralph start(argc, argv)
52412382Sralph 	char *argv[];
52512382Sralph {
52612382Sralph 	register int c, status;
52712382Sralph 	register char *cp1, *cp2;
52812382Sralph 	char prbuf[100];
52912382Sralph 
53012382Sralph 	if (argc == 1) {
53112382Sralph 		printf("Usage: start {all | printer ...}\n");
53212382Sralph 		return;
53312382Sralph 	}
53412382Sralph 	gethostname(host, sizeof(host));
53512382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
53612382Sralph 		printer = prbuf;
53712382Sralph 		while (getprent(line) > 0) {
53812382Sralph 			cp1 = prbuf;
53912382Sralph 			cp2 = line;
54012382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
54112382Sralph 				*cp1++ = c;
54212382Sralph 			*cp1 = '\0';
54312382Sralph 			startpr(1);
54412382Sralph 		}
54512382Sralph 		return;
54612382Sralph 	}
54712382Sralph 	while (--argc) {
54812382Sralph 		printer = *++argv;
54912382Sralph 		if ((status = pgetent(line, printer)) < 0) {
55012514Sralph 			printf("cannot open printer description file\n");
55112382Sralph 			continue;
55212382Sralph 		} else if (status == 0) {
55312514Sralph 			printf("unknown printer %s\n", printer);
55412382Sralph 			continue;
55512382Sralph 		}
55612382Sralph 		startpr(1);
55712382Sralph 	}
55812382Sralph }
55912382Sralph 
56012382Sralph startpr(enable)
56112382Sralph {
56212382Sralph 	struct stat stbuf;
56312382Sralph 
56412382Sralph 	bp = pbuf;
56512382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
56612382Sralph 		SD = DEFSPOOL;
56712382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
56812382Sralph 		LO = DEFLOCK;
56912382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
57012382Sralph 	printf("%s:\n", printer);
57112382Sralph 
57212382Sralph 	/*
57312382Sralph 	 * Turn off the owner execute bit of the lock file to enable printing.
57412382Sralph 	 */
57512382Sralph 	if (enable && stat(line, &stbuf) >= 0) {
57612382Sralph 		if (chmod(line, stbuf.st_mode & 0677) < 0)
57712382Sralph 			printf("\tcannot enable printing\n");
57812382Sralph 		else
57912382Sralph 			printf("\tprinting enabled\n");
58012382Sralph 	}
58113727Sroot 	if (!startdaemon(printer))
58212382Sralph 		printf("\tcouldn't start daemon\n");
58312382Sralph 	else
58412382Sralph 		printf("\tdaemon started\n");
58512382Sralph }
58612382Sralph 
58712382Sralph /*
58812382Sralph  * Print the status of each queue listed or all the queues.
58912382Sralph  */
59012382Sralph status(argc, argv)
59112382Sralph 	char *argv[];
59212382Sralph {
59312382Sralph 	register int c, status;
59412382Sralph 	register char *cp1, *cp2;
59512382Sralph 	char prbuf[100];
59612382Sralph 
59712382Sralph 	if (argc == 1) {
59812382Sralph 		printer = prbuf;
59912382Sralph 		while (getprent(line) > 0) {
60012382Sralph 			cp1 = prbuf;
60112382Sralph 			cp2 = line;
60212382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
60312382Sralph 				*cp1++ = c;
60412382Sralph 			*cp1 = '\0';
60512382Sralph 			prstat();
60612382Sralph 		}
60712382Sralph 		return;
60812382Sralph 	}
60912382Sralph 	while (--argc) {
61012382Sralph 		printer = *++argv;
61112382Sralph 		if ((status = pgetent(line, printer)) < 0) {
61212514Sralph 			printf("cannot open printer description file\n");
61312382Sralph 			continue;
61412382Sralph 		} else if (status == 0) {
61512514Sralph 			printf("unknown printer %s\n", printer);
61612382Sralph 			continue;
61712382Sralph 		}
61812382Sralph 		prstat();
61912382Sralph 	}
62012382Sralph }
62112382Sralph 
62212382Sralph /*
62312382Sralph  * Print the status of the printer queue.
62412382Sralph  */
62512382Sralph prstat()
62612382Sralph {
62712382Sralph 	struct stat stbuf;
62812382Sralph 	register int fd, i;
62912382Sralph 	register struct direct *dp;
63012382Sralph 	DIR *dirp;
63112382Sralph 
63212382Sralph 	bp = pbuf;
63312382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
63412382Sralph 		SD = DEFSPOOL;
63512382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
63612382Sralph 		LO = DEFLOCK;
63712382Sralph 	if ((ST = pgetstr("st", &bp)) == NULL)
63812382Sralph 		ST = DEFSTAT;
63912382Sralph 	printf("%s:\n", printer);
64012382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
64112382Sralph 	if (stat(line, &stbuf) >= 0) {
64212382Sralph 		printf("\tqueuing is %s\n",
64312382Sralph 			(stbuf.st_mode & 010) ? "disabled" : "enabled");
64412382Sralph 		printf("\tprinting is %s\n",
64512382Sralph 			(stbuf.st_mode & 0100) ? "disabled" : "enabled");
64612382Sralph 	} else {
64712382Sralph 		printf("\tqueuing is enabled\n");
64812382Sralph 		printf("\tprinting is enabled\n");
64912382Sralph 	}
65012382Sralph 	if ((dirp = opendir(SD)) == NULL) {
65112382Sralph 		printf("\tcannot examine spool directory\n");
65212382Sralph 		return;
65312382Sralph 	}
65412382Sralph 	i = 0;
65512382Sralph 	while ((dp = readdir(dirp)) != NULL) {
65612382Sralph 		if (*dp->d_name == 'c' && dp->d_name[1] == 'f')
65712382Sralph 			i++;
65812382Sralph 	}
65912382Sralph 	closedir(dirp);
66012382Sralph 	if (i == 0)
66112382Sralph 		printf("\tno entries\n");
66212382Sralph 	else if (i == 1)
66312382Sralph 		printf("\t1 entry in spool area\n");
66412382Sralph 	else
66512382Sralph 		printf("\t%d entries in spool area\n", i);
66613146Ssam 	fd = open(line, O_RDONLY);
66713146Ssam 	if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) {
66813168Sralph 		(void) close(fd);	/* unlocks as well */
66912382Sralph 		printf("\tno daemon present\n");
67012382Sralph 		return;
67112382Sralph 	}
67212382Sralph 	(void) close(fd);
67312382Sralph 	putchar('\t');
67412382Sralph 	(void) sprintf(line, "%s/%s", SD, ST);
67513146Ssam 	fd = open(line, O_RDONLY);
67613146Ssam 	if (fd >= 0) {
67713146Ssam 		(void) flock(fd, LOCK_SH);
67812382Sralph 		while ((i = read(fd, line, sizeof(line))) > 0)
67912382Sralph 			(void) fwrite(line, 1, i, stdout);
68013168Sralph 		(void) close(fd);	/* unlocks as well */
68112382Sralph 	}
68212382Sralph }
68312382Sralph 
68412382Sralph /*
68512382Sralph  * Stop the specified daemon after completing the current job and disable
68612382Sralph  * printing.
68712382Sralph  */
68812382Sralph stop(argc, argv)
68912382Sralph 	char *argv[];
69012382Sralph {
69112382Sralph 	register int c, status;
69212382Sralph 	register char *cp1, *cp2;
69312382Sralph 	char prbuf[100];
69412382Sralph 
69512382Sralph 	if (argc == 1) {
69612382Sralph 		printf("Usage: stop {all | printer ...}\n");
69712382Sralph 		return;
69812382Sralph 	}
69912382Sralph 	if (argc == 2 && !strcmp(argv[1], "all")) {
70012382Sralph 		printer = prbuf;
70112382Sralph 		while (getprent(line) > 0) {
70212382Sralph 			cp1 = prbuf;
70312382Sralph 			cp2 = line;
70412382Sralph 			while ((c = *cp2++) && c != '|' && c != ':')
70512382Sralph 				*cp1++ = c;
70612382Sralph 			*cp1 = '\0';
70712382Sralph 			stoppr();
70812382Sralph 		}
70912382Sralph 		return;
71012382Sralph 	}
71112382Sralph 	while (--argc) {
71212382Sralph 		printer = *++argv;
71312382Sralph 		if ((status = pgetent(line, printer)) < 0) {
71412514Sralph 			printf("cannot open printer description file\n");
71512382Sralph 			continue;
71612382Sralph 		} else if (status == 0) {
71712514Sralph 			printf("unknown printer %s\n", printer);
71812382Sralph 			continue;
71912382Sralph 		}
72012382Sralph 		stoppr();
72112382Sralph 	}
72212382Sralph }
72312382Sralph 
72412382Sralph stoppr()
72512382Sralph {
72612382Sralph 	register int fd;
72712382Sralph 	struct stat stbuf;
72812382Sralph 
72912382Sralph 	bp = pbuf;
73012382Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
73112382Sralph 		SD = DEFSPOOL;
73212382Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
73312382Sralph 		LO = DEFLOCK;
73412382Sralph 	(void) sprintf(line, "%s/%s", SD, LO);
73512382Sralph 	printf("%s:\n", printer);
73612382Sralph 
73712382Sralph 	/*
73812382Sralph 	 * Turn on the owner execute bit of the lock file to disable printing.
73912382Sralph 	 */
74012382Sralph 	if (stat(line, &stbuf) >= 0) {
74112382Sralph 		if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
74212382Sralph 			printf("\tcannot disable printing\n");
74312382Sralph 		else
74412382Sralph 			printf("\tprinting disabled\n");
74512382Sralph 	} else if (errno == ENOENT) {
74613146Ssam 		if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
74712382Sralph 			printf("\tcannot create lock file\n");
74812382Sralph 		else {
74912382Sralph 			(void) close(fd);
75012382Sralph 			printf("\tprinting disabled\n");
75112382Sralph 		}
75212382Sralph 	} else
75312382Sralph 		printf("\tcannot stat lock file\n");
75412382Sralph }
75513727Sroot 
75615719Sralph struct	queue **queue;
75715719Sralph int	nitems;
75815719Sralph time_t	mtime;
75915719Sralph 
76013727Sroot /*
76113727Sroot  * Put the specified jobs at the top of printer queue.
76213727Sroot  */
76313727Sroot topq(argc, argv)
76413727Sroot 	char *argv[];
76513727Sroot {
76615719Sralph 	register int n, i;
76713727Sroot 	struct stat stbuf;
76813727Sroot 	register char *cfname;
76915719Sralph 	int status, changed;
77013727Sroot 
77115719Sralph 	if (argc < 3) {
77213727Sroot 		printf("Usage: topq printer [jobnum ...] [user ...]\n");
77313727Sroot 		return;
77413727Sroot 	}
77513727Sroot 
77613727Sroot 	--argc;
77713727Sroot 	printer = *++argv;
77813727Sroot 	status = pgetent(line, printer);
77913727Sroot 	if (status < 0) {
78013727Sroot 		printf("cannot open printer description file\n");
78113727Sroot 		return;
78214151Sralph 	} else if (status == 0) {
78313727Sroot 		printf("%s: unknown printer\n", printer);
78413727Sroot 		return;
78513727Sroot 	}
78613727Sroot 	bp = pbuf;
78713727Sroot 	if ((SD = pgetstr("sd", &bp)) == NULL)
78813727Sroot 		SD = DEFSPOOL;
78913727Sroot 	if ((LO = pgetstr("lo", &bp)) == NULL)
79013727Sroot 		LO = DEFLOCK;
79113727Sroot 	printf("%s:\n", printer);
79213727Sroot 
79313727Sroot 	if (chdir(SD) < 0) {
79413727Sroot 		printf("\tcannot chdir to %s\n", SD);
79513727Sroot 		return;
79613727Sroot 	}
79713727Sroot 	nitems = getq(&queue);
79815719Sralph 	if (nitems == 0)
79915719Sralph 		return;
80015719Sralph 	changed = 0;
80115719Sralph 	mtime = queue[0]->q_time;
80215719Sralph 	for (i = argc; --i; ) {
80315719Sralph 		if (doarg(argv[i]) == 0) {
80415719Sralph 			printf("\tjob %s is not in the queue\n", argv[i]);
80513727Sroot 			continue;
80615719Sralph 		} else
80714151Sralph 			changed++;
80813727Sroot 	}
80915719Sralph 	for (i = 0; i < nitems; i++)
81015719Sralph 		free(queue[i]);
81115719Sralph 	free(queue);
81215719Sralph 	if (!changed) {
81315719Sralph 		printf("\tqueue order unchanged\n");
81415719Sralph 		return;
81513727Sroot 	}
81613727Sroot 	/*
81713727Sroot 	 * Turn on the public execute bit of the lock file to
81813727Sroot 	 * get lpd to rebuild the queue after the current job.
81913727Sroot 	 */
82014151Sralph 	if (changed && stat(LO, &stbuf) >= 0)
82114151Sralph 		(void) chmod(LO, (stbuf.st_mode & 0777) | 01);
82213727Sroot }
82313727Sroot 
82415719Sralph /*
82515719Sralph  * Reposition the job by changing the modification time of
82615719Sralph  * the control file.
82713727Sroot  */
82815719Sralph touch(q)
82915719Sralph 	struct queue *q;
83013727Sroot {
83115719Sralph 	struct timeval tvp[2];
83213727Sroot 
83315719Sralph 	tvp[0].tv_sec = tvp[1].tv_sec = --mtime;
83415719Sralph 	tvp[0].tv_usec = tvp[1].tv_usec = 0;
83515719Sralph 	return(utimes(q->q_name, tvp));
83613727Sroot }
83713727Sroot 
83813727Sroot /*
83913727Sroot  * Checks if specified job name is in the printer's queue.
84013727Sroot  * Returns:  negative (-1) if argument name is not in the queue.
84113727Sroot  */
84215719Sralph doarg(job)
84313727Sroot 	char *job;
84413727Sroot {
84515719Sralph 	register struct queue **qq;
84615719Sralph 	register int jobnum, n;
84715719Sralph 	register char *cp, *machine;
84815719Sralph 	int cnt = 0;
84914151Sralph 	FILE *fp;
85013727Sroot 
85115719Sralph 	/*
85215719Sralph 	 * Look for a job item consisting of system name, colon, number
85315719Sralph 	 * (example: ucbarpa:114)
85415719Sralph 	 */
85515719Sralph 	if ((cp = index(job, ':')) != NULL) {
85615719Sralph 		machine = job;
85715719Sralph 		*cp++ = '\0';
85815719Sralph 		job = cp;
85915719Sralph 	} else
86015719Sralph 		machine = NULL;
86115719Sralph 
86215719Sralph 	/*
86315719Sralph 	 * Check for job specified by number (example: 112 or 235ucbarpa).
86415719Sralph 	 */
86513727Sroot 	if (isdigit(*job)) {
86613727Sroot 		jobnum = 0;
86713727Sroot 		do
86813727Sroot 			jobnum = jobnum * 10 + (*job++ - '0');
86913727Sroot 		while (isdigit(*job));
87015719Sralph 		for (qq = queue + nitems; --qq >= queue; ) {
87113727Sroot 			n = 0;
87215719Sralph 			for (cp = (*qq)->q_name+3; isdigit(*cp); )
87314151Sralph 				n = n * 10 + (*cp++ - '0');
87415719Sralph 			if (jobnum != n)
87515719Sralph 				continue;
87615719Sralph 			if (*job && strcmp(job, cp) != 0)
87715719Sralph 				continue;
87815719Sralph 			if (machine != NULL && strcmp(machine, cp) != 0)
87915719Sralph 				continue;
88015719Sralph 			if (touch(*qq) == 0) {
88115719Sralph 				printf("\tmoved %s\n", (*qq)->q_name);
88215719Sralph 				cnt++;
88315719Sralph 			}
88413727Sroot 		}
88515719Sralph 		return(cnt);
88615719Sralph 	}
88715719Sralph 	/*
88815719Sralph 	 * Process item consisting of owner's name (example: henry).
88915719Sralph 	 */
89015719Sralph 	for (qq = queue + nitems; --qq >= queue; ) {
89115719Sralph 		if ((fp = fopen((*qq)->q_name, "r")) == NULL)
89213727Sroot 			continue;
89315719Sralph 		while (getline(fp) > 0)
89415719Sralph 			if (line[0] == 'P')
89515719Sralph 				break;
89615719Sralph 		(void) fclose(fp);
89715719Sralph 		if (line[0] != 'P' || strcmp(job, line+1) != 0)
89815719Sralph 			continue;
89915719Sralph 		if (touch(*qq) == 0) {
90015719Sralph 			printf("\tmoved %s\n", (*qq)->q_name);
90115719Sralph 			cnt++;
90213727Sroot 		}
90313727Sroot 	}
90415719Sralph 	return(cnt);
90513727Sroot }
906