|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that the above copyright notice and this paragraph are ! 7: * duplicated in all such forms and that any documentation, ! 8: * advertising materials, and other materials related to such ! 9: * distribution and use acknowledge that the software was developed ! 10: * by the University of California, Berkeley. The name of the ! 11: * University may not be used to endorse or promote products derived ! 12: * from this software without specific prior written permission. ! 13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 16: */ ! 17: ! 18: #ifndef lint ! 19: char copyright[] = ! 20: "@(#) Copyright (c) 1983 Regents of the University of California.\n\ ! 21: All rights reserved.\n"; ! 22: #endif /* not lint */ ! 23: ! 24: #ifndef lint ! 25: static char sccsid[] = "@(#)timedc.c 2.6 (Berkeley) 6/18/88"; ! 26: #endif /* not lint */ ! 27: ! 28: #include "timedc.h" ! 29: #include <signal.h> ! 30: #include <ctype.h> ! 31: #include <setjmp.h> ! 32: #include <syslog.h> ! 33: ! 34: int top; ! 35: int margc; ! 36: int fromatty; ! 37: char *margv[20]; ! 38: char cmdline[200]; ! 39: jmp_buf toplevel; ! 40: int intr(); ! 41: int priv_resources(); ! 42: struct cmd *getcmd(); ! 43: ! 44: ! 45: main(argc, argv) ! 46: char *argv[]; ! 47: { ! 48: register struct cmd *c; ! 49: ! 50: openlog("timedc", LOG_ODELAY, LOG_AUTH); ! 51: ! 52: /* ! 53: * security dictates! ! 54: */ ! 55: if (priv_resources() < 0) { ! 56: fprintf(stderr, "Could not get priviledged resources\n"); ! 57: exit(1); ! 58: } ! 59: (void) setuid(getuid()); ! 60: ! 61: if (--argc > 0) { ! 62: c = getcmd(*++argv); ! 63: if (c == (struct cmd *)-1) { ! 64: printf("?Ambiguous command\n"); ! 65: exit(1); ! 66: } ! 67: if (c == 0) { ! 68: printf("?Invalid command\n"); ! 69: exit(1); ! 70: } ! 71: if (c->c_priv && getuid()) { ! 72: printf("?Privileged command\n"); ! 73: exit(1); ! 74: } ! 75: (*c->c_handler)(argc, argv); ! 76: exit(0); ! 77: } ! 78: fromatty = isatty(fileno(stdin)); ! 79: top = setjmp(toplevel) == 0; ! 80: if (top) ! 81: (void) signal(SIGINT, intr); ! 82: for (;;) { ! 83: cmdscanner(top); ! 84: top = 1; ! 85: } ! 86: } ! 87: ! 88: intr() ! 89: { ! 90: if (!fromatty) ! 91: exit(0); ! 92: longjmp(toplevel, 1); ! 93: } ! 94: ! 95: /* ! 96: * Command parser. ! 97: */ ! 98: cmdscanner(top) ! 99: int top; ! 100: { ! 101: register struct cmd *c; ! 102: extern int help(); ! 103: ! 104: if (!top) ! 105: putchar('\n'); ! 106: for (;;) { ! 107: if (fromatty) { ! 108: printf("timedc> "); ! 109: (void) fflush(stdout); ! 110: } ! 111: if (gets(cmdline) == 0) ! 112: quit(); ! 113: if (cmdline[0] == 0) ! 114: break; ! 115: makeargv(); ! 116: c = getcmd(margv[0]); ! 117: if (c == (struct cmd *)-1) { ! 118: printf("?Ambiguous command\n"); ! 119: continue; ! 120: } ! 121: if (c == 0) { ! 122: printf("?Invalid command\n"); ! 123: continue; ! 124: } ! 125: if (c->c_priv && getuid()) { ! 126: printf("?Privileged command\n"); ! 127: continue; ! 128: } ! 129: (*c->c_handler)(margc, margv); ! 130: } ! 131: longjmp(toplevel, 0); ! 132: } ! 133: ! 134: struct cmd * ! 135: getcmd(name) ! 136: register char *name; ! 137: { ! 138: register char *p, *q; ! 139: register struct cmd *c, *found; ! 140: register int nmatches, longest; ! 141: extern struct cmd cmdtab[]; ! 142: extern int NCMDS; ! 143: ! 144: longest = 0; ! 145: nmatches = 0; ! 146: found = 0; ! 147: for (c = cmdtab; c < &cmdtab[NCMDS]; c++) { ! 148: p = c->c_name; ! 149: for (q = name; *q == *p++; q++) ! 150: if (*q == 0) /* exact match? */ ! 151: return(c); ! 152: if (!*q) { /* the name was a prefix */ ! 153: if (q - name > longest) { ! 154: longest = q - name; ! 155: nmatches = 1; ! 156: found = c; ! 157: } else if (q - name == longest) ! 158: nmatches++; ! 159: } ! 160: } ! 161: if (nmatches > 1) ! 162: return((struct cmd *)-1); ! 163: return(found); ! 164: } ! 165: ! 166: /* ! 167: * Slice a string up into argc/argv. ! 168: */ ! 169: makeargv() ! 170: { ! 171: register char *cp; ! 172: register char **argp = margv; ! 173: ! 174: margc = 0; ! 175: for (cp = cmdline; *cp;) { ! 176: while (isspace(*cp)) ! 177: cp++; ! 178: if (*cp == '\0') ! 179: break; ! 180: *argp++ = cp; ! 181: margc += 1; ! 182: while (*cp != '\0' && !isspace(*cp)) ! 183: cp++; ! 184: if (*cp == '\0') ! 185: break; ! 186: *cp++ = '\0'; ! 187: } ! 188: *argp++ = 0; ! 189: } ! 190: ! 191: #define HELPINDENT (sizeof ("directory")) ! 192: ! 193: /* ! 194: * Help command. ! 195: */ ! 196: help(argc, argv) ! 197: int argc; ! 198: char *argv[]; ! 199: { ! 200: register struct cmd *c; ! 201: extern struct cmd cmdtab[]; ! 202: ! 203: if (argc == 1) { ! 204: register int i, j, w; ! 205: int columns, width = 0, lines; ! 206: extern int NCMDS; ! 207: ! 208: printf("Commands may be abbreviated. Commands are:\n\n"); ! 209: for (c = cmdtab; c < &cmdtab[NCMDS]; c++) { ! 210: int len = strlen(c->c_name); ! 211: ! 212: if (len > width) ! 213: width = len; ! 214: } ! 215: width = (width + 8) &~ 7; ! 216: columns = 80 / width; ! 217: if (columns == 0) ! 218: columns = 1; ! 219: lines = (NCMDS + columns - 1) / columns; ! 220: for (i = 0; i < lines; i++) { ! 221: for (j = 0; j < columns; j++) { ! 222: c = cmdtab + j * lines + i; ! 223: printf("%s", c->c_name); ! 224: if (c + lines >= &cmdtab[NCMDS]) { ! 225: printf("\n"); ! 226: break; ! 227: } ! 228: w = strlen(c->c_name); ! 229: while (w < width) { ! 230: w = (w + 8) &~ 7; ! 231: putchar('\t'); ! 232: } ! 233: } ! 234: } ! 235: return; ! 236: } ! 237: while (--argc > 0) { ! 238: register char *arg; ! 239: arg = *++argv; ! 240: c = getcmd(arg); ! 241: if (c == (struct cmd *)-1) ! 242: printf("?Ambiguous help command %s\n", arg); ! 243: else if (c == (struct cmd *)0) ! 244: printf("?Invalid help command %s\n", arg); ! 245: else ! 246: printf("%-*s\t%s\n", HELPINDENT, ! 247: c->c_name, c->c_help); ! 248: } ! 249: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.