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