diff options
Diffstat (limited to 'usr.sbin/lpr/lpc/lpc.c')
-rw-r--r-- | usr.sbin/lpr/lpc/lpc.c | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/usr.sbin/lpr/lpc/lpc.c b/usr.sbin/lpr/lpc/lpc.c new file mode 100644 index 0000000..01cfc12 --- /dev/null +++ b/usr.sbin/lpr/lpc/lpc.c @@ -0,0 +1,277 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1983, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)lpc.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include <sys/param.h> + +#include <dirent.h> +#include <signal.h> +#include <setjmp.h> +#include <syslog.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include "lp.h" +#include "lpc.h" +#include "extern.h" + +/* + * lpc -- line printer control program + */ + +int fromatty; + +char cmdline[200]; +int margc; +char *margv[20]; +int top; + +jmp_buf toplevel; + +static void cmdscanner __P((int)); +static struct cmd *getcmd __P((char *)); +static void intr __P((int)); +static void makeargv __P((void)); + +int +main(argc, argv) + int argc; + char *argv[]; +{ + register struct cmd *c; + + name = argv[0]; + openlog("lpd", 0, LOG_LPR); + + if (--argc > 0) { + c = getcmd(*++argv); + if (c == (struct cmd *)-1) { + printf("?Ambiguous command\n"); + exit(1); + } + if (c == 0) { + printf("?Invalid command\n"); + exit(1); + } + if (c->c_priv && getuid()) { + printf("?Privileged command\n"); + exit(1); + } + (*c->c_handler)(argc, argv); + exit(0); + } + fromatty = isatty(fileno(stdin)); + top = setjmp(toplevel) == 0; + if (top) + signal(SIGINT, intr); + for (;;) { + cmdscanner(top); + top = 1; + } +} + +static void +intr(signo) + int signo; +{ + if (!fromatty) + exit(0); + longjmp(toplevel, 1); +} + +/* + * Command parser. + */ +static void +cmdscanner(top) + int top; +{ + register struct cmd *c; + + if (!top) + putchar('\n'); + for (;;) { + if (fromatty) { + printf("lpc> "); + fflush(stdout); + } + if (fgets(cmdline, sizeof(cmdline), stdin) == 0) + quit(0, NULL); + if (cmdline[0] == 0 || cmdline[0] == '\n') + break; + makeargv(); + c = getcmd(margv[0]); + if (c == (struct cmd *)-1) { + printf("?Ambiguous command\n"); + continue; + } + if (c == 0) { + printf("?Invalid command\n"); + continue; + } + if (c->c_priv && getuid()) { + printf("?Privileged command\n"); + continue; + } + (*c->c_handler)(margc, margv); + } + longjmp(toplevel, 0); +} + +struct cmd * +getcmd(name) + register char *name; +{ + register char *p, *q; + register struct cmd *c, *found; + register int nmatches, longest; + + longest = 0; + nmatches = 0; + found = 0; + for (c = cmdtab; p = c->c_name; c++) { + for (q = name; *q == *p++; q++) + if (*q == 0) /* exact match? */ + return(c); + if (!*q) { /* the name was a prefix */ + if (q - name > longest) { + longest = q - name; + nmatches = 1; + found = c; + } else if (q - name == longest) + nmatches++; + } + } + if (nmatches > 1) + return((struct cmd *)-1); + return(found); +} + +/* + * Slice a string up into argc/argv. + */ +static void +makeargv() +{ + register char *cp; + register char **argp = margv; + + margc = 0; + for (cp = cmdline; *cp;) { + while (isspace(*cp)) + cp++; + if (*cp == '\0') + break; + *argp++ = cp; + margc += 1; + while (*cp != '\0' && !isspace(*cp)) + cp++; + if (*cp == '\0') + break; + *cp++ = '\0'; + } + *argp++ = 0; +} + +#define HELPINDENT (sizeof ("directory")) + +/* + * Help command. + */ +void +help(argc, argv) + int argc; + char *argv[]; +{ + register struct cmd *c; + + if (argc == 1) { + register int i, j, w; + int columns, width = 0, lines; + extern int NCMDS; + + printf("Commands may be abbreviated. Commands are:\n\n"); + for (c = cmdtab; c->c_name; c++) { + int len = strlen(c->c_name); + + if (len > width) + width = len; + } + width = (width + 8) &~ 7; + columns = 80 / width; + if (columns == 0) + columns = 1; + lines = (NCMDS + columns - 1) / columns; + for (i = 0; i < lines; i++) { + for (j = 0; j < columns; j++) { + c = cmdtab + j * lines + i; + if (c->c_name) + printf("%s", c->c_name); + if (c + lines >= &cmdtab[NCMDS]) { + printf("\n"); + break; + } + w = strlen(c->c_name); + while (w < width) { + w = (w + 8) &~ 7; + putchar('\t'); + } + } + } + return; + } + while (--argc > 0) { + register char *arg; + arg = *++argv; + c = getcmd(arg); + if (c == (struct cmd *)-1) + printf("?Ambiguous help command %s\n", arg); + else if (c == (struct cmd *)0) + printf("?Invalid help command %s\n", arg); + else + printf("%-*s\t%s\n", HELPINDENT, + c->c_name, c->c_help); + } +} |