home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2870 / interact.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-28  |  5.7 KB  |  321 lines

  1. /*
  2.  * Copyright 1988, 1991, John F. Haugh II
  3.  * All rights reserved.
  4.  *
  5.  * Permission is granted to copy and create derivative works for any
  6.  * non-commercial purpose, provided this copyright notice is preserved
  7.  * in all copies of source code, or included in human readable form
  8.  * and conspicuously displayed on all copies of object code or
  9.  * distribution media.
  10.  */
  11.  
  12. #ifndef    lint
  13. static    char    sccsid[] = "@(#)interact.c    2.1    09:26:38    2/27/91";
  14. #endif
  15.  
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <ctype.h>
  19. #include <setjmp.h>
  20. #include <signal.h>
  21.  
  22. extern    od ();
  23. extern    prbufs ();
  24. extern    prbdevs ();
  25. extern    prcdevs ();
  26. extern    prfiles ();
  27. extern    prinodes ();
  28. extern    prmounts ();
  29. extern    prprocs ();
  30. extern    prstats ();
  31. extern    prtexts ();
  32. extern    prusers ();
  33. extern    prvars ();
  34. extern    prdataaddr ();
  35. extern    prsymbol ();
  36. extern    prtextaddr ();
  37. extern    prttys ();
  38. extern    quit ();
  39. extern    help ();
  40. extern    int    errno;
  41.  
  42. jmp_buf    del;
  43. int    delflag;
  44.  
  45. struct    func {
  46.     void    (*f_func)();
  47.     char    *f_name;
  48.     enum { none, numbers, string } f_type;
  49. };
  50.  
  51. struct    func    commands[] = {
  52.     { prbufs, "b", numbers },
  53.     { prbdevs, "bd", numbers },
  54.     { prbdevs, "bdevsw", numbers },
  55.     { prbufs, "buf", numbers },
  56.     { prcdevs, "cd", numbers },
  57.     { prcdevs, "cdevsw", numbers },
  58.     { prdataaddr, "ds", string },
  59.     { prfiles, "f", numbers },
  60.     { prfiles, "file", numbers },
  61.     { help, "h", none },
  62.     { help, "help", none },
  63.     { prinodes, "i", numbers },
  64.     { prinodes, "ino", numbers },
  65.     { prinodes, "inode", numbers },
  66.     { prmounts, "m", numbers },
  67.     { prmounts, "mount", numbers },
  68.     { prsymbol, "nm", string },
  69.     { od, "od", string },
  70.     { prprocs, "p", numbers },
  71.     { prprocs, "proc", numbers },
  72.     { quit, "q", none },
  73.     { quit, "quit", none },
  74.     { prstats, "s", none },
  75.     { prstats, "stat", none },
  76.     { prtexts, "t", numbers },
  77.     { prtexts, "text", numbers },
  78.     { prtextaddr, "ts", string },
  79.     { prttys, "tty", string },
  80.     { prusers, "u", numbers },
  81.     { prusers, "user", numbers },
  82.     { prvars, "v", none },
  83.     { prvars, "var", none },
  84.     { 0, 0, none }
  85. };
  86.  
  87. help ()
  88. {
  89.     printf ("command summary\n\n");
  90.  
  91.     printf ("buf (b)        - buffer headers\n");
  92.     printf ("file (f)       - open files\n");
  93.     printf ("help (h,?)     - list commands\n");
  94.     printf ("inode (ino,i)  - active inodes\n");
  95.     printf ("mount (m)      - mounted file systems\n");
  96.     printf ("proc (p)       - active and defunct processes\n");
  97.     printf ("quit (q,^D)    - exit crash\n");
  98.     printf ("stat (s)       - crash statistics, age, time\n");
  99.     printf ("text (t)       - active and sticky bit text segments\n");
  100.     printf ("user (u)       - user page information\n");
  101.     printf ("var (v)        - tunable parameters\n");
  102. }
  103.  
  104. quit ()
  105. {
  106.     exit (0);
  107. }
  108.  
  109. interupt (sig)
  110. int    sig;
  111. {
  112.     delflag = 1;
  113.     fflush (stdout);
  114.     fflush (stderr);
  115.     longjmp (del, sig);
  116. }
  117.  
  118. static int
  119. number (cpp, value)
  120. char    **cpp;
  121. int    *value;
  122. {
  123.     char    *cp = *cpp;
  124.     char    *end;
  125.     char    buf[16];
  126.     int    i;
  127.  
  128.     while (*cp && isspace (*cp))
  129.         cp++;
  130.  
  131.     for (i = 0;i < 15 && isdigit (*cp);i++, cp++)
  132.         buf[i] = *cp;
  133.  
  134.     while (*cp && isspace (*cp))
  135.         cp++;
  136.  
  137.     if (cp == *cpp)
  138.         return -1;
  139.  
  140.     buf[i] = '\0';
  141.     i = (int) strtol (buf, &end, 0);
  142.     if (*end)
  143.         return -1;
  144.  
  145.     *value = i;
  146.     *cpp = cp;
  147.     return 0;
  148. }
  149.  
  150. static int
  151. range (cpp, value, cnt)
  152. char    **cpp;
  153. int    **value;
  154. int    *cnt;
  155. {
  156.     int    min, max;
  157.     char    *cp = *cpp;
  158.  
  159.     if (number (&cp, &min)) {
  160.         *cpp = cp;
  161.         return -1;
  162.     }
  163.     while (*cp && isspace (*cp))
  164.         cp++;
  165.  
  166.     if (*cp == ',' || *cp == '\0') {
  167.         *((*value)++) = min;
  168.         (*cnt)--;
  169.         *cpp = cp;
  170.         return 0;
  171.     } else if (*cp != '-') {
  172.         *cpp = cp;
  173.         return -1;
  174.     }
  175.     cp++;
  176.  
  177.     while (*cp && isspace (*cp))
  178.         cp++;
  179.  
  180.     if (number (&cp, &max)) {
  181.         *cpp = cp;
  182.         return -1;
  183.     }
  184.     while (min <= max && (*cnt) > 0) {
  185.         *((*value)++) = min++;
  186.         (*cnt)--;
  187.     }
  188.     if ((*cnt) == 0 && min <= max)
  189.         return -1;
  190.  
  191.     *cpp = cp;
  192.     return 0;
  193. }
  194.  
  195. list (cp, items, max)
  196. char    *cp;
  197. int    *items;
  198. int    max;
  199. {
  200.     int    cnt = max;
  201.  
  202.     /*
  203.      * number lists are of the form
  204.      *
  205.      *    <list> ::= <range> | <list> ',' <range>
  206.      *    <range> ::= <number> '-' <number> | <number>
  207.      *    <number> ::= <one or more decimal digits>
  208.      */
  209.  
  210.     while (*cp && cnt > 0) {
  211.         while (*cp && isspace (*cp))
  212.             cp++;
  213.  
  214.         if (range (&cp, &items, &cnt))
  215.             break;
  216.  
  217.         if (*cp) {
  218.             if (*cp == ',')
  219.                 cp++;
  220.             else
  221.                 break;
  222.         }
  223.     }
  224.     if (*cp) {
  225.         printf ("error at '%.15s'\n", cp);
  226.         return -1;
  227.     }
  228.     return max - cnt;
  229. }
  230.  
  231. interact ()
  232. {
  233.     int    i;
  234.     long    l;
  235.     int    cnt;
  236.     char    *cp;
  237.     char    *com;
  238.     char    *num;
  239.     char    buf[BUFSIZ];
  240.     int    items[100];
  241.  
  242.     while (setjmp (del))        /* catch that first interupt */
  243.         fprintf (stderr, "\nq to quit\n");
  244.  
  245.     signal (SIGINT, interupt);    /* and setup the handler */
  246.  
  247.     while (fprintf (stderr, "> "), gets (buf) != (char *) 0) {
  248.         while (setjmp (del))
  249.             goto eh;
  250.  
  251.         /*
  252.          * find first non-white space character and skip if
  253.          * a blank line
  254.          */
  255.  
  256.         for (com = buf;*com && (*com == ' ' || *com == '\t');com++)
  257.             ;
  258.  
  259.         if (*com == '\0')
  260.             continue;
  261.  
  262.         /*
  263.          * find the entire command word
  264.          */
  265.  
  266.         if (*com == '?') {
  267.             help ();
  268.             continue;
  269.         } else if (*com == '!') {
  270.             system (com + 1);
  271.             continue;
  272.         } else if (*com == '=') {
  273.             com++;
  274.             if (expr (&com, &l))
  275.                 goto eh;
  276.             printf ("%d (%x)\n", l, l);
  277.             continue;
  278.         }
  279.         for (cp = com;*cp >= 'a' && *cp <= 'z';cp++)
  280.             ;
  281.  
  282.         if (*cp != '\0')
  283.             *cp++ = '\0';
  284.  
  285.         for (i = 0;commands[i].f_name != (char *) 0;i++)
  286.             if (strcmp (commands[i].f_name, com) == 0)
  287.                 break;
  288.  
  289.         if (commands[i].f_name == (char *) 0)
  290.             goto eh;
  291.  
  292.         if (commands[i].f_type == numbers) {
  293.             while (*cp && isspace (*cp))
  294.                 cp++;
  295.  
  296.             if ((cnt = list (cp, items, 100)) < 0)
  297.                 goto eh;
  298.  
  299.             (*commands[i].f_func) (cnt ? items:0, cnt);
  300.             continue;
  301.         } else if (commands[i].f_type == string) {
  302.             while (*cp && isspace (*cp))
  303.                 cp++;
  304.  
  305.             (*commands[i].f_func) (cp);
  306.             continue;
  307.         }
  308.  
  309.         /*
  310.          * common error handler.  get here if an error is found.
  311.          */
  312. eh:
  313.         if (delflag) {
  314.             putc ('\n', stderr);
  315.             delflag = 0;
  316.         }
  317.         fprintf (stderr, "eh?\n");
  318.         signal (SIGINT, interupt);
  319.     }
  320. }
  321.