122428Sdist /* 222428Sdist * Copyright (c) 1983 Regents of the University of California. 334203Sbostic * All rights reserved. 434203Sbostic * 5*42801Sbostic * %sccs.include.redist.c% 622428Sdist */ 722428Sdist 812380Sralph #ifndef lint 922428Sdist char copyright[] = 1022428Sdist "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 1122428Sdist All rights reserved.\n"; 1234203Sbostic #endif /* not lint */ 1312380Sralph 1422428Sdist #ifndef lint 15*42801Sbostic static char sccsid[] = "@(#)lpc.c 5.10 (Berkeley) 06/01/90"; 1634203Sbostic #endif /* not lint */ 1722428Sdist 1812380Sralph /* 1912380Sralph * lpc -- line printer control program 2012380Sralph */ 2112380Sralph #include <stdio.h> 2212380Sralph #include <signal.h> 2312380Sralph #include <ctype.h> 2412380Sralph #include <setjmp.h> 2525494Seric #include <syslog.h> 2612380Sralph 2712380Sralph #include "lpc.h" 2812380Sralph 2912380Sralph int fromatty; 3012380Sralph 3112380Sralph char cmdline[200]; 3212380Sralph int margc; 3312380Sralph char *margv[20]; 3412380Sralph int top; 3512380Sralph int intr(); 3612380Sralph struct cmd *getcmd(); 3712380Sralph 3812380Sralph jmp_buf toplevel; 3912380Sralph 4012380Sralph main(argc, argv) 4112380Sralph char *argv[]; 4212380Sralph { 4312380Sralph register struct cmd *c; 4412744Sralph extern char *name; 4512380Sralph 4612744Sralph name = argv[0]; 4725494Seric openlog("lpd", 0, LOG_LPR); 4812744Sralph 4912380Sralph if (--argc > 0) { 5012380Sralph c = getcmd(*++argv); 5112380Sralph if (c == (struct cmd *)-1) { 5212380Sralph printf("?Ambiguous command\n"); 5312380Sralph exit(1); 5412380Sralph } 5512380Sralph if (c == 0) { 5612380Sralph printf("?Invalid command\n"); 5712380Sralph exit(1); 5812380Sralph } 5912380Sralph if (c->c_priv && getuid()) { 6012380Sralph printf("?Privileged command\n"); 6112380Sralph exit(1); 6212380Sralph } 6312380Sralph (*c->c_handler)(argc, argv); 6412380Sralph exit(0); 6512380Sralph } 6612380Sralph fromatty = isatty(fileno(stdin)); 6712380Sralph top = setjmp(toplevel) == 0; 6812380Sralph if (top) 6913147Ssam signal(SIGINT, intr); 7012380Sralph for (;;) { 7112380Sralph cmdscanner(top); 7212380Sralph top = 1; 7312380Sralph } 7412380Sralph } 7512380Sralph 7612380Sralph intr() 7712380Sralph { 7812380Sralph if (!fromatty) 7912380Sralph exit(0); 8012380Sralph longjmp(toplevel, 1); 8112380Sralph } 8212380Sralph 8312380Sralph /* 8412380Sralph * Command parser. 8512380Sralph */ 8612380Sralph cmdscanner(top) 8712380Sralph int top; 8812380Sralph { 8912380Sralph register struct cmd *c; 9012380Sralph 9112380Sralph if (!top) 9212380Sralph putchar('\n'); 9312380Sralph for (;;) { 9412380Sralph if (fromatty) { 9512380Sralph printf("lpc> "); 9612380Sralph fflush(stdout); 9712380Sralph } 9836247Sbostic if (fgets(cmdline, sizeof(cmdline), stdin) == 0) 9912380Sralph quit(); 10040549Stef if (cmdline[0] == 0 || cmdline[0] == '\n') 10112380Sralph break; 10212380Sralph makeargv(); 10312380Sralph c = getcmd(margv[0]); 10412380Sralph if (c == (struct cmd *)-1) { 10512380Sralph printf("?Ambiguous command\n"); 10612380Sralph continue; 10712380Sralph } 10812380Sralph if (c == 0) { 10912380Sralph printf("?Invalid command\n"); 11012380Sralph continue; 11112380Sralph } 11212380Sralph if (c->c_priv && getuid()) { 11312380Sralph printf("?Privileged command\n"); 11412380Sralph continue; 11512380Sralph } 11612380Sralph (*c->c_handler)(margc, margv); 11712380Sralph } 11812380Sralph longjmp(toplevel, 0); 11912380Sralph } 12012380Sralph 12133069Sbostic extern struct cmd cmdtab[]; 12233069Sbostic 12312380Sralph struct cmd * 12412380Sralph getcmd(name) 12512380Sralph register char *name; 12612380Sralph { 12712380Sralph register char *p, *q; 12812380Sralph register struct cmd *c, *found; 12912380Sralph register int nmatches, longest; 13012380Sralph 13112380Sralph longest = 0; 13212380Sralph nmatches = 0; 13312380Sralph found = 0; 13412380Sralph for (c = cmdtab; p = c->c_name; c++) { 13512380Sralph for (q = name; *q == *p++; q++) 13612380Sralph if (*q == 0) /* exact match? */ 13712380Sralph return(c); 13812380Sralph if (!*q) { /* the name was a prefix */ 13912380Sralph if (q - name > longest) { 14012380Sralph longest = q - name; 14112380Sralph nmatches = 1; 14212380Sralph found = c; 14312380Sralph } else if (q - name == longest) 14412380Sralph nmatches++; 14512380Sralph } 14612380Sralph } 14712380Sralph if (nmatches > 1) 14812380Sralph return((struct cmd *)-1); 14912380Sralph return(found); 15012380Sralph } 15112380Sralph 15212380Sralph /* 15312380Sralph * Slice a string up into argc/argv. 15412380Sralph */ 15512380Sralph makeargv() 15612380Sralph { 15712380Sralph register char *cp; 15812380Sralph register char **argp = margv; 15912380Sralph 16012380Sralph margc = 0; 16112380Sralph for (cp = cmdline; *cp;) { 16212380Sralph while (isspace(*cp)) 16312380Sralph cp++; 16412380Sralph if (*cp == '\0') 16512380Sralph break; 16612380Sralph *argp++ = cp; 16712380Sralph margc += 1; 16812380Sralph while (*cp != '\0' && !isspace(*cp)) 16912380Sralph cp++; 17012380Sralph if (*cp == '\0') 17112380Sralph break; 17212380Sralph *cp++ = '\0'; 17312380Sralph } 17412380Sralph *argp++ = 0; 17512380Sralph } 17612380Sralph 17712380Sralph #define HELPINDENT (sizeof ("directory")) 17812380Sralph 17912380Sralph /* 18012380Sralph * Help command. 18112380Sralph */ 18212380Sralph help(argc, argv) 18312380Sralph int argc; 18412380Sralph char *argv[]; 18512380Sralph { 18612380Sralph register struct cmd *c; 18712380Sralph 18812380Sralph if (argc == 1) { 18912380Sralph register int i, j, w; 19012380Sralph int columns, width = 0, lines; 19112380Sralph extern int NCMDS; 19212380Sralph 19312380Sralph printf("Commands may be abbreviated. Commands are:\n\n"); 19439727Sbostic for (c = cmdtab; c->c_name; c++) { 19512380Sralph int len = strlen(c->c_name); 19612380Sralph 19712380Sralph if (len > width) 19812380Sralph width = len; 19912380Sralph } 20012380Sralph width = (width + 8) &~ 7; 20112380Sralph columns = 80 / width; 20212380Sralph if (columns == 0) 20312380Sralph columns = 1; 20412380Sralph lines = (NCMDS + columns - 1) / columns; 20512380Sralph for (i = 0; i < lines; i++) { 20612380Sralph for (j = 0; j < columns; j++) { 20712380Sralph c = cmdtab + j * lines + i; 20839727Sbostic if (c->c_name) 20939727Sbostic printf("%s", c->c_name); 21012380Sralph if (c + lines >= &cmdtab[NCMDS]) { 21112380Sralph printf("\n"); 21212380Sralph break; 21312380Sralph } 21412380Sralph w = strlen(c->c_name); 21512380Sralph while (w < width) { 21612380Sralph w = (w + 8) &~ 7; 21712380Sralph putchar('\t'); 21812380Sralph } 21912380Sralph } 22012380Sralph } 22112380Sralph return; 22212380Sralph } 22312380Sralph while (--argc > 0) { 22412380Sralph register char *arg; 22512380Sralph arg = *++argv; 22612380Sralph c = getcmd(arg); 22712380Sralph if (c == (struct cmd *)-1) 22812380Sralph printf("?Ambiguous help command %s\n", arg); 22912380Sralph else if (c == (struct cmd *)0) 23012380Sralph printf("?Invalid help command %s\n", arg); 23112380Sralph else 23212380Sralph printf("%-*s\t%s\n", HELPINDENT, 23312380Sralph c->c_name, c->c_help); 23412380Sralph } 23512380Sralph } 236