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