|
|
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[] = "@(#)timedc.c 2.9 (Berkeley) 6/1/90";
28: #endif /* not lint */
29:
30: #include "timedc.h"
31: #include <signal.h>
32: #include <ctype.h>
33: #include <setjmp.h>
34: #include <syslog.h>
35:
36: int top;
37: int margc;
38: int fromatty;
39: char *margv[20];
40: char cmdline[200];
41: jmp_buf toplevel;
42: int intr();
43: int priv_resources();
44: struct cmd *getcmd();
45:
46:
47: main(argc, argv)
48: char *argv[];
49: {
50: register struct cmd *c;
51:
52: openlog("timedc", LOG_ODELAY, LOG_AUTH);
53:
54: /*
55: * security dictates!
56: */
57: if (priv_resources() < 0) {
58: fprintf(stderr, "Could not get privileged resources\n");
59: exit(1);
60: }
61: (void) setuid(getuid());
62:
63: if (--argc > 0) {
64: c = getcmd(*++argv);
65: if (c == (struct cmd *)-1) {
66: printf("?Ambiguous command\n");
67: exit(1);
68: }
69: if (c == 0) {
70: printf("?Invalid command\n");
71: exit(1);
72: }
73: if (c->c_priv && getuid()) {
74: printf("?Privileged command\n");
75: exit(1);
76: }
77: (*c->c_handler)(argc, argv);
78: exit(0);
79: }
80: fromatty = isatty(fileno(stdin));
81: top = setjmp(toplevel) == 0;
82: if (top)
83: (void) signal(SIGINT, intr);
84: for (;;) {
85: cmdscanner(top);
86: top = 1;
87: }
88: }
89:
90: intr()
91: {
92: if (!fromatty)
93: exit(0);
94: longjmp(toplevel, 1);
95: }
96:
97: /*
98: * Command parser.
99: */
100: cmdscanner(top)
101: int top;
102: {
103: register struct cmd *c;
104: extern int help();
105:
106: if (!top)
107: putchar('\n');
108: for (;;) {
109: if (fromatty) {
110: printf("timedc> ");
111: (void) fflush(stdout);
112: }
113: if (fgets(cmdline, sizeof(cmdline), stdin) == 0)
114: quit();
115: if (cmdline[0] == 0)
116: break;
117: makeargv();
118: c = getcmd(margv[0]);
119: if (c == (struct cmd *)-1) {
120: printf("?Ambiguous command\n");
121: continue;
122: }
123: if (c == 0) {
124: printf("?Invalid command\n");
125: continue;
126: }
127: if (c->c_priv && getuid()) {
128: printf("?Privileged command\n");
129: continue;
130: }
131: (*c->c_handler)(margc, margv);
132: }
133: longjmp(toplevel, 0);
134: }
135:
136: struct cmd *
137: getcmd(name)
138: register char *name;
139: {
140: register char *p, *q;
141: register struct cmd *c, *found;
142: register int nmatches, longest;
143: extern struct cmd cmdtab[];
144: extern int NCMDS;
145:
146: longest = 0;
147: nmatches = 0;
148: found = 0;
149: for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
150: p = c->c_name;
151: for (q = name; *q == *p++; q++)
152: if (*q == 0) /* exact match? */
153: return(c);
154: if (!*q) { /* the name was a prefix */
155: if (q - name > longest) {
156: longest = q - name;
157: nmatches = 1;
158: found = c;
159: } else if (q - name == longest)
160: nmatches++;
161: }
162: }
163: if (nmatches > 1)
164: return((struct cmd *)-1);
165: return(found);
166: }
167:
168: /*
169: * Slice a string up into argc/argv.
170: */
171: makeargv()
172: {
173: register char *cp;
174: register char **argp = margv;
175:
176: margc = 0;
177: for (cp = cmdline; *cp;) {
178: while (isspace(*cp))
179: cp++;
180: if (*cp == '\0')
181: break;
182: *argp++ = cp;
183: margc += 1;
184: while (*cp != '\0' && !isspace(*cp))
185: cp++;
186: if (*cp == '\0')
187: break;
188: *cp++ = '\0';
189: }
190: *argp++ = 0;
191: }
192:
193: #define HELPINDENT (sizeof ("directory"))
194:
195: /*
196: * Help command.
197: */
198: help(argc, argv)
199: int argc;
200: char *argv[];
201: {
202: register struct cmd *c;
203: extern struct cmd cmdtab[];
204:
205: if (argc == 1) {
206: register int i, j, w;
207: int columns, width = 0, lines;
208: extern int NCMDS;
209:
210: printf("Commands may be abbreviated. Commands are:\n\n");
211: for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
212: int len = strlen(c->c_name);
213:
214: if (len > width)
215: width = len;
216: }
217: width = (width + 8) &~ 7;
218: columns = 80 / width;
219: if (columns == 0)
220: columns = 1;
221: lines = (NCMDS + columns - 1) / columns;
222: for (i = 0; i < lines; i++) {
223: for (j = 0; j < columns; j++) {
224: c = cmdtab + j * lines + i;
225: printf("%s", c->c_name);
226: if (c + lines >= &cmdtab[NCMDS]) {
227: printf("\n");
228: break;
229: }
230: w = strlen(c->c_name);
231: while (w < width) {
232: w = (w + 8) &~ 7;
233: putchar('\t');
234: }
235: }
236: }
237: return;
238: }
239: while (--argc > 0) {
240: register char *arg;
241: arg = *++argv;
242: c = getcmd(arg);
243: if (c == (struct cmd *)-1)
244: printf("?Ambiguous help command %s\n", arg);
245: else if (c == (struct cmd *)0)
246: printf("?Invalid help command %s\n", arg);
247: else
248: printf("%-*s\t%s\n", HELPINDENT,
249: c->c_name, c->c_help);
250: }
251: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.