beta test release of crash 2.0 for SCO Xenix
John F Haugh II
jfh at rpp386.cactus.org
Thu Feb 28 02:42:08 AEST 1991
This is the latest version of the crash dump analyzer for SCO Xenix.
It was started in 1988 because SCO doesn't include the crash command.
I have added a few features recently because of discussions in
comp.unix.wizards about snooping around the kernel. I use this command
to determine what is wedged and why.
As always, constructive comments are appreciated and earn you a place
in the README file. Flames are ignored for the most part.
Unshar and enjoy!
--
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
# README
# Makefile
# crash.c
# interact.c
# files.c
# inodes.c
# mounts.c
# procs.c
# texts.c
# user.c
# vars.c
# stats.c
# bufs.c
# syms.c
# devs.c
# expr.c
# od.c
# ttys.c
# crash.h
# This archive created: Wed Feb 27 09:38:49 1991
# By: John F Haugh II (River Parishes Programming, Austin TX)
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'README'" '(8001 characters)'
if test -f 'README'
then
echo shar: "will not over-write existing file 'README'"
else
sed 's/^X//' << \SHAR_EOF > 'README'
Xcrash(1L) Version 2.0 08/11/88
X
XIntroduction
X
XCrash is a utility for examining kernel tables while the system is
Xrunning, or if there is a facility for taking crash dumps, examining the
Xsystem after it has crashed. SCO does not provide a crash dump facility
Xat this time, so that functionality is not present.
X
XThe kernel structures which can be examined at present are:
X
X block buffer headers
X open file table entries
X active inode table entries
X mounted file system table entries
X process table entries
X system statistics such as name, version, age
X active and sticky bit text table entries
X tty structures
X system namelist
X per process user page information
X tunable parameters
X arbitrary kernel memory addresses
X
XUsing this information, it is possible to determine what files a given
Xprocess is using, what device they reside on, who owns them and where
Xthe file pointer is currently positioned. Other information on running
Xprocesses may also be determined.
X
XThis version of crash differs from most other versions, such as that
Xproduced by AT&T for their UNIX(tm) systems, in that swapped user pages
Xmay be printed and the name for swapped processes is given. Also, not
Xall of the aliases which are listed in the manual page from AT&T are
Xprovided. A number of commands have been left out, and some of the
Xoptions for the included commands have been omitted as well.
X
XCommands
X
XMost commands take a list of table entries, which if not present
Xdefaults to all elements in the table.
X
XPrint Buffer Headers
XSyntax: buf, b
X
XPrints the selected block buffer headers.
X
XExample:
X> buf 0 1 2 3 4
X BUF MAJ MIN BLOCK FLAGS
X 0 001 0047 20925 read done
X 1 001 0037 2817 read done
X 2 001 0050 2801 read done
X 3 001 0037 15175 read done
X 4 001 0050 6 done
X
XPrint Open File Table Entries
XSyntax: file, f
X
XPrints the selected open file table entries, with cross references
Xto the associated inodes, and the current file pointer.
X
XExample:
X> file 0 1 2 3 4
XSLOT FLAG COUNT INODE OFFSET
X 0 001 R 1 9 0
X 1 003 RW 3 3 18
X 2 003 RW 7 11 26800
X 3 002 W 2 4 169
X 4 001 R 1 8 0
X
XDisplay Command Summary
XSyntax: help, h, ?
X
XPrints the list of currently available commands and the aliases
Xfor them.
X
XExample:
X> help
Xcommand summary
X
Xbuf (b) - buffer headers
Xfile (f) - open files
Xhelp (h,?) - list commands
Xinode (ino,i) - active inodes
Xmount (m) - mounted file systems
Xproc (p) - active and defunct processes
Xquit (q,^D) - exit crash
Xstat (s) - crash statistics, age, time
Xtext (t) - active and sticky bit text segments
Xuser (u) - user page information
Xvar (v) - tunable parameters
X
XDisplay Active Inode Table Entries
XSyntax: inode, ino, i
X
XPrints selected active inode table entries giving device, file
Xsize, permissions, and owners. Cross referenced from mount and
Xfile tables.
X
XExample:
X> inode 0 2 6 8 20
XSLOT MAJ MIN INUMB REF LINK UID GID SIZE MODE SMAJ SMIN FLAGS
X 0 001 0050 2 5 13 0 0 464 d---755 - -
X 2 001 0050 44 1 1 3 3 13472 f---700 - - txt
X 6 001 0050 204 1 2 0 0 32 d---777 - - mnt
X 8 001 0050 87 2 1 10 10 0 c---666 0004 0002
X 20 001 0050 471 1 1 3 3 50102 f---711 - - acc txt
X
XDisplay Mounted File System Table Entries
XSyntax: mount, m
X
XPrints the system entries for mounted on file systems. The
Xdevice, mount point, file system sizes and free blocks and inodes
Xare displayed.
X
XExample:
X> mount
XSLOT MAJ MIN INODE BUF VOLUME PACK BLOCKS INODES BFREE IFREE
X 0 1 050 0 10 7163 1808 1237 1251
X 1 1 037 6 230 usr rpp386 34000 17024 1320 14238
X 2 1 047 7 245 22950 15024 5499 9800
X 3 2 064 23 387 1200 320 210 50
X
XDisplay Process Table Entries
XSyntax: proc, p
X
XPrints selected running and defunct process information. The process
Xids, user ids, CPU usage, scheduling priority and wait event are
Xdisplayed. The process name is determined by locating the user page.
X
XExample:
X> proc 0 1 2 3 4
XSLT ST PID PPID PGRP UID EUID PRI CPU EVENT NAME FLAGS
X 0 s 0 0 0 0 0 0 15 16c5c swapper incore sched
X 1 s 1 0 0 0 0 30 0 eeac init incore text
X 2 s 9389 1 9389 100 100 30 0 ef54 csh incore text
X 3 s 31 1 0 0 0 26 0 5eac logger swapped
X 4 s 30 1 0 0 0 40 0 6000000 update incore text
X
XExit Crash Command
XSyntax: quit, q, ^D
X
XExits Crash.
X
XExample:
X> quit
X$
X
XPrint System Statics
XSyntax: stat, s
X
XPrints information regarding system name, operating system release, version,
Xdate of crash, and uptime at time of crash.
X
XExample:
X> stat
X sysname: XENIX
X nodename: rpp386
X release: 2.2.1
X version: SysV
X machine: i80386
X time of crash: Thu Aug 11 11:18:00 1988
X age of system: 35 days, 23 hrs., 7 mins.
X
XPrint Text Table Entries
XSyntax: text, t
X
XPrints current text table entries. Cross references to inode number
Xand process table entry and gives the number of processes which are
Xcurrently referencing this table entry.
XExample:
X> text 0 1 2 3 4
XSLOT INODE REF LDREF PROC SWAPLO+ SIZE FLAGS
X 0 2 1 1 1 0 0 write
X 1 20 2 1 9 0 0 write
X 2 5 1 1 4 0 0 write
X 3 10 1 0 0 0 0 write
X 4 21 1 1 10 0 0 write
X
XPrint Per Process User Page Information
XSyntax: user, u
X
XPrints the user page for the current process or a group of processes.
XThe argument is the process table slot. If omitted, the currently
Xrunning process, which will invariably be crash, user page will be
Xdisplayed. Information includes user and system times, user and
Xgroup ids, file I/O, system accounting and open file information.
XProvides a list of currently open files by file table entry number.
X
XExample:
X> user
XPER PROCESS USER AREA:
XUSER ID's: uid: 100, gid: 0, real uid: 100, real gid: 0
XPROCESS TIMES: user: 16, sys: 22, child user: 0, child sys: 0
XPROCESS MISC: proc slot: 10, cntrl tty: maj(0) min(0)
XIPC: locks: unlocked
XFILE I/O: user addr: 25703640, file offset: 100665344, bytes: 1892,
X segment: user, umask: 22, ulimit: 2097152
XACCOUNTING: command: crash, memory: 1987167, type: exec
X start: Thu Aug 11 11:28:10 1988
XOPEN FILES: file desc: 0 1 2 3 4 5
X file slot: 11 13 13 18 19 20
X
XPrint Tunable Parameter Information
XSyntax: var, v
X
XDisplays the tunable parameter values which were used at the time
Xof system generation. Included are number of open files, processes
Xper user, inodes, mounts, pure text entries and other related
Xinformation.
X
XExample:
X> var
Xbuffers 512
Xcalls 30
Xinodes 100
Xe_inodes 100
Xfiles 100
Xe_files 100
Xmounts 8
Xe_mounts 8
Xprocs 60
Xe_procs 16
Xtexts 40
Xe_texts 40
Xclists 64
Xsabufs 64
Xmaxproc 30
Xhashbuf 512
Xhashmask 511
X
XCaveats and Features
X
XThis release of crash is known to run under SCO Xenix 2.2.3. No other
Xports are presently known of. For the most part, porting to a different
Xrelease of Xenix should be quite painless. The principle changes are
Xlikely to be in the user area, process table entries, and system namelist
Xfunctions.
X
XNone of the options are presently implemented. Commands which have been
Ximplemented have only one format.
X
XMost of the commands are available as command line options. Use the one
Xletter command alias as the command line option. The output defaults
Xto what it would be if that one letter alias were issued to crash as a
Xcommand. Multiple flags may be given. When in doubt, read the source.
SHAR_EOF
if test 8001 -ne "`wc -c < 'README'`"
then
echo shar: "error transmitting 'README'" '(should have been 8001 characters)'
fi
fi
echo shar: "extracting 'Makefile'" '(1540 characters)'
if test -f 'Makefile'
then
echo shar: "will not over-write existing file 'Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'Makefile'
X# Copyright 1988, John F. Haugh II
X# All rights reserved.
X#
X# Permission is granted to copy and create derivative works for any
X# non-commercial purpose, provided this copyright notice is preserved
X# in all copies of source code, or included in human readable form
X# and conspicuously displayed on all copies of object code or
X# distribution media.
X#
X# %W% %U% %G%
X#
X# Your favorite Bourne Shell and Mine ...
XSHELL=/bin/sh
X# A list of all object files which need to be made
XOBJS = crash.o interact.o files.o inodes.o mounts.o procs.o texts.o \
X user.o vars.o stats.o bufs.o syms.o devs.o expr.o od.o ttys.o
X# A list of C files and such for sharchiving
XFILES = README Makefile \
X crash.c interact.c files.c inodes.c mounts.c procs.c texts.c \
X user.c vars.c stats.c bufs.c syms.c devs.c expr.c od.c ttys.c \
X crash.h
X# C flags, suitable for debugging or production.
XCFLAGS = -c -Ox -g
XGFLAGS = -t -r2
X
Xcrash: $(OBJS)
X cc -o crash -g $(OBJS)
X
Xclean:
X rm -f *.o a.out
X
Xclobber: clean
X rm -f crash core
X
Xnuke: clobber
X -for file in * ; do \
X if [ -f s.$$file -a ! -f p.$$file ] ; then \
X rm -f $$file ;\
X fi ;\
X done
X
XREADME:
X get -p $(GFLAGS) s.README > README
X
Xshar: $(FILES)
X shar -a $(FILES) > crash.shar
X
Xcrash.o: crash.h crash.c
X
Xinteract.o: interact.c
X
Xfiles.o: crash.h files.c
X
Xinodes.o: crash.h inodes.c
X
Xmounts.o: crash.h mounts.c
X
Xprocs.o: crash.h procs.c
X
Xstats.o: crash.h stats.c
X
Xtexts.o: crash.h texts.c
X
Xuser.o: crash.h user.c
X
Xvars.o: crash.h vars.c
X
Xbufs.o: crash.h bufs.c
X
Xdevs.o: crash.h devs.c
X
Xttys.o: crash.h ttys.c
X
SHAR_EOF
if test 1540 -ne "`wc -c < 'Makefile'`"
then
echo shar: "error transmitting 'Makefile'" '(should have been 1540 characters)'
fi
fi
echo shar: "extracting 'crash.c'" '(4818 characters)'
if test -f 'crash.c'
then
echo shar: "will not over-write existing file 'crash.c'"
else
sed 's/^X//' << \SHAR_EOF > 'crash.c'
X/*
X * Copyright 1988, 1991, John F. Haugh II
X * All rights reserved.
X *
X * Permission is granted to copy and create derivative works for any
X * non-commercial purpose, provided this copyright notice is preserved
X * in all copies of source code, or included in human readable form
X * and conspicuously displayed on all copies of object code or
X * distribution media.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)crash.c 2.1 07:11:33 2/27/91";
X#endif
X
X#include <sys/param.h>
X#include <sys/sysmacros.h>
X#include <sys/types.h>
X#include <sys/page.h>
X#include <sys/seg.h>
X#include <sys/proc.h>
X#include <sys/signal.h>
X#include <sys/dir.h>
X#include <sys/user.h>
X#include <sys/var.h>
X#include <sys/utsname.h>
X#include <sys/conf.h>
X#include <fcntl.h>
X#include <stdio.h>
X#include "crash.h"
X
Xint memfd;
Xint kmemfd;
Xint swapfd;
X
Xint bflag;
Xint fflag;
Xint iflag;
Xint mflag;
Xint pflag;
Xint sflag;
Xint tflag;
Xint uflag;
Xint vflag;
X
Xint anyflag;
X
Xstruct var v;
Xstruct file *files;
Xstruct inode *inodes;
Xstruct text *texts;
Xstruct proc *procs;
Xstruct mount *mounts;
Xstruct buf *bufs;
Xstruct buf *bufstart;
Xstruct cdevsw *Cdevsw;
Xstruct bdevsw *Bdevsw;
Xint Cdevcnt;
Xint Bdevcnt;
Xstruct user user;
Xdaddr_t swplo;
Xstruct utsname utsname;
Xtime_t ktime;
Xtime_t klbolt;
X
Xstruct xlist namelist[] = {
X { 0, 0, 0, "_v" },
X { 0, 0, 0, "_file" },
X { 0, 0, 0, "_inode" },
X { 0, 0, 0, "_proc" },
X { 0, 0, 0, "_text" },
X { 0, 0, 0, "_mount" },
X { 0, 0, 0, "_bufstrt" },
X { 0, 0, 0, "_swplo" },
X { 0, 0, 0, "_time" },
X { 0, 0, 0, "_lbolt" },
X { 0, 0, 0, "_utsname" },
X { 0, 0, 0, "_u" },
X { 0, 0, 0, "_cdevcnt" },
X { 0, 0, 0, "_cdevsw" },
X { 0, 0, 0, "_bdevcnt" },
X { 0, 0, 0, "_bdevsw" },
X { 0, 0, 0, (char *) 0 }
X};
X
Xusage ()
X{
X fprintf (stderr, "usage: crash -bfimpstv [ -N namelist ] ");
X fprintf (stderr, "[ -C corefile ] [ -S swapfile ]\n");
X exit (1);
X}
X
Xr_read (fd, buf, n)
Xint fd;
Xchar *buf;
Xint n;
X{
X int i;
X
X if ((i = read (fd, buf, n)) == -1) {
X perror ("error on read");
X return (-1);
X } else
X return (i);
X}
X
Xlong l_lseek (fd, offs, whence)
Xint fd;
Xlong offs;
Xint whence;
X{
X long i;
X long lseek ();
X
X if ((i = lseek (fd, offs, whence)) == -1L) {
X perror ("error on lseek");
X return (-1);
X } else
X return (i);
X}
X
Xmain (argc, argv)
Xint argc;
Xchar **argv;
X{
X char newname[10];
X char *namefile = "/xenix";
X char *corefile = "/dev/mem";
X char *kmemfile = "/dev/kmem";
X char *swapfile = "/dev/swap";
X int c;
X extern int optind;
X extern char *optarg;
X
X setbuf (stdout, NULL);
X setbuf (stderr, NULL);
X
X while ((c = getopt (argc, argv, "bfimpstuvN:C:S:")) != EOF) {
X switch (c) {
X case 'b':
X bflag++;
X anyflag++;
X break;
X case 'C':
X corefile = optarg;
X kmemfile = optarg;
X break;
X case 'f':
X fflag++;
X anyflag++;
X break;
X case 'i':
X iflag++;
X anyflag++;
X break;
X case 'm':
X mflag++;
X anyflag++;
X break;
X case 'N':
X namefile = optarg;
X break;
X case 'p':
X pflag++;
X anyflag++;
X break;
X case 's':
X sflag++;
X anyflag++;
X break;
X case 'S':
X swapfile = optarg;
X break;
X case 't':
X tflag++;
X anyflag++;
X break;
X case 'u':
X uflag++;
X anyflag++;
X break;
X case 'v':
X vflag++;
X anyflag++;
X break;
X default:
X usage ();
X }
X }
X if (xlist (namefile, namelist) != 0) {
X perror ("pstat: namelist");
X exit (1);
X }
X if (initsyms (namefile)) {
X fprintf (stderr, "unable to initialize symbol table\n");
X exit (1);
X }
X if ((memfd = open (corefile, O_RDONLY)) < 0) {
X perror ("pstat: corefile");
X exit (1);
X }
X if ((kmemfd = open (kmemfile, O_RDONLY)) < 0) {
X perror ("pstat: kmemfile");
X exit (1);
X }
X if ((swapfd = open (swapfile, O_RDONLY)) < 0) {
X perror ("pstat: swapfile");
X exit (1);
X }
X l_lseek (kmemfd, namelist[NM_V].xl_value, 0);
X r_read (kmemfd, &v, sizeof v);
X l_lseek (kmemfd, namelist[NM_SWPLO].xl_value, 0);
X r_read (kmemfd, &swplo, sizeof swplo);
X
X l_lseek (kmemfd, namelist[NM_CDEVCNT].xl_value, 0);
X r_read (kmemfd, &Cdevcnt, sizeof Cdevcnt);
X Cdevsw = (struct cdevsw *) malloc (Cdevcnt * sizeof *Cdevsw);
X l_lseek (kmemfd, namelist[NM_CDEVSW].xl_value, 0);
X r_read (kmemfd, Cdevsw, Cdevcnt * sizeof *Cdevsw);
X
X l_lseek (kmemfd, namelist[NM_BDEVCNT].xl_value, 0);
X r_read (kmemfd, &Bdevcnt, sizeof Bdevcnt);
X Bdevsw = (struct bdevsw *) malloc (Bdevcnt * sizeof *Bdevsw);
X l_lseek (kmemfd, namelist[NM_BDEVSW].xl_value, 0);
X r_read (kmemfd, Bdevsw, Bdevcnt * sizeof *Bdevsw);
X
X if (bflag)
X prbufs ((int *) 0, 0);
X
X if (fflag)
X prfiles ((int *) 0, 0);
X
X if (iflag)
X prinodes ((int *) 0, 0);
X
X if (mflag)
X prmounts ((int *) 0, 0);
X
X if (pflag)
X prprocs ((int *) 0, 0);
X
X if (sflag)
X prstats ((int *) 0, 0);
X
X if (tflag)
X prtexts ((int *) 0, 0);
X
X if (uflag)
X prusers ((int *) 0, 0);
X
X if (vflag)
X prvars ((int *) 0, 0);
X
X if (! anyflag) {
X interact ();
X exit (0);
X } else {
X exit (0);
X }
X}
SHAR_EOF
if test 4818 -ne "`wc -c < 'crash.c'`"
then
echo shar: "error transmitting 'crash.c'" '(should have been 4818 characters)'
fi
fi
echo shar: "extracting 'interact.c'" '(5858 characters)'
if test -f 'interact.c'
then
echo shar: "will not over-write existing file 'interact.c'"
else
sed 's/^X//' << \SHAR_EOF > 'interact.c'
X/*
X * Copyright 1988, 1991, John F. Haugh II
X * All rights reserved.
X *
X * Permission is granted to copy and create derivative works for any
X * non-commercial purpose, provided this copyright notice is preserved
X * in all copies of source code, or included in human readable form
X * and conspicuously displayed on all copies of object code or
X * distribution media.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)interact.c 2.1 09:26:38 2/27/91";
X#endif
X
X#include <stdio.h>
X#include <string.h>
X#include <ctype.h>
X#include <setjmp.h>
X#include <signal.h>
X
Xextern od ();
Xextern prbufs ();
Xextern prbdevs ();
Xextern prcdevs ();
Xextern prfiles ();
Xextern prinodes ();
Xextern prmounts ();
Xextern prprocs ();
Xextern prstats ();
Xextern prtexts ();
Xextern prusers ();
Xextern prvars ();
Xextern prdataaddr ();
Xextern prsymbol ();
Xextern prtextaddr ();
Xextern prttys ();
Xextern quit ();
Xextern help ();
Xextern int errno;
X
Xjmp_buf del;
Xint delflag;
X
Xstruct func {
X void (*f_func)();
X char *f_name;
X enum { none, numbers, string } f_type;
X};
X
Xstruct func commands[] = {
X { prbufs, "b", numbers },
X { prbdevs, "bd", numbers },
X { prbdevs, "bdevsw", numbers },
X { prbufs, "buf", numbers },
X { prcdevs, "cd", numbers },
X { prcdevs, "cdevsw", numbers },
X { prdataaddr, "ds", string },
X { prfiles, "f", numbers },
X { prfiles, "file", numbers },
X { help, "h", none },
X { help, "help", none },
X { prinodes, "i", numbers },
X { prinodes, "ino", numbers },
X { prinodes, "inode", numbers },
X { prmounts, "m", numbers },
X { prmounts, "mount", numbers },
X { prsymbol, "nm", string },
X { od, "od", string },
X { prprocs, "p", numbers },
X { prprocs, "proc", numbers },
X { quit, "q", none },
X { quit, "quit", none },
X { prstats, "s", none },
X { prstats, "stat", none },
X { prtexts, "t", numbers },
X { prtexts, "text", numbers },
X { prtextaddr, "ts", string },
X { prttys, "tty", string },
X { prusers, "u", numbers },
X { prusers, "user", numbers },
X { prvars, "v", none },
X { prvars, "var", none },
X { 0, 0, none }
X};
X
Xhelp ()
X{
X printf ("command summary\n\n");
X
X printf ("buf (b) - buffer headers\n");
X printf ("file (f) - open files\n");
X printf ("help (h,?) - list commands\n");
X printf ("inode (ino,i) - active inodes\n");
X printf ("mount (m) - mounted file systems\n");
X printf ("proc (p) - active and defunct processes\n");
X printf ("quit (q,^D) - exit crash\n");
X printf ("stat (s) - crash statistics, age, time\n");
X printf ("text (t) - active and sticky bit text segments\n");
X printf ("user (u) - user page information\n");
X printf ("var (v) - tunable parameters\n");
X}
X
Xquit ()
X{
X exit (0);
X}
X
Xinterupt (sig)
Xint sig;
X{
X delflag = 1;
X fflush (stdout);
X fflush (stderr);
X longjmp (del, sig);
X}
X
Xstatic int
Xnumber (cpp, value)
Xchar **cpp;
Xint *value;
X{
X char *cp = *cpp;
X char *end;
X char buf[16];
X int i;
X
X while (*cp && isspace (*cp))
X cp++;
X
X for (i = 0;i < 15 && isdigit (*cp);i++, cp++)
X buf[i] = *cp;
X
X while (*cp && isspace (*cp))
X cp++;
X
X if (cp == *cpp)
X return -1;
X
X buf[i] = '\0';
X i = (int) strtol (buf, &end, 0);
X if (*end)
X return -1;
X
X *value = i;
X *cpp = cp;
X return 0;
X}
X
Xstatic int
Xrange (cpp, value, cnt)
Xchar **cpp;
Xint **value;
Xint *cnt;
X{
X int min, max;
X char *cp = *cpp;
X
X if (number (&cp, &min)) {
X *cpp = cp;
X return -1;
X }
X while (*cp && isspace (*cp))
X cp++;
X
X if (*cp == ',' || *cp == '\0') {
X *((*value)++) = min;
X (*cnt)--;
X *cpp = cp;
X return 0;
X } else if (*cp != '-') {
X *cpp = cp;
X return -1;
X }
X cp++;
X
X while (*cp && isspace (*cp))
X cp++;
X
X if (number (&cp, &max)) {
X *cpp = cp;
X return -1;
X }
X while (min <= max && (*cnt) > 0) {
X *((*value)++) = min++;
X (*cnt)--;
X }
X if ((*cnt) == 0 && min <= max)
X return -1;
X
X *cpp = cp;
X return 0;
X}
X
Xlist (cp, items, max)
Xchar *cp;
Xint *items;
Xint max;
X{
X int cnt = max;
X
X /*
X * number lists are of the form
X *
X * <list> ::= <range> | <list> ',' <range>
X * <range> ::= <number> '-' <number> | <number>
X * <number> ::= <one or more decimal digits>
X */
X
X while (*cp && cnt > 0) {
X while (*cp && isspace (*cp))
X cp++;
X
X if (range (&cp, &items, &cnt))
X break;
X
X if (*cp) {
X if (*cp == ',')
X cp++;
X else
X break;
X }
X }
X if (*cp) {
X printf ("error at '%.15s'\n", cp);
X return -1;
X }
X return max - cnt;
X}
X
Xinteract ()
X{
X int i;
X long l;
X int cnt;
X char *cp;
X char *com;
X char *num;
X char buf[BUFSIZ];
X int items[100];
X
X while (setjmp (del)) /* catch that first interupt */
X fprintf (stderr, "\nq to quit\n");
X
X signal (SIGINT, interupt); /* and setup the handler */
X
X while (fprintf (stderr, "> "), gets (buf) != (char *) 0) {
X while (setjmp (del))
X goto eh;
X
X /*
X * find first non-white space character and skip if
X * a blank line
X */
X
X for (com = buf;*com && (*com == ' ' || *com == '\t');com++)
X ;
X
X if (*com == '\0')
X continue;
X
X /*
X * find the entire command word
X */
X
X if (*com == '?') {
X help ();
X continue;
X } else if (*com == '!') {
X system (com + 1);
X continue;
X } else if (*com == '=') {
X com++;
X if (expr (&com, &l))
X goto eh;
X printf ("%d (%x)\n", l, l);
X continue;
X }
X for (cp = com;*cp >= 'a' && *cp <= 'z';cp++)
X ;
X
X if (*cp != '\0')
X *cp++ = '\0';
X
X for (i = 0;commands[i].f_name != (char *) 0;i++)
X if (strcmp (commands[i].f_name, com) == 0)
X break;
X
X if (commands[i].f_name == (char *) 0)
X goto eh;
X
X if (commands[i].f_type == numbers) {
X while (*cp && isspace (*cp))
X cp++;
X
X if ((cnt = list (cp, items, 100)) < 0)
X goto eh;
X
X (*commands[i].f_func) (cnt ? items:0, cnt);
X continue;
X } else if (commands[i].f_type == string) {
X while (*cp && isspace (*cp))
X cp++;
X
X (*commands[i].f_func) (cp);
X continue;
X }
X
X /*
X * common error handler. get here if an error is found.
X */
Xeh:
X if (delflag) {
X putc ('\n', stderr);
X delflag = 0;
X }
X fprintf (stderr, "eh?\n");
X signal (SIGINT, interupt);
X }
X}
SHAR_EOF
if test 5858 -ne "`wc -c < 'interact.c'`"
then
echo shar: "error transmitting 'interact.c'" '(should have been 5858 characters)'
fi
fi
echo shar: "extracting 'files.c'" '(1868 characters)'
if test -f 'files.c'
then
echo shar: "will not over-write existing file 'files.c'"
else
sed 's/^X//' << \SHAR_EOF > 'files.c'
X/*
X * Copyright 1988, John F. Haugh II
X * All rights reserved.
X *
X * Permission is granted to copy and create derivative works for any
X * non-commercial purpose, provided this copyright notice is preserved
X * in all copies of source code, or included in human readable form
X * and conspicuously displayed on all copies of object code or
X * distribution media.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)files.c 1.2 22:55:32 2/21/91";
X#endif
X
X#include <sys/param.h>
X#include <sys/sysmacros.h>
X#include <sys/types.h>
X#include <sys/var.h>
X#include <sys/inode.h>
X#include <sys/file.h>
X#include <sys/page.h>
X#include <sys/seg.h>
X#include <sys/signal.h>
X#include <sys/dir.h>
X#include <sys/user.h>
X#include "crash.h"
X
Xprfiles (items, cnt)
Xint *items;
Xint cnt;
X{
X int i;
X
X files = (struct file *) malloc (v.v_file * sizeof (struct file));
X l_lseek (kmemfd, namelist[NM_FILE].xl_value, 0);
X r_read (kmemfd, files, sizeof (struct file) * v.v_file);
X
X printf ("SLOT FLAG COUNT INODE OFFSET\n");
X if (cnt == 0) {
X for (i = 0;i < v.v_file;i++) {
X if (files[i].f_count == 0 || files[i].f_flag == 0)
X continue;
X
X dofile (i);
X }
X } else {
X for (i = 0;i < cnt;i++) {
X if (items[i] >= v.v_file)
X printf ("value (%d) out of range\n", items[i]);
X else
X dofile (items[i]);
X }
X }
X free ((char *) files);
X}
X
X
Xdofile (i)
Xint i;
X{
X printf ("%4d %03o %c%c%c%c%c%c%c%c %5d %5d %10ld\n",
X i, files[i].f_flag & FMASK,
X (files[i].f_flag & FREAD) ? 'R':' ',
X (files[i].f_flag & FWRITE) ? 'W':' ',
X (files[i].f_flag & FNDELAY) ? 'N':' ',
X (files[i].f_flag & FAPPEND) ? 'A':' ',
X (files[i].f_flag & FSYNC) ? 'S':' ',
X (files[i].f_flag & FCREAT) ? 'C':' ',
X (files[i].f_flag & FTRUNC) ? 'T':' ',
X (files[i].f_flag & FEXCL) ? 'X':' ',
X files[i].f_count,
X files[i].f_inode - (struct inode *) namelist[NM_INODE].xl_value,
X files[i].f_offset);
X}
SHAR_EOF
if test 1868 -ne "`wc -c < 'files.c'`"
then
echo shar: "error transmitting 'files.c'" '(should have been 1868 characters)'
fi
fi
echo shar: "extracting 'inodes.c'" '(2345 characters)'
if test -f 'inodes.c'
then
echo shar: "will not over-write existing file 'inodes.c'"
else
sed 's/^X//' << \SHAR_EOF > 'inodes.c'
X/*
X * Copyright 1988, John F. Haugh II
X * All rights reserved.
X *
X * Permission is granted to copy and create derivative works for any
X * non-commercial purpose, provided this copyright notice is preserved
X * in all copies of source code, or included in human readable form
X * and conspicuously displayed on all copies of object code or
X * distribution media.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)inodes.c 1.2 22:55:34 2/21/91";
X#endif
X
X#include <sys/param.h>
X#include <sys/sysmacros.h>
X#include <sys/types.h>
X#include <sys/var.h>
X#include <sys/inode.h>
X#include <a.out.h>
X#include "crash.h"
X
Xprinodes (items, cnt)
Xint *items;
Xint cnt;
X{
X int i;
X
X inodes = (struct inode *) malloc (v.v_inode * sizeof (struct inode));
X l_lseek (kmemfd, namelist[NM_INODE].xl_value, 0);
X r_read (kmemfd, inodes, sizeof (struct inode) * v.v_inode);
X
X printf ("SLOT MAJ MIN INUMB REF LINK UID GID SIZE MODE SMAJ SMIN FLAGS\n");
X
X if (cnt == 0) {
X for (i = 0;i < v.v_inode;i++) {
X if (inodes[i].i_count == 0)
X continue;
X
X doinode (i);
X }
X } else {
X for (i = 0;i < cnt;i++) {
X if (items[i] >= v.v_inode)
X printf ("value (%d) out of range\n", items[i]);
X else
X doinode (items[i]);
X }
X }
X free ((char *) inodes);
X}
X
Xdoinode (i)
Xint i;
X{
X char *modes = " pcCd bBf";
X struct inode *ip;
X
X ip = &inodes[i];
X
X printf ("%4d %03o %04o %5d %3d %4d%5d%5d %8ld %c%c%c%c%03o",
X i, major (ip->i_dev), minor (ip->i_dev), ip->i_number,
X ip->i_count, ip->i_nlink, ip->i_uid, ip->i_gid,
X ip->i_size,
X modes[(ip->i_mode & IFMT) >> 12],
X (ip->i_mode & ISUID) ? 'u':'-',
X (ip->i_mode & ISGID) ? 'g':'-',
X (ip->i_mode & ISVTX) ? 't':'-',
X (ip->i_mode & 0777));
X
X if (! (((ip->i_mode & IFMT) == IFDIR) ||
X ((ip->i_mode & IFMT) == IFREG) ||
X ((ip->i_mode & IFMT) == IFIFO)))
X printf (" %04o %04o", major (ip->i_rdev),
X minor (ip->i_rdev));
X else
X printf (" - -"); /* special file stuff */
X if (ip->i_flag & IUPD) printf (" upd");
X if (ip->i_flag & IACC) printf (" acc");
X if (ip->i_flag & ICHG) printf (" chg");
X if (ip->i_flag & IMOUNT) printf (" mnt");
X if (ip->i_flag & ITEXT) printf (" txt");
X if (ip->i_flag & ILOCK) printf (" lck");
X#ifdef ISYN
X if (ip->i_flag & ISYN) printf (" syn");
X#endif
X#ifdef IRMT
X if (ip->i_flag & IRMT) printf (" rmt");
X#endif
X if (ip->i_flag & IWANT) printf (" wnt");
X
X printf ("\n");
X}
SHAR_EOF
if test 2345 -ne "`wc -c < 'inodes.c'`"
then
echo shar: "error transmitting 'inodes.c'" '(should have been 2345 characters)'
fi
fi
echo shar: "extracting 'mounts.c'" '(2319 characters)'
if test -f 'mounts.c'
then
echo shar: "will not over-write existing file 'mounts.c'"
else
sed 's/^X//' << \SHAR_EOF > 'mounts.c'
X/*
X * Copyright 1988, John F. Haugh II
X * All rights reserved.
X *
X * Permission is granted to copy and create derivative works for any
X * non-commercial purpose, provided this copyright notice is preserved
X * in all copies of source code, or included in human readable form
X * and conspicuously displayed on all copies of object code or
X * distribution media.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)mounts.c 1.2 22:55:36 2/21/91";
X#endif
X
X#include <sys/param.h>
X#include <sys/sysmacros.h>
X#include <sys/types.h>
X#include <sys/var.h>
X#include <sys/inode.h>
X#include <sys/ino.h>
X#include <sys/buf.h>
X#include <sys/filsys.h>
X#include <sys/mount.h>
X#include <a.out.h>
X#include "crash.h"
X
Xprmounts (items, cnt)
Xint *items;
Xint cnt;
X{
X int i;
X
X mounts = (struct mount *) malloc (v.v_mount * sizeof (struct mount));
X l_lseek (kmemfd, namelist[NM_MOUNT].xl_value, 0);
X r_read (kmemfd, mounts, sizeof (struct mount) * v.v_mount);
X l_lseek (kmemfd, namelist[NM_BUFFER].xl_value, 0);
X r_read (kmemfd, &bufstart, sizeof bufstart);
X
X printf ("SLOT MAJ MIN INODE BUF VOLUME PACK BLOCKS INODES BFREE IFREE\n");
X
X if (cnt == 0) {
X for (i = 0;i < v.v_mount;i++) {
X if (mounts[i].m_flags == 0)
X continue;
X
X domount (i);
X }
X } else {
X for (i = 0;i < cnt;i++) {
X if (items[i] >= v.v_mount)
X printf ("value (%d) out of range\n", items[i]);
X else
X domount (items[i]);
X }
X }
X free ((char *) mounts);
X}
X
Xdomount (i)
Xint i;
X{
X struct filsys filsys;
X struct buf buf;
X struct inode *ip = (struct inode *) namelist[NM_INODE].xl_value;
X
X printf ("%4d %4o %03o %6d %4d",
X i, major (mounts[i].m_dev), minor (mounts[i].m_dev),
X mounts[i].m_inodp ?
X mounts[i].m_inodp - ip : 0,
X mounts[i].m_bufp ?
X mounts[i].m_bufp - bufstart : 0);
X
X /*
X * zero before using since unused mount entries don't have
X * buffers and such.
X */
X
X memset (&buf, 0, sizeof buf);
X memset (&filsys, 0, sizeof filsys);
X
X if (mounts[i].m_flags != 0) {
X l_lseek (memfd, (long) mounts[i].m_bufp, 0);
X r_read (memfd, &buf, sizeof buf);
X l_lseek (memfd, (long) buf.b_paddr, 0);
X r_read (memfd, &filsys, sizeof filsys);
X }
X printf (" %-6.6s %-6.6s",
X filsys.s_fname, filsys.s_fpack);
X
X printf (" %6ld %6ld %6ld %6ld",
X filsys.s_fsize, INOPB * filsys.s_isize,
X (long) filsys.s_tfree, (long) filsys.s_tinode);
X
X putchar ('\n');
X}
SHAR_EOF
if test 2319 -ne "`wc -c < 'mounts.c'`"
then
echo shar: "error transmitting 'mounts.c'" '(should have been 2319 characters)'
fi
fi
echo shar: "extracting 'procs.c'" '(2465 characters)'
if test -f 'procs.c'
then
echo shar: "will not over-write existing file 'procs.c'"
else
sed 's/^X//' << \SHAR_EOF > 'procs.c'
X/*
X * Copyright 1988, John F. Haugh II
X * All rights reserved.
X *
X * Permission is granted to copy and create derivative works for any
X * non-commercial purpose, provided this copyright notice is preserved
X * in all copies of source code, or included in human readable form
X * and conspicuously displayed on all copies of object code or
X * distribution media.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)procs.c 1.2 22:55:38 2/21/91";
X#endif
X
X#include <sys/param.h>
X#include <sys/sysmacros.h>
X#include <sys/types.h>
X#include <sys/var.h>
X#include <sys/text.h>
X#include <sys/page.h>
X#include <sys/seg.h>
X#include <sys/proc.h>
X#include <sys/signal.h>
X#include <sys/dir.h>
X#include <sys/user.h>
X#include "crash.h"
X
X/*
X * prprocs - output the process table
X */
X
Xprprocs (items, cnt)
Xint *items;
Xint cnt;
X{
X struct proc *pp;
X struct user user;
X int i;
X
X procs = (struct proc *) malloc (v.v_proc * sizeof (struct proc));
X lseek (kmemfd, namelist[NM_PROC].xl_value, 0);
X read (kmemfd, procs, sizeof (struct proc) * v.v_proc);
X
X printf ("SLT ST PID PPID PGRP UID EUID PRI CPU EVENT NAME FLAGS\n");
X
X if (cnt == 0) {
X for (i = 0;i < v.v_proc;i++) {
X if (procs[i].p_stat == 0)
X continue;
X
X doproc (i);
X }
X } else {
X for (i = 0;i < cnt;i++) {
X if (items[i] >= v.v_proc)
X printf ("value (%d) out of range\n", items[i]);
X else
X doproc (items[i]);
X }
X }
X free ((char *) procs);
X}
X
Xdoproc (i)
Xint i;
X{
X struct proc *pp;
X
X pp = &procs[i];
X
X printf ("%3d %c %5d %5d %5d %5d %5d %3d %3d", i,
X " swriztBST"[pp->p_stat], pp->p_pid, pp->p_ppid,
X pp->p_pgrp, pp->p_uid, pp->p_suid,
X pp->p_pri & 0377, pp->p_cpu & 0377);
X
X if (pp->p_wchan)
X printf (" %8x", pp->p_wchan);
X else
X printf (" ");
X
X if (pp->p_stat == SZOMB) {
X printf (" ZOMBIE ");
X } else if (pp->p_flag & SSYS) {
X printf (" swapper ");
X } else if (pp->p_stat != 0) {
X if (findu (pp, i, &user))
X printf (" %-10.10s", user.u_comm);
X else
X printf (" SWAPPED ");
X } else {
X printf (" ");
X }
X if (pp->p_stat == SRUN) printf (" running");
X if (pp->p_stat == SZOMB) printf (" zombie");
X if (pp->p_flag & SLOAD) printf (" incore");
X else printf (" swapped");
X if (pp->p_flag & SSYS) printf (" sched");
X if (pp->p_flag & SLOCK) printf (" locked");
X if (pp->p_flag & STRC) printf (" traced");
X if (pp->p_flag & SWTED) printf (" wanted");
X if (pp->p_flag & STEXT) printf (" text");
X if (pp->p_flag & SSPART) printf (" part-swap");
X
X printf ("\n");
X}
SHAR_EOF
if test 2465 -ne "`wc -c < 'procs.c'`"
then
echo shar: "error transmitting 'procs.c'" '(should have been 2465 characters)'
fi
fi
echo shar: "extracting 'texts.c'" '(1980 characters)'
if test -f 'texts.c'
then
echo shar: "will not over-write existing file 'texts.c'"
else
sed 's/^X//' << \SHAR_EOF > 'texts.c'
X/*
X * Copyright 1988, John F. Haugh II
X * All rights reserved.
X *
X * Permission is granted to copy and create derivative works for any
X * non-commercial purpose, provided this copyright notice is preserved
X * in all copies of source code, or included in human readable form
X * and conspicuously displayed on all copies of object code or
X * distribution media.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)texts.c 1.2 22:55:40 2/21/91";
X#endif
X
X#include <sys/param.h>
X#include <sys/sysmacros.h>
X#include <sys/types.h>
X#include <sys/var.h>
X#include <sys/inode.h>
X#include <sys/text.h>
X#include <sys/page.h>
X#include <sys/seg.h>
X#include <sys/proc.h>
X#include <a.out.h>
X#include "crash.h"
X
Xprtexts (items, cnt)
Xint *items;
Xint cnt;
X{
X int i;
X
X texts = (struct text *) malloc (v.v_text * sizeof (struct text));
X lseek (kmemfd, namelist[NM_TEXT].xl_value, 0);
X read (kmemfd, texts, sizeof (struct text) * v.v_text);
X
X printf ("SLOT INODE REF LDREF PROC SWAPLO+ SIZE FLAGS\n");
X
X if (cnt == 0) {
X for (i = 0;i < v.v_text;i++) {
X if (texts[i].x_count == 0)
X continue;
X
X dotext (i);
X }
X } else {
X for (i = 0;i < cnt;i++) {
X if (items[i] >= v.v_text)
X printf ("value (%d) out of range\n", items[i]);
X else
X dotext (items[i]);
X }
X }
X free ((char *) texts);
X}
X
Xdotext (i)
Xint i;
X{
X struct text *tp;
X int procnum;
X
X tp = &texts[i];
X
X if (tp->x_ccount > 0)
X procnum = tp->x_caddr -
X (struct proc *) namelist[NM_PROC].xl_value;
X else
X procnum = 0;
X
X printf ("%4d %5d %3d %5d %4d %7d %5d ", i,
X tp->x_iptr - (struct inode *) namelist[NM_INODE].xl_value,
X tp->x_count, tp->x_ccount, procnum,
X tp->x_daddr, tp->x_size);
X
X if (tp->x_flag & XTRC) printf (" trace");
X if (tp->x_flag & XWRIT) printf (" write");
X if (tp->x_flag & XLOAD) printf (" loaded");
X if (tp->x_flag & XLOCK) printf (" locked");
X if (tp->x_flag & XWANT) printf (" wanted");
X if (tp->x_flag & XLARGE) printf (" large");
X if (tp->x_flag & XFPU) printf (" fpu");
X
X printf ("\n");
X}
SHAR_EOF
if test 1980 -ne "`wc -c < 'texts.c'`"
then
echo shar: "error transmitting 'texts.c'" '(should have been 1980 characters)'
fi
fi
echo shar: "extracting 'user.c'" '(3411 characters)'
if test -f 'user.c'
then
echo shar: "will not over-write existing file 'user.c'"
else
sed 's/^X//' << \SHAR_EOF > 'user.c'
X/*
X * Copyright 1988, John F. Haugh II
X * All rights reserved.
X *
X * Permission is granted to copy and create derivative works for any
X * non-commercial purpose, provided this copyright notice is preserved
X * in all copies of source code, or included in human readable form
X * and conspicuously displayed on all copies of object code or
X * distribution media.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)user.c 1.2 22:55:41 2/21/91";
X#endif
X
X#include <sys/param.h>
X#include <sys/sysmacros.h>
X#include <sys/types.h>
X#include <sys/page.h>
X#include <sys/seg.h>
X#include <sys/file.h>
X#include <sys/proc.h>
X#include <sys/signal.h>
X#include <sys/dir.h>
X#include <sys/user.h>
X#include <sys/var.h>
X#include <sys/lock.h>
X#include "crash.h"
X
Xfindu (proc, slot, user)
Xstruct proc *proc;
Xint slot;
Xstruct user *user;
X{
X struct proc *procs = (struct proc *) namelist[NM_PROC].xl_value;
X long swapaddr;
X int i;
X
X if ((proc->p_flag & (SSWAP|SSPART)) || ! (proc->p_flag & SLOAD)) {
X swapaddr = proc->p_addr[0].te_frameno * NBPC;
X l_lseek (swapfd, swapaddr, 0);
X r_read (swapfd, user, sizeof *user);
X } else {
X l_lseek (memfd, proc->p_addr[0].te_frameno * NBPC, 0);
X r_read (memfd, user, sizeof *user);
X }
X if (user->u_procp - procs == slot)
X return (1);
X else
X return (0);
X}
X
Xprusers (items, cnt)
Xint *items;
Xint cnt;
X{
X int i;
X
X if (cnt == 0) {
X douser (-1);
X return (1);
X }
X for (i = 0;i < cnt;i++) {
X if (items[i] >= v.v_proc) {
X printf ("value (%d) out of range\n", items[i]);
X continue;
X } else {
X douser (items[i]);
X }
X }
X}
X
Xdouser (i)
X{
X struct file *fp;
X struct proc proc;
X struct proc *pp;
X static char *segments[] = { "user", "system", "user i" };
X int fileno;
X
X pp = (struct proc *) namelist[NM_PROC].xl_value;
X fp = (struct file *) namelist[NM_FILE].xl_value;
X
X if (i >= 0) {
X l_lseek (kmemfd, (long) &pp[i], 0);
X r_read (kmemfd, &proc, sizeof proc);
X
X if (! findu (&proc, i, &user))
X return (0);
X } else {
X l_lseek (kmemfd, namelist[NM_USER].xl_value, 0);
X r_read (kmemfd, &user, sizeof user);
X }
X printf ("PER PROCESS USER AREA:\n");
X printf ("USER ID's: uid: %d, gid: %d, real uid: %d, real gid: %d\n",
X user.u_uid, user.u_gid, user.u_ruid, user.u_rgid);
X printf ("PROCESS TIMES: user: %d, sys: %d, child user: %d, child sys: %d\n",
X user.u_utime, user.u_stime, user.u_cutime, user.u_cstime);
X printf ("PROCESS MISC: proc slot: %d, cntrl tty: maj(%d) min(%d)\n",
X user.u_procp - pp, major (user.u_ttyd), minor (user.u_ttyd));
X printf ("IPC: locks:%s%s%s%s%s\n",
X user.u_lock == UNLOCK ? " unlocked":"",
X user.u_lock & PROCLOCK ? " proc":"",
X user.u_lock & TXTLOCK ? " text":"",
X user.u_lock & DATLOCK ? " data":"",
X user.u_lock & HUGELOCK ? " huge":"");
X printf ("FILE I/O: user addr: %ld, file offset: %ld, bytes: %ld,\n",
X user.u_baseu, user.u_offset, user.u_count);
X printf (" segment: %s, umask: %01o, ulimit: %ld\n",
X segments[user.u_segflg], user.u_cmask, user.u_limit);
X printf ("ACCOUNTING: command: %s, memory: %ld, type: %s\n",
X user.u_comm, user.u_mem, user.u_acflag ? "fork":"exec");
X printf (" start: %s",
X ctime (&user.u_start));
X
X printf ("OPEN FILES: file desc: ");
X for (i = 0;i < NOFILE;i++)
X if (user.u_ofile[i] != (struct file *) 0)
X printf ("%4d", i);
X putchar ('\n');
X
X printf (" file slot: ");
X for (i = 0;i < NOFILE;i++)
X if (user.u_ofile[i] != (struct file *) 0)
X printf ("%4d", user.u_ofile[i] - fp);
X putchar ('\n');
X
X return (0);
X}
SHAR_EOF
if test 3411 -ne "`wc -c < 'user.c'`"
then
echo shar: "error transmitting 'user.c'" '(should have been 3411 characters)'
fi
fi
echo shar: "extracting 'vars.c'" '(1811 characters)'
if test -f 'vars.c'
then
echo shar: "will not over-write existing file 'vars.c'"
else
sed 's/^X//' << \SHAR_EOF > 'vars.c'
X/*
X * Copyright 1988, John F. Haugh II
X * All rights reserved.
X *
X * Permission is granted to copy and create derivative works for any
X * non-commercial purpose, provided this copyright notice is preserved
X * in all copies of source code, or included in human readable form
X * and conspicuously displayed on all copies of object code or
X * distribution media.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)vars.c 1.2 22:55:43 2/21/91";
X#endif
X
X#include <sys/param.h>
X#include <sys/sysmacros.h>
X#include <sys/types.h>
X#include <sys/file.h>
X#include <sys/inode.h>
X#include <sys/page.h>
X#include <sys/seg.h>
X#include <sys/proc.h>
X#include <sys/text.h>
X#include <sys/mount.h>
X#include <sys/var.h>
X#include <a.out.h>
X#include "crash.h"
X
Xprvars ()
X{
X printf ("buffers %3d\n",
X v.v_buf);
X printf ("calls %3d\n",
X v.v_call);
X printf ("inodes %3d\n",
X v.v_inode);
X printf ("e_inodes %3d\n",
X v.ve_inode - (struct inode *) namelist[NM_INODE].xl_value);
X printf ("files %3d\n",
X v.v_file);
X printf ("e_files %3d\n",
X v.ve_file - (struct file *) namelist[NM_FILE].xl_value);
X printf ("mounts %3d\n",
X v.v_mount);
X printf ("e_mounts %3d\n",
X v.ve_mount - (struct mount *) namelist[NM_MOUNT].xl_value);
X printf ("procs %3d\n",
X v.v_proc);
X printf ("e_procs %3d\n",
X v.ve_proc - (struct proc *) namelist[NM_PROC].xl_value);
X printf ("texts %3d\n",
X v.v_text);
X printf ("e_texts %3d\n",
X v.ve_text - (struct text *) namelist[NM_TEXT].xl_value);
X printf ("clists %3d\n",
X v.v_clist);
X printf ("sabufs %3d\n",
X v.v_sabuf);
X printf ("maxproc %3d\n",
X v.v_maxup);
X/*
Xswapmap 105
X*/
X printf ("hashbuf %3d\n",
X v.v_hbuf);
X printf ("hashmask %3d\n",
X v.v_hmask);
X}
SHAR_EOF
if test 1811 -ne "`wc -c < 'vars.c'`"
then
echo shar: "error transmitting 'vars.c'" '(should have been 1811 characters)'
fi
fi
echo shar: "extracting 'stats.c'" '(1805 characters)'
if test -f 'stats.c'
then
echo shar: "will not over-write existing file 'stats.c'"
else
sed 's/^X//' << \SHAR_EOF > 'stats.c'
X/*
X * Copyright 1988, John F. Haugh II
X * All rights reserved.
X *
X * Permission is granted to copy and create derivative works for any
X * non-commercial purpose, provided this copyright notice is preserved
X * in all copies of source code, or included in human readable form
X * and conspicuously displayed on all copies of object code or
X * distribution media.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)stats.c 1.2 22:55:39 2/21/91";
X#endif
X
X#include <sys/param.h>
X#include <sys/sysmacros.h>
X#include <sys/types.h>
X#include <sys/utsname.h>
X#include <sys/param.h>
X#include <a.out.h>
X#include <time.h>
X#include "crash.h"
X
X#define MINUTE (60L)
X#define HOUR (MINUTE*60L)
X#define DAY (HOUR*24L)
X
Xprstats ()
X{
X l_lseek (kmemfd, namelist[NM_UTSNAME].xl_value, 0);
X r_read (kmemfd, &utsname, sizeof utsname);
X
X l_lseek (kmemfd, namelist[NM_TIME].xl_value, 0);
X r_read (kmemfd, &ktime, sizeof ktime);
X
X l_lseek (kmemfd, namelist[NM_LBOLT].xl_value, 0);
X r_read (kmemfd, &klbolt, sizeof klbolt);
X
X printf (" sysname: %.*s\n",
X sizeof utsname.sysname, utsname.sysname);
X printf (" nodename: %.*s\n",
X sizeof utsname.nodename, utsname.nodename);
X printf (" release: %.*s\n",
X sizeof utsname.release, utsname.release);
X printf (" version: %.*s\n",
X sizeof utsname.version, utsname.version);
X printf (" machine: %.*s\n",
X sizeof utsname.machine, utsname.machine);
X
X printf (" time of crash: %s", ctime (&ktime));
X
X klbolt /= HZ; /* convert to seconds */
X
X printf (" age of system:");
X
X if (klbolt >= DAY)
X printf (" %d %s,", klbolt / DAY,
X klbolt >= (2*DAY) ? "days":"day");
X
X klbolt %= DAY;
X
X if (klbolt >= HOUR)
X printf (" %d %s,", klbolt / HOUR,
X klbolt >= (2*HOUR) ? "hrs.":"hr.");
X
X klbolt %= HOUR;
X klbolt /= MINUTE;
X
X printf (" %d %s\n", klbolt,
X klbolt == 0 || klbolt >= 2 ? "mins.":"min.");
X}
SHAR_EOF
if test 1805 -ne "`wc -c < 'stats.c'`"
then
echo shar: "error transmitting 'stats.c'" '(should have been 1805 characters)'
fi
fi
echo shar: "extracting 'bufs.c'" '(2101 characters)'
if test -f 'bufs.c'
then
echo shar: "will not over-write existing file 'bufs.c'"
else
sed 's/^X//' << \SHAR_EOF > 'bufs.c'
X/*
X * Copyright 1988, John F. Haugh II
X * All rights reserved.
X *
X * Permission is granted to copy and create derivative works for any
X * non-commercial purpose, provided this copyright notice is preserved
X * in all copies of source code, or included in human readable form
X * and conspicuously displayed on all copies of object code or
X * distribution media.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)bufs.c 1.2 22:55:28 2/21/91";
X#endif
X
X#include <sys/param.h>
X#include <sys/sysmacros.h>
X#include <sys/types.h>
X#include <sys/var.h>
X#include <sys/inode.h>
X#include <sys/ino.h>
X#include <sys/buf.h>
X#include <a.out.h>
X#include "crash.h"
X
Xprbufs (items, cnt)
Xint *items;
Xint cnt;
X{
X int i;
X
X bufs = (struct buf *) malloc (v.v_buf * sizeof (struct buf));
X
X l_lseek (kmemfd, namelist[NM_BUFFER].xl_value, 0);
X r_read (kmemfd, &bufstart, sizeof bufstart);
X
X l_lseek (memfd, bufstart, 0);
X r_read (memfd, bufs, v.v_buf * sizeof (struct buf));
X
X printf (" BUF MAJ MIN BLOCK FLAGS\n");
X
X if (cnt == 0) {
X for (i = 0;i < v.v_buf;i++) {
X if (bufs[i].b_flags == 0)
X continue;
X
X dobuf (i);
X }
X } else {
X for (i = 0;i < cnt;i++) {
X if (items[i] >= v.v_buf)
X printf ("value (%d) out of range\n", items[i]);
X else
X dobuf (items[i]);
X }
X }
X free ((char *) bufs);
X}
X
Xdobuf (i)
Xint i;
X{
X struct buf *bp;
X
X bp = &bufs[i];
X
X printf ("%4d %03.3o %04.4o %8d",
X i, major (bp->b_dev) & 0377, minor (bp->b_dev), bp->b_blkno);
X
X if (bp->b_flags & B_READ) printf (" read");
X if (bp->b_flags & B_DONE) printf (" done");
X if (bp->b_flags & B_ERROR) printf (" error");
X if (bp->b_flags & B_BUSY) printf (" busy");
X if (bp->b_flags & B_PHYS) printf (" phys");
X if (bp->b_flags & B_MAP) printf (" map");
X if (bp->b_flags & B_WANTED) printf (" wanted");
X if (bp->b_flags & B_AGE) printf (" age");
X if (bp->b_flags & B_ASYNC) printf (" async");
X if (bp->b_flags & B_DELWRI) printf (" delwri");
X if (bp->b_flags & B_OPEN) printf (" open");
X if (bp->b_flags & B_STALE) printf (" stale");
X if (bp->b_flags & B_NOCROSS) printf (" nocross");
X if (bp->b_flags & B_FLUSH) printf (" flush");
X
X putchar ('\n');
X}
SHAR_EOF
if test 2101 -ne "`wc -c < 'bufs.c'`"
then
echo shar: "error transmitting 'bufs.c'" '(should have been 2101 characters)'
fi
fi
echo shar: "extracting 'syms.c'" '(6139 characters)'
if test -f 'syms.c'
then
echo shar: "will not over-write existing file 'syms.c'"
else
sed 's/^X//' << \SHAR_EOF > 'syms.c'
X/*
X * Copyright 1991, John F. Haugh II
X * An unpublished work.
X * All rights reserved.
X *
X * Permission is granted to copy and create derivative works for any
X * non-commercial purpose, provided this copyright notice is preserved
X * in all copies of source code, or included in human readable form
X * and conspicuously displayed on all copies of object code or
X * distribution media.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)syms.c 2.1 07:15:42 2/27/91";
X#endif
X
X#include <sys/types.h>
X#include <sys/a.out.h>
X#include <sys/relsym.h>
X#include <stdio.h>
X
Xstruct xlist3 {
X unsigned short xl3_type;
X unsigned short xl3_seg;
X unsigned long xl3_value;
X};
X
Xstruct xlist **symbols;
Xint nsymbols;
Xint maxsymbols;
X
Xextern char *strdup();
X
Xint
Xinitsyms (file)
Xchar *file;
X{
X FILE *fp;
X long segsize;
X long pad;
X struct xexec xexec;
X struct xext xext;
X struct xseg xseg;
X struct xlist xlist;
X char buf[BUFSIZ];
X char *cp;
X
X if (! (fp = fopen (file, "r"))) {
X perror (file);
X return -1;
X }
X if (fread (&xexec, sizeof xexec, 1, fp) != 1) {
X printf ("error reading xexec header\n");
X return -1;
X }
X if (xexec.x_magic != X_MAGIC) {
X printf ("not a valid x.out header\n");
X return -1;
X }
X if (! (xexec.x_renv & XE_SEG)) {
X printf ("not a segmented object\n");
X return -1;
X }
X if (fread (&xext, sizeof xext, 1, fp) != 1) {
X printf ("error reading xext record\n");
X return -1;
X }
X if (fseek (fp, xext.xe_segpos, 0) == -1) {
X printf ("error seeking to segment table\n");
X return -1;
X }
X while (fread (&xseg, sizeof xseg, 1, fp) == 1 && xext.xe_segsize > 0) {
X if (xseg.xs_type == XS_TSYMS)
X break;
X
X xext.xe_segsize -= sizeof xseg;
X }
X if (xext.xe_segsize <= 0) {
X printf ("error locating symbol table\n");
X return -1;
X }
X if (fseek (fp, xseg.xs_filpos, 0) == -1) {
X printf ("error seeking to symbol table\n");
X return -1;
X }
X while (ftell (fp) < xseg.xs_filpos + xseg.xs_psize) {
X if (nsymbols == maxsymbols) {
X if (nsymbols == 0) {
X maxsymbols = 10;
X symbols = (struct xlist **)
X malloc (maxsymbols * sizeof *symbols);
X } else {
X maxsymbols *= 2;
X symbols = (struct xlist **) realloc (symbols,
X maxsymbols * sizeof *symbols);
X }
X }
X if (symbols == 0) {
X printf ("error allocating memory for symbol table\n");
X return -1;
X }
X fread (&xlist, sizeof (struct xlist3), 1, fp);
X for (cp = buf;*cp++ = getc (fp);)
X ;
X
X xlist.xl_name = strdup (buf);
X
X symbols[nsymbols] = (struct xlist *)
X malloc (sizeof (struct xlist));
X *(symbols[nsymbols++]) = xlist;
X }
X fclose (fp);
X return 0;
X}
X
Xlong
Xsym2addr (sym, type)
Xchar *sym;
Xint type;
X{
X int i;
X int symbol_type;
X
X if (symbols == 0)
X return -1;
X
X for (i = 0;i < nsymbols;i++) {
X symbol_type = symbols[i]->xl_type & S_TYPE;
X
X if (type == 0 && strcmp (sym, symbols[i]->xl_name) == 0)
X return symbols[i]->xl_value;
X
X if (type == symbol_type && ! strcmp (sym, symbols[i]->xl_name))
X return symbols[i]->xl_value;
X }
X return -1;
X}
X
Xchar *
Xaddr2sym (addr, diffp, type)
Xlong addr;
Xlong *diffp;
Xint type;
X{
X int guess = -1;
X int i;
X int symbol_type;
X
X if (symbols == 0)
X return 0;
X
X for (i = 0;i < nsymbols;i++) {
X symbol_type = symbols[i]->xl_type & S_TYPE;
X
X if (type == 0 && addr >= symbols[i]->xl_value &&
X (guess == -1 ||
X symbols[i]->xl_value > symbols[guess]->xl_value))
X guess = i;
X
X if (type == symbol_type && addr >= symbols[i]->xl_value &&
X (guess == -1 ||
X symbols[i]->xl_value > symbols[guess]->xl_value))
X guess = i;
X }
X if (guess == -1)
X return 0;
X
X *diffp = addr - symbols[guess]->xl_value;
X return symbols[guess]->xl_name;
X}
X
Xchar *
Xtext2sym (addr, diffp)
Xlong addr;
Xlong *diffp;
X{
X return addr2sym (addr, diffp, S_TEXT);
X}
X
Xchar *
Xdata2sym (addr, diffp)
Xlong addr;
Xlong *diffp;
X{
X char *sym1, *sym2;
X long diff1, diff2;
X
X sym1 = addr2sym (addr, &diff1, S_DATA);
X sym2 = addr2sym (addr, &diff2, S_BSS);
X
X if (sym1 && sym2) {
X if (diff1 < diff2) {
X *diffp = diff1;
X return sym1;
X } else {
X *diffp = diff2;
X return sym2;
X }
X }
X if (sym1) {
X *diffp = diff1;
X return sym1;
X } else if (sym2) {
X *diffp = diff2;
X return sym2;
X } else
X return 0;
X}
X
Xprtextaddr (cp)
Xchar *cp;
X{
X long addr;
X char *sym;
X long diff;
X
X if (expr (&cp, &addr)) {
X printf ("error in '%.15s'\n", cp);
X return;
X }
X if (! (sym = text2sym (addr, &diff))) {
X printf ("no text address for %d (%x)\n", addr, addr);
X return;
X }
X if (diff != 0)
X printf ("%d (%x) = %s+%d (%x)\n", addr, addr, sym, diff, diff);
X else
X printf ("%d (%x) = %s\n", addr, addr, sym);
X}
X
Xprdataaddr (cp)
Xchar *cp;
X{
X long addr;
X char *sym;
X long diff;
X
X if (expr (&cp, &addr)) {
X printf ("error in '%.15s'\n", cp);
X return;
X }
X if (! (sym = data2sym (addr, &diff))) {
X printf ("no data address for %d (%x)\n", addr, addr);
X return;
X }
X if (diff != 0)
X printf ("%d (%x) = %s+%d (%x)\n", addr, addr, sym, diff, diff);
X else
X printf ("%d (%x) = %s\n", addr, addr, sym);
X}
X
Xprsymbol (cp)
Xchar *cp;
X{
X char buf[BUFSIZ];
X long addr;
X int type;
X char *sym;
X
X buf[0] = '_';
X strcpy (buf + 1, cp);
X
X if ((addr = sym2addr (sym = buf + 1, type = S_TEXT)) == -1 &&
X (addr = sym2addr (sym = buf, type = S_TEXT)) == -1 &&
X (addr = sym2addr (sym = buf + 1, type = S_DATA)) == -1 &&
X (addr = sym2addr (sym = buf, type = S_DATA)) == -1 &&
X (addr = sym2addr (sym = buf + 1, type = S_BSS)) == -1 &&
X (addr = sym2addr (sym = buf, type = S_BSS)) == -1) {
X printf ("%s not found\n", cp);
X return;
X }
X printf ("%s (%s) = %d (%x)\n", sym, type == S_TEXT ? "text":
X (type == S_DATA ? "data":
X (type == S_BSS ? "bss":"unknown")), addr, addr);
X}
X
X#ifdef TEST
Xmain (argc, argv)
Xint argc;
Xchar **argv;
X{
X int i;
X long addr;
X long diff;
X char *sym;
X char buf[BUFSIZ];
X char *cp;
X
X if (initsyms (argv[1]))
X exit (1);
X
X printf ("allocated %d slots for %d symbols\n", maxsymbols, nsymbols);
X
X while (gets (buf)) {
X if (buf[0] >= '0' && buf[0] <= '9') {
X cp = buf;
X if (expr (&cp, &addr)) {
X printf ("error at '%.15s'\n", cp);
X continue;
X }
X sym = addr2sym (addr, &diff, 0);
X printf ("name of %s (%x) is %s+%d\n",
X buf, addr, sym, diff);
X } else {
X addr = sym2addr (buf, 0);
X printf ("address of %s is %d (%x)\n", buf, addr, addr);
X }
X }
X}
X#endif
SHAR_EOF
if test 6139 -ne "`wc -c < 'syms.c'`"
then
echo shar: "error transmitting 'syms.c'" '(should have been 6139 characters)'
fi
fi
echo shar: "extracting 'devs.c'" '(3101 characters)'
if test -f 'devs.c'
then
echo shar: "will not over-write existing file 'devs.c'"
else
sed 's/^X//' << \SHAR_EOF > 'devs.c'
X/*
X * Copyright 1991, John F. Haugh II
X * An unpublished work.
X * All rights reserved.
X *
X * Permission is granted to copy and create derivative works for any
X * non-commercial purpose, provided this copyright notice is preserved
X * in all copies of source code, or included in human readable form
X * and conspicuously displayed on all copies of object code or
X * distribution media.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)devs.c 2.1 07:14:51 2/27/91";
X#endif
X
X#include <sys/types.h>
X#include <sys/conf.h>
X#include <stdio.h>
X#include "crash.h"
X
Xextern char *text2sym();
Xextern char *data2sym();
X
Xchar *
Xkgets (off, buf)
Xlong off;
Xchar *buf;
X{
X char c;
X char *orig = buf;
X
X l_lseek (kmemfd, off, 0);
X while (r_read (kmemfd, &c, 1) == 1 && (*buf++ = c))
X ;
X
X if (c)
X return 0;
X else
X return orig;
X}
X
Xpr1cdev (cmajor)
Xint cmajor;
X{
X char *sym;
X char buf[BUFSIZ];
X long diff;
X
X if (cmajor < 0 || cmajor >= Cdevcnt) {
X printf ("value (%d) out of range\n", cmajor);
X return;
X }
X printf ("cdevsw[%d]: ", cmajor);
X
X if (Cdevsw[cmajor].d_name)
X printf ("%s ", kgets (Cdevsw[cmajor].d_name, buf));
X else
X printf ("(unnamed) ");
X
X if (sym = text2sym (Cdevsw[cmajor].d_open, &diff))
X printf ("%s ", sym);
X else
X printf ("0x%x ", Cdevsw[cmajor].d_open);
X
X if (sym = text2sym (Cdevsw[cmajor].d_close, &diff))
X printf ("%s ", sym);
X else
X printf ("0x%x ", Cdevsw[cmajor].d_close);
X
X if (sym = text2sym (Cdevsw[cmajor].d_read, &diff))
X printf ("%s ", sym);
X else
X printf ("0x%x ", Cdevsw[cmajor].d_read);
X
X if (sym = text2sym (Cdevsw[cmajor].d_write, &diff))
X printf ("%s ", sym);
X else
X printf ("0x%x ", Cdevsw[cmajor].d_write);
X
X if (sym = text2sym (Cdevsw[cmajor].d_ioctl, &diff))
X printf ("%s ", sym);
X else
X printf ("0x%x ", Cdevsw[cmajor].d_ioctl);
X
X if (sym = data2sym (Cdevsw[cmajor].d_ttys, &diff))
X printf ("%s ", sym);
X else
X printf ("0x%x ", Cdevsw[cmajor].d_ttys);
X
X putchar ('\n');
X}
X
Xprcdevs (list, cnt)
Xint *list;
Xint cnt;
X{
X int i;
X
X if (list == 0) {
X for (i = 0;i < Cdevcnt;i++) {
X if (Cdevsw[i].d_name == 0)
X continue;
X
X pr1cdev (i);
X }
X } else
X for (i = 0;i < cnt;i++) {
X pr1cdev (list[i]);
X }
X}
X
Xpr1bdev (bmajor)
Xint bmajor;
X{
X char *sym;
X char buf[BUFSIZ];
X long diff;
X
X if (bmajor < 0 || bmajor >= Bdevcnt) {
X printf ("value (%d) out of range\n", bmajor);
X return;
X }
X printf ("bdevsw[%d]: ", bmajor);
X
X if (Bdevsw[bmajor].d_name)
X printf ("%s ", kgets (Bdevsw[bmajor].d_name, buf));
X else
X printf ("(unnamed) ");
X
X if (sym = text2sym (Bdevsw[bmajor].d_open, &diff))
X printf ("%s ", sym);
X else
X printf ("0x%x ", Bdevsw[bmajor].d_open);
X
X if (sym = text2sym (Bdevsw[bmajor].d_close, &diff))
X printf ("%s ", sym);
X else
X printf ("0x%x ", Bdevsw[bmajor].d_close);
X
X if (sym = text2sym (Bdevsw[bmajor].d_strategy, &diff))
X printf ("%s ", sym);
X else
X printf ("0x%x ", Bdevsw[bmajor].d_strategy);
X
X
X putchar ('\n');
X}
X
Xprbdevs (list, cnt)
Xint *list;
Xint cnt;
X{
X int i;
X
X if (list == 0) {
X for (i = 0;i < Bdevcnt;i++) {
X if (Bdevsw[i].d_name == 0)
X continue;
X
X pr1bdev (i);
X }
X } else
X for (i = 0;i < cnt;i++) {
X pr1bdev (list[i]);
X }
X}
SHAR_EOF
if test 3101 -ne "`wc -c < 'devs.c'`"
then
echo shar: "error transmitting 'devs.c'" '(should have been 3101 characters)'
fi
fi
echo shar: "extracting 'expr.c'" '(4388 characters)'
if test -f 'expr.c'
then
echo shar: "will not over-write existing file 'expr.c'"
else
sed 's/^X//' << \SHAR_EOF > 'expr.c'
X/*
X * Copyright 1991, John F. Haugh II
X * All rights reserved.
X *
X * Permission is granted to copy and create derivative works for any
X * non-commercial purpose, provided this copyright notice is preserved
X * in all copies of source code, or included in human readable form
X * and conspicuously displayed on all copies of object code or
X * distribution media.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)expr.c 2.2 09:26:00 2/27/91";
X#endif
X
X#include <ctype.h>
X
X/*
X * number - parse numbers
X */
X
Xstatic int
Xnumber (cpp, result)
Xchar **cpp;
Xlong *result;
X{
X char *cp = *cpp;
X char *ep;
X char buf[101];
X int i;
X int base;
X long value;
X
X if (! isdigit (*cp))
X return -1;
X
X if (*cp == '0' && *(cp + 1) == 'x') {
X base = 16;
X cp += 2;
X for (i = 0;*cp && isxdigit (*cp);)
X buf[i++] = *cp++;
X } else if (*cp == '0') {
X base = 8;
X cp += 1;
X for (i = 0;*cp && *cp >= '0' && *cp <= '7';)
X buf[i++] = *cp++;
X } else {
X base = 10;
X for (i = 0;*cp && isdigit (*cp);)
X buf[i++] = *cp++;
X }
X buf[i] = '\0';
X *result = strtol (buf, &ep, base);
X if (*ep) {
X *cpp = *cpp + (ep - buf);
X return -1;
X }
X *cpp = cp;
X return 0;
X}
X
X/*
X * symbol - lookup symbol names
X */
X
Xstatic int
Xsymbol (cpp, result)
Xchar **cpp;
Xlong *result;
X{
X char *cp = *cpp;
X char buf[101]; /* yes, the longest symbol is 100 characters */
X int i;
X
X buf[0] = '_'; i = 1;
X
X if (*cp != '_' && ! isalpha (*cp))
X return -1;
X
X while (i < 100 && (*cp == '_' || isalpha (*cp) || isdigit (*cp)))
X buf[i++] = *cp++;
X
X if (i == 100) {
X *cpp = cp;
X return -1;
X }
X buf[i++] = '\0';
X
X if ((*result = sym2addr (buf + 1, 0)) == -1 &&
X (*result = sym2addr (buf, 0)) == -1)
X return -1;
X
X *cpp = cp;
X return 0;
X}
X
X/*
X * term - parse terms
X *
X * <term> ::= '(' <expr> ')' | <number> | <symbol> | '-' <number
X */
X
Xstatic int
Xterm (cpp, result)
Xchar **cpp;
Xlong *result;
X{
X char *cp = *cpp;
X
X while (*cp && isspace (*cp))
X cp++;
X
X if (isdigit (*cp)) {
X if (number (&cp, result)) {
X *cpp = cp;
X return -1;
X }
X } else if (*cp == '_' || isalpha (*cp)) {
X if (symbol (&cp, result)) {
X *cpp = cp;
X return -1;
X }
X } else if (*cp == '(') {
X cp++;
X if (expr (&cp, result)) {
X *cpp = cp;
X return -1;
X }
X while (*cp && isspace (*cp))
X cp++;
X
X if (*cp != ')') {
X *cpp = cp;
X return -1;
X }
X cp++;
X } else if (*cp == '-') {
X cp++;
X if (number (&cp, result)) {
X *cpp = cp;
X return -1;
X }
X *result = - *result;
X } else
X return -1;
X
X *cpp = cp;
X return 0;
X}
X
X/*
X * prod - parse expressions
X *
X * <prod> ::= <prod> ('*' | '/' | '%' | '&') <term> | <term>
X */
X
Xstatic int
Xprod (cpp, result)
Xchar **cpp;
Xlong *result;
X{
X long left, right;
X enum { star, slash, percent, ampersand } op;
X char *cp = *cpp;
X
X while (*cp && isspace (*cp))
X cp++;
X
X if (term (&cp, &left)) {
X *cpp = cp;
X return -1;
X }
X while (*cp) {
X while (*cp && isspace (*cp))
X cp++;
X
X if (! *cp)
X break;
X
X switch (*cp) {
X case '+':
X case '-':
X case '|':
X case '^':
X case ')': *cpp = cp;
X *result = left;
X return 0;
X case '*': op = star; break;
X case '/': op = slash; break;
X case '%': op = percent; break;
X case '&': op = ampersand; break;
X default: *cpp = cp;
X return -1;
X }
X cp++;
X if (term (&cp, &right)) {
X *cpp = cp;
X return -1;
X }
X switch (op) {
X case star: left *= right; break;
X case slash: if (right == 0)
X return -1;
X left /= right; break;
X case percent: if (right == 0)
X return -1;
X left %= right; break;
X case ampersand: left &= right; break;
X }
X }
X *result = left;
X *cpp = cp;
X return 0;
X}
X
X/*
X * expr - parse expressions
X *
X * <expr> ::= <expr> ('+' | '-' | '|' | '^') <prod> | <prod>
X */
X
Xint
Xexpr (cpp, result)
Xchar **cpp;
Xlong *result;
X{
X long left, right;
X enum { plus, minus, pipe, caret } op;
X char *cp = *cpp;
X
X while (*cp && isspace (*cp))
X cp++;
X
X if (prod (&cp, &left)) {
X *cpp = cp;
X return -1;
X }
X while (*cp) {
X while (*cp && isspace (*cp))
X cp++;
X
X if (! *cp)
X break;
X
X switch (*cp) {
X case '+': op = plus; break;
X case '-': op = minus; break;
X case '|': op = pipe; break;
X case '^': op = caret; break;
X default: *cpp = cp;
X return -1;
X }
X cp++;
X if (prod (&cp, &right)) {
X *cpp = cp;
X return -1;
X }
X switch (op) {
X case plus: left += right; break;
X case minus: left -= right; break;
X case pipe: left |= right; break;
X case caret: left ^= right; break;
X }
X }
X *result = left;
X *cpp = cp;
X return 0;
X}
SHAR_EOF
if test 4388 -ne "`wc -c < 'expr.c'`"
then
echo shar: "error transmitting 'expr.c'" '(should have been 4388 characters)'
fi
fi
echo shar: "extracting 'od.c'" '(3597 characters)'
if test -f 'od.c'
then
echo shar: "will not over-write existing file 'od.c'"
else
sed 's/^X//' << \SHAR_EOF > 'od.c'
X/*
X * Copyright 1991, John F. Haugh II
X * An unpublished work.
X * All rights reserved.
X *
X * Permission is granted to copy and create derivative works for any
X * non-commercial purpose, provided this copyright notice is preserved
X * in all copies of source code, or included in human readable form
X * and conspicuously displayed on all copies of object code or
X * distribution media.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)od.c 2.1 07:15:25 2/27/91";
X#endif
X
X#define SKIP_SPACE(cp) while (*cp && isspace (*cp)) *cp++
X
X#include <sys/types.h>
X#include <ctype.h>
X#include "crash.h"
X
Xod (string)
Xchar *string;
X{
X long base;
X long length = 0;
X char *cp;
X char *fmt = 0;
X int i, j;
X unsigned char c;
X unsigned short s;
X long l;
X
X for (cp = string;*cp && *cp != ',';cp++)
X ;
X
X if (*cp == ',')
X *cp++ = '\0';
X
X if (expr (&string, &base))
X return -1;
X else
X string = cp;
X
X if (*string) {
X SKIP_SPACE(string);
X
X for (cp = string;*cp && *cp != ',';cp++)
X ;
X
X if (*cp == ',')
X *cp++ = '\0';
X
X if (expr (&string, &length))
X return -1;
X else
X string = cp;
X
X SKIP_SPACE(string);
X if (*string)
X fmt = string;
X else
X fmt = "x";
X } else {
X length = 16;
X fmt = "x";
X }
X if (strlen (fmt) > 1) {
X while (length > 0) {
X printf ("%0.8x", base);
X
X for (cp = fmt;length > 0 && *cp;) {
X if (l_lseek (memfd, base, 0) == -1)
X return;
X
X switch (*cp) {
X case 'a':
X printf ("\n%0.8x", base);
X break;
X case 'n':
X printf ("\n ");
X break;
X case 'c':
X case 'b':
X if (r_read (memfd, &c, 1) == -1)
X return;
X base += 1;
X length -= 1;
X if (*fmt == 'b' ||
X (c <= ' ' || c > '~'))
X printf (" %0.2x", c);
X else
X printf (" '%c", c);
X break;
X case 'd':
X case 'o':
X case 'x':
X if (r_read (memfd, &s, 2) == -1)
X return;
X base += 2;
X length -= 2;
X printf (*cp == 'd' ? " %5u":
X (*cp == 'o' ? " %6o":
X " %0.4x"), s);
X break;
X case 'D':
X case 'O':
X case 'X':
X if (r_read (memfd, &l, 4) == -1)
X return;
X base += 4;
X length -= 4;
X printf (*cp == 'D' ? " %9lu":
X (*cp == 'O' ? " %11lo":
X " %0.8lx"), l);
X break;
X case 'Y':
X if (r_read (memfd, &l, 4) == -1)
X return;
X base += 4;
X printf (" %.24s", ctime (&l));
X break;
X }
X cp++;
X }
X putchar ('\n');
X }
X } else {
X while (length > 0) {
X printf ("%0.8x", base);
X
X for (i = 0;i < 16 && length > 0;) {
X if (l_lseek (memfd, base, 0) == -1)
X return;
X
X switch (*fmt) {
X case 'c':
X case 'b':
X if (r_read (memfd, &c, 1) == -1)
X return;
X base += 1;
X i += 1;
X length -= 1;
X if (*fmt == 'b' ||
X (c <= ' ' || c > '~'))
X printf (" %0.2x", c);
X else
X printf (" '%c", c);
X break;
X case 'd':
X case 'o':
X case 'x':
X if (r_read (memfd, &s, 2) == -1)
X return;
X base += 2;
X i += 2;
X length -= 2;
X printf (*fmt == 'd' ? " %5u":
X (*fmt == 'o' ? " %6o":
X " %0.4x"), s);
X break;
X case 'D':
X case 'O':
X case 'X':
X if (r_read (memfd, &l, 4) == -1)
X return;
X base += 4;
X i += 4;
X length -= 4;
X printf (*fmt == 'D' ? " %9lu":
X (*fmt == 'O' ? " %11lo":
X " %0.8lx"), l);
X break;
X case 'Y':
X if (r_read (memfd, &l, 4) == -1)
X return;
X base += 4;
X i += 16;
X length -= 4;
X printf (" %.24s", ctime (&l));
X break;
X }
X }
X putchar ('\n');
X }
X if (i != 16)
X printf ("%0.8x", base);
X }
X}
SHAR_EOF
if test 3597 -ne "`wc -c < 'od.c'`"
then
echo shar: "error transmitting 'od.c'" '(should have been 3597 characters)'
fi
fi
echo shar: "extracting 'ttys.c'" '(4724 characters)'
if test -f 'ttys.c'
then
echo shar: "will not over-write existing file 'ttys.c'"
else
sed 's/^X//' << \SHAR_EOF > 'ttys.c'
X/*
X * Copyright 1991, John F. Haugh II
X * An unpublished work.
X * All rights reserved.
X *
X * Permission is granted to copy and create derivative works for any
X * non-commercial purpose, provided this copyright notice is preserved
X * in all copies of source code, or included in human readable form
X * and conspicuously displayed on all copies of object code or
X * distribution media.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)ttys.c 2.1 09:26:58 2/27/91";
X#endif
X
X#include <sys/types.h>
X#include <sys/termio.h>
X#include <sys/tty.h>
X#include <ctype.h>
X#include "crash.h"
X
Xstruct bits {
X char *b_name;
X int b_value;
X int b_mask;
X};
X
Xstruct bits ibits[] = {
X "ignbrk", IGNBRK, IGNBRK,
X "brkint", BRKINT, BRKINT,
X "ignpar", IGNPAR, IGNPAR,
X "parmrk", PARMRK, PARMRK,
X "inpck", INPCK, INPCK,
X "istrip", ISTRIP, ISTRIP,
X "inlcr", INLCR, INLCR,
X "igncr", IGNCR, IGNCR,
X "icrnl", ICRNL, ICRNL,
X "iuclc", IUCLC, IUCLC,
X "ixon", IXON, IXON,
X "ixany", IXANY, IXANY,
X "ixoff", IXOFF, IXOFF,
X 0, 0, 0
X};
X
Xstruct bits obits[] = {
X "opost", OPOST, OPOST,
X "olcuc", OLCUC, OLCUC,
X "onlcr", ONLCR, ONLCR,
X "ocrnl", OCRNL, OCRNL,
X "onocr", ONOCR, ONOCR,
X "onlret", ONLRET, ONLRET,
X "ofill", OFILL, OFILL,
X "ofdel", OFDEL, OFDEL,
X "nl1", NL1, NLDLY,
X "cr1", CR1, CRDLY,
X "cr2", CR2, CRDLY,
X "cr3", CR3, CRDLY,
X "tab1", TAB1, TABDLY,
X "tab2", TAB2, TABDLY,
X "tab3", TAB3, TABDLY,
X "bs1", BS1, BSDLY,
X "vt1", VT1, VTDLY,
X "ff1", FF1, FFDLY,
X 0, 0, 0
X};
X
Xstruct bits cbits[] = {
X "b50", B50, CBAUD,
X "b75", B75, CBAUD,
X "b110", B110, CBAUD,
X "b134", B134, CBAUD,
X "b150", B150, CBAUD,
X "b200", B200, CBAUD,
X "b300", B300, CBAUD,
X "b600", B600, CBAUD,
X "b1200", B1200, CBAUD,
X "b1800", B1800, CBAUD,
X "b2400", B2400, CBAUD,
X "b4800", B4800, CBAUD,
X "b9600", B9600, CBAUD,
X "exta", EXTA, CBAUD,
X "extb", EXTB, CBAUD,
X "cs6", CS6, CSIZE,
X "cs7", CS7, CSIZE,
X "cs8", CS8, CSIZE,
X "cstopb", CSTOPB, CSTOPB,
X "cread", CREAD, CREAD,
X "parenb", PARENB, PARENB,
X "parodd", PARODD, PARODD,
X "hupcl", HUPCL, HUPCL,
X "clocal", CLOCAL, CLOCAL,
X "loblk", LOBLK, LOBLK,
X "ctsflow", CTSFLOW,CTSFLOW,
X "rtsflow", RTSFLOW,RTSFLOW,
X 0, 0, 0
X};
X
Xstruct bits lbits[] = {
X "isig", ISIG, ISIG,
X "icanon", ICANON, ICANON,
X "xcase", XCASE, XCASE,
X "echo", ECHO, ECHO,
X "echoe", ECHOE, ECHOE,
X "echok", ECHOK, ECHOK,
X "echonl", ECHONL, ECHONL,
X "noflsh", NOFLSH, NOFLSH,
X 0, 0, 0
X};
X
Xstruct bits state[] = {
X "timeout", TIMEOUT, TIMEOUT,
X "wopen", WOPEN, WOPEN,
X "isopen", ISOPEN, ISOPEN,
X "tblock", TBLOCK, TBLOCK,
X "carr_on", CARR_ON, CARR_ON,
X "busy", BUSY, BUSY,
X "oaslp", OASLP, OASLP,
X "iaslp", IASLP, IASLP,
X "ttstop", TTSTOP, TTSTOP,
X "extproc", EXTPROC, EXTPROC,
X "tact", TACT, TACT,
X "clesc", CLESC, CLESC,
X "rto", RTO, RTO,
X "ttiow", TTIOW, TTIOW,
X "ttxon", TTXON, TTXON,
X "ttxoff", TTXOFF, TTXOFF,
X 0, 0, 0
X};
X
Xstatic void
Xprbits (table, value)
Xstruct bits *table;
Xint value;
X{
X int i;
X
X for (i = 0;table[i].b_name;i++)
X if (table[i].b_value == (table[i].b_mask & value))
X printf (" %s", table[i].b_name);
X}
X
Xprttys (string)
Xchar *string;
X{
X char *cp;
X char *device;
X int items[100];
X int cnt;
X long addr;
X long diff;
X int i, j;
X struct tty tty;
X
X while (*string && isspace (*string))
X string++;
X
X device = string;
X
X while (*string && *string != ',')
X string++;
X
X if (*string == ',') {
X *string++ = '\0';
X while (*string && isspace (*string))
X string++;
X }
X if (expr (&device, &addr)) {
X printf ("error in tty address at '%.15s'\n", device);
X return;
X }
X if (! *string) {
X printf ("no ttys requested\n");
X return;
X }
X if ((cnt = list (string, items, 100)) <= 0)
X return;
X
X *string++ = '\0';
X
X if (device = data2sym (addr, &diff))
X if (diff % sizeof tty != 0)
X device = (char *) 0;
X
X for (i = 0;i < cnt;i++) {
X if (l_lseek (memfd, addr + items[i] * sizeof tty, 0) == -1 ||
X r_read (memfd, &tty, sizeof tty) != sizeof tty)
X return;
X
X if (i != 0)
X putchar ('\n');
X
X if (device)
X printf ("%s[%d]:\n", device,
X diff / sizeof tty + items[i]);
X else
X printf ("tty[%d]:\n", items[i]);
X
X printf ("iflag:"); prbits (ibits, tty.t_iflag); putchar ('\n');
X printf ("oflag:"); prbits (obits, tty.t_oflag); putchar ('\n');
X printf ("cflag:"); prbits (cbits, tty.t_cflag); putchar ('\n');
X printf ("lflag:"); prbits (lbits, tty.t_lflag); putchar ('\n');
X printf ("state:"); prbits (state, tty.t_state); putchar ('\n');
X printf ("line disc: %d\n", tty.t_line);
X printf ("pgrp: %d\n", tty.t_pgrp);
X
X printf ("special characters:");
X for (j = 0;j < NCC;j++) {
X if (tty.t_cc[j] <= ' ' && tty.t_cc[j] >= 0)
X printf (" ^%c", tty.t_cc[j] + '@');
X else if (tty.t_cc[j] >= '~')
X printf (" %0.2x", tty.t_cc[j]);
X else
X printf (" '%c", tty.t_cc[j]);
X }
X putchar ('\n');
X }
X}
SHAR_EOF
if test 4724 -ne "`wc -c < 'ttys.c'`"
then
echo shar: "error transmitting 'ttys.c'" '(should have been 4724 characters)'
fi
fi
echo shar: "extracting 'crash.h'" '(1267 characters)'
if test -f 'crash.h'
then
echo shar: "will not over-write existing file 'crash.h'"
else
sed 's/^X//' << \SHAR_EOF > 'crash.h'
X/*
X * Copyright 1988, 1991, John F. Haugh II
X * All rights reserved.
X *
X * Permission is granted to copy and create derivative works for any
X * non-commercial purpose, provided this copyright notice is preserved
X * in all copies of source code, or included in human readable form
X * and conspicuously displayed on all copies of object code or
X * distribution media.
X *
X * @(#)crash.h 2.1 07:08:34 2/27/91
X */
X
Xextern int memfd;
Xextern int kmemfd;
Xextern int swapfd;
X
X#define NM_V 0
X#define NM_FILE 1
X#define NM_INODE 2
X#define NM_PROC 3
X#define NM_TEXT 4
X#define NM_MOUNT 5
X#define NM_BUFFER 6
X#define NM_SWPLO 7
X#define NM_TIME 8
X#define NM_LBOLT 9
X#define NM_UTSNAME 10
X#define NM_USER 11
X#define NM_CDEVCNT 12
X#define NM_CDEVSW 13
X#define NM_BDEVCNT 14
X#define NM_BDEVSW 15
X#define NM_NAMES 16
X
Xextern struct xlist namelist[];
Xextern struct var v;
Xextern struct file *files;
Xextern struct inode *inodes;
Xextern struct text *texts;
Xextern struct proc *procs;
Xextern struct mount *mounts;
Xextern struct buf *bufs;
Xextern struct buf *bufstart;
Xextern struct user user;
Xextern daddr_t swplo;
Xextern time_t ktime;
Xextern time_t klbolt;
Xextern struct utsname utsname;
Xextern int Cdevcnt;
Xextern int Bdevcnt;
Xextern struct cdevsw *Cdevsw;
Xextern struct bdevsw *Bdevsw;
SHAR_EOF
if test 1267 -ne "`wc -c < 'crash.h'`"
then
echo shar: "error transmitting 'crash.h'" '(should have been 1267 characters)'
fi
fi
exit 0
# End of shell archive
--
John F. Haugh II UUCP: ...!cs.utexas.edu!rpp386!jfh
Ma Bell: (512) 832-8832 Domain: jfh at rpp386.cactus.org
"I've never written a device driver, but I have written a device driver manual"
-- Robert Hartman, IDE Corp.
More information about the Alt.sources
mailing list