home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.sbin / lpr / lpc / lpc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-19  |  5.6 KB  |  263 lines

  1. /*
  2.  * Copyright (c) 1983 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. char copyright[] =
  36. "@(#) Copyright (c) 1983 Regents of the University of California.\n\
  37.  All rights reserved.\n";
  38. #endif /* not lint */
  39.  
  40. #ifndef lint
  41. static char sccsid[] = "@(#)lpc.c    5.11 (Berkeley) 3/2/91";
  42. #endif /* not lint */
  43.  
  44. /*
  45.  * lpc -- line printer control program
  46.  */
  47. #include <stdio.h>
  48. #include <signal.h>
  49. #include <ctype.h>
  50. #include <setjmp.h>
  51. #include <syslog.h>
  52.  
  53. #include "lpc.h"
  54.  
  55. int    fromatty;
  56.  
  57. char    cmdline[200];
  58. int    margc;
  59. char    *margv[20];
  60. int    top;
  61. void    intr();
  62. struct    cmd *getcmd();
  63.  
  64. jmp_buf    toplevel;
  65.  
  66. main(argc, argv)
  67.     char *argv[];
  68. {
  69.     register struct cmd *c;
  70.     extern char *name;
  71.  
  72.     name = argv[0];
  73.     openlog("lpd", 0, LOG_LPR);
  74.  
  75.     if (--argc > 0) {
  76.         c = getcmd(*++argv);
  77.         if (c == (struct cmd *)-1) {
  78.             printf("?Ambiguous command\n");
  79.             exit(1);
  80.         }
  81.         if (c == 0) {
  82.             printf("?Invalid command\n");
  83.             exit(1);
  84.         }
  85.         if (c->c_priv && getuid()) {
  86.             printf("?Privileged command\n");
  87.             exit(1);
  88.         }
  89.         (*c->c_handler)(argc, argv);
  90.         exit(0);
  91.     }
  92.     fromatty = isatty(fileno(stdin));
  93.     top = setjmp(toplevel) == 0;
  94.     if (top)
  95.         signal(SIGINT, intr);
  96.     for (;;) {
  97.         cmdscanner(top);
  98.         top = 1;
  99.     }
  100. }
  101.  
  102. void
  103. intr()
  104. {
  105.     if (!fromatty)
  106.         exit(0);
  107.     longjmp(toplevel, 1);
  108. }
  109.  
  110. /*
  111.  * Command parser.
  112.  */
  113. cmdscanner(top)
  114.     int top;
  115. {
  116.     register struct cmd *c;
  117.  
  118.     if (!top)
  119.         putchar('\n');
  120.     for (;;) {
  121.         if (fromatty) {
  122.             printf("lpc> ");
  123.             fflush(stdout);
  124.         }
  125.         if (fgets(cmdline, sizeof(cmdline), stdin) == 0)
  126.             quit();
  127.         if (cmdline[0] == 0 || cmdline[0] == '\n')
  128.             break;
  129.         makeargv();
  130.         c = getcmd(margv[0]);
  131.         if (c == (struct cmd *)-1) {
  132.             printf("?Ambiguous command\n");
  133.             continue;
  134.         }
  135.         if (c == 0) {
  136.             printf("?Invalid command\n");
  137.             continue;
  138.         }
  139.         if (c->c_priv && getuid()) {
  140.             printf("?Privileged command\n");
  141.             continue;
  142.         }
  143.         (*c->c_handler)(margc, margv);
  144.     }
  145.     longjmp(toplevel, 0);
  146. }
  147.  
  148. extern struct cmd cmdtab[];
  149.  
  150. struct cmd *
  151. getcmd(name)
  152.     register char *name;
  153. {
  154.     register char *p, *q;
  155.     register struct cmd *c, *found;
  156.     register int nmatches, longest;
  157.  
  158.     longest = 0;
  159.     nmatches = 0;
  160.     found = 0;
  161.     for (c = cmdtab; p = c->c_name; c++) {
  162.         for (q = name; *q == *p++; q++)
  163.             if (*q == 0)        /* exact match? */
  164.                 return(c);
  165.         if (!*q) {            /* the name was a prefix */
  166.             if (q - name > longest) {
  167.                 longest = q - name;
  168.                 nmatches = 1;
  169.                 found = c;
  170.             } else if (q - name == longest)
  171.                 nmatches++;
  172.         }
  173.     }
  174.     if (nmatches > 1)
  175.         return((struct cmd *)-1);
  176.     return(found);
  177. }
  178.  
  179. /*
  180.  * Slice a string up into argc/argv.
  181.  */
  182. makeargv()
  183. {
  184.     register char *cp;
  185.     register char **argp = margv;
  186.  
  187.     margc = 0;
  188.     for (cp = cmdline; *cp;) {
  189.         while (isspace(*cp))
  190.             cp++;
  191.         if (*cp == '\0')
  192.             break;
  193.         *argp++ = cp;
  194.         margc += 1;
  195.         while (*cp != '\0' && !isspace(*cp))
  196.             cp++;
  197.         if (*cp == '\0')
  198.             break;
  199.         *cp++ = '\0';
  200.     }
  201.     *argp++ = 0;
  202. }
  203.  
  204. #define HELPINDENT (sizeof ("directory"))
  205.  
  206. /*
  207.  * Help command.
  208.  */
  209. help(argc, argv)
  210.     int argc;
  211.     char *argv[];
  212. {
  213.     register struct cmd *c;
  214.  
  215.     if (argc == 1) {
  216.         register int i, j, w;
  217.         int columns, width = 0, lines;
  218.         extern int NCMDS;
  219.  
  220.         printf("Commands may be abbreviated.  Commands are:\n\n");
  221.         for (c = cmdtab; c->c_name; c++) {
  222.             int len = strlen(c->c_name);
  223.  
  224.             if (len > width)
  225.                 width = len;
  226.         }
  227.         width = (width + 8) &~ 7;
  228.         columns = 80 / width;
  229.         if (columns == 0)
  230.             columns = 1;
  231.         lines = (NCMDS + columns - 1) / columns;
  232.         for (i = 0; i < lines; i++) {
  233.             for (j = 0; j < columns; j++) {
  234.                 c = cmdtab + j * lines + i;
  235.                 if (c->c_name)
  236.                     printf("%s", c->c_name);
  237.                 if (c + lines >= &cmdtab[NCMDS]) {
  238.                     printf("\n");
  239.                     break;
  240.                 }
  241.                 w = strlen(c->c_name);
  242.                 while (w < width) {
  243.                     w = (w + 8) &~ 7;
  244.                     putchar('\t');
  245.                 }
  246.             }
  247.         }
  248.         return;
  249.     }
  250.     while (--argc > 0) {
  251.         register char *arg;
  252.         arg = *++argv;
  253.         c = getcmd(arg);
  254.         if (c == (struct cmd *)-1)
  255.             printf("?Ambiguous help command %s\n", arg);
  256.         else if (c == (struct cmd *)0)
  257.             printf("?Invalid help command %s\n", arg);
  258.         else
  259.             printf("%-*s\t%s\n", HELPINDENT,
  260.                 c->c_name, c->c_help);
  261.     }
  262. }
  263.