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