123670Sgusella /* 223670Sgusella * Copyright (c) 1983 Regents of the University of California. 323670Sgusella * All rights reserved. The Berkeley software License Agreement 423670Sgusella * specifies the terms and conditions for redistribution. 523670Sgusella */ 623670Sgusella 723670Sgusella #ifndef lint 823670Sgusella char copyright[] = 923670Sgusella "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 1023670Sgusella All rights reserved.\n"; 1123670Sgusella #endif not lint 1223670Sgusella 1323670Sgusella #ifndef lint 14*25961Sbloom static char sccsid[] = "@(#)timedc.c 2.2 (Berkeley) 01/24/86"; 1523670Sgusella #endif not lint 1623670Sgusella 1723670Sgusella #include "timedc.h" 1823670Sgusella #include <signal.h> 1923670Sgusella #include <ctype.h> 2023670Sgusella #include <setjmp.h> 2124908Sbloom #include <syslog.h> 2223670Sgusella 2323670Sgusella int top; 2423670Sgusella int margc; 2523670Sgusella int fromatty; 2623670Sgusella char *margv[20]; 2723670Sgusella char cmdline[200]; 2823670Sgusella jmp_buf toplevel; 2923670Sgusella int intr(); 3023670Sgusella int priv_resources(); 3123670Sgusella struct cmd *getcmd(); 3223670Sgusella 3323670Sgusella 3423670Sgusella main(argc, argv) 3523670Sgusella char *argv[]; 3623670Sgusella { 3723670Sgusella register struct cmd *c; 3823670Sgusella 3924872Seric openlog("timedc", LOG_ODELAY, LOG_AUTH); 4024872Seric 4123670Sgusella /* 4223670Sgusella * security dictates! 4323670Sgusella */ 4423670Sgusella if (priv_resources() < 0) { 4523670Sgusella fprintf(stderr, "Could not get priviledged resources\n"); 4623670Sgusella exit(1); 4723670Sgusella } 4823670Sgusella (void) setuid(getuid()); 4923670Sgusella 5023670Sgusella if (--argc > 0) { 5123670Sgusella c = getcmd(*++argv); 5223670Sgusella if (c == (struct cmd *)-1) { 5323670Sgusella printf("?Ambiguous command\n"); 5423670Sgusella exit(1); 5523670Sgusella } 5623670Sgusella if (c == 0) { 5723670Sgusella printf("?Invalid command\n"); 5823670Sgusella exit(1); 5923670Sgusella } 6023670Sgusella (*c->c_handler)(argc, argv); 6123670Sgusella exit(0); 6223670Sgusella } 6323670Sgusella fromatty = isatty(fileno(stdin)); 6423670Sgusella top = setjmp(toplevel) == 0; 6523670Sgusella if (top) 6623670Sgusella (void) signal(SIGINT, intr); 6723670Sgusella for (;;) { 6823670Sgusella cmdscanner(top); 6923670Sgusella top = 1; 7023670Sgusella } 7123670Sgusella } 7223670Sgusella 7323670Sgusella intr() 7423670Sgusella { 7523670Sgusella if (!fromatty) 7623670Sgusella exit(0); 7723670Sgusella longjmp(toplevel, 1); 7823670Sgusella } 7923670Sgusella 8023670Sgusella /* 8123670Sgusella * Command parser. 8223670Sgusella */ 8323670Sgusella cmdscanner(top) 8423670Sgusella int top; 8523670Sgusella { 8623670Sgusella register struct cmd *c; 8723670Sgusella extern struct cmd cmdtab[]; 8823670Sgusella extern int help(); 8923670Sgusella 9023670Sgusella if (!top) 9123670Sgusella putchar('\n'); 9223670Sgusella for (;;) { 9323670Sgusella if (fromatty) { 9423670Sgusella printf("timedc> "); 9523670Sgusella (void) fflush(stdout); 9623670Sgusella } 9723670Sgusella if (gets(cmdline) == 0) 9823670Sgusella quit(); 9923670Sgusella if (cmdline[0] == 0) 10023670Sgusella break; 10123670Sgusella makeargv(); 10223670Sgusella c = getcmd(margv[0]); 10323670Sgusella if (c == (struct cmd *)-1) { 10423670Sgusella printf("?Ambiguous command\n"); 10523670Sgusella continue; 10623670Sgusella } 10723670Sgusella if (c == 0) { 10823670Sgusella printf("?Invalid command\n"); 10923670Sgusella continue; 11023670Sgusella } 11123670Sgusella if (c->c_priv && getuid()) { 11223670Sgusella printf("?Privileged command\n"); 11323670Sgusella continue; 11423670Sgusella } 11523670Sgusella (*c->c_handler)(margc, margv); 11623670Sgusella } 11723670Sgusella longjmp(toplevel, 0); 11823670Sgusella } 11923670Sgusella 12023670Sgusella struct cmd * 12123670Sgusella getcmd(name) 12223670Sgusella register char *name; 12323670Sgusella { 12423670Sgusella register char *p, *q; 12523670Sgusella register struct cmd *c, *found; 12623670Sgusella register int nmatches, longest; 127*25961Sbloom extern int NCMDS; 12823670Sgusella 12923670Sgusella longest = 0; 13023670Sgusella nmatches = 0; 13123670Sgusella found = 0; 132*25961Sbloom for (c = cmdtab; c < &cmdtab[NCMDS]; c++) { 133*25961Sbloom 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 */ 15423670Sgusella makeargv() 15523670Sgusella { 15623670Sgusella register char *cp; 15723670Sgusella register char **argp = margv; 15823670Sgusella 15923670Sgusella margc = 0; 16023670Sgusella for (cp = cmdline; *cp;) { 16123670Sgusella while (isspace(*cp)) 16223670Sgusella cp++; 16323670Sgusella if (*cp == '\0') 16423670Sgusella break; 16523670Sgusella *argp++ = cp; 16623670Sgusella margc += 1; 16723670Sgusella while (*cp != '\0' && !isspace(*cp)) 16823670Sgusella cp++; 16923670Sgusella if (*cp == '\0') 17023670Sgusella break; 17123670Sgusella *cp++ = '\0'; 17223670Sgusella } 17323670Sgusella *argp++ = 0; 17423670Sgusella } 17523670Sgusella 17623670Sgusella #define HELPINDENT (sizeof ("directory")) 17723670Sgusella 17823670Sgusella /* 17923670Sgusella * Help command. 18023670Sgusella */ 18123670Sgusella help(argc, argv) 18223670Sgusella int argc; 18323670Sgusella char *argv[]; 18423670Sgusella { 18523670Sgusella register struct cmd *c; 18623670Sgusella 18723670Sgusella if (argc == 1) { 18823670Sgusella register int i, j, w; 18923670Sgusella int columns, width = 0, lines; 19023670Sgusella extern int NCMDS; 19123670Sgusella 19223670Sgusella printf("Commands may be abbreviated. Commands are:\n\n"); 19323670Sgusella for (c = cmdtab; c < &cmdtab[NCMDS]; c++) { 19423670Sgusella int len = strlen(c->c_name); 19523670Sgusella 19623670Sgusella if (len > width) 19723670Sgusella width = len; 19823670Sgusella } 19923670Sgusella width = (width + 8) &~ 7; 20023670Sgusella columns = 80 / width; 20123670Sgusella if (columns == 0) 20223670Sgusella columns = 1; 20323670Sgusella lines = (NCMDS + columns - 1) / columns; 20423670Sgusella for (i = 0; i < lines; i++) { 20523670Sgusella for (j = 0; j < columns; j++) { 20623670Sgusella c = cmdtab + j * lines + i; 20723670Sgusella printf("%s", c->c_name); 20823670Sgusella if (c + lines >= &cmdtab[NCMDS]) { 20923670Sgusella printf("\n"); 21023670Sgusella break; 21123670Sgusella } 21223670Sgusella w = strlen(c->c_name); 21323670Sgusella while (w < width) { 21423670Sgusella w = (w + 8) &~ 7; 21523670Sgusella putchar('\t'); 21623670Sgusella } 21723670Sgusella } 21823670Sgusella } 21923670Sgusella return; 22023670Sgusella } 22123670Sgusella while (--argc > 0) { 22223670Sgusella register char *arg; 22323670Sgusella arg = *++argv; 22423670Sgusella c = getcmd(arg); 22523670Sgusella if (c == (struct cmd *)-1) 22623670Sgusella printf("?Ambiguous help command %s\n", arg); 22723670Sgusella else if (c == (struct cmd *)0) 22823670Sgusella printf("?Invalid help command %s\n", arg); 22923670Sgusella else 23023670Sgusella printf("%-*s\t%s\n", HELPINDENT, 23123670Sgusella c->c_name, c->c_help); 23223670Sgusella } 23323670Sgusella } 234