prevent stupid Ambiquous Command error on null input line
[unix-history] / usr / src / usr.sbin / lpr / lpc / lpc.c
CommitLineData
d0aeaf5a
DF
1/*
2 * Copyright (c) 1983 Regents of the University of California.
9d85c861
KB
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
a399f6c8
KB
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
d0aeaf5a
DF
16 */
17
18#ifndef lint
19char copyright[] =
20"@(#) Copyright (c) 1983 Regents of the University of California.\n\
21 All rights reserved.\n";
9d85c861 22#endif /* not lint */
d0aeaf5a 23
a3d12e3d 24#ifndef lint
c0413642 25static char sccsid[] = "@(#)lpc.c 5.9 (Berkeley) %G%";
9d85c861 26#endif /* not lint */
a3d12e3d
RC
27
28/*
29 * lpc -- line printer control program
30 */
31#include <stdio.h>
32#include <signal.h>
33#include <ctype.h>
34#include <setjmp.h>
126fc76f 35#include <syslog.h>
a3d12e3d
RC
36
37#include "lpc.h"
38
39int fromatty;
40
41char cmdline[200];
42int margc;
43char *margv[20];
44int top;
45int intr();
46struct cmd *getcmd();
47
48jmp_buf toplevel;
49
50main(argc, argv)
51 char *argv[];
52{
53 register struct cmd *c;
2fbdb9a6
RC
54 extern char *name;
55
56 name = argv[0];
126fc76f 57 openlog("lpd", 0, LOG_LPR);
a3d12e3d
RC
58
59 if (--argc > 0) {
60 c = getcmd(*++argv);
61 if (c == (struct cmd *)-1) {
62 printf("?Ambiguous command\n");
63 exit(1);
64 }
65 if (c == 0) {
66 printf("?Invalid command\n");
67 exit(1);
68 }
69 if (c->c_priv && getuid()) {
70 printf("?Privileged command\n");
71 exit(1);
72 }
73 (*c->c_handler)(argc, argv);
74 exit(0);
75 }
76 fromatty = isatty(fileno(stdin));
77 top = setjmp(toplevel) == 0;
78 if (top)
adec4d9e 79 signal(SIGINT, intr);
a3d12e3d
RC
80 for (;;) {
81 cmdscanner(top);
82 top = 1;
83 }
84}
85
86intr()
87{
88 if (!fromatty)
89 exit(0);
90 longjmp(toplevel, 1);
91}
92
93/*
94 * Command parser.
95 */
96cmdscanner(top)
97 int top;
98{
99 register struct cmd *c;
a3d12e3d
RC
100
101 if (!top)
102 putchar('\n');
103 for (;;) {
104 if (fromatty) {
105 printf("lpc> ");
106 fflush(stdout);
107 }
c9fba2a7 108 if (fgets(cmdline, sizeof(cmdline), stdin) == 0)
a3d12e3d 109 quit();
c0413642 110 if (cmdline[0] == 0 || cmdline[0] == '\n')
a3d12e3d
RC
111 break;
112 makeargv();
113 c = getcmd(margv[0]);
114 if (c == (struct cmd *)-1) {
115 printf("?Ambiguous command\n");
116 continue;
117 }
118 if (c == 0) {
119 printf("?Invalid command\n");
120 continue;
121 }
122 if (c->c_priv && getuid()) {
123 printf("?Privileged command\n");
124 continue;
125 }
126 (*c->c_handler)(margc, margv);
127 }
128 longjmp(toplevel, 0);
129}
130
a59237a4
KB
131extern struct cmd cmdtab[];
132
a3d12e3d
RC
133struct cmd *
134getcmd(name)
135 register char *name;
136{
137 register char *p, *q;
138 register struct cmd *c, *found;
139 register int nmatches, longest;
140
141 longest = 0;
142 nmatches = 0;
143 found = 0;
144 for (c = cmdtab; p = c->c_name; c++) {
145 for (q = name; *q == *p++; q++)
146 if (*q == 0) /* exact match? */
147 return(c);
148 if (!*q) { /* the name was a prefix */
149 if (q - name > longest) {
150 longest = q - name;
151 nmatches = 1;
152 found = c;
153 } else if (q - name == longest)
154 nmatches++;
155 }
156 }
157 if (nmatches > 1)
158 return((struct cmd *)-1);
159 return(found);
160}
161
162/*
163 * Slice a string up into argc/argv.
164 */
165makeargv()
166{
167 register char *cp;
168 register char **argp = margv;
169
170 margc = 0;
171 for (cp = cmdline; *cp;) {
172 while (isspace(*cp))
173 cp++;
174 if (*cp == '\0')
175 break;
176 *argp++ = cp;
177 margc += 1;
178 while (*cp != '\0' && !isspace(*cp))
179 cp++;
180 if (*cp == '\0')
181 break;
182 *cp++ = '\0';
183 }
184 *argp++ = 0;
185}
186
187#define HELPINDENT (sizeof ("directory"))
188
189/*
190 * Help command.
191 */
192help(argc, argv)
193 int argc;
194 char *argv[];
195{
196 register struct cmd *c;
197
198 if (argc == 1) {
199 register int i, j, w;
200 int columns, width = 0, lines;
201 extern int NCMDS;
202
203 printf("Commands may be abbreviated. Commands are:\n\n");
d587cea4 204 for (c = cmdtab; c->c_name; c++) {
a3d12e3d
RC
205 int len = strlen(c->c_name);
206
207 if (len > width)
208 width = len;
209 }
210 width = (width + 8) &~ 7;
211 columns = 80 / width;
212 if (columns == 0)
213 columns = 1;
214 lines = (NCMDS + columns - 1) / columns;
215 for (i = 0; i < lines; i++) {
216 for (j = 0; j < columns; j++) {
217 c = cmdtab + j * lines + i;
d587cea4
KB
218 if (c->c_name)
219 printf("%s", c->c_name);
a3d12e3d
RC
220 if (c + lines >= &cmdtab[NCMDS]) {
221 printf("\n");
222 break;
223 }
224 w = strlen(c->c_name);
225 while (w < width) {
226 w = (w + 8) &~ 7;
227 putchar('\t');
228 }
229 }
230 }
231 return;
232 }
233 while (--argc > 0) {
234 register char *arg;
235 arg = *++argv;
236 c = getcmd(arg);
237 if (c == (struct cmd *)-1)
238 printf("?Ambiguous help command %s\n", arg);
239 else if (c == (struct cmd *)0)
240 printf("?Invalid help command %s\n", arg);
241 else
242 printf("%-*s\t%s\n", HELPINDENT,
243 c->c_name, c->c_help);
244 }
245}