|
|
1.1 root 1: /*
2: * Copyright (c) 1983 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
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.
16: */
17:
18: #ifndef lint
19: char copyright[] =
20: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
21: All rights reserved.\n";
22: #endif /* not lint */
23:
24: #ifndef lint
25: static char sccsid[] = "@(#)lpc.c 5.6 (Berkeley) 6/30/88";
26: #endif /* not lint */
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>
35: #include <syslog.h>
36:
37: #include "lpc.h"
38:
39: int fromatty;
40:
41: char cmdline[200];
42: int margc;
43: char *margv[20];
44: int top;
45: int intr();
46: struct cmd *getcmd();
47:
48: jmp_buf toplevel;
49:
50: main(argc, argv)
51: char *argv[];
52: {
53: register struct cmd *c;
54: extern char *name;
55:
56: name = argv[0];
57: openlog("lpd", 0, LOG_LPR);
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)
79: signal(SIGINT, intr);
80: for (;;) {
81: cmdscanner(top);
82: top = 1;
83: }
84: }
85:
86: intr()
87: {
88: if (!fromatty)
89: exit(0);
90: longjmp(toplevel, 1);
91: }
92:
93: /*
94: * Command parser.
95: */
96: cmdscanner(top)
97: int top;
98: {
99: register struct cmd *c;
100:
101: if (!top)
102: putchar('\n');
103: for (;;) {
104: if (fromatty) {
105: printf("lpc> ");
106: fflush(stdout);
107: }
108: if (gets(cmdline) == 0)
109: quit();
110: if (cmdline[0] == 0)
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:
131: extern struct cmd cmdtab[];
132:
133: struct cmd *
134: getcmd(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: */
165: makeargv()
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: */
192: help(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");
204: for (c = cmdtab; c < &cmdtab[NCMDS - 1]; c++) {
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;
218: printf("%s", c->c_name);
219: if (c + lines >= &cmdtab[NCMDS]) {
220: printf("\n");
221: break;
222: }
223: w = strlen(c->c_name);
224: while (w < width) {
225: w = (w + 8) &~ 7;
226: putchar('\t');
227: }
228: }
229: }
230: return;
231: }
232: while (--argc > 0) {
233: register char *arg;
234: arg = *++argv;
235: c = getcmd(arg);
236: if (c == (struct cmd *)-1)
237: printf("?Ambiguous help command %s\n", arg);
238: else if (c == (struct cmd *)0)
239: printf("?Invalid help command %s\n", arg);
240: else
241: printf("%-*s\t%s\n", HELPINDENT,
242: c->c_name, c->c_help);
243: }
244: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.