Annotation of researchv10no/cmd/dumpcatch.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *             D U M P  C A T C H
                      3:  *
                      4:  * This program examines kernel memory through /dev/kmem, and looks at
                      5:  * the dump buffers in the dumpld line discipline (see /usr/sys/dev/dumpld.c).
                      6:  * The command takes a filename prefix.  For any active dump buffers,
                      7:  * an identification code is appended to the filename prefix, and everything
                      8:  * placed into the buffer by dumpld is appended to the resulting file.
                      9:  * The identification code is 'M.m.ls', where 'M' is the major device number,
                     10:  * 'm' is the minor device number, 'l' is the line-discipline number (from 0),
                     11:  * and 's' (side) is 'w' for the writer or 'r' for the reader.  If the old
                     12:  * version of dumpld is installed in the kernel, the identification code is
                     13:  * just the buffer number (from 0).
                     14:  *
                     15:  *
                     16:  * Written by Kurt Gollhardt  (Nirvonics, Inc.)
                     17:  * Last update Sun Mar 31 03:32:57 1985
                     18:  *
                     19:  */
                     20: 
                     21: #include <stdio.h>
                     22: #include <ctype.h>
                     23: #include <nlist.h>
                     24: #include <sys/types.h>
                     25: #include <sys/dumpl.h>
                     26: #include <sys/stream.h>
                     27: 
                     28: #define getme(s, kind, off, type)  _get(kind, off, 1, sizeof(type), &s)
                     29: #define getarray(s, kind, n, type) _get(kind, 0, n, sizeof(type), s)
                     30: #define getspace(s, n, type)  s = (type *)malloc((n) * sizeof(type))
                     31: 
                     32: struct nlist nl[] = {
                     33: #define _ndumpbuf   0
                     34:      {"_ndumpbuf"},
                     35: #define _dumpld     1
                     36:      {"_dumpld"},
                     37: #define _dumpver    2
                     38:      {"_dumpver"},
                     39: #define _dumpinf   3
                     40:      {"_dumpinf"},
                     41:      {""}
                     42: };
                     43: 
                     44: #define MEMFILE     "/dev/kmem"
                     45: #define SYMFILE     "/unix"
                     46: 
                     47: struct blockdump {
                     48:      struct dumpheader  h;
                     49:      char               buf[1024];
                     50:      char               *fillp;
                     51: };
                     52: 
                     53: int  mem;
                     54: struct dumpld      *dumpld;
                     55: struct dumpinf     *dumpinf;
                     56: struct blockdump    *bdump;
                     57: int  ndumpbuf, dumpver;
                     58: FILE **file;
                     59: char **readp;
                     60: 
                     61: char *malloc(), *calloc();
                     62: 
                     63: 
                     64: main(ac, av)
                     65:      char *av[];
                     66: {
                     67:      struct dumpld  *di;
                     68:      register int   i;
                     69: 
                     70:      if (ac != 2) {
                     71:           fprintf(stderr, "Usage: %s filename_prefix\n", av[0]);
                     72:          exit(1);
                     73:      }
                     74: 
                     75:      if (access(SYMFILE, 0) < 0) {
                     76:           perror(SYMFILE);
                     77:          exit(2);
                     78:      }
                     79:      if ((mem = open(MEMFILE, 0)) < 0) {
                     80:           perror(MEMFILE);
                     81:          exit(2);
                     82:      }
                     83: 
                     84:      nlist(SYMFILE, nl);
                     85:      if (nl[_ndumpbuf].n_value == 0) {
                     86:           fprintf(stderr, "No dumpld line-discipline present\n");
                     87:          exit(5);
                     88:      }
                     89:      getme(ndumpbuf, _ndumpbuf, 0, int);
                     90: 
                     91:      if (nl[_dumpver].n_value == 0)
                     92:          dumpver = 0;
                     93:      else
                     94:          getme(dumpver, _dumpver, 0, int);
                     95: 
                     96:      getspace(dumpld, ndumpbuf, struct dumpld);
                     97:      getspace(readp, ndumpbuf, char *);
                     98:      file = (FILE **)calloc(sizeof(FILE *), ndumpbuf);
                     99:      if (dumpld == NULL || file == NULL || readp == NULL) {
                    100:           fprintf(stderr, "Can't allocate enough memory\n");
                    101:          exit(3);
                    102:      }
                    103:      if (dumpver > 0) {
                    104:          getspace(dumpinf, ndumpbuf, struct dumpinf);
                    105:          getspace(bdump, ndumpbuf, struct blockdump);
                    106:          if (dumpinf == NULL || bdump== NULL) {
                    107:               fprintf(stderr, "Can't allocate enough memory\n");
                    108:               exit(3);
                    109:          }
                    110:          for (i = 0; i < ndumpbuf; ++i)
                    111:               bdump[i].fillp = (char *)&bdump[i];
                    112:      }
                    113: 
                    114:      for (;;) {
                    115:           getarray(dumpld, _dumpld, ndumpbuf, struct dumpld);
                    116:          if (dumpver > 0)
                    117:               getarray(dumpinf, _dumpinf, ndumpbuf, struct dumpinf);
                    118:          for (di = dumpld; di < &dumpld[ndumpbuf]; di++)
                    119:               if (di->base != NULL) {
                    120:                    if (file[di - dumpld] == 0)
                    121:                         new_file(di - dumpld, av[1]);
                    122:                     if (readp[di - dumpld] != di->fillp)
                    123:                         read_buf(di - dumpld, di);
                    124:                }
                    125:      }
                    126: }
                    127: 
                    128: 
                    129: new_file(i, prefix)
                    130:      char *prefix;
                    131: {
                    132:      char filename[100];
                    133: 
                    134:      if (dumpver == 0)
                    135:          sprintf(filename, "%s%d", prefix, i);
                    136:      else
                    137:          sprintf(filename, "%s%d.%d.%d%c", prefix, major(dumpinf[i].dev),
                    138:                              minor(dumpinf[i].dev), i/2, (i&1 ? 'w' : 'r'));
                    139:      if ((file[i] = fopen(filename, "a")) == NULL) {
                    140:           perror(filename);
                    141:          exit(4);
                    142:      }
                    143: 
                    144:      readp[i] = dumpld[i].base;
                    145: }
                    146: 
                    147: 
                    148: read_buf(i, di)
                    149:      register struct dumpld   *di;
                    150: {
                    151:      if (di->fillp < readp[i]) {
                    152:           dump(readp[i], (di->base + di->size) - readp[i], file[i], i);
                    153:          readp[i] = di->base;
                    154:      }
                    155:      if (di->fillp > readp[i]) {
                    156:           dump(readp[i], di->fillp - readp[i], file[i], i);
                    157:          readp[i] = di->fillp;
                    158:      }
                    159:      fflush(file[i]);
                    160: }
                    161: 
                    162: 
                    163: char buf[BUFSIZ];
                    164: 
                    165: dump(loc, n, stream, i)
                    166:      char *loc;
                    167:      FILE *stream;
                    168: {
                    169:      int  count;
                    170: 
                    171:      if (dumpver > 0)
                    172:          return fancy_dump(loc, n, stream, i);
                    173: 
                    174:      while (n > 0) {
                    175:           count = (n > BUFSIZ ? BUFSIZ : n);
                    176:          getarray(buf, loc, count, char);
                    177:          fwrite(buf, 1, count, stream);
                    178:          n -= count;
                    179:          loc += count;
                    180:      }
                    181: }
                    182: 
                    183: 
                    184: fancy_dump(loc, count, stream, i)
                    185:      char      *loc;
                    186:      FILE      *stream;
                    187: {
                    188:      register struct blockdump    *bd = &bdump[i];
                    189:      register int   n, have_block;
                    190: 
                    191:      while (count > 0) {
                    192:          have_block = 0;
                    193:          n = bd->buf - bd->fillp;
                    194:          if (n <= 0) {
                    195:               have_block = 1;
                    196:               n += bd->h.count;
                    197:          }
                    198:          if (count < n) {
                    199:               have_block = 0;
                    200:               n = count;
                    201:          }
                    202:          if (n > 0) {
                    203:               getarray(bd->fillp, loc, n, char);
                    204:               loc += n;  bd->fillp += n;
                    205:               count -= n;
                    206:          }
                    207:          if (have_block) {
                    208:               dump_block(bd, stream);
                    209:               bd->fillp = (char *)bd;
                    210:          }
                    211:      }
                    212: }
                    213: 
                    214: 
                    215: #define BYTE_PER_LINE   16
                    216: 
                    217: dump_block(bd, stream)
                    218:      struct blockdump   *bd;
                    219:      FILE               *stream;
                    220: {
                    221:      print_type(bd->h.type, stream);
                    222:      fprintf(stream, ":%s", (bd->h.count == 0 ? "\n" : ""));
                    223:      bd->fillp = bd->buf;
                    224:      while (bd->h.count > 0) {
                    225:          dump_line(bd, stream);
                    226:          bd->h.count -= BYTE_PER_LINE;
                    227:          bd->fillp += BYTE_PER_LINE;
                    228:      }
                    229: }
                    230: 
                    231: 
                    232: dump_line(bd, stream)
                    233:      struct blockdump   *bd;
                    234:      FILE               *stream;
                    235: {
                    236:      register int   n, byte;
                    237:      register char  *p;
                    238:      char ascii[BYTE_PER_LINE+1];
                    239: 
                    240:      putc('\t', stream);
                    241:      p = bd->fillp;
                    242:      for (n = 0; n < BYTE_PER_LINE; n++) {
                    243:          byte = *p++ & 0xFF;
                    244:          if (n < bd->h.count)
                    245:               fprintf(stream, "%02x ", byte);
                    246:          else
                    247:               fprintf(stream, "   ");
                    248:          ascii[n] = (n < bd->h.count && isprint(byte) ? byte : '.');
                    249:      }
                    250:      ascii[BYTE_PER_LINE] = '\0';
                    251:      fprintf(stream, "!%s!\n", ascii);
                    252: }
                    253: 
                    254: 
                    255: char *mtype_names[] = {
                    256:      "DATA",   "BREAK",         "HANGUP", "DELIM",  "ECHO",   "ACK",    "IOCTL",
                    257:      "DELAY",  "CTL",   "PASS",   "SIGNAL", "FLUSH",  "STOP",   "START",
                    258:      "IOCACK", "IOCNAK", "CLOSE",  "YDEL",   "NDEL",   "IOCWAIT",NULL
                    259: };
                    260: int  mtype_codes[] = {
                    261:      M_DATA,   M_BREAK,         M_HANGUP, M_DELIM,  M_ECHO,   M_ACK,    M_IOCTL,
                    262:      M_DELAY,  M_CTL,   M_PASS,   M_SIGNAL, M_FLUSH,  M_STOP,   M_START,
                    263:      M_IOCACK, M_IOCNAK, M_CLOSE,  M_YDEL,   M_NDEL,   M_IOCWAIT,0
                    264: };
                    265: 
                    266: print_type(type, stream)
                    267:      FILE      *stream;
                    268: {
                    269:      register int   i;
                    270: 
                    271:      for (i = 0; mtype_names[i] != NULL; ++i)
                    272:          if (mtype_codes[i] == type) {
                    273:               fputs(mtype_names[i], stream);
                    274:               return;
                    275:          }
                    276: 
                    277:      fprintf(stream, "[%02x]", type);
                    278: }
                    279: 
                    280: 
                    281: _get(addr, off, n, size, loc)
                    282: unsigned long addr;
                    283: char *loc;
                    284: {
                    285:      if (addr < sizeof(nl)/sizeof(nl[0]))
                    286:           addr = nl[addr].n_value;
                    287:      addr += off*size;
                    288:      lseek(mem, addr, 0);
                    289:      read(mem, loc, n*size);
                    290:      return(addr);
                    291: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.