122428Sdist /* 222428Sdist * Copyright (c) 1983 Regents of the University of California. 3*34203Sbostic * All rights reserved. 4*34203Sbostic * 5*34203Sbostic * Redistribution and use in source and binary forms are permitted 6*34203Sbostic * provided that this notice is preserved and that due credit is given 7*34203Sbostic * to the University of California at Berkeley. The name of the University 8*34203Sbostic * may not be used to endorse or promote products derived from this 9*34203Sbostic * software without specific prior written permission. This software 10*34203Sbostic * is provided ``as is'' without express or implied warranty. 1122428Sdist */ 1222428Sdist 1312380Sralph #ifndef lint 1422428Sdist char copyright[] = 1522428Sdist "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 1622428Sdist All rights reserved.\n"; 17*34203Sbostic #endif /* not lint */ 1812380Sralph 1922428Sdist #ifndef lint 20*34203Sbostic static char sccsid[] = "@(#)lpc.c 5.5 (Berkeley) 05/05/88"; 21*34203Sbostic #endif /* not lint */ 2222428Sdist 2312380Sralph /* 2412380Sralph * lpc -- line printer control program 2512380Sralph */ 2612380Sralph #include <stdio.h> 2712380Sralph #include <signal.h> 2812380Sralph #include <ctype.h> 2912380Sralph #include <setjmp.h> 3025494Seric #include <syslog.h> 3112380Sralph 3212380Sralph #include "lpc.h" 3312380Sralph 3412380Sralph int fromatty; 3512380Sralph 3612380Sralph char cmdline[200]; 3712380Sralph int margc; 3812380Sralph char *margv[20]; 3912380Sralph int top; 4012380Sralph int intr(); 4112380Sralph struct cmd *getcmd(); 4212380Sralph 4312380Sralph jmp_buf toplevel; 4412380Sralph 4512380Sralph main(argc, argv) 4612380Sralph char *argv[]; 4712380Sralph { 4812380Sralph register struct cmd *c; 4912744Sralph extern char *name; 5012380Sralph 5112744Sralph name = argv[0]; 5225494Seric openlog("lpd", 0, LOG_LPR); 5312744Sralph 5412380Sralph if (--argc > 0) { 5512380Sralph c = getcmd(*++argv); 5612380Sralph if (c == (struct cmd *)-1) { 5712380Sralph printf("?Ambiguous command\n"); 5812380Sralph exit(1); 5912380Sralph } 6012380Sralph if (c == 0) { 6112380Sralph printf("?Invalid command\n"); 6212380Sralph exit(1); 6312380Sralph } 6412380Sralph if (c->c_priv && getuid()) { 6512380Sralph printf("?Privileged command\n"); 6612380Sralph exit(1); 6712380Sralph } 6812380Sralph (*c->c_handler)(argc, argv); 6912380Sralph exit(0); 7012380Sralph } 7112380Sralph fromatty = isatty(fileno(stdin)); 7212380Sralph top = setjmp(toplevel) == 0; 7312380Sralph if (top) 7413147Ssam signal(SIGINT, intr); 7512380Sralph for (;;) { 7612380Sralph cmdscanner(top); 7712380Sralph top = 1; 7812380Sralph } 7912380Sralph } 8012380Sralph 8112380Sralph intr() 8212380Sralph { 8312380Sralph if (!fromatty) 8412380Sralph exit(0); 8512380Sralph longjmp(toplevel, 1); 8612380Sralph } 8712380Sralph 8812380Sralph /* 8912380Sralph * Command parser. 9012380Sralph */ 9112380Sralph cmdscanner(top) 9212380Sralph int top; 9312380Sralph { 9412380Sralph register struct cmd *c; 9512380Sralph 9612380Sralph if (!top) 9712380Sralph putchar('\n'); 9812380Sralph for (;;) { 9912380Sralph if (fromatty) { 10012380Sralph printf("lpc> "); 10112380Sralph fflush(stdout); 10212380Sralph } 10312380Sralph if (gets(cmdline) == 0) 10412380Sralph quit(); 10512380Sralph if (cmdline[0] == 0) 10612380Sralph break; 10712380Sralph makeargv(); 10812380Sralph c = getcmd(margv[0]); 10912380Sralph if (c == (struct cmd *)-1) { 11012380Sralph printf("?Ambiguous command\n"); 11112380Sralph continue; 11212380Sralph } 11312380Sralph if (c == 0) { 11412380Sralph printf("?Invalid command\n"); 11512380Sralph continue; 11612380Sralph } 11712380Sralph if (c->c_priv && getuid()) { 11812380Sralph printf("?Privileged command\n"); 11912380Sralph continue; 12012380Sralph } 12112380Sralph (*c->c_handler)(margc, margv); 12212380Sralph } 12312380Sralph longjmp(toplevel, 0); 12412380Sralph } 12512380Sralph 12633069Sbostic extern struct cmd cmdtab[]; 12733069Sbostic 12812380Sralph struct cmd * 12912380Sralph getcmd(name) 13012380Sralph register char *name; 13112380Sralph { 13212380Sralph register char *p, *q; 13312380Sralph register struct cmd *c, *found; 13412380Sralph register int nmatches, longest; 13512380Sralph 13612380Sralph longest = 0; 13712380Sralph nmatches = 0; 13812380Sralph found = 0; 13912380Sralph for (c = cmdtab; p = c->c_name; c++) { 14012380Sralph for (q = name; *q == *p++; q++) 14112380Sralph if (*q == 0) /* exact match? */ 14212380Sralph return(c); 14312380Sralph if (!*q) { /* the name was a prefix */ 14412380Sralph if (q - name > longest) { 14512380Sralph longest = q - name; 14612380Sralph nmatches = 1; 14712380Sralph found = c; 14812380Sralph } else if (q - name == longest) 14912380Sralph nmatches++; 15012380Sralph } 15112380Sralph } 15212380Sralph if (nmatches > 1) 15312380Sralph return((struct cmd *)-1); 15412380Sralph return(found); 15512380Sralph } 15612380Sralph 15712380Sralph /* 15812380Sralph * Slice a string up into argc/argv. 15912380Sralph */ 16012380Sralph makeargv() 16112380Sralph { 16212380Sralph register char *cp; 16312380Sralph register char **argp = margv; 16412380Sralph 16512380Sralph margc = 0; 16612380Sralph for (cp = cmdline; *cp;) { 16712380Sralph while (isspace(*cp)) 16812380Sralph cp++; 16912380Sralph if (*cp == '\0') 17012380Sralph break; 17112380Sralph *argp++ = cp; 17212380Sralph margc += 1; 17312380Sralph while (*cp != '\0' && !isspace(*cp)) 17412380Sralph cp++; 17512380Sralph if (*cp == '\0') 17612380Sralph break; 17712380Sralph *cp++ = '\0'; 17812380Sralph } 17912380Sralph *argp++ = 0; 18012380Sralph } 18112380Sralph 18212380Sralph #define HELPINDENT (sizeof ("directory")) 18312380Sralph 18412380Sralph /* 18512380Sralph * Help command. 18612380Sralph */ 18712380Sralph help(argc, argv) 18812380Sralph int argc; 18912380Sralph char *argv[]; 19012380Sralph { 19112380Sralph register struct cmd *c; 19212380Sralph 19312380Sralph if (argc == 1) { 19412380Sralph register int i, j, w; 19512380Sralph int columns, width = 0, lines; 19612380Sralph extern int NCMDS; 19712380Sralph 19812380Sralph printf("Commands may be abbreviated. Commands are:\n\n"); 19932157Sbostic for (c = cmdtab; c < &cmdtab[NCMDS - 1]; c++) { 20012380Sralph int len = strlen(c->c_name); 20112380Sralph 20212380Sralph if (len > width) 20312380Sralph width = len; 20412380Sralph } 20512380Sralph width = (width + 8) &~ 7; 20612380Sralph columns = 80 / width; 20712380Sralph if (columns == 0) 20812380Sralph columns = 1; 20912380Sralph lines = (NCMDS + columns - 1) / columns; 21012380Sralph for (i = 0; i < lines; i++) { 21112380Sralph for (j = 0; j < columns; j++) { 21212380Sralph c = cmdtab + j * lines + i; 21312380Sralph printf("%s", c->c_name); 21412380Sralph if (c + lines >= &cmdtab[NCMDS]) { 21512380Sralph printf("\n"); 21612380Sralph break; 21712380Sralph } 21812380Sralph w = strlen(c->c_name); 21912380Sralph while (w < width) { 22012380Sralph w = (w + 8) &~ 7; 22112380Sralph putchar('\t'); 22212380Sralph } 22312380Sralph } 22412380Sralph } 22512380Sralph return; 22612380Sralph } 22712380Sralph while (--argc > 0) { 22812380Sralph register char *arg; 22912380Sralph arg = *++argv; 23012380Sralph c = getcmd(arg); 23112380Sralph if (c == (struct cmd *)-1) 23212380Sralph printf("?Ambiguous help command %s\n", arg); 23312380Sralph else if (c == (struct cmd *)0) 23412380Sralph printf("?Invalid help command %s\n", arg); 23512380Sralph else 23612380Sralph printf("%-*s\t%s\n", HELPINDENT, 23712380Sralph c->c_name, c->c_help); 23812380Sralph } 23912380Sralph } 240