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