put sccs id's to some use
[unix-history] / usr / src / usr.sbin / lpr / lpc / lpc.c
CommitLineData
a3d12e3d 1#ifndef lint
5f84f8f0 2static char sccsid[] = "@(#)lpc.c 4.4 (Berkeley) %G%";
a3d12e3d
RC
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
15int fromatty;
16
17char cmdline[200];
18int margc;
19char *margv[20];
20int top;
21int intr();
22struct cmd *getcmd();
23
24jmp_buf toplevel;
25
26main(argc, argv)
27 char *argv[];
28{
29 register struct cmd *c;
2fbdb9a6
RC
30 extern char *name;
31
32 name = argv[0];
a3d12e3d
RC
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)
adec4d9e 54 signal(SIGINT, intr);
a3d12e3d
RC
55 for (;;) {
56 cmdscanner(top);
57 top = 1;
58 }
59}
60
61intr()
62{
63 if (!fromatty)
64 exit(0);
65 longjmp(toplevel, 1);
66}
67
68/*
69 * Command parser.
70 */
71cmdscanner(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
108struct cmd *
109getcmd(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 */
140makeargv()
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 */
167help(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}