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