122428Sdist /* 222428Sdist * Copyright (c) 1983 Regents of the University of California. 334203Sbostic * All rights reserved. 434203Sbostic * 534203Sbostic * Redistribution and use in source and binary forms are permitted 634936Sbostic * provided that the above copyright notice and this paragraph are 734936Sbostic * duplicated in all such forms and that any documentation, 834936Sbostic * advertising materials, and other materials related to such 934936Sbostic * distribution and use acknowledge that the software was developed 1034936Sbostic * by the University of California, Berkeley. The name of the 1134936Sbostic * University may not be used to endorse or promote products derived 1234936Sbostic * from this software without specific prior written permission. 1334936Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1434936Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1534936Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1622428Sdist */ 1722428Sdist 1812380Sralph #ifndef lint 1922428Sdist char copyright[] = 2022428Sdist "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 2122428Sdist All rights reserved.\n"; 2234203Sbostic #endif /* not lint */ 2312380Sralph 2422428Sdist #ifndef lint 25*39727Sbostic static char sccsid[] = "@(#)lpc.c 5.8 (Berkeley) 12/18/89"; 2634203Sbostic #endif /* not lint */ 2722428Sdist 2812380Sralph /* 2912380Sralph * lpc -- line printer control program 3012380Sralph */ 3112380Sralph #include <stdio.h> 3212380Sralph #include <signal.h> 3312380Sralph #include <ctype.h> 3412380Sralph #include <setjmp.h> 3525494Seric #include <syslog.h> 3612380Sralph 3712380Sralph #include "lpc.h" 3812380Sralph 3912380Sralph int fromatty; 4012380Sralph 4112380Sralph char cmdline[200]; 4212380Sralph int margc; 4312380Sralph char *margv[20]; 4412380Sralph int top; 4512380Sralph int intr(); 4612380Sralph struct cmd *getcmd(); 4712380Sralph 4812380Sralph jmp_buf toplevel; 4912380Sralph 5012380Sralph main(argc, argv) 5112380Sralph char *argv[]; 5212380Sralph { 5312380Sralph register struct cmd *c; 5412744Sralph extern char *name; 5512380Sralph 5612744Sralph name = argv[0]; 5725494Seric openlog("lpd", 0, LOG_LPR); 5812744Sralph 5912380Sralph if (--argc > 0) { 6012380Sralph c = getcmd(*++argv); 6112380Sralph if (c == (struct cmd *)-1) { 6212380Sralph printf("?Ambiguous command\n"); 6312380Sralph exit(1); 6412380Sralph } 6512380Sralph if (c == 0) { 6612380Sralph printf("?Invalid command\n"); 6712380Sralph exit(1); 6812380Sralph } 6912380Sralph if (c->c_priv && getuid()) { 7012380Sralph printf("?Privileged command\n"); 7112380Sralph exit(1); 7212380Sralph } 7312380Sralph (*c->c_handler)(argc, argv); 7412380Sralph exit(0); 7512380Sralph } 7612380Sralph fromatty = isatty(fileno(stdin)); 7712380Sralph top = setjmp(toplevel) == 0; 7812380Sralph if (top) 7913147Ssam signal(SIGINT, intr); 8012380Sralph for (;;) { 8112380Sralph cmdscanner(top); 8212380Sralph top = 1; 8312380Sralph } 8412380Sralph } 8512380Sralph 8612380Sralph intr() 8712380Sralph { 8812380Sralph if (!fromatty) 8912380Sralph exit(0); 9012380Sralph longjmp(toplevel, 1); 9112380Sralph } 9212380Sralph 9312380Sralph /* 9412380Sralph * Command parser. 9512380Sralph */ 9612380Sralph cmdscanner(top) 9712380Sralph int top; 9812380Sralph { 9912380Sralph register struct cmd *c; 10012380Sralph 10112380Sralph if (!top) 10212380Sralph putchar('\n'); 10312380Sralph for (;;) { 10412380Sralph if (fromatty) { 10512380Sralph printf("lpc> "); 10612380Sralph fflush(stdout); 10712380Sralph } 10836247Sbostic if (fgets(cmdline, sizeof(cmdline), stdin) == 0) 10912380Sralph quit(); 11012380Sralph if (cmdline[0] == 0) 11112380Sralph break; 11212380Sralph makeargv(); 11312380Sralph c = getcmd(margv[0]); 11412380Sralph if (c == (struct cmd *)-1) { 11512380Sralph printf("?Ambiguous command\n"); 11612380Sralph continue; 11712380Sralph } 11812380Sralph if (c == 0) { 11912380Sralph printf("?Invalid command\n"); 12012380Sralph continue; 12112380Sralph } 12212380Sralph if (c->c_priv && getuid()) { 12312380Sralph printf("?Privileged command\n"); 12412380Sralph continue; 12512380Sralph } 12612380Sralph (*c->c_handler)(margc, margv); 12712380Sralph } 12812380Sralph longjmp(toplevel, 0); 12912380Sralph } 13012380Sralph 13133069Sbostic extern struct cmd cmdtab[]; 13233069Sbostic 13312380Sralph struct cmd * 13412380Sralph getcmd(name) 13512380Sralph register char *name; 13612380Sralph { 13712380Sralph register char *p, *q; 13812380Sralph register struct cmd *c, *found; 13912380Sralph register int nmatches, longest; 14012380Sralph 14112380Sralph longest = 0; 14212380Sralph nmatches = 0; 14312380Sralph found = 0; 14412380Sralph for (c = cmdtab; p = c->c_name; c++) { 14512380Sralph for (q = name; *q == *p++; q++) 14612380Sralph if (*q == 0) /* exact match? */ 14712380Sralph return(c); 14812380Sralph if (!*q) { /* the name was a prefix */ 14912380Sralph if (q - name > longest) { 15012380Sralph longest = q - name; 15112380Sralph nmatches = 1; 15212380Sralph found = c; 15312380Sralph } else if (q - name == longest) 15412380Sralph nmatches++; 15512380Sralph } 15612380Sralph } 15712380Sralph if (nmatches > 1) 15812380Sralph return((struct cmd *)-1); 15912380Sralph return(found); 16012380Sralph } 16112380Sralph 16212380Sralph /* 16312380Sralph * Slice a string up into argc/argv. 16412380Sralph */ 16512380Sralph makeargv() 16612380Sralph { 16712380Sralph register char *cp; 16812380Sralph register char **argp = margv; 16912380Sralph 17012380Sralph margc = 0; 17112380Sralph for (cp = cmdline; *cp;) { 17212380Sralph while (isspace(*cp)) 17312380Sralph cp++; 17412380Sralph if (*cp == '\0') 17512380Sralph break; 17612380Sralph *argp++ = cp; 17712380Sralph margc += 1; 17812380Sralph while (*cp != '\0' && !isspace(*cp)) 17912380Sralph cp++; 18012380Sralph if (*cp == '\0') 18112380Sralph break; 18212380Sralph *cp++ = '\0'; 18312380Sralph } 18412380Sralph *argp++ = 0; 18512380Sralph } 18612380Sralph 18712380Sralph #define HELPINDENT (sizeof ("directory")) 18812380Sralph 18912380Sralph /* 19012380Sralph * Help command. 19112380Sralph */ 19212380Sralph help(argc, argv) 19312380Sralph int argc; 19412380Sralph char *argv[]; 19512380Sralph { 19612380Sralph register struct cmd *c; 19712380Sralph 19812380Sralph if (argc == 1) { 19912380Sralph register int i, j, w; 20012380Sralph int columns, width = 0, lines; 20112380Sralph extern int NCMDS; 20212380Sralph 20312380Sralph printf("Commands may be abbreviated. Commands are:\n\n"); 204*39727Sbostic for (c = cmdtab; c->c_name; c++) { 20512380Sralph int len = strlen(c->c_name); 20612380Sralph 20712380Sralph if (len > width) 20812380Sralph width = len; 20912380Sralph } 21012380Sralph width = (width + 8) &~ 7; 21112380Sralph columns = 80 / width; 21212380Sralph if (columns == 0) 21312380Sralph columns = 1; 21412380Sralph lines = (NCMDS + columns - 1) / columns; 21512380Sralph for (i = 0; i < lines; i++) { 21612380Sralph for (j = 0; j < columns; j++) { 21712380Sralph c = cmdtab + j * lines + i; 218*39727Sbostic if (c->c_name) 219*39727Sbostic printf("%s", c->c_name); 22012380Sralph if (c + lines >= &cmdtab[NCMDS]) { 22112380Sralph printf("\n"); 22212380Sralph break; 22312380Sralph } 22412380Sralph w = strlen(c->c_name); 22512380Sralph while (w < width) { 22612380Sralph w = (w + 8) &~ 7; 22712380Sralph putchar('\t'); 22812380Sralph } 22912380Sralph } 23012380Sralph } 23112380Sralph return; 23212380Sralph } 23312380Sralph while (--argc > 0) { 23412380Sralph register char *arg; 23512380Sralph arg = *++argv; 23612380Sralph c = getcmd(arg); 23712380Sralph if (c == (struct cmd *)-1) 23812380Sralph printf("?Ambiguous help command %s\n", arg); 23912380Sralph else if (c == (struct cmd *)0) 24012380Sralph printf("?Invalid help command %s\n", arg); 24112380Sralph else 24212380Sralph printf("%-*s\t%s\n", HELPINDENT, 24312380Sralph c->c_name, c->c_help); 24412380Sralph } 24512380Sralph } 246