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