home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1988, 1991, John F. Haugh II
- * All rights reserved.
- *
- * Permission is granted to copy and create derivative works for any
- * non-commercial purpose, provided this copyright notice is preserved
- * in all copies of source code, or included in human readable form
- * and conspicuously displayed on all copies of object code or
- * distribution media.
- */
-
- #ifndef lint
- static char sccsid[] = "@(#)interact.c 2.1 09:26:38 2/27/91";
- #endif
-
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include <setjmp.h>
- #include <signal.h>
-
- extern od ();
- extern prbufs ();
- extern prbdevs ();
- extern prcdevs ();
- extern prfiles ();
- extern prinodes ();
- extern prmounts ();
- extern prprocs ();
- extern prstats ();
- extern prtexts ();
- extern prusers ();
- extern prvars ();
- extern prdataaddr ();
- extern prsymbol ();
- extern prtextaddr ();
- extern prttys ();
- extern quit ();
- extern help ();
- extern int errno;
-
- jmp_buf del;
- int delflag;
-
- struct func {
- void (*f_func)();
- char *f_name;
- enum { none, numbers, string } f_type;
- };
-
- struct func commands[] = {
- { prbufs, "b", numbers },
- { prbdevs, "bd", numbers },
- { prbdevs, "bdevsw", numbers },
- { prbufs, "buf", numbers },
- { prcdevs, "cd", numbers },
- { prcdevs, "cdevsw", numbers },
- { prdataaddr, "ds", string },
- { prfiles, "f", numbers },
- { prfiles, "file", numbers },
- { help, "h", none },
- { help, "help", none },
- { prinodes, "i", numbers },
- { prinodes, "ino", numbers },
- { prinodes, "inode", numbers },
- { prmounts, "m", numbers },
- { prmounts, "mount", numbers },
- { prsymbol, "nm", string },
- { od, "od", string },
- { prprocs, "p", numbers },
- { prprocs, "proc", numbers },
- { quit, "q", none },
- { quit, "quit", none },
- { prstats, "s", none },
- { prstats, "stat", none },
- { prtexts, "t", numbers },
- { prtexts, "text", numbers },
- { prtextaddr, "ts", string },
- { prttys, "tty", string },
- { prusers, "u", numbers },
- { prusers, "user", numbers },
- { prvars, "v", none },
- { prvars, "var", none },
- { 0, 0, none }
- };
-
- help ()
- {
- printf ("command summary\n\n");
-
- printf ("buf (b) - buffer headers\n");
- printf ("file (f) - open files\n");
- printf ("help (h,?) - list commands\n");
- printf ("inode (ino,i) - active inodes\n");
- printf ("mount (m) - mounted file systems\n");
- printf ("proc (p) - active and defunct processes\n");
- printf ("quit (q,^D) - exit crash\n");
- printf ("stat (s) - crash statistics, age, time\n");
- printf ("text (t) - active and sticky bit text segments\n");
- printf ("user (u) - user page information\n");
- printf ("var (v) - tunable parameters\n");
- }
-
- quit ()
- {
- exit (0);
- }
-
- interupt (sig)
- int sig;
- {
- delflag = 1;
- fflush (stdout);
- fflush (stderr);
- longjmp (del, sig);
- }
-
- static int
- number (cpp, value)
- char **cpp;
- int *value;
- {
- char *cp = *cpp;
- char *end;
- char buf[16];
- int i;
-
- while (*cp && isspace (*cp))
- cp++;
-
- for (i = 0;i < 15 && isdigit (*cp);i++, cp++)
- buf[i] = *cp;
-
- while (*cp && isspace (*cp))
- cp++;
-
- if (cp == *cpp)
- return -1;
-
- buf[i] = '\0';
- i = (int) strtol (buf, &end, 0);
- if (*end)
- return -1;
-
- *value = i;
- *cpp = cp;
- return 0;
- }
-
- static int
- range (cpp, value, cnt)
- char **cpp;
- int **value;
- int *cnt;
- {
- int min, max;
- char *cp = *cpp;
-
- if (number (&cp, &min)) {
- *cpp = cp;
- return -1;
- }
- while (*cp && isspace (*cp))
- cp++;
-
- if (*cp == ',' || *cp == '\0') {
- *((*value)++) = min;
- (*cnt)--;
- *cpp = cp;
- return 0;
- } else if (*cp != '-') {
- *cpp = cp;
- return -1;
- }
- cp++;
-
- while (*cp && isspace (*cp))
- cp++;
-
- if (number (&cp, &max)) {
- *cpp = cp;
- return -1;
- }
- while (min <= max && (*cnt) > 0) {
- *((*value)++) = min++;
- (*cnt)--;
- }
- if ((*cnt) == 0 && min <= max)
- return -1;
-
- *cpp = cp;
- return 0;
- }
-
- list (cp, items, max)
- char *cp;
- int *items;
- int max;
- {
- int cnt = max;
-
- /*
- * number lists are of the form
- *
- * <list> ::= <range> | <list> ',' <range>
- * <range> ::= <number> '-' <number> | <number>
- * <number> ::= <one or more decimal digits>
- */
-
- while (*cp && cnt > 0) {
- while (*cp && isspace (*cp))
- cp++;
-
- if (range (&cp, &items, &cnt))
- break;
-
- if (*cp) {
- if (*cp == ',')
- cp++;
- else
- break;
- }
- }
- if (*cp) {
- printf ("error at '%.15s'\n", cp);
- return -1;
- }
- return max - cnt;
- }
-
- interact ()
- {
- int i;
- long l;
- int cnt;
- char *cp;
- char *com;
- char *num;
- char buf[BUFSIZ];
- int items[100];
-
- while (setjmp (del)) /* catch that first interupt */
- fprintf (stderr, "\nq to quit\n");
-
- signal (SIGINT, interupt); /* and setup the handler */
-
- while (fprintf (stderr, "> "), gets (buf) != (char *) 0) {
- while (setjmp (del))
- goto eh;
-
- /*
- * find first non-white space character and skip if
- * a blank line
- */
-
- for (com = buf;*com && (*com == ' ' || *com == '\t');com++)
- ;
-
- if (*com == '\0')
- continue;
-
- /*
- * find the entire command word
- */
-
- if (*com == '?') {
- help ();
- continue;
- } else if (*com == '!') {
- system (com + 1);
- continue;
- } else if (*com == '=') {
- com++;
- if (expr (&com, &l))
- goto eh;
- printf ("%d (%x)\n", l, l);
- continue;
- }
- for (cp = com;*cp >= 'a' && *cp <= 'z';cp++)
- ;
-
- if (*cp != '\0')
- *cp++ = '\0';
-
- for (i = 0;commands[i].f_name != (char *) 0;i++)
- if (strcmp (commands[i].f_name, com) == 0)
- break;
-
- if (commands[i].f_name == (char *) 0)
- goto eh;
-
- if (commands[i].f_type == numbers) {
- while (*cp && isspace (*cp))
- cp++;
-
- if ((cnt = list (cp, items, 100)) < 0)
- goto eh;
-
- (*commands[i].f_func) (cnt ? items:0, cnt);
- continue;
- } else if (commands[i].f_type == string) {
- while (*cp && isspace (*cp))
- cp++;
-
- (*commands[i].f_func) (cp);
- continue;
- }
-
- /*
- * common error handler. get here if an error is found.
- */
- eh:
- if (delflag) {
- putc ('\n', stderr);
- delflag = 0;
- }
- fprintf (stderr, "eh?\n");
- signal (SIGINT, interupt);
- }
- }
-