|
|
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 provided ! 6: * that: (1) source distributions retain this entire copyright notice and ! 7: * comment, and (2) distributions including binaries display the following ! 8: * acknowledgement: ``This product includes software developed by the ! 9: * University of California, Berkeley and its contributors'' in the ! 10: * documentation or other materials provided with the distribution and in ! 11: * all advertising materials mentioning features or use of this software. ! 12: * Neither the name of the University nor the names of its contributors may ! 13: * be used to endorse or promote products derived from this software without ! 14: * specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: char copyright[] = ! 22: "@(#) Copyright (c) 1983 Regents of the University of California.\n\ ! 23: All rights reserved.\n"; ! 24: #endif /* not lint */ ! 25: ! 26: #ifndef lint ! 27: static char sccsid[] = "@(#)lpc.c 5.10 (Berkeley) 6/1/90"; ! 28: #endif /* not lint */ ! 29: ! 30: /* ! 31: * lpc -- line printer control program ! 32: */ ! 33: #include <stdio.h> ! 34: #include <signal.h> ! 35: #include <ctype.h> ! 36: #include <setjmp.h> ! 37: #include <syslog.h> ! 38: ! 39: #include "lpc.h" ! 40: ! 41: int fromatty; ! 42: ! 43: char cmdline[200]; ! 44: int margc; ! 45: char *margv[20]; ! 46: int top; ! 47: int intr(); ! 48: struct cmd *getcmd(); ! 49: ! 50: jmp_buf toplevel; ! 51: ! 52: main(argc, argv) ! 53: char *argv[]; ! 54: { ! 55: register struct cmd *c; ! 56: extern char *name; ! 57: ! 58: name = argv[0]; ! 59: openlog("lpd", 0, LOG_LPR); ! 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: 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: ! 103: if (!top) ! 104: putchar('\n'); ! 105: for (;;) { ! 106: if (fromatty) { ! 107: printf("lpc> "); ! 108: fflush(stdout); ! 109: } ! 110: if (fgets(cmdline, sizeof(cmdline), stdin) == 0) ! 111: quit(); ! 112: if (cmdline[0] == 0 || cmdline[0] == '\n') ! 113: break; ! 114: makeargv(); ! 115: c = getcmd(margv[0]); ! 116: if (c == (struct cmd *)-1) { ! 117: printf("?Ambiguous command\n"); ! 118: continue; ! 119: } ! 120: if (c == 0) { ! 121: printf("?Invalid command\n"); ! 122: continue; ! 123: } ! 124: if (c->c_priv && getuid()) { ! 125: printf("?Privileged command\n"); ! 126: continue; ! 127: } ! 128: (*c->c_handler)(margc, margv); ! 129: } ! 130: longjmp(toplevel, 0); ! 131: } ! 132: ! 133: extern struct cmd cmdtab[]; ! 134: ! 135: struct cmd * ! 136: getcmd(name) ! 137: register char *name; ! 138: { ! 139: register char *p, *q; ! 140: register struct cmd *c, *found; ! 141: register int nmatches, longest; ! 142: ! 143: longest = 0; ! 144: nmatches = 0; ! 145: found = 0; ! 146: for (c = cmdtab; p = c->c_name; c++) { ! 147: for (q = name; *q == *p++; q++) ! 148: if (*q == 0) /* exact match? */ ! 149: return(c); ! 150: if (!*q) { /* the name was a prefix */ ! 151: if (q - name > longest) { ! 152: longest = q - name; ! 153: nmatches = 1; ! 154: found = c; ! 155: } else if (q - name == longest) ! 156: nmatches++; ! 157: } ! 158: } ! 159: if (nmatches > 1) ! 160: return((struct cmd *)-1); ! 161: return(found); ! 162: } ! 163: ! 164: /* ! 165: * Slice a string up into argc/argv. ! 166: */ ! 167: makeargv() ! 168: { ! 169: register char *cp; ! 170: register char **argp = margv; ! 171: ! 172: margc = 0; ! 173: for (cp = cmdline; *cp;) { ! 174: while (isspace(*cp)) ! 175: cp++; ! 176: if (*cp == '\0') ! 177: break; ! 178: *argp++ = cp; ! 179: margc += 1; ! 180: while (*cp != '\0' && !isspace(*cp)) ! 181: cp++; ! 182: if (*cp == '\0') ! 183: break; ! 184: *cp++ = '\0'; ! 185: } ! 186: *argp++ = 0; ! 187: } ! 188: ! 189: #define HELPINDENT (sizeof ("directory")) ! 190: ! 191: /* ! 192: * Help command. ! 193: */ ! 194: help(argc, argv) ! 195: int argc; ! 196: char *argv[]; ! 197: { ! 198: register struct cmd *c; ! 199: ! 200: if (argc == 1) { ! 201: register int i, j, w; ! 202: int columns, width = 0, lines; ! 203: extern int NCMDS; ! 204: ! 205: printf("Commands may be abbreviated. Commands are:\n\n"); ! 206: for (c = cmdtab; c->c_name; c++) { ! 207: int len = strlen(c->c_name); ! 208: ! 209: if (len > width) ! 210: width = len; ! 211: } ! 212: width = (width + 8) &~ 7; ! 213: columns = 80 / width; ! 214: if (columns == 0) ! 215: columns = 1; ! 216: lines = (NCMDS + columns - 1) / columns; ! 217: for (i = 0; i < lines; i++) { ! 218: for (j = 0; j < columns; j++) { ! 219: c = cmdtab + j * lines + i; ! 220: if (c->c_name) ! 221: printf("%s", c->c_name); ! 222: if (c + lines >= &cmdtab[NCMDS]) { ! 223: printf("\n"); ! 224: break; ! 225: } ! 226: w = strlen(c->c_name); ! 227: while (w < width) { ! 228: w = (w + 8) &~ 7; ! 229: putchar('\t'); ! 230: } ! 231: } ! 232: } ! 233: return; ! 234: } ! 235: while (--argc > 0) { ! 236: register char *arg; ! 237: arg = *++argv; ! 238: c = getcmd(arg); ! 239: if (c == (struct cmd *)-1) ! 240: printf("?Ambiguous help command %s\n", arg); ! 241: else if (c == (struct cmd *)0) ! 242: printf("?Invalid help command %s\n", arg); ! 243: else ! 244: printf("%-*s\t%s\n", HELPINDENT, ! 245: c->c_name, c->c_help); ! 246: } ! 247: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.