122428Sdist /* 261843Sbostic * Copyright (c) 1983, 1993 361843Sbostic * The Regents of the University of California. All rights reserved. 434203Sbostic * 556121Selan * 656250Selan * %sccs.include.redist.c% 722428Sdist */ 822428Sdist 912380Sralph #ifndef lint 1056264Selan static char copyright[] = 1161843Sbostic "@(#) Copyright (c) 1983, 1993\n\ 1261843Sbostic The Regents of the University of California. All rights reserved.\n"; 1334203Sbostic #endif /* not lint */ 1412380Sralph 1522428Sdist #ifndef lint 16*69027Stef static char sccsid[] = "@(#)lpc.c 8.2 (Berkeley) 04/28/95"; 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> 30*69027Stef #include "extern.h" 31*69027Stef #include <sys/param.h> 32*69027Stef #include <grp.h> 3355472Sbostic #include "lp.h" 3412380Sralph #include "lpc.h" 3555472Sbostic #include "extern.h" 3612380Sralph 37*69027Stef #ifndef LPR_OPER 38*69027Stef #define LPR_OPER "operator" /* group name of lpr operators */ 39*69027Stef #endif 40*69027Stef 4155472Sbostic /* 4255472Sbostic * lpc -- line printer control program 4355472Sbostic */ 4455472Sbostic 4512380Sralph int fromatty; 4612380Sralph 4712380Sralph char cmdline[200]; 4812380Sralph int margc; 4912380Sralph char *margv[20]; 5012380Sralph int top; 5112380Sralph 5212380Sralph jmp_buf toplevel; 5312380Sralph 5455472Sbostic static void cmdscanner __P((int)); 5555472Sbostic static struct cmd *getcmd __P((char *)); 5655472Sbostic static void intr __P((int)); 5755472Sbostic static void makeargv __P((void)); 58*69027Stef static int ingroup __P((char *)); 5955472Sbostic 6055472Sbostic int 6112380Sralph main(argc, argv) 6255472Sbostic int argc; 6312380Sralph char *argv[]; 6412380Sralph { 6512380Sralph register struct cmd *c; 6612380Sralph 6712744Sralph name = argv[0]; 6825494Seric openlog("lpd", 0, LOG_LPR); 6912744Sralph 7012380Sralph if (--argc > 0) { 7112380Sralph c = getcmd(*++argv); 7212380Sralph if (c == (struct cmd *)-1) { 7312380Sralph printf("?Ambiguous command\n"); 7412380Sralph exit(1); 7512380Sralph } 7612380Sralph if (c == 0) { 7712380Sralph printf("?Invalid command\n"); 7812380Sralph exit(1); 7912380Sralph } 80*69027Stef if (c->c_priv && getuid() && ingroup(LPR_OPER) == 0) { 8112380Sralph printf("?Privileged command\n"); 8212380Sralph exit(1); 8312380Sralph } 8412380Sralph (*c->c_handler)(argc, argv); 8512380Sralph exit(0); 8612380Sralph } 8712380Sralph fromatty = isatty(fileno(stdin)); 8812380Sralph top = setjmp(toplevel) == 0; 8912380Sralph if (top) 9013147Ssam signal(SIGINT, intr); 9112380Sralph for (;;) { 9212380Sralph cmdscanner(top); 9312380Sralph top = 1; 9412380Sralph } 9512380Sralph } 9612380Sralph 9755472Sbostic static void 9855472Sbostic intr(signo) 9955472Sbostic int signo; 10012380Sralph { 10112380Sralph if (!fromatty) 10212380Sralph exit(0); 10312380Sralph longjmp(toplevel, 1); 10412380Sralph } 10512380Sralph 10612380Sralph /* 10712380Sralph * Command parser. 10812380Sralph */ 10955472Sbostic static void 11012380Sralph cmdscanner(top) 11112380Sralph int top; 11212380Sralph { 11312380Sralph register struct cmd *c; 11412380Sralph 11512380Sralph if (!top) 11612380Sralph putchar('\n'); 11712380Sralph for (;;) { 11812380Sralph if (fromatty) { 11912380Sralph printf("lpc> "); 12012380Sralph fflush(stdout); 12112380Sralph } 12236247Sbostic if (fgets(cmdline, sizeof(cmdline), stdin) == 0) 12355472Sbostic quit(0, NULL); 12440549Stef if (cmdline[0] == 0 || cmdline[0] == '\n') 12512380Sralph break; 12612380Sralph makeargv(); 12712380Sralph c = getcmd(margv[0]); 12812380Sralph if (c == (struct cmd *)-1) { 12912380Sralph printf("?Ambiguous command\n"); 13012380Sralph continue; 13112380Sralph } 13212380Sralph if (c == 0) { 13312380Sralph printf("?Invalid command\n"); 13412380Sralph continue; 13512380Sralph } 136*69027Stef if (c->c_priv && getuid() && ingroup(LPR_OPER) == 0) { 13712380Sralph printf("?Privileged command\n"); 13812380Sralph continue; 13912380Sralph } 14012380Sralph (*c->c_handler)(margc, margv); 14112380Sralph } 14212380Sralph longjmp(toplevel, 0); 14312380Sralph } 14412380Sralph 145*69027Stef static struct cmd * 14612380Sralph getcmd(name) 14712380Sralph register char *name; 14812380Sralph { 14912380Sralph register char *p, *q; 15012380Sralph register struct cmd *c, *found; 15112380Sralph register int nmatches, longest; 15212380Sralph 15312380Sralph longest = 0; 15412380Sralph nmatches = 0; 15512380Sralph found = 0; 15612380Sralph for (c = cmdtab; p = c->c_name; c++) { 15712380Sralph for (q = name; *q == *p++; q++) 15812380Sralph if (*q == 0) /* exact match? */ 15912380Sralph return(c); 16012380Sralph if (!*q) { /* the name was a prefix */ 16112380Sralph if (q - name > longest) { 16212380Sralph longest = q - name; 16312380Sralph nmatches = 1; 16412380Sralph found = c; 16512380Sralph } else if (q - name == longest) 16612380Sralph nmatches++; 16712380Sralph } 16812380Sralph } 16912380Sralph if (nmatches > 1) 17012380Sralph return((struct cmd *)-1); 17112380Sralph return(found); 17212380Sralph } 17312380Sralph 17412380Sralph /* 17512380Sralph * Slice a string up into argc/argv. 17612380Sralph */ 17755472Sbostic static void 17812380Sralph makeargv() 17912380Sralph { 18012380Sralph register char *cp; 18112380Sralph register char **argp = margv; 18212380Sralph 18312380Sralph margc = 0; 18412380Sralph for (cp = cmdline; *cp;) { 18512380Sralph while (isspace(*cp)) 18612380Sralph cp++; 18712380Sralph if (*cp == '\0') 18812380Sralph break; 18912380Sralph *argp++ = cp; 19012380Sralph margc += 1; 19112380Sralph while (*cp != '\0' && !isspace(*cp)) 19212380Sralph cp++; 19312380Sralph if (*cp == '\0') 19412380Sralph break; 19512380Sralph *cp++ = '\0'; 19612380Sralph } 19712380Sralph *argp++ = 0; 19812380Sralph } 19912380Sralph 20012380Sralph #define HELPINDENT (sizeof ("directory")) 20112380Sralph 20212380Sralph /* 20312380Sralph * Help command. 20412380Sralph */ 20555472Sbostic void 20612380Sralph help(argc, argv) 20712380Sralph int argc; 20812380Sralph char *argv[]; 20912380Sralph { 21012380Sralph register struct cmd *c; 21112380Sralph 21212380Sralph if (argc == 1) { 21312380Sralph register int i, j, w; 21412380Sralph int columns, width = 0, lines; 21512380Sralph extern int NCMDS; 21612380Sralph 21712380Sralph printf("Commands may be abbreviated. Commands are:\n\n"); 21839727Sbostic for (c = cmdtab; c->c_name; c++) { 21912380Sralph int len = strlen(c->c_name); 22012380Sralph 22112380Sralph if (len > width) 22212380Sralph width = len; 22312380Sralph } 22412380Sralph width = (width + 8) &~ 7; 22512380Sralph columns = 80 / width; 22612380Sralph if (columns == 0) 22712380Sralph columns = 1; 22812380Sralph lines = (NCMDS + columns - 1) / columns; 22912380Sralph for (i = 0; i < lines; i++) { 23012380Sralph for (j = 0; j < columns; j++) { 23112380Sralph c = cmdtab + j * lines + i; 23239727Sbostic if (c->c_name) 23339727Sbostic printf("%s", c->c_name); 23412380Sralph if (c + lines >= &cmdtab[NCMDS]) { 23512380Sralph printf("\n"); 23612380Sralph break; 23712380Sralph } 23812380Sralph w = strlen(c->c_name); 23912380Sralph while (w < width) { 24012380Sralph w = (w + 8) &~ 7; 24112380Sralph putchar('\t'); 24212380Sralph } 24312380Sralph } 24412380Sralph } 24512380Sralph return; 24612380Sralph } 24712380Sralph while (--argc > 0) { 24812380Sralph register char *arg; 24912380Sralph arg = *++argv; 25012380Sralph c = getcmd(arg); 25112380Sralph if (c == (struct cmd *)-1) 25212380Sralph printf("?Ambiguous help command %s\n", arg); 25312380Sralph else if (c == (struct cmd *)0) 25412380Sralph printf("?Invalid help command %s\n", arg); 25512380Sralph else 25612380Sralph printf("%-*s\t%s\n", HELPINDENT, 25712380Sralph c->c_name, c->c_help); 25812380Sralph } 25912380Sralph } 260*69027Stef 261*69027Stef /* 262*69027Stef * return non-zero if the user is a member of the given group 263*69027Stef */ 264*69027Stef static int 265*69027Stef ingroup(grname) 266*69027Stef char *grname; 267*69027Stef { 268*69027Stef static struct group *gptr=NULL; 269*69027Stef static gid_t groups[NGROUPS]; 270*69027Stef register gid_t gid; 271*69027Stef register int i; 272*69027Stef 273*69027Stef if (gptr == NULL) { 274*69027Stef if ((gptr = getgrnam(grname)) == NULL) { 275*69027Stef fprintf(stderr, "Warning: unknown group '%s'\n", 276*69027Stef grname); 277*69027Stef return(0); 278*69027Stef } 279*69027Stef if (getgroups(NGROUPS, groups) < 0) { 280*69027Stef perror("getgroups"); 281*69027Stef exit(1); 282*69027Stef } 283*69027Stef } 284*69027Stef gid = gptr->gr_gid; 285*69027Stef for (i = 0; i < NGROUPS; i++) 286*69027Stef if (gid == groups[i]) 287*69027Stef return(1); 288*69027Stef return(0); 289*69027Stef } 290