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