home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.sbin / timed / timedc / timedc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-20  |  5.8 KB  |  267 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[] = "@(#)timedc.c    2.10 (Berkeley) 3/5/91";
  42. #endif /* not lint */
  43.  
  44. #include "timedc.h"
  45. #include <signal.h>
  46. #include <ctype.h>
  47. #include <setjmp.h>
  48. #include <syslog.h>
  49.  
  50. int    top;
  51. int    margc;
  52. int    fromatty;
  53. char    *margv[20];
  54. char    cmdline[200];
  55. jmp_buf    toplevel;
  56. void    intr();
  57. int priv_resources();
  58. struct    cmd *getcmd();
  59.  
  60.  
  61. main(argc, argv)
  62.     char *argv[];
  63. {
  64.     register struct cmd *c;
  65.  
  66.     openlog("timedc", LOG_ODELAY, LOG_AUTH);
  67.  
  68.     /*
  69.      * security dictates!
  70.      */
  71.     if (priv_resources() < 0) {
  72.         fprintf(stderr, "Could not get privileged resources\n");
  73.         exit(1);
  74.     }
  75.     (void) setuid(getuid());
  76.  
  77.     if (--argc > 0) {
  78.         c = getcmd(*++argv);
  79.         if (c == (struct cmd *)-1) {
  80.             printf("?Ambiguous command\n");
  81.             exit(1);
  82.         }
  83.         if (c == 0) {
  84.             printf("?Invalid command\n");
  85.             exit(1);
  86.         }
  87.         if (c->c_priv && getuid()) {
  88.             printf("?Privileged command\n");
  89.             exit(1);
  90.         }
  91.         (*c->c_handler)(argc, argv);
  92.         exit(0);
  93.     }
  94.     fromatty = isatty(fileno(stdin));
  95.     top = setjmp(toplevel) == 0;
  96.     if (top)
  97.         (void) signal(SIGINT, intr);
  98.     for (;;) {
  99.         cmdscanner(top);
  100.         top = 1;
  101.     }
  102. }
  103.  
  104. void
  105. intr()
  106. {
  107.     if (!fromatty)
  108.         exit(0);
  109.     longjmp(toplevel, 1);
  110. }
  111.  
  112. /*
  113.  * Command parser.
  114.  */
  115. cmdscanner(top)
  116.     int top;
  117. {
  118.     register struct cmd *c;
  119.     extern int help();
  120.  
  121.     if (!top)
  122.         putchar('\n');
  123.     for (;;) {
  124.         if (fromatty) {
  125.             printf("timedc> ");
  126.             (void) fflush(stdout);
  127.         }
  128.         if (fgets(cmdline, sizeof(cmdline), stdin) == 0)
  129.             quit();
  130.         if (cmdline[0] == 0)
  131.             break;
  132.         makeargv();
  133.         c = getcmd(margv[0]);
  134.         if (c == (struct cmd *)-1) {
  135.             printf("?Ambiguous command\n");
  136.             continue;
  137.         }
  138.         if (c == 0) {
  139.             printf("?Invalid command\n");
  140.             continue;
  141.         }
  142.         if (c->c_priv && getuid()) {
  143.             printf("?Privileged command\n");
  144.             continue;
  145.         }
  146.         (*c->c_handler)(margc, margv);
  147.     }
  148.     longjmp(toplevel, 0);
  149. }
  150.  
  151. struct cmd *
  152. getcmd(name)
  153.     register char *name;
  154. {
  155.     register char *p, *q;
  156.     register struct cmd *c, *found;
  157.     register int nmatches, longest;
  158.     extern struct cmd cmdtab[];
  159.     extern int NCMDS;
  160.  
  161.     longest = 0;
  162.     nmatches = 0;
  163.     found = 0;
  164.     for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
  165.         p = c->c_name;
  166.         for (q = name; *q == *p++; q++)
  167.             if (*q == 0)        /* exact match? */
  168.                 return(c);
  169.         if (!*q) {            /* the name was a prefix */
  170.             if (q - name > longest) {
  171.                 longest = q - name;
  172.                 nmatches = 1;
  173.                 found = c;
  174.             } else if (q - name == longest)
  175.                 nmatches++;
  176.         }
  177.     }
  178.     if (nmatches > 1)
  179.         return((struct cmd *)-1);
  180.     return(found);
  181. }
  182.  
  183. /*
  184.  * Slice a string up into argc/argv.
  185.  */
  186. makeargv()
  187. {
  188.     register char *cp;
  189.     register char **argp = margv;
  190.  
  191.     margc = 0;
  192.     for (cp = cmdline; *cp;) {
  193.         while (isspace(*cp))
  194.             cp++;
  195.         if (*cp == '\0')
  196.             break;
  197.         *argp++ = cp;
  198.         margc += 1;
  199.         while (*cp != '\0' && !isspace(*cp))
  200.             cp++;
  201.         if (*cp == '\0')
  202.             break;
  203.         *cp++ = '\0';
  204.     }
  205.     *argp++ = 0;
  206. }
  207.  
  208. #define HELPINDENT (sizeof ("directory"))
  209.  
  210. /*
  211.  * Help command.
  212.  */
  213. help(argc, argv)
  214.     int argc;
  215.     char *argv[];
  216. {
  217.     register struct cmd *c;
  218.     extern struct cmd cmdtab[];
  219.  
  220.     if (argc == 1) {
  221.         register int i, j, w;
  222.         int columns, width = 0, lines;
  223.         extern int NCMDS;
  224.  
  225.         printf("Commands may be abbreviated.  Commands are:\n\n");
  226.         for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
  227.             int len = strlen(c->c_name);
  228.  
  229.             if (len > width)
  230.                 width = len;
  231.         }
  232.         width = (width + 8) &~ 7;
  233.         columns = 80 / width;
  234.         if (columns == 0)
  235.             columns = 1;
  236.         lines = (NCMDS + columns - 1) / columns;
  237.         for (i = 0; i < lines; i++) {
  238.             for (j = 0; j < columns; j++) {
  239.                 c = cmdtab + j * lines + i;
  240.                 printf("%s", c->c_name);
  241.                 if (c + lines >= &cmdtab[NCMDS]) {
  242.                     printf("\n");
  243.                     break;
  244.                 }
  245.                 w = strlen(c->c_name);
  246.                 while (w < width) {
  247.                     w = (w + 8) &~ 7;
  248.                     putchar('\t');
  249.                 }
  250.             }
  251.         }
  252.         return;
  253.     }
  254.     while (--argc > 0) {
  255.         register char *arg;
  256.         arg = *++argv;
  257.         c = getcmd(arg);
  258.         if (c == (struct cmd *)-1)
  259.             printf("?Ambiguous help command %s\n", arg);
  260.         else if (c == (struct cmd *)0)
  261.             printf("?Invalid help command %s\n", arg);
  262.         else
  263.             printf("%-*s\t%s\n", HELPINDENT,
  264.                 c->c_name, c->c_help);
  265.     }
  266. }
  267.