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