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.10 (Berkeley) 06/01/90"; 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 int 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 intr() 77 { 78 if (!fromatty) 79 exit(0); 80 longjmp(toplevel, 1); 81 } 82 83 /* 84 * Command parser. 85 */ 86 cmdscanner(top) 87 int top; 88 { 89 register struct cmd *c; 90 91 if (!top) 92 putchar('\n'); 93 for (;;) { 94 if (fromatty) { 95 printf("lpc> "); 96 fflush(stdout); 97 } 98 if (fgets(cmdline, sizeof(cmdline), stdin) == 0) 99 quit(); 100 if (cmdline[0] == 0 || cmdline[0] == '\n') 101 break; 102 makeargv(); 103 c = getcmd(margv[0]); 104 if (c == (struct cmd *)-1) { 105 printf("?Ambiguous command\n"); 106 continue; 107 } 108 if (c == 0) { 109 printf("?Invalid command\n"); 110 continue; 111 } 112 if (c->c_priv && getuid()) { 113 printf("?Privileged command\n"); 114 continue; 115 } 116 (*c->c_handler)(margc, margv); 117 } 118 longjmp(toplevel, 0); 119 } 120 121 extern struct cmd cmdtab[]; 122 123 struct cmd * 124 getcmd(name) 125 register char *name; 126 { 127 register char *p, *q; 128 register struct cmd *c, *found; 129 register int nmatches, longest; 130 131 longest = 0; 132 nmatches = 0; 133 found = 0; 134 for (c = cmdtab; p = c->c_name; c++) { 135 for (q = name; *q == *p++; q++) 136 if (*q == 0) /* exact match? */ 137 return(c); 138 if (!*q) { /* the name was a prefix */ 139 if (q - name > longest) { 140 longest = q - name; 141 nmatches = 1; 142 found = c; 143 } else if (q - name == longest) 144 nmatches++; 145 } 146 } 147 if (nmatches > 1) 148 return((struct cmd *)-1); 149 return(found); 150 } 151 152 /* 153 * Slice a string up into argc/argv. 154 */ 155 makeargv() 156 { 157 register char *cp; 158 register char **argp = margv; 159 160 margc = 0; 161 for (cp = cmdline; *cp;) { 162 while (isspace(*cp)) 163 cp++; 164 if (*cp == '\0') 165 break; 166 *argp++ = cp; 167 margc += 1; 168 while (*cp != '\0' && !isspace(*cp)) 169 cp++; 170 if (*cp == '\0') 171 break; 172 *cp++ = '\0'; 173 } 174 *argp++ = 0; 175 } 176 177 #define HELPINDENT (sizeof ("directory")) 178 179 /* 180 * Help command. 181 */ 182 help(argc, argv) 183 int argc; 184 char *argv[]; 185 { 186 register struct cmd *c; 187 188 if (argc == 1) { 189 register int i, j, w; 190 int columns, width = 0, lines; 191 extern int NCMDS; 192 193 printf("Commands may be abbreviated. Commands are:\n\n"); 194 for (c = cmdtab; c->c_name; c++) { 195 int len = strlen(c->c_name); 196 197 if (len > width) 198 width = len; 199 } 200 width = (width + 8) &~ 7; 201 columns = 80 / width; 202 if (columns == 0) 203 columns = 1; 204 lines = (NCMDS + columns - 1) / columns; 205 for (i = 0; i < lines; i++) { 206 for (j = 0; j < columns; j++) { 207 c = cmdtab + j * lines + i; 208 if (c->c_name) 209 printf("%s", c->c_name); 210 if (c + lines >= &cmdtab[NCMDS]) { 211 printf("\n"); 212 break; 213 } 214 w = strlen(c->c_name); 215 while (w < width) { 216 w = (w + 8) &~ 7; 217 putchar('\t'); 218 } 219 } 220 } 221 return; 222 } 223 while (--argc > 0) { 224 register char *arg; 225 arg = *++argv; 226 c = getcmd(arg); 227 if (c == (struct cmd *)-1) 228 printf("?Ambiguous help command %s\n", arg); 229 else if (c == (struct cmd *)0) 230 printf("?Invalid help command %s\n", arg); 231 else 232 printf("%-*s\t%s\n", HELPINDENT, 233 c->c_name, c->c_help); 234 } 235 } 236