122428Sdist /* 2*56250Selan * Copyright (c) 1983 The Regents of the University of California. 334203Sbostic * All rights reserved. 434203Sbostic * 556121Selan * 6*56250Selan * %sccs.include.redist.c% 722428Sdist */ 822428Sdist 912380Sralph #ifndef lint 1022428Sdist char copyright[] = 11*56250Selan "@(#) Copyright (c) 1983 The Regents of the University of California.\n\ 1222428Sdist All rights reserved.\n"; 1334203Sbostic #endif /* not lint */ 1412380Sralph 1522428Sdist #ifndef lint 16*56250Selan static char sccsid[] = "@(#)lpc.c 5.14 (Berkeley) 09/15/92"; 1734203Sbostic #endif /* not lint */ 1822428Sdist 1955472Sbostic #include <sys/param.h> 2055472Sbostic 2155472Sbostic #include <dirent.h> 2212380Sralph #include <signal.h> 2312380Sralph #include <setjmp.h> 2425494Seric #include <syslog.h> 2555472Sbostic #include <unistd.h> 2655472Sbostic #include <stdlib.h> 2755472Sbostic #include <stdio.h> 2855472Sbostic #include <ctype.h> 2955472Sbostic #include <string.h> 3055472Sbostic #include "lp.h" 3112380Sralph #include "lpc.h" 3255472Sbostic #include "extern.h" 3312380Sralph 3455472Sbostic /* 3555472Sbostic * lpc -- line printer control program 3655472Sbostic */ 3755472Sbostic 3812380Sralph int fromatty; 3912380Sralph 4012380Sralph char cmdline[200]; 4112380Sralph int margc; 4212380Sralph char *margv[20]; 4312380Sralph int top; 4412380Sralph 4512380Sralph jmp_buf toplevel; 4612380Sralph 4755472Sbostic static void cmdscanner __P((int)); 4855472Sbostic static struct cmd *getcmd __P((char *)); 4955472Sbostic static void intr __P((int)); 5055472Sbostic static void makeargv __P((void)); 5155472Sbostic 5255472Sbostic int 5312380Sralph main(argc, argv) 5455472Sbostic int argc; 5512380Sralph char *argv[]; 5612380Sralph { 5712380Sralph register struct cmd *c; 5812380Sralph 5912744Sralph name = argv[0]; 6025494Seric openlog("lpd", 0, LOG_LPR); 6112744Sralph 6212380Sralph if (--argc > 0) { 6312380Sralph c = getcmd(*++argv); 6412380Sralph if (c == (struct cmd *)-1) { 6512380Sralph printf("?Ambiguous command\n"); 6612380Sralph exit(1); 6712380Sralph } 6812380Sralph if (c == 0) { 6912380Sralph printf("?Invalid command\n"); 7012380Sralph exit(1); 7112380Sralph } 7212380Sralph if (c->c_priv && getuid()) { 7312380Sralph printf("?Privileged command\n"); 7412380Sralph exit(1); 7512380Sralph } 7612380Sralph (*c->c_handler)(argc, argv); 7712380Sralph exit(0); 7812380Sralph } 7912380Sralph fromatty = isatty(fileno(stdin)); 8012380Sralph top = setjmp(toplevel) == 0; 8112380Sralph if (top) 8213147Ssam signal(SIGINT, intr); 8312380Sralph for (;;) { 8412380Sralph cmdscanner(top); 8512380Sralph top = 1; 8612380Sralph } 8712380Sralph } 8812380Sralph 8955472Sbostic static void 9055472Sbostic intr(signo) 9155472Sbostic int signo; 9212380Sralph { 9312380Sralph if (!fromatty) 9412380Sralph exit(0); 9512380Sralph longjmp(toplevel, 1); 9612380Sralph } 9712380Sralph 9812380Sralph /* 9912380Sralph * Command parser. 10012380Sralph */ 10155472Sbostic static void 10212380Sralph cmdscanner(top) 10312380Sralph int top; 10412380Sralph { 10512380Sralph register struct cmd *c; 10612380Sralph 10712380Sralph if (!top) 10812380Sralph putchar('\n'); 10912380Sralph for (;;) { 11012380Sralph if (fromatty) { 11112380Sralph printf("lpc> "); 11212380Sralph fflush(stdout); 11312380Sralph } 11436247Sbostic if (fgets(cmdline, sizeof(cmdline), stdin) == 0) 11555472Sbostic quit(0, NULL); 11640549Stef if (cmdline[0] == 0 || cmdline[0] == '\n') 11712380Sralph break; 11812380Sralph makeargv(); 11912380Sralph c = getcmd(margv[0]); 12012380Sralph if (c == (struct cmd *)-1) { 12112380Sralph printf("?Ambiguous command\n"); 12212380Sralph continue; 12312380Sralph } 12412380Sralph if (c == 0) { 12512380Sralph printf("?Invalid command\n"); 12612380Sralph continue; 12712380Sralph } 12812380Sralph if (c->c_priv && getuid()) { 12912380Sralph printf("?Privileged command\n"); 13012380Sralph continue; 13112380Sralph } 13212380Sralph (*c->c_handler)(margc, margv); 13312380Sralph } 13412380Sralph longjmp(toplevel, 0); 13512380Sralph } 13612380Sralph 13712380Sralph struct cmd * 13812380Sralph getcmd(name) 13912380Sralph register char *name; 14012380Sralph { 14112380Sralph register char *p, *q; 14212380Sralph register struct cmd *c, *found; 14312380Sralph register int nmatches, longest; 14412380Sralph 14512380Sralph longest = 0; 14612380Sralph nmatches = 0; 14712380Sralph found = 0; 14812380Sralph for (c = cmdtab; p = c->c_name; c++) { 14912380Sralph for (q = name; *q == *p++; q++) 15012380Sralph if (*q == 0) /* exact match? */ 15112380Sralph return(c); 15212380Sralph if (!*q) { /* the name was a prefix */ 15312380Sralph if (q - name > longest) { 15412380Sralph longest = q - name; 15512380Sralph nmatches = 1; 15612380Sralph found = c; 15712380Sralph } else if (q - name == longest) 15812380Sralph nmatches++; 15912380Sralph } 16012380Sralph } 16112380Sralph if (nmatches > 1) 16212380Sralph return((struct cmd *)-1); 16312380Sralph return(found); 16412380Sralph } 16512380Sralph 16612380Sralph /* 16712380Sralph * Slice a string up into argc/argv. 16812380Sralph */ 16955472Sbostic static void 17012380Sralph makeargv() 17112380Sralph { 17212380Sralph register char *cp; 17312380Sralph register char **argp = margv; 17412380Sralph 17512380Sralph margc = 0; 17612380Sralph for (cp = cmdline; *cp;) { 17712380Sralph while (isspace(*cp)) 17812380Sralph cp++; 17912380Sralph if (*cp == '\0') 18012380Sralph break; 18112380Sralph *argp++ = cp; 18212380Sralph margc += 1; 18312380Sralph while (*cp != '\0' && !isspace(*cp)) 18412380Sralph cp++; 18512380Sralph if (*cp == '\0') 18612380Sralph break; 18712380Sralph *cp++ = '\0'; 18812380Sralph } 18912380Sralph *argp++ = 0; 19012380Sralph } 19112380Sralph 19212380Sralph #define HELPINDENT (sizeof ("directory")) 19312380Sralph 19412380Sralph /* 19512380Sralph * Help command. 19612380Sralph */ 19755472Sbostic void 19812380Sralph help(argc, argv) 19912380Sralph int argc; 20012380Sralph char *argv[]; 20112380Sralph { 20212380Sralph register struct cmd *c; 20312380Sralph 20412380Sralph if (argc == 1) { 20512380Sralph register int i, j, w; 20612380Sralph int columns, width = 0, lines; 20712380Sralph extern int NCMDS; 20812380Sralph 20912380Sralph printf("Commands may be abbreviated. Commands are:\n\n"); 21039727Sbostic for (c = cmdtab; c->c_name; c++) { 21112380Sralph int len = strlen(c->c_name); 21212380Sralph 21312380Sralph if (len > width) 21412380Sralph width = len; 21512380Sralph } 21612380Sralph width = (width + 8) &~ 7; 21712380Sralph columns = 80 / width; 21812380Sralph if (columns == 0) 21912380Sralph columns = 1; 22012380Sralph lines = (NCMDS + columns - 1) / columns; 22112380Sralph for (i = 0; i < lines; i++) { 22212380Sralph for (j = 0; j < columns; j++) { 22312380Sralph c = cmdtab + j * lines + i; 22439727Sbostic if (c->c_name) 22539727Sbostic printf("%s", c->c_name); 22612380Sralph if (c + lines >= &cmdtab[NCMDS]) { 22712380Sralph printf("\n"); 22812380Sralph break; 22912380Sralph } 23012380Sralph w = strlen(c->c_name); 23112380Sralph while (w < width) { 23212380Sralph w = (w + 8) &~ 7; 23312380Sralph putchar('\t'); 23412380Sralph } 23512380Sralph } 23612380Sralph } 23712380Sralph return; 23812380Sralph } 23912380Sralph while (--argc > 0) { 24012380Sralph register char *arg; 24112380Sralph arg = *++argv; 24212380Sralph c = getcmd(arg); 24312380Sralph if (c == (struct cmd *)-1) 24412380Sralph printf("?Ambiguous help command %s\n", arg); 24512380Sralph else if (c == (struct cmd *)0) 24612380Sralph printf("?Invalid help command %s\n", arg); 24712380Sralph else 24812380Sralph printf("%-*s\t%s\n", HELPINDENT, 24912380Sralph c->c_name, c->c_help); 25012380Sralph } 25112380Sralph } 252