xref: /csrg-svn/usr.sbin/lpr/lpc/lpc.c (revision 40549)
122428Sdist /*
222428Sdist  * 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.
1622428Sdist  */
1722428Sdist 
1812380Sralph #ifndef lint
1922428Sdist char copyright[] =
2022428Sdist "@(#) Copyright (c) 1983 Regents of the University of California.\n\
2122428Sdist  All rights reserved.\n";
2234203Sbostic #endif /* not lint */
2312380Sralph 
2422428Sdist #ifndef lint
25*40549Stef static char sccsid[] = "@(#)lpc.c	5.9 (Berkeley) 03/20/90";
2634203Sbostic #endif /* not lint */
2722428Sdist 
2812380Sralph /*
2912380Sralph  * lpc -- line printer control program
3012380Sralph  */
3112380Sralph #include <stdio.h>
3212380Sralph #include <signal.h>
3312380Sralph #include <ctype.h>
3412380Sralph #include <setjmp.h>
3525494Seric #include <syslog.h>
3612380Sralph 
3712380Sralph #include "lpc.h"
3812380Sralph 
3912380Sralph int	fromatty;
4012380Sralph 
4112380Sralph char	cmdline[200];
4212380Sralph int	margc;
4312380Sralph char	*margv[20];
4412380Sralph int	top;
4512380Sralph int	intr();
4612380Sralph struct	cmd *getcmd();
4712380Sralph 
4812380Sralph jmp_buf	toplevel;
4912380Sralph 
5012380Sralph main(argc, argv)
5112380Sralph 	char *argv[];
5212380Sralph {
5312380Sralph 	register struct cmd *c;
5412744Sralph 	extern char *name;
5512380Sralph 
5612744Sralph 	name = argv[0];
5725494Seric 	openlog("lpd", 0, LOG_LPR);
5812744Sralph 
5912380Sralph 	if (--argc > 0) {
6012380Sralph 		c = getcmd(*++argv);
6112380Sralph 		if (c == (struct cmd *)-1) {
6212380Sralph 			printf("?Ambiguous command\n");
6312380Sralph 			exit(1);
6412380Sralph 		}
6512380Sralph 		if (c == 0) {
6612380Sralph 			printf("?Invalid command\n");
6712380Sralph 			exit(1);
6812380Sralph 		}
6912380Sralph 		if (c->c_priv && getuid()) {
7012380Sralph 			printf("?Privileged command\n");
7112380Sralph 			exit(1);
7212380Sralph 		}
7312380Sralph 		(*c->c_handler)(argc, argv);
7412380Sralph 		exit(0);
7512380Sralph 	}
7612380Sralph 	fromatty = isatty(fileno(stdin));
7712380Sralph 	top = setjmp(toplevel) == 0;
7812380Sralph 	if (top)
7913147Ssam 		signal(SIGINT, intr);
8012380Sralph 	for (;;) {
8112380Sralph 		cmdscanner(top);
8212380Sralph 		top = 1;
8312380Sralph 	}
8412380Sralph }
8512380Sralph 
8612380Sralph intr()
8712380Sralph {
8812380Sralph 	if (!fromatty)
8912380Sralph 		exit(0);
9012380Sralph 	longjmp(toplevel, 1);
9112380Sralph }
9212380Sralph 
9312380Sralph /*
9412380Sralph  * Command parser.
9512380Sralph  */
9612380Sralph cmdscanner(top)
9712380Sralph 	int top;
9812380Sralph {
9912380Sralph 	register struct cmd *c;
10012380Sralph 
10112380Sralph 	if (!top)
10212380Sralph 		putchar('\n');
10312380Sralph 	for (;;) {
10412380Sralph 		if (fromatty) {
10512380Sralph 			printf("lpc> ");
10612380Sralph 			fflush(stdout);
10712380Sralph 		}
10836247Sbostic 		if (fgets(cmdline, sizeof(cmdline), stdin) == 0)
10912380Sralph 			quit();
110*40549Stef 		if (cmdline[0] == 0 || cmdline[0] == '\n')
11112380Sralph 			break;
11212380Sralph 		makeargv();
11312380Sralph 		c = getcmd(margv[0]);
11412380Sralph 		if (c == (struct cmd *)-1) {
11512380Sralph 			printf("?Ambiguous command\n");
11612380Sralph 			continue;
11712380Sralph 		}
11812380Sralph 		if (c == 0) {
11912380Sralph 			printf("?Invalid command\n");
12012380Sralph 			continue;
12112380Sralph 		}
12212380Sralph 		if (c->c_priv && getuid()) {
12312380Sralph 			printf("?Privileged command\n");
12412380Sralph 			continue;
12512380Sralph 		}
12612380Sralph 		(*c->c_handler)(margc, margv);
12712380Sralph 	}
12812380Sralph 	longjmp(toplevel, 0);
12912380Sralph }
13012380Sralph 
13133069Sbostic extern struct cmd cmdtab[];
13233069Sbostic 
13312380Sralph struct cmd *
13412380Sralph getcmd(name)
13512380Sralph 	register char *name;
13612380Sralph {
13712380Sralph 	register char *p, *q;
13812380Sralph 	register struct cmd *c, *found;
13912380Sralph 	register int nmatches, longest;
14012380Sralph 
14112380Sralph 	longest = 0;
14212380Sralph 	nmatches = 0;
14312380Sralph 	found = 0;
14412380Sralph 	for (c = cmdtab; p = c->c_name; c++) {
14512380Sralph 		for (q = name; *q == *p++; q++)
14612380Sralph 			if (*q == 0)		/* exact match? */
14712380Sralph 				return(c);
14812380Sralph 		if (!*q) {			/* the name was a prefix */
14912380Sralph 			if (q - name > longest) {
15012380Sralph 				longest = q - name;
15112380Sralph 				nmatches = 1;
15212380Sralph 				found = c;
15312380Sralph 			} else if (q - name == longest)
15412380Sralph 				nmatches++;
15512380Sralph 		}
15612380Sralph 	}
15712380Sralph 	if (nmatches > 1)
15812380Sralph 		return((struct cmd *)-1);
15912380Sralph 	return(found);
16012380Sralph }
16112380Sralph 
16212380Sralph /*
16312380Sralph  * Slice a string up into argc/argv.
16412380Sralph  */
16512380Sralph makeargv()
16612380Sralph {
16712380Sralph 	register char *cp;
16812380Sralph 	register char **argp = margv;
16912380Sralph 
17012380Sralph 	margc = 0;
17112380Sralph 	for (cp = cmdline; *cp;) {
17212380Sralph 		while (isspace(*cp))
17312380Sralph 			cp++;
17412380Sralph 		if (*cp == '\0')
17512380Sralph 			break;
17612380Sralph 		*argp++ = cp;
17712380Sralph 		margc += 1;
17812380Sralph 		while (*cp != '\0' && !isspace(*cp))
17912380Sralph 			cp++;
18012380Sralph 		if (*cp == '\0')
18112380Sralph 			break;
18212380Sralph 		*cp++ = '\0';
18312380Sralph 	}
18412380Sralph 	*argp++ = 0;
18512380Sralph }
18612380Sralph 
18712380Sralph #define HELPINDENT (sizeof ("directory"))
18812380Sralph 
18912380Sralph /*
19012380Sralph  * Help command.
19112380Sralph  */
19212380Sralph help(argc, argv)
19312380Sralph 	int argc;
19412380Sralph 	char *argv[];
19512380Sralph {
19612380Sralph 	register struct cmd *c;
19712380Sralph 
19812380Sralph 	if (argc == 1) {
19912380Sralph 		register int i, j, w;
20012380Sralph 		int columns, width = 0, lines;
20112380Sralph 		extern int NCMDS;
20212380Sralph 
20312380Sralph 		printf("Commands may be abbreviated.  Commands are:\n\n");
20439727Sbostic 		for (c = cmdtab; c->c_name; c++) {
20512380Sralph 			int len = strlen(c->c_name);
20612380Sralph 
20712380Sralph 			if (len > width)
20812380Sralph 				width = len;
20912380Sralph 		}
21012380Sralph 		width = (width + 8) &~ 7;
21112380Sralph 		columns = 80 / width;
21212380Sralph 		if (columns == 0)
21312380Sralph 			columns = 1;
21412380Sralph 		lines = (NCMDS + columns - 1) / columns;
21512380Sralph 		for (i = 0; i < lines; i++) {
21612380Sralph 			for (j = 0; j < columns; j++) {
21712380Sralph 				c = cmdtab + j * lines + i;
21839727Sbostic 				if (c->c_name)
21939727Sbostic 					printf("%s", c->c_name);
22012380Sralph 				if (c + lines >= &cmdtab[NCMDS]) {
22112380Sralph 					printf("\n");
22212380Sralph 					break;
22312380Sralph 				}
22412380Sralph 				w = strlen(c->c_name);
22512380Sralph 				while (w < width) {
22612380Sralph 					w = (w + 8) &~ 7;
22712380Sralph 					putchar('\t');
22812380Sralph 				}
22912380Sralph 			}
23012380Sralph 		}
23112380Sralph 		return;
23212380Sralph 	}
23312380Sralph 	while (--argc > 0) {
23412380Sralph 		register char *arg;
23512380Sralph 		arg = *++argv;
23612380Sralph 		c = getcmd(arg);
23712380Sralph 		if (c == (struct cmd *)-1)
23812380Sralph 			printf("?Ambiguous help command %s\n", arg);
23912380Sralph 		else if (c == (struct cmd *)0)
24012380Sralph 			printf("?Invalid help command %s\n", arg);
24112380Sralph 		else
24212380Sralph 			printf("%-*s\t%s\n", HELPINDENT,
24312380Sralph 				c->c_name, c->c_help);
24412380Sralph 	}
24512380Sralph }
246