1*23670Sgusella /* 2*23670Sgusella * Copyright (c) 1983 Regents of the University of California. 3*23670Sgusella * All rights reserved. The Berkeley software License Agreement 4*23670Sgusella * specifies the terms and conditions for redistribution. 5*23670Sgusella */ 6*23670Sgusella 7*23670Sgusella #ifndef lint 8*23670Sgusella char copyright[] = 9*23670Sgusella "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 10*23670Sgusella All rights reserved.\n"; 11*23670Sgusella #endif not lint 12*23670Sgusella 13*23670Sgusella #ifndef lint 14*23670Sgusella static char sccsid[] = "@(#)timedc.c 1.1 (Berkeley) 06/22/85"; 15*23670Sgusella #endif not lint 16*23670Sgusella 17*23670Sgusella #include "timedc.h" 18*23670Sgusella #include <signal.h> 19*23670Sgusella #include <ctype.h> 20*23670Sgusella #include <setjmp.h> 21*23670Sgusella 22*23670Sgusella int top; 23*23670Sgusella int margc; 24*23670Sgusella int fromatty; 25*23670Sgusella char *margv[20]; 26*23670Sgusella char cmdline[200]; 27*23670Sgusella jmp_buf toplevel; 28*23670Sgusella int intr(); 29*23670Sgusella int priv_resources(); 30*23670Sgusella struct cmd *getcmd(); 31*23670Sgusella 32*23670Sgusella 33*23670Sgusella main(argc, argv) 34*23670Sgusella char *argv[]; 35*23670Sgusella { 36*23670Sgusella register struct cmd *c; 37*23670Sgusella 38*23670Sgusella /* 39*23670Sgusella * security dictates! 40*23670Sgusella */ 41*23670Sgusella if (priv_resources() < 0) { 42*23670Sgusella fprintf(stderr, "Could not get priviledged resources\n"); 43*23670Sgusella exit(1); 44*23670Sgusella } 45*23670Sgusella (void) setuid(getuid()); 46*23670Sgusella 47*23670Sgusella if (--argc > 0) { 48*23670Sgusella c = getcmd(*++argv); 49*23670Sgusella if (c == (struct cmd *)-1) { 50*23670Sgusella printf("?Ambiguous command\n"); 51*23670Sgusella exit(1); 52*23670Sgusella } 53*23670Sgusella if (c == 0) { 54*23670Sgusella printf("?Invalid command\n"); 55*23670Sgusella exit(1); 56*23670Sgusella } 57*23670Sgusella (*c->c_handler)(argc, argv); 58*23670Sgusella exit(0); 59*23670Sgusella } 60*23670Sgusella fromatty = isatty(fileno(stdin)); 61*23670Sgusella top = setjmp(toplevel) == 0; 62*23670Sgusella if (top) 63*23670Sgusella (void) signal(SIGINT, intr); 64*23670Sgusella for (;;) { 65*23670Sgusella cmdscanner(top); 66*23670Sgusella top = 1; 67*23670Sgusella } 68*23670Sgusella } 69*23670Sgusella 70*23670Sgusella intr() 71*23670Sgusella { 72*23670Sgusella if (!fromatty) 73*23670Sgusella exit(0); 74*23670Sgusella longjmp(toplevel, 1); 75*23670Sgusella } 76*23670Sgusella 77*23670Sgusella /* 78*23670Sgusella * Command parser. 79*23670Sgusella */ 80*23670Sgusella cmdscanner(top) 81*23670Sgusella int top; 82*23670Sgusella { 83*23670Sgusella register struct cmd *c; 84*23670Sgusella extern struct cmd cmdtab[]; 85*23670Sgusella extern int help(); 86*23670Sgusella 87*23670Sgusella if (!top) 88*23670Sgusella putchar('\n'); 89*23670Sgusella for (;;) { 90*23670Sgusella if (fromatty) { 91*23670Sgusella printf("timedc> "); 92*23670Sgusella (void) fflush(stdout); 93*23670Sgusella } 94*23670Sgusella if (gets(cmdline) == 0) 95*23670Sgusella quit(); 96*23670Sgusella if (cmdline[0] == 0) 97*23670Sgusella break; 98*23670Sgusella makeargv(); 99*23670Sgusella c = getcmd(margv[0]); 100*23670Sgusella if (c == (struct cmd *)-1) { 101*23670Sgusella printf("?Ambiguous command\n"); 102*23670Sgusella continue; 103*23670Sgusella } 104*23670Sgusella if (c == 0) { 105*23670Sgusella printf("?Invalid command\n"); 106*23670Sgusella continue; 107*23670Sgusella } 108*23670Sgusella if (c->c_priv && getuid()) { 109*23670Sgusella printf("?Privileged command\n"); 110*23670Sgusella continue; 111*23670Sgusella } 112*23670Sgusella (*c->c_handler)(margc, margv); 113*23670Sgusella } 114*23670Sgusella longjmp(toplevel, 0); 115*23670Sgusella } 116*23670Sgusella 117*23670Sgusella struct cmd * 118*23670Sgusella getcmd(name) 119*23670Sgusella register char *name; 120*23670Sgusella { 121*23670Sgusella register char *p, *q; 122*23670Sgusella register struct cmd *c, *found; 123*23670Sgusella register int nmatches, longest; 124*23670Sgusella 125*23670Sgusella longest = 0; 126*23670Sgusella nmatches = 0; 127*23670Sgusella found = 0; 128*23670Sgusella for (c = cmdtab; p = c->c_name; c++) { 129*23670Sgusella for (q = name; *q == *p++; q++) 130*23670Sgusella if (*q == 0) /* exact match? */ 131*23670Sgusella return(c); 132*23670Sgusella if (!*q) { /* the name was a prefix */ 133*23670Sgusella if (q - name > longest) { 134*23670Sgusella longest = q - name; 135*23670Sgusella nmatches = 1; 136*23670Sgusella found = c; 137*23670Sgusella } else if (q - name == longest) 138*23670Sgusella nmatches++; 139*23670Sgusella } 140*23670Sgusella } 141*23670Sgusella if (nmatches > 1) 142*23670Sgusella return((struct cmd *)-1); 143*23670Sgusella return(found); 144*23670Sgusella } 145*23670Sgusella 146*23670Sgusella /* 147*23670Sgusella * Slice a string up into argc/argv. 148*23670Sgusella */ 149*23670Sgusella makeargv() 150*23670Sgusella { 151*23670Sgusella register char *cp; 152*23670Sgusella register char **argp = margv; 153*23670Sgusella 154*23670Sgusella margc = 0; 155*23670Sgusella for (cp = cmdline; *cp;) { 156*23670Sgusella while (isspace(*cp)) 157*23670Sgusella cp++; 158*23670Sgusella if (*cp == '\0') 159*23670Sgusella break; 160*23670Sgusella *argp++ = cp; 161*23670Sgusella margc += 1; 162*23670Sgusella while (*cp != '\0' && !isspace(*cp)) 163*23670Sgusella cp++; 164*23670Sgusella if (*cp == '\0') 165*23670Sgusella break; 166*23670Sgusella *cp++ = '\0'; 167*23670Sgusella } 168*23670Sgusella *argp++ = 0; 169*23670Sgusella } 170*23670Sgusella 171*23670Sgusella #define HELPINDENT (sizeof ("directory")) 172*23670Sgusella 173*23670Sgusella /* 174*23670Sgusella * Help command. 175*23670Sgusella */ 176*23670Sgusella help(argc, argv) 177*23670Sgusella int argc; 178*23670Sgusella char *argv[]; 179*23670Sgusella { 180*23670Sgusella register struct cmd *c; 181*23670Sgusella 182*23670Sgusella if (argc == 1) { 183*23670Sgusella register int i, j, w; 184*23670Sgusella int columns, width = 0, lines; 185*23670Sgusella extern int NCMDS; 186*23670Sgusella 187*23670Sgusella printf("Commands may be abbreviated. Commands are:\n\n"); 188*23670Sgusella for (c = cmdtab; c < &cmdtab[NCMDS]; c++) { 189*23670Sgusella int len = strlen(c->c_name); 190*23670Sgusella 191*23670Sgusella if (len > width) 192*23670Sgusella width = len; 193*23670Sgusella } 194*23670Sgusella width = (width + 8) &~ 7; 195*23670Sgusella columns = 80 / width; 196*23670Sgusella if (columns == 0) 197*23670Sgusella columns = 1; 198*23670Sgusella lines = (NCMDS + columns - 1) / columns; 199*23670Sgusella for (i = 0; i < lines; i++) { 200*23670Sgusella for (j = 0; j < columns; j++) { 201*23670Sgusella c = cmdtab + j * lines + i; 202*23670Sgusella printf("%s", c->c_name); 203*23670Sgusella if (c + lines >= &cmdtab[NCMDS]) { 204*23670Sgusella printf("\n"); 205*23670Sgusella break; 206*23670Sgusella } 207*23670Sgusella w = strlen(c->c_name); 208*23670Sgusella while (w < width) { 209*23670Sgusella w = (w + 8) &~ 7; 210*23670Sgusella putchar('\t'); 211*23670Sgusella } 212*23670Sgusella } 213*23670Sgusella } 214*23670Sgusella return; 215*23670Sgusella } 216*23670Sgusella while (--argc > 0) { 217*23670Sgusella register char *arg; 218*23670Sgusella arg = *++argv; 219*23670Sgusella c = getcmd(arg); 220*23670Sgusella if (c == (struct cmd *)-1) 221*23670Sgusella printf("?Ambiguous help command %s\n", arg); 222*23670Sgusella else if (c == (struct cmd *)0) 223*23670Sgusella printf("?Invalid help command %s\n", arg); 224*23670Sgusella else 225*23670Sgusella printf("%-*s\t%s\n", HELPINDENT, 226*23670Sgusella c->c_name, c->c_help); 227*23670Sgusella } 228*23670Sgusella } 229