xref: /csrg-svn/usr.sbin/lpr/lpc/lpc.c (revision 12380)
1*12380Sralph #ifndef lint
2*12380Sralph static char sccsid[] = "@(#)lpc.c	4.1 (Berkeley) 05/11/83";
3*12380Sralph #endif
4*12380Sralph 
5*12380Sralph /*
6*12380Sralph  * lpc -- line printer control program
7*12380Sralph  */
8*12380Sralph #include <stdio.h>
9*12380Sralph #include <signal.h>
10*12380Sralph #include <ctype.h>
11*12380Sralph #include <setjmp.h>
12*12380Sralph 
13*12380Sralph #include "lpc.h"
14*12380Sralph 
15*12380Sralph int	fromatty;
16*12380Sralph 
17*12380Sralph char	cmdline[200];
18*12380Sralph int	margc;
19*12380Sralph char	*margv[20];
20*12380Sralph int	top;
21*12380Sralph int	intr();
22*12380Sralph struct	cmd *getcmd();
23*12380Sralph 
24*12380Sralph jmp_buf	toplevel;
25*12380Sralph 
26*12380Sralph main(argc, argv)
27*12380Sralph 	char *argv[];
28*12380Sralph {
29*12380Sralph 	register struct cmd *c;
30*12380Sralph 
31*12380Sralph 	if (--argc > 0) {
32*12380Sralph 		c = getcmd(*++argv);
33*12380Sralph 		if (c == (struct cmd *)-1) {
34*12380Sralph 			printf("?Ambiguous command\n");
35*12380Sralph 			exit(1);
36*12380Sralph 		}
37*12380Sralph 		if (c == 0) {
38*12380Sralph 			printf("?Invalid command\n");
39*12380Sralph 			exit(1);
40*12380Sralph 		}
41*12380Sralph 		if (c->c_priv && getuid()) {
42*12380Sralph 			printf("?Privileged command\n");
43*12380Sralph 			exit(1);
44*12380Sralph 		}
45*12380Sralph 		(*c->c_handler)(argc, argv);
46*12380Sralph 		exit(0);
47*12380Sralph 	}
48*12380Sralph 	fromatty = isatty(fileno(stdin));
49*12380Sralph 	top = setjmp(toplevel) == 0;
50*12380Sralph 	if (top)
51*12380Sralph 		sigset(SIGINT, intr);
52*12380Sralph 	for (;;) {
53*12380Sralph 		cmdscanner(top);
54*12380Sralph 		top = 1;
55*12380Sralph 	}
56*12380Sralph }
57*12380Sralph 
58*12380Sralph intr()
59*12380Sralph {
60*12380Sralph 	if (!fromatty)
61*12380Sralph 		exit(0);
62*12380Sralph 	longjmp(toplevel, 1);
63*12380Sralph }
64*12380Sralph 
65*12380Sralph /*
66*12380Sralph  * Command parser.
67*12380Sralph  */
68*12380Sralph cmdscanner(top)
69*12380Sralph 	int top;
70*12380Sralph {
71*12380Sralph 	register struct cmd *c;
72*12380Sralph 	extern struct cmd cmdtab[];
73*12380Sralph 	extern int help();
74*12380Sralph 
75*12380Sralph 	if (!top)
76*12380Sralph 		putchar('\n');
77*12380Sralph 	for (;;) {
78*12380Sralph 		if (fromatty) {
79*12380Sralph 			printf("lpc> ");
80*12380Sralph 			fflush(stdout);
81*12380Sralph 		}
82*12380Sralph 		if (gets(cmdline) == 0)
83*12380Sralph 			quit();
84*12380Sralph 		if (cmdline[0] == 0)
85*12380Sralph 			break;
86*12380Sralph 		makeargv();
87*12380Sralph 		c = getcmd(margv[0]);
88*12380Sralph 		if (c == (struct cmd *)-1) {
89*12380Sralph 			printf("?Ambiguous command\n");
90*12380Sralph 			continue;
91*12380Sralph 		}
92*12380Sralph 		if (c == 0) {
93*12380Sralph 			printf("?Invalid command\n");
94*12380Sralph 			continue;
95*12380Sralph 		}
96*12380Sralph 		if (c->c_priv && getuid()) {
97*12380Sralph 			printf("?Privileged command\n");
98*12380Sralph 			continue;
99*12380Sralph 		}
100*12380Sralph 		(*c->c_handler)(margc, margv);
101*12380Sralph 	}
102*12380Sralph 	longjmp(toplevel, 0);
103*12380Sralph }
104*12380Sralph 
105*12380Sralph struct cmd *
106*12380Sralph getcmd(name)
107*12380Sralph 	register char *name;
108*12380Sralph {
109*12380Sralph 	register char *p, *q;
110*12380Sralph 	register struct cmd *c, *found;
111*12380Sralph 	register int nmatches, longest;
112*12380Sralph 
113*12380Sralph 	longest = 0;
114*12380Sralph 	nmatches = 0;
115*12380Sralph 	found = 0;
116*12380Sralph 	for (c = cmdtab; p = c->c_name; c++) {
117*12380Sralph 		for (q = name; *q == *p++; q++)
118*12380Sralph 			if (*q == 0)		/* exact match? */
119*12380Sralph 				return(c);
120*12380Sralph 		if (!*q) {			/* the name was a prefix */
121*12380Sralph 			if (q - name > longest) {
122*12380Sralph 				longest = q - name;
123*12380Sralph 				nmatches = 1;
124*12380Sralph 				found = c;
125*12380Sralph 			} else if (q - name == longest)
126*12380Sralph 				nmatches++;
127*12380Sralph 		}
128*12380Sralph 	}
129*12380Sralph 	if (nmatches > 1)
130*12380Sralph 		return((struct cmd *)-1);
131*12380Sralph 	return(found);
132*12380Sralph }
133*12380Sralph 
134*12380Sralph /*
135*12380Sralph  * Slice a string up into argc/argv.
136*12380Sralph  */
137*12380Sralph makeargv()
138*12380Sralph {
139*12380Sralph 	register char *cp;
140*12380Sralph 	register char **argp = margv;
141*12380Sralph 
142*12380Sralph 	margc = 0;
143*12380Sralph 	for (cp = cmdline; *cp;) {
144*12380Sralph 		while (isspace(*cp))
145*12380Sralph 			cp++;
146*12380Sralph 		if (*cp == '\0')
147*12380Sralph 			break;
148*12380Sralph 		*argp++ = cp;
149*12380Sralph 		margc += 1;
150*12380Sralph 		while (*cp != '\0' && !isspace(*cp))
151*12380Sralph 			cp++;
152*12380Sralph 		if (*cp == '\0')
153*12380Sralph 			break;
154*12380Sralph 		*cp++ = '\0';
155*12380Sralph 	}
156*12380Sralph 	*argp++ = 0;
157*12380Sralph }
158*12380Sralph 
159*12380Sralph #define HELPINDENT (sizeof ("directory"))
160*12380Sralph 
161*12380Sralph /*
162*12380Sralph  * Help command.
163*12380Sralph  */
164*12380Sralph help(argc, argv)
165*12380Sralph 	int argc;
166*12380Sralph 	char *argv[];
167*12380Sralph {
168*12380Sralph 	register struct cmd *c;
169*12380Sralph 
170*12380Sralph 	if (argc == 1) {
171*12380Sralph 		register int i, j, w;
172*12380Sralph 		int columns, width = 0, lines;
173*12380Sralph 		extern int NCMDS;
174*12380Sralph 
175*12380Sralph 		printf("Commands may be abbreviated.  Commands are:\n\n");
176*12380Sralph 		for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
177*12380Sralph 			int len = strlen(c->c_name);
178*12380Sralph 
179*12380Sralph 			if (len > width)
180*12380Sralph 				width = len;
181*12380Sralph 		}
182*12380Sralph 		width = (width + 8) &~ 7;
183*12380Sralph 		columns = 80 / width;
184*12380Sralph 		if (columns == 0)
185*12380Sralph 			columns = 1;
186*12380Sralph 		lines = (NCMDS + columns - 1) / columns;
187*12380Sralph 		for (i = 0; i < lines; i++) {
188*12380Sralph 			for (j = 0; j < columns; j++) {
189*12380Sralph 				c = cmdtab + j * lines + i;
190*12380Sralph 				printf("%s", c->c_name);
191*12380Sralph 				if (c + lines >= &cmdtab[NCMDS]) {
192*12380Sralph 					printf("\n");
193*12380Sralph 					break;
194*12380Sralph 				}
195*12380Sralph 				w = strlen(c->c_name);
196*12380Sralph 				while (w < width) {
197*12380Sralph 					w = (w + 8) &~ 7;
198*12380Sralph 					putchar('\t');
199*12380Sralph 				}
200*12380Sralph 			}
201*12380Sralph 		}
202*12380Sralph 		return;
203*12380Sralph 	}
204*12380Sralph 	while (--argc > 0) {
205*12380Sralph 		register char *arg;
206*12380Sralph 		arg = *++argv;
207*12380Sralph 		c = getcmd(arg);
208*12380Sralph 		if (c == (struct cmd *)-1)
209*12380Sralph 			printf("?Ambiguous help command %s\n", arg);
210*12380Sralph 		else if (c == (struct cmd *)0)
211*12380Sralph 			printf("?Invalid help command %s\n", arg);
212*12380Sralph 		else
213*12380Sralph 			printf("%-*s\t%s\n", HELPINDENT,
214*12380Sralph 				c->c_name, c->c_help);
215*12380Sralph 	}
216*12380Sralph }
217