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