xref: /csrg-svn/usr.sbin/timed/timedc/timedc.c (revision 61885)
159906Sbostic /*-
2*61885Sbostic  * Copyright (c) 1985, 1993
3*61885Sbostic  *	The Regents of the University of California.  All rights reserved.
433123Sbostic  *
542829Sbostic  * %sccs.include.redist.c%
623670Sgusella  */
723670Sgusella 
823670Sgusella #ifndef lint
9*61885Sbostic static char copyright[] =
10*61885Sbostic "@(#) Copyright (c) 1985, 1993\n\
11*61885Sbostic 	The Regents of the University of California.  All rights reserved.\n";
1233123Sbostic #endif /* not lint */
1323670Sgusella 
1423670Sgusella #ifndef lint
15*61885Sbostic static char sccsid[] = "@(#)timedc.c	8.1 (Berkeley) 06/06/93";
1633123Sbostic #endif /* not lint */
1723670Sgusella 
1859906Sbostic #ifdef sgi
1959906Sbostic #ident "$Revision: 1.6 $"
2059906Sbostic #endif
2159906Sbostic 
2223670Sgusella #include "timedc.h"
2359906Sbostic #include <strings.h>
2423670Sgusella #include <signal.h>
2523670Sgusella #include <ctype.h>
2623670Sgusella #include <setjmp.h>
2759906Sbostic #include <unistd.h>
2859906Sbostic #include <stdlib.h>
2924908Sbloom #include <syslog.h>
3023670Sgusella 
3159906Sbostic int trace = 0;
3259906Sbostic FILE *fd = 0;
3323670Sgusella int	margc;
3423670Sgusella int	fromatty;
3523670Sgusella char	*margv[20];
3623670Sgusella char	cmdline[200];
3723670Sgusella jmp_buf	toplevel;
3859906Sbostic static struct cmd *getcmd __P((char *));
3923670Sgusella 
4059906Sbostic int
main(argc,argv)4123670Sgusella main(argc, argv)
4259906Sbostic 	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 	}
7559906Sbostic 
7623670Sgusella 	fromatty = isatty(fileno(stdin));
7759906Sbostic 	if (setjmp(toplevel))
7823670Sgusella 		putchar('\n');
7959906Sbostic 	(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();
9059906Sbostic 		if (margv[0] == 0)
9159906Sbostic 			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 	}
10759906Sbostic 	return 0;
10823670Sgusella }
10923670Sgusella 
11059906Sbostic void
intr(signo)11159906Sbostic intr(signo)
11259906Sbostic 	int signo;
11359906Sbostic {
11459906Sbostic 	if (!fromatty)
11559906Sbostic 		exit(0);
11659906Sbostic 	longjmp(toplevel, 1);
11759906Sbostic }
11859906Sbostic 
11959906Sbostic 
12059906Sbostic static struct cmd *
getcmd(name)12123670Sgusella getcmd(name)
12259906Sbostic 	char *name;
12323670Sgusella {
12423670Sgusella 	register char *p, *q;
12523670Sgusella 	register struct cmd *c, *found;
12623670Sgusella 	register int nmatches, longest;
12725961Sbloom 	extern int NCMDS;
12823670Sgusella 
12923670Sgusella 	longest = 0;
13023670Sgusella 	nmatches = 0;
13123670Sgusella 	found = 0;
13225961Sbloom 	for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
13325961Sbloom 		p = c->c_name;
13423670Sgusella 		for (q = name; *q == *p++; q++)
13523670Sgusella 			if (*q == 0)		/* exact match? */
13623670Sgusella 				return(c);
13723670Sgusella 		if (!*q) {			/* the name was a prefix */
13823670Sgusella 			if (q - name > longest) {
13923670Sgusella 				longest = q - name;
14023670Sgusella 				nmatches = 1;
14123670Sgusella 				found = c;
14223670Sgusella 			} else if (q - name == longest)
14323670Sgusella 				nmatches++;
14423670Sgusella 		}
14523670Sgusella 	}
14623670Sgusella 	if (nmatches > 1)
14723670Sgusella 		return((struct cmd *)-1);
14823670Sgusella 	return(found);
14923670Sgusella }
15023670Sgusella 
15123670Sgusella /*
15223670Sgusella  * Slice a string up into argc/argv.
15323670Sgusella  */
15459906Sbostic void
makeargv()15523670Sgusella makeargv()
15623670Sgusella {
15723670Sgusella 	register char *cp;
15823670Sgusella 	register char **argp = margv;
15923670Sgusella 
16023670Sgusella 	margc = 0;
16123670Sgusella 	for (cp = cmdline; *cp;) {
16223670Sgusella 		while (isspace(*cp))
16323670Sgusella 			cp++;
16423670Sgusella 		if (*cp == '\0')
16523670Sgusella 			break;
16623670Sgusella 		*argp++ = cp;
16723670Sgusella 		margc += 1;
16823670Sgusella 		while (*cp != '\0' && !isspace(*cp))
16923670Sgusella 			cp++;
17023670Sgusella 		if (*cp == '\0')
17123670Sgusella 			break;
17223670Sgusella 		*cp++ = '\0';
17323670Sgusella 	}
17423670Sgusella 	*argp++ = 0;
17523670Sgusella }
17623670Sgusella 
17723670Sgusella #define HELPINDENT (sizeof ("directory"))
17823670Sgusella 
17923670Sgusella /*
18023670Sgusella  * Help command.
18123670Sgusella  */
18259906Sbostic void
help(argc,argv)18323670Sgusella help(argc, argv)
18423670Sgusella 	int argc;
18523670Sgusella 	char *argv[];
18623670Sgusella {
18723670Sgusella 	register struct cmd *c;
18823670Sgusella 
18923670Sgusella 	if (argc == 1) {
19023670Sgusella 		register int i, j, w;
19123670Sgusella 		int columns, width = 0, lines;
19223670Sgusella 		extern int NCMDS;
19323670Sgusella 
19423670Sgusella 		printf("Commands may be abbreviated.  Commands are:\n\n");
19523670Sgusella 		for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
19623670Sgusella 			int len = strlen(c->c_name);
19723670Sgusella 
19823670Sgusella 			if (len > width)
19923670Sgusella 				width = len;
20023670Sgusella 		}
20123670Sgusella 		width = (width + 8) &~ 7;
20223670Sgusella 		columns = 80 / width;
20323670Sgusella 		if (columns == 0)
20423670Sgusella 			columns = 1;
20523670Sgusella 		lines = (NCMDS + columns - 1) / columns;
20623670Sgusella 		for (i = 0; i < lines; i++) {
20723670Sgusella 			for (j = 0; j < columns; j++) {
20823670Sgusella 				c = cmdtab + j * lines + i;
20923670Sgusella 				printf("%s", c->c_name);
21023670Sgusella 				if (c + lines >= &cmdtab[NCMDS]) {
21123670Sgusella 					printf("\n");
21223670Sgusella 					break;
21323670Sgusella 				}
21423670Sgusella 				w = strlen(c->c_name);
21523670Sgusella 				while (w < width) {
21623670Sgusella 					w = (w + 8) &~ 7;
21723670Sgusella 					putchar('\t');
21823670Sgusella 				}
21923670Sgusella 			}
22023670Sgusella 		}
22123670Sgusella 		return;
22223670Sgusella 	}
22323670Sgusella 	while (--argc > 0) {
22423670Sgusella 		register char *arg;
22523670Sgusella 		arg = *++argv;
22623670Sgusella 		c = getcmd(arg);
22723670Sgusella 		if (c == (struct cmd *)-1)
22823670Sgusella 			printf("?Ambiguous help command %s\n", arg);
22923670Sgusella 		else if (c == (struct cmd *)0)
23023670Sgusella 			printf("?Invalid help command %s\n", arg);
23123670Sgusella 		else
23259906Sbostic 			printf("%-*s\t%s\n", (int)HELPINDENT,
23323670Sgusella 				c->c_name, c->c_help);
23423670Sgusella 	}
23523670Sgusella }
236