xref: /original-bsd/usr.sbin/timed/timedc/timedc.c (revision 81aa1937)
1 /*-
2  * Copyright (c) 1985, 1993 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 char copyright[] =
10 "@(#) Copyright (c) 1985, 1993 The Regents of the University of California.\n\
11  All rights reserved.\n";
12 #endif /* not lint */
13 
14 #ifndef lint
15 static char sccsid[] = "@(#)timedc.c	5.1 (Berkeley) 05/11/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 struct cmd cmdtab[];
128 	extern int NCMDS;
129 
130 	longest = 0;
131 	nmatches = 0;
132 	found = 0;
133 	for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
134 		p = c->c_name;
135 		for (q = name; *q == *p++; q++)
136 			if (*q == 0)		/* exact match? */
137 				return(c);
138 		if (!*q) {			/* the name was a prefix */
139 			if (q - name > longest) {
140 				longest = q - name;
141 				nmatches = 1;
142 				found = c;
143 			} else if (q - name == longest)
144 				nmatches++;
145 		}
146 	}
147 	if (nmatches > 1)
148 		return((struct cmd *)-1);
149 	return(found);
150 }
151 
152 /*
153  * Slice a string up into argc/argv.
154  */
155 void
156 makeargv()
157 {
158 	register char *cp;
159 	register char **argp = margv;
160 
161 	margc = 0;
162 	for (cp = cmdline; *cp;) {
163 		while (isspace(*cp))
164 			cp++;
165 		if (*cp == '\0')
166 			break;
167 		*argp++ = cp;
168 		margc += 1;
169 		while (*cp != '\0' && !isspace(*cp))
170 			cp++;
171 		if (*cp == '\0')
172 			break;
173 		*cp++ = '\0';
174 	}
175 	*argp++ = 0;
176 }
177 
178 #define HELPINDENT (sizeof ("directory"))
179 
180 /*
181  * Help command.
182  */
183 void
184 help(argc, argv)
185 	int argc;
186 	char *argv[];
187 {
188 	register struct cmd *c;
189 	extern struct cmd cmdtab[];
190 
191 	if (argc == 1) {
192 		register int i, j, w;
193 		int columns, width = 0, lines;
194 		extern int NCMDS;
195 
196 		printf("Commands may be abbreviated.  Commands are:\n\n");
197 		for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
198 			int len = strlen(c->c_name);
199 
200 			if (len > width)
201 				width = len;
202 		}
203 		width = (width + 8) &~ 7;
204 		columns = 80 / width;
205 		if (columns == 0)
206 			columns = 1;
207 		lines = (NCMDS + columns - 1) / columns;
208 		for (i = 0; i < lines; i++) {
209 			for (j = 0; j < columns; j++) {
210 				c = cmdtab + j * lines + i;
211 				printf("%s", c->c_name);
212 				if (c + lines >= &cmdtab[NCMDS]) {
213 					printf("\n");
214 					break;
215 				}
216 				w = strlen(c->c_name);
217 				while (w < width) {
218 					w = (w + 8) &~ 7;
219 					putchar('\t');
220 				}
221 			}
222 		}
223 		return;
224 	}
225 	while (--argc > 0) {
226 		register char *arg;
227 		arg = *++argv;
228 		c = getcmd(arg);
229 		if (c == (struct cmd *)-1)
230 			printf("?Ambiguous help command %s\n", arg);
231 		else if (c == (struct cmd *)0)
232 			printf("?Invalid help command %s\n", arg);
233 		else
234 			printf("%-*s\t%s\n", (int)HELPINDENT,
235 				c->c_name, c->c_help);
236 	}
237 }
238