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