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