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