xref: /csrg-svn/usr.sbin/timed/timedc/timedc.c (revision 59906)
1*59906Sbostic /*-
2*59906Sbostic  * Copyright (c) 1985, 1993 The Regents of the University of California.
333123Sbostic  * All rights reserved.
433123Sbostic  *
542829Sbostic  * %sccs.include.redist.c%
623670Sgusella  */
723670Sgusella 
823670Sgusella #ifndef lint
923670Sgusella char copyright[] =
10*59906Sbostic "@(#) Copyright (c) 1985, 1993 The Regents of the University of California.\n\
1123670Sgusella  All rights reserved.\n";
1233123Sbostic #endif /* not lint */
1323670Sgusella 
1423670Sgusella #ifndef lint
15*59906Sbostic static char sccsid[] = "@(#)timedc.c	5.1 (Berkeley) 05/11/93";
1633123Sbostic #endif /* not lint */
1723670Sgusella 
18*59906Sbostic #ifdef sgi
19*59906Sbostic #ident "$Revision: 1.6 $"
20*59906Sbostic #endif
21*59906Sbostic 
2223670Sgusella #include "timedc.h"
23*59906Sbostic #include <strings.h>
2423670Sgusella #include <signal.h>
2523670Sgusella #include <ctype.h>
2623670Sgusella #include <setjmp.h>
27*59906Sbostic #include <unistd.h>
28*59906Sbostic #include <stdlib.h>
2924908Sbloom #include <syslog.h>
3023670Sgusella 
31*59906Sbostic int trace = 0;
32*59906Sbostic FILE *fd = 0;
3323670Sgusella int	margc;
3423670Sgusella int	fromatty;
3523670Sgusella char	*margv[20];
3623670Sgusella char	cmdline[200];
3723670Sgusella jmp_buf	toplevel;
38*59906Sbostic static struct cmd *getcmd __P((char *));
3923670Sgusella 
40*59906Sbostic int
4123670Sgusella main(argc, argv)
42*59906Sbostic 	int argc;
4323670Sgusella 	char *argv[];
4423670Sgusella {
4523670Sgusella 	register struct cmd *c;
4623670Sgusella 
4724872Seric 	openlog("timedc", LOG_ODELAY, LOG_AUTH);
4824872Seric 
4923670Sgusella 	/*
5023670Sgusella 	 * security dictates!
5123670Sgusella 	 */
5223670Sgusella 	if (priv_resources() < 0) {
5339719Sbostic 		fprintf(stderr, "Could not get privileged resources\n");
5423670Sgusella 		exit(1);
5523670Sgusella 	}
5623670Sgusella 	(void) setuid(getuid());
5723670Sgusella 
5823670Sgusella 	if (--argc > 0) {
5923670Sgusella 		c = getcmd(*++argv);
6023670Sgusella 		if (c == (struct cmd *)-1) {
6123670Sgusella 			printf("?Ambiguous command\n");
6223670Sgusella 			exit(1);
6323670Sgusella 		}
6423670Sgusella 		if (c == 0) {
6523670Sgusella 			printf("?Invalid command\n");
6623670Sgusella 			exit(1);
6723670Sgusella 		}
6829348Sbloom 		if (c->c_priv && getuid()) {
6929348Sbloom 			printf("?Privileged command\n");
7029348Sbloom 			exit(1);
7129348Sbloom 		}
7223670Sgusella 		(*c->c_handler)(argc, argv);
7323670Sgusella 		exit(0);
7423670Sgusella 	}
75*59906Sbostic 
7623670Sgusella 	fromatty = isatty(fileno(stdin));
77*59906Sbostic 	if (setjmp(toplevel))
7823670Sgusella 		putchar('\n');
79*59906Sbostic 	(void) signal(SIGINT, intr);
8023670Sgusella 	for (;;) {
8123670Sgusella 		if (fromatty) {
8223670Sgusella 			printf("timedc> ");
8323670Sgusella 			(void) fflush(stdout);
8423670Sgusella 		}
8536246Sbostic 		if (fgets(cmdline, sizeof(cmdline), stdin) == 0)
8623670Sgusella 			quit();
8723670Sgusella 		if (cmdline[0] == 0)
8823670Sgusella 			break;
8923670Sgusella 		makeargv();
90*59906Sbostic 		if (margv[0] == 0)
91*59906Sbostic 			continue;
9223670Sgusella 		c = getcmd(margv[0]);
9323670Sgusella 		if (c == (struct cmd *)-1) {
9423670Sgusella 			printf("?Ambiguous command\n");
9523670Sgusella 			continue;
9623670Sgusella 		}
9723670Sgusella 		if (c == 0) {
9823670Sgusella 			printf("?Invalid command\n");
9923670Sgusella 			continue;
10023670Sgusella 		}
10123670Sgusella 		if (c->c_priv && getuid()) {
10223670Sgusella 			printf("?Privileged command\n");
10323670Sgusella 			continue;
10423670Sgusella 		}
10523670Sgusella 		(*c->c_handler)(margc, margv);
10623670Sgusella 	}
107*59906Sbostic 	return 0;
10823670Sgusella }
10923670Sgusella 
110*59906Sbostic void
111*59906Sbostic intr(signo)
112*59906Sbostic 	int signo;
113*59906Sbostic {
114*59906Sbostic 	if (!fromatty)
115*59906Sbostic 		exit(0);
116*59906Sbostic 	longjmp(toplevel, 1);
117*59906Sbostic }
118*59906Sbostic 
119*59906Sbostic 
120*59906Sbostic static struct cmd *
12123670Sgusella getcmd(name)
122*59906Sbostic 	char *name;
12323670Sgusella {
12423670Sgusella 	register char *p, *q;
12523670Sgusella 	register struct cmd *c, *found;
12623670Sgusella 	register int nmatches, longest;
12733158Sbostic 	extern struct cmd cmdtab[];
12825961Sbloom 	extern int NCMDS;
12923670Sgusella 
13023670Sgusella 	longest = 0;
13123670Sgusella 	nmatches = 0;
13223670Sgusella 	found = 0;
13325961Sbloom 	for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
13425961Sbloom 		p = c->c_name;
13523670Sgusella 		for (q = name; *q == *p++; q++)
13623670Sgusella 			if (*q == 0)		/* exact match? */
13723670Sgusella 				return(c);
13823670Sgusella 		if (!*q) {			/* the name was a prefix */
13923670Sgusella 			if (q - name > longest) {
14023670Sgusella 				longest = q - name;
14123670Sgusella 				nmatches = 1;
14223670Sgusella 				found = c;
14323670Sgusella 			} else if (q - name == longest)
14423670Sgusella 				nmatches++;
14523670Sgusella 		}
14623670Sgusella 	}
14723670Sgusella 	if (nmatches > 1)
14823670Sgusella 		return((struct cmd *)-1);
14923670Sgusella 	return(found);
15023670Sgusella }
15123670Sgusella 
15223670Sgusella /*
15323670Sgusella  * Slice a string up into argc/argv.
15423670Sgusella  */
155*59906Sbostic void
15623670Sgusella makeargv()
15723670Sgusella {
15823670Sgusella 	register char *cp;
15923670Sgusella 	register char **argp = margv;
16023670Sgusella 
16123670Sgusella 	margc = 0;
16223670Sgusella 	for (cp = cmdline; *cp;) {
16323670Sgusella 		while (isspace(*cp))
16423670Sgusella 			cp++;
16523670Sgusella 		if (*cp == '\0')
16623670Sgusella 			break;
16723670Sgusella 		*argp++ = cp;
16823670Sgusella 		margc += 1;
16923670Sgusella 		while (*cp != '\0' && !isspace(*cp))
17023670Sgusella 			cp++;
17123670Sgusella 		if (*cp == '\0')
17223670Sgusella 			break;
17323670Sgusella 		*cp++ = '\0';
17423670Sgusella 	}
17523670Sgusella 	*argp++ = 0;
17623670Sgusella }
17723670Sgusella 
17823670Sgusella #define HELPINDENT (sizeof ("directory"))
17923670Sgusella 
18023670Sgusella /*
18123670Sgusella  * Help command.
18223670Sgusella  */
183*59906Sbostic void
18423670Sgusella help(argc, argv)
18523670Sgusella 	int argc;
18623670Sgusella 	char *argv[];
18723670Sgusella {
18823670Sgusella 	register struct cmd *c;
18933158Sbostic 	extern struct cmd cmdtab[];
19023670Sgusella 
19123670Sgusella 	if (argc == 1) {
19223670Sgusella 		register int i, j, w;
19323670Sgusella 		int columns, width = 0, lines;
19423670Sgusella 		extern int NCMDS;
19523670Sgusella 
19623670Sgusella 		printf("Commands may be abbreviated.  Commands are:\n\n");
19723670Sgusella 		for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
19823670Sgusella 			int len = strlen(c->c_name);
19923670Sgusella 
20023670Sgusella 			if (len > width)
20123670Sgusella 				width = len;
20223670Sgusella 		}
20323670Sgusella 		width = (width + 8) &~ 7;
20423670Sgusella 		columns = 80 / width;
20523670Sgusella 		if (columns == 0)
20623670Sgusella 			columns = 1;
20723670Sgusella 		lines = (NCMDS + columns - 1) / columns;
20823670Sgusella 		for (i = 0; i < lines; i++) {
20923670Sgusella 			for (j = 0; j < columns; j++) {
21023670Sgusella 				c = cmdtab + j * lines + i;
21123670Sgusella 				printf("%s", c->c_name);
21223670Sgusella 				if (c + lines >= &cmdtab[NCMDS]) {
21323670Sgusella 					printf("\n");
21423670Sgusella 					break;
21523670Sgusella 				}
21623670Sgusella 				w = strlen(c->c_name);
21723670Sgusella 				while (w < width) {
21823670Sgusella 					w = (w + 8) &~ 7;
21923670Sgusella 					putchar('\t');
22023670Sgusella 				}
22123670Sgusella 			}
22223670Sgusella 		}
22323670Sgusella 		return;
22423670Sgusella 	}
22523670Sgusella 	while (--argc > 0) {
22623670Sgusella 		register char *arg;
22723670Sgusella 		arg = *++argv;
22823670Sgusella 		c = getcmd(arg);
22923670Sgusella 		if (c == (struct cmd *)-1)
23023670Sgusella 			printf("?Ambiguous help command %s\n", arg);
23123670Sgusella 		else if (c == (struct cmd *)0)
23223670Sgusella 			printf("?Invalid help command %s\n", arg);
23323670Sgusella 		else
234*59906Sbostic 			printf("%-*s\t%s\n", (int)HELPINDENT,
23523670Sgusella 				c->c_name, c->c_help);
23623670Sgusella 	}
23723670Sgusella }
238