xref: /csrg-svn/usr.sbin/timed/timedc/timedc.c (revision 23670)
1*23670Sgusella /*
2*23670Sgusella  * Copyright (c) 1983 Regents of the University of California.
3*23670Sgusella  * All rights reserved.  The Berkeley software License Agreement
4*23670Sgusella  * specifies the terms and conditions for redistribution.
5*23670Sgusella  */
6*23670Sgusella 
7*23670Sgusella #ifndef lint
8*23670Sgusella char copyright[] =
9*23670Sgusella "@(#) Copyright (c) 1983 Regents of the University of California.\n\
10*23670Sgusella  All rights reserved.\n";
11*23670Sgusella #endif not lint
12*23670Sgusella 
13*23670Sgusella #ifndef lint
14*23670Sgusella static char sccsid[] = "@(#)timedc.c	1.1 (Berkeley) 06/22/85";
15*23670Sgusella #endif not lint
16*23670Sgusella 
17*23670Sgusella #include "timedc.h"
18*23670Sgusella #include <signal.h>
19*23670Sgusella #include <ctype.h>
20*23670Sgusella #include <setjmp.h>
21*23670Sgusella 
22*23670Sgusella int	top;
23*23670Sgusella int	margc;
24*23670Sgusella int	fromatty;
25*23670Sgusella char	*margv[20];
26*23670Sgusella char	cmdline[200];
27*23670Sgusella jmp_buf	toplevel;
28*23670Sgusella int	intr();
29*23670Sgusella int priv_resources();
30*23670Sgusella struct	cmd *getcmd();
31*23670Sgusella 
32*23670Sgusella 
33*23670Sgusella main(argc, argv)
34*23670Sgusella 	char *argv[];
35*23670Sgusella {
36*23670Sgusella 	register struct cmd *c;
37*23670Sgusella 
38*23670Sgusella 	/*
39*23670Sgusella 	 * security dictates!
40*23670Sgusella 	 */
41*23670Sgusella 	if (priv_resources() < 0) {
42*23670Sgusella 		fprintf(stderr, "Could not get priviledged resources\n");
43*23670Sgusella 		exit(1);
44*23670Sgusella 	}
45*23670Sgusella 	(void) setuid(getuid());
46*23670Sgusella 
47*23670Sgusella 	if (--argc > 0) {
48*23670Sgusella 		c = getcmd(*++argv);
49*23670Sgusella 		if (c == (struct cmd *)-1) {
50*23670Sgusella 			printf("?Ambiguous command\n");
51*23670Sgusella 			exit(1);
52*23670Sgusella 		}
53*23670Sgusella 		if (c == 0) {
54*23670Sgusella 			printf("?Invalid command\n");
55*23670Sgusella 			exit(1);
56*23670Sgusella 		}
57*23670Sgusella 		(*c->c_handler)(argc, argv);
58*23670Sgusella 		exit(0);
59*23670Sgusella 	}
60*23670Sgusella 	fromatty = isatty(fileno(stdin));
61*23670Sgusella 	top = setjmp(toplevel) == 0;
62*23670Sgusella 	if (top)
63*23670Sgusella 		(void) signal(SIGINT, intr);
64*23670Sgusella 	for (;;) {
65*23670Sgusella 		cmdscanner(top);
66*23670Sgusella 		top = 1;
67*23670Sgusella 	}
68*23670Sgusella }
69*23670Sgusella 
70*23670Sgusella intr()
71*23670Sgusella {
72*23670Sgusella 	if (!fromatty)
73*23670Sgusella 		exit(0);
74*23670Sgusella 	longjmp(toplevel, 1);
75*23670Sgusella }
76*23670Sgusella 
77*23670Sgusella /*
78*23670Sgusella  * Command parser.
79*23670Sgusella  */
80*23670Sgusella cmdscanner(top)
81*23670Sgusella 	int top;
82*23670Sgusella {
83*23670Sgusella 	register struct cmd *c;
84*23670Sgusella 	extern struct cmd cmdtab[];
85*23670Sgusella 	extern int help();
86*23670Sgusella 
87*23670Sgusella 	if (!top)
88*23670Sgusella 		putchar('\n');
89*23670Sgusella 	for (;;) {
90*23670Sgusella 		if (fromatty) {
91*23670Sgusella 			printf("timedc> ");
92*23670Sgusella 			(void) fflush(stdout);
93*23670Sgusella 		}
94*23670Sgusella 		if (gets(cmdline) == 0)
95*23670Sgusella 			quit();
96*23670Sgusella 		if (cmdline[0] == 0)
97*23670Sgusella 			break;
98*23670Sgusella 		makeargv();
99*23670Sgusella 		c = getcmd(margv[0]);
100*23670Sgusella 		if (c == (struct cmd *)-1) {
101*23670Sgusella 			printf("?Ambiguous command\n");
102*23670Sgusella 			continue;
103*23670Sgusella 		}
104*23670Sgusella 		if (c == 0) {
105*23670Sgusella 			printf("?Invalid command\n");
106*23670Sgusella 			continue;
107*23670Sgusella 		}
108*23670Sgusella 		if (c->c_priv && getuid()) {
109*23670Sgusella 			printf("?Privileged command\n");
110*23670Sgusella 			continue;
111*23670Sgusella 		}
112*23670Sgusella 		(*c->c_handler)(margc, margv);
113*23670Sgusella 	}
114*23670Sgusella 	longjmp(toplevel, 0);
115*23670Sgusella }
116*23670Sgusella 
117*23670Sgusella struct cmd *
118*23670Sgusella getcmd(name)
119*23670Sgusella 	register char *name;
120*23670Sgusella {
121*23670Sgusella 	register char *p, *q;
122*23670Sgusella 	register struct cmd *c, *found;
123*23670Sgusella 	register int nmatches, longest;
124*23670Sgusella 
125*23670Sgusella 	longest = 0;
126*23670Sgusella 	nmatches = 0;
127*23670Sgusella 	found = 0;
128*23670Sgusella 	for (c = cmdtab; p = c->c_name; c++) {
129*23670Sgusella 		for (q = name; *q == *p++; q++)
130*23670Sgusella 			if (*q == 0)		/* exact match? */
131*23670Sgusella 				return(c);
132*23670Sgusella 		if (!*q) {			/* the name was a prefix */
133*23670Sgusella 			if (q - name > longest) {
134*23670Sgusella 				longest = q - name;
135*23670Sgusella 				nmatches = 1;
136*23670Sgusella 				found = c;
137*23670Sgusella 			} else if (q - name == longest)
138*23670Sgusella 				nmatches++;
139*23670Sgusella 		}
140*23670Sgusella 	}
141*23670Sgusella 	if (nmatches > 1)
142*23670Sgusella 		return((struct cmd *)-1);
143*23670Sgusella 	return(found);
144*23670Sgusella }
145*23670Sgusella 
146*23670Sgusella /*
147*23670Sgusella  * Slice a string up into argc/argv.
148*23670Sgusella  */
149*23670Sgusella makeargv()
150*23670Sgusella {
151*23670Sgusella 	register char *cp;
152*23670Sgusella 	register char **argp = margv;
153*23670Sgusella 
154*23670Sgusella 	margc = 0;
155*23670Sgusella 	for (cp = cmdline; *cp;) {
156*23670Sgusella 		while (isspace(*cp))
157*23670Sgusella 			cp++;
158*23670Sgusella 		if (*cp == '\0')
159*23670Sgusella 			break;
160*23670Sgusella 		*argp++ = cp;
161*23670Sgusella 		margc += 1;
162*23670Sgusella 		while (*cp != '\0' && !isspace(*cp))
163*23670Sgusella 			cp++;
164*23670Sgusella 		if (*cp == '\0')
165*23670Sgusella 			break;
166*23670Sgusella 		*cp++ = '\0';
167*23670Sgusella 	}
168*23670Sgusella 	*argp++ = 0;
169*23670Sgusella }
170*23670Sgusella 
171*23670Sgusella #define HELPINDENT (sizeof ("directory"))
172*23670Sgusella 
173*23670Sgusella /*
174*23670Sgusella  * Help command.
175*23670Sgusella  */
176*23670Sgusella help(argc, argv)
177*23670Sgusella 	int argc;
178*23670Sgusella 	char *argv[];
179*23670Sgusella {
180*23670Sgusella 	register struct cmd *c;
181*23670Sgusella 
182*23670Sgusella 	if (argc == 1) {
183*23670Sgusella 		register int i, j, w;
184*23670Sgusella 		int columns, width = 0, lines;
185*23670Sgusella 		extern int NCMDS;
186*23670Sgusella 
187*23670Sgusella 		printf("Commands may be abbreviated.  Commands are:\n\n");
188*23670Sgusella 		for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
189*23670Sgusella 			int len = strlen(c->c_name);
190*23670Sgusella 
191*23670Sgusella 			if (len > width)
192*23670Sgusella 				width = len;
193*23670Sgusella 		}
194*23670Sgusella 		width = (width + 8) &~ 7;
195*23670Sgusella 		columns = 80 / width;
196*23670Sgusella 		if (columns == 0)
197*23670Sgusella 			columns = 1;
198*23670Sgusella 		lines = (NCMDS + columns - 1) / columns;
199*23670Sgusella 		for (i = 0; i < lines; i++) {
200*23670Sgusella 			for (j = 0; j < columns; j++) {
201*23670Sgusella 				c = cmdtab + j * lines + i;
202*23670Sgusella 				printf("%s", c->c_name);
203*23670Sgusella 				if (c + lines >= &cmdtab[NCMDS]) {
204*23670Sgusella 					printf("\n");
205*23670Sgusella 					break;
206*23670Sgusella 				}
207*23670Sgusella 				w = strlen(c->c_name);
208*23670Sgusella 				while (w < width) {
209*23670Sgusella 					w = (w + 8) &~ 7;
210*23670Sgusella 					putchar('\t');
211*23670Sgusella 				}
212*23670Sgusella 			}
213*23670Sgusella 		}
214*23670Sgusella 		return;
215*23670Sgusella 	}
216*23670Sgusella 	while (--argc > 0) {
217*23670Sgusella 		register char *arg;
218*23670Sgusella 		arg = *++argv;
219*23670Sgusella 		c = getcmd(arg);
220*23670Sgusella 		if (c == (struct cmd *)-1)
221*23670Sgusella 			printf("?Ambiguous help command %s\n", arg);
222*23670Sgusella 		else if (c == (struct cmd *)0)
223*23670Sgusella 			printf("?Invalid help command %s\n", arg);
224*23670Sgusella 		else
225*23670Sgusella 			printf("%-*s\t%s\n", HELPINDENT,
226*23670Sgusella 				c->c_name, c->c_help);
227*23670Sgusella 	}
228*23670Sgusella }
229