|
|
researchv8 Dan Cross
#include <nlist.h>
#include "/usr/sys/h/param.h"
#include <ctype.h>
#include "/usr/sys/h/stream.h"
#include "/usr/sys/h/inode.h"
#include "/usr/sys/h/conf.h"
struct nlist nl[] ={
#define QNL 0
{"_queue"},
#define BLNL 1
{"_cblock"},
#define STNL 2
{"_streams"},
#define QFNL 3
{"_qfreelist"},
#define DTNL 4
{"_dtlinfo"},
#define DKPNL 5
{ "_dkpinfo" },
#define NBLOCK 6
{ "_Nblock"},
#define NQUEUE 7
{ "_Nqueue"},
#define NSTREAM 8
{ "_Nstream"},
#define C 9
{"_cblockC"},
#define M 10
{"_cblockM"},
#define N4 11
{"_Nblk4"},
#define N16 12
{"_Nblk16"},
#define N64 13
{"_Nblk64"},
#define NBIG 14
{"_Nblkbig"},
#define DZNL 15
{"_dzinfo"},
#define CDKPNL 16
{ "_cdkpinfo" },
{ "" },
};
struct qinit **qall;
char *ball;
char *core = "/dev/mem";
char *sys = "/unix";
int mem;
int Nblock;
int Nqueue;
int Nstream;
struct dt {
char nack;
char cack;
char nchar;
char state;
short lastecho;
struct queue *queue;
};
struct dkp {
struct queue *rdq; /* associated read queue */
struct block *inp; /* msg being collected */
struct block *inpe; /* end of msg */
short state; /* flags */
short trx; /* # bytes in trailer being collected */
short indata; /* # bytes in message being collected */
u_char iseq; /* last good input sequence number */
u_char lastecho; /* last echo/rej sent */
u_char WS; /* first non-accepted message */
u_char WACK; /* first non-received message */
u_char WNX; /* next message to be sent */
u_char XW; /* size of xmit window */
u_char timer; /* timeout for xmit */
u_char outcnt; /* count output chars cor char mode */
u_char trbuf[3]; /* trailer being collected */
struct block *xb[8]; /* the xmit window buffer */
};
#define DK_OPEN 01
#define DK_LCLOSE 02
#define DK_RCLOSE 04
#define DK_XCHARMODE 010
#define DK_RCHARMODE 0200
#define DK_OPENING 020
struct dz {
short state;
short flags;
struct block *oblock;
struct queue *rdq;
char board;
char line;
char speed;
};
#define getme(s, kind, off, type) _get(kind, off, sizeof(type), &s)
struct flags {
int flag;
char *name;
};
struct flags stflags[] = {
IOCWAIT, "IOC",
RSLEEP, "RSLEEP",
WSLEEP, "WSLEEP",
HUNGUP, "HUNGUP",
RSEL, "RSEL",
WSEL, "WSEL",
EXCL, "EXCL",
STWOPEN, "WOPEN",
0
};
struct flags qflags[] = {
QUSE, "use",
QREADR, "read",
QNOENB, "noenb",
QENAB, "enab",
QWANTR, "wantr",
QWANTW, "wantw",
QFULL, "full",
QDELIM, "delim",
QBIGB, "bigb",
0
};
#define CLOG1 01
#define CLOG2 02
#define STOPDT 04
#define USEDT 010
struct flags dtflags[] = {
CLOG1, "clog1",
CLOG2, "clog2",
STOPDT, "stop",
USEDT, "use",
0
};
struct flags dkpflags[] = {
DK_OPEN, "open",
DK_LCLOSE, "lclose",
DK_RCLOSE, "rclose",
DK_XCHARMODE, "xcharmode",
DK_RCHARMODE, "rcharmode",
DK_OPENING, "opening",
0
};
#define DZEXIST 01
#define DZISOPEN 02
#define DZWOPEN 04
#define DZTIME 010
#define DZCARR 020
#define DZSTOP 040
#define DZHUPCL 0100
struct flags dzflags[] = {
DZEXIST, "exists",
DZISOPEN, "open",
DZWOPEN, "wopen",
DZTIME, "time",
DZCARR, "carrier",
DZSTOP, "stop",
DZHUPCL, "hupcl",
0
};
int vflag;
int sflag;
int mflag;
main(argc, argv)
char **argv;
{
struct queue q;
struct block b;
struct stdata s;
int i;
int nq = 0;
int blkcur[4],blkmin[4];
int b4, b16, b64, bBIG;
for (;;argc--, argv++) {
if (argc>1 && strcmp(argv[1], "-v")==0) {
vflag++;
continue;
}
if (argc>1 && strcmp(argv[1], "-m")==0) {
mflag++;
continue;
}
if (argc>1 && strcmp(argv[1], "-V")==0) {
vflag = 2;
continue;
}
if (argc>1 && strcmp(argv[1], "-s")==0) {
sflag++;
continue;
}
break;
}
if (argc>1)
sys = argv[1];
if (argc>2)
core = argv[2];
nlist(sys, nl);
mem = open(core, 0);
if (mem<0) {
printf("can't open %s\n", core);
exit(1);
}
getme(blkcur[0], C, 0, blkcur);
getme(blkmin[0], M, 0, blkmin);
getme(b4, N4, 0, b4);
getme(b16, N16, 0, b16);
getme(b64, N64, 0, b64);
getme(bBIG, NBIG, 0, int);
getme(Nqueue, NQUEUE, 0, int);
getme(Nstream, NSTREAM, 0, int);
getme(Nblock, NBLOCK, 0, int);
printf("blocks max: %.0f%% (%d,%d,%d,%d)\n",
100.*(Nblock-blkmin[0]-blkmin[1]-blkmin[2])/Nblock,
b4-blkmin[0], b16-blkmin[1], b64-blkmin[2], bBIG-blkmin[3]);
ball = (char *)malloc(Nblock*sizeof(char));
qall = (struct qinit **)malloc(Nqueue*sizeof(struct queue *));
for (i=0; i<Nblock; i++)
ball[i] = 0;
for (i=0; i<Nqueue; i++) {
getme(q, QNL, i, struct queue);
if (q.flag==0)
qall[i] = 0;
else {
qall[i] = q.qinfo;
nq++;
}
}
for (i=0; i<Nstream; i++) {
pstream(i);
}
for (i=0; i<Nqueue; i++) {
if (qall[i])
printf("Loose queue %d, info %x\n", i, qall[i]);
}
printf("%d queues in use\n", nq);
bfreecount();
nq = 0;
for (i=0; i<Nblock; i++)
if (ball[i]==0) {
struct block b;
if (mflag) {
getme(b, BLNL, i, struct block);
pblock(&b);
}
nq++;
}
if (!sflag)
printf("%d blocks missing\n", nq);
nq = 0;
for (i=0; i<Nblock; i++) {
if (ball[i]==0 && nq < 5) {
printf("%x\n", (struct block *)nl[BLNL].n_value+i);
nq++;
}
}
}
pstream(i)
{
struct stdata s;
struct queue rq, wq;
struct inode ino;
struct queue *rqp, *wqp;
struct stdata *sp;
struct streamtab st, st1, st2, st3;
int d;
int forward = 1;
sp = (struct stdata *)getme(s, STNL, i, struct stdata);
if (s.wrq==NULL)
return;
if (!sflag)
printf("\nstream %d: ", i);
getme(ino, s.inode, 0, struct inode);
d = ino.i_un.i_rdev;
if (!sflag) {
printf("dev %d,%d ", major(d), minor(d));
printf("count %d ", s.count);
flags(stflags, s.flag);
if (vflag)
printf(" pgrp %d", s.pgrp);
printf("\n");
}
wqp = (struct queue *)getme(wq, s.wrq, 0, struct queue);
rqp = (struct queue *)getme(rq, RD(s.wrq), 0, struct queue);
if ((struct stdata *)rq.ptr != sp)
printf("rq ptr? = %x\n", rq.ptr);
getme(st, DTNL, 0, struct streamtab);
getme(st1, DKPNL, 0, struct streamtab);
getme(st3, CDKPNL, 0, struct streamtab);
getme(st2, DZNL, 0, struct streamtab);
for (;;) {
d = rqp - (struct queue *)nl[QNL].n_value;
if (d<0 || d>=Nqueue)
printf("?");
else
qall[d] = 0;
d = wqp - (struct queue *)nl[QNL].n_value;
if (d<0 || d>=Nqueue)
printf("?");
else
qall[d] = 0;
if (!sflag) {
printf(" RQ %x: ", rqp);
flags(qflags, rq.flag);
if (vflag)
printf(" ptr %x, inf %x", rq.ptr, rq.qinfo);
printf("\n");
pblocks(&rq);
printf(" WQ %x: ", wqp);
flags(qflags, wq.flag);
if (vflag)
printf(" ptr %x, inf %x", wq.ptr, wq.qinfo);
printf("\n");
pblocks(&wq);
if (wq.qinfo == st.wrinit)
pdtline(&wq);
if (wq.qinfo == st1.wrinit || wq.qinfo == st3.wrinit)
dkpline(&wq);
if (wq.qinfo == st2.wrinit)
dzfacts(&wq);
}
if (forward) {
if (wq.next == NULL)
break;
wqp = (struct queue *)
getme(wq, wq.next, 0, struct queue);
if (wq.flag&QREADR) {
printf(" <>\n");
forward = 0;
rqp = wqp;
rq = wq;
wqp = (struct queue *)
getme(wq, WR(rqp), 0, struct queue);
} else
rqp = (struct queue *)
getme(rq, RD(wqp), 0, struct queue);
} else {
if (rq.next == NULL)
break;
rqp = (struct queue *)
getme(rq, rq.next, 0, struct queue);
if ((rq.flag&QREADR) == 0) {
printf(" <>\n");
forward = 1;
wqp = rqp;
wq = rq;
rqp = (struct queue *)
getme(rq, RD(wqp), 0, struct queue);
} else
wqp = (struct queue *)
getme(wq, WR(rqp), 0, struct queue);
}
}
}
pdtline(q)
register struct queue *q;
{
struct dt dt;
getme(dt, q->ptr, 0, struct dt);
printf(" nack %o cack %o nchar %d lastecho %o q %lx ", dt.nack,dt.cack,
dt.nchar, dt.lastecho, dt.queue);
flags(dtflags, dt.state);
printf("\n");
}
dzfacts(q)
register struct queue *q;
{
struct dz dz;
getme(dz, q->ptr, 0, struct dz);
printf(" DZ: ");
flags(dzflags, dz.state);
printf("\n");
}
dkpline(q)
register struct queue *q;
{
struct dkp dkp;
register i;
getme(dkp, q->ptr, 0, struct dkp);
printf(" WS %o WACK %o WNX %o iseq %o; ", dkp.WS, dkp.WACK,
dkp.WNX, dkp.iseq);
flags(dkpflags, dkp.state);
printf("\n ");
for (i=0; i<8; i++)
printf(" %x", dkp.xb[i]);
printf("\n");
}
pblocks(q)
register struct queue *q;
{
struct block b, *bp;
int nb = 0;
u_char buf[512];
register i, bno;
bp = q->first;
for (i = 0; i < 1000; i++) {
if (bp==NULL)
break;
bno = bp - (struct block *)nl[BLNL].n_value;
nb++;
baccount(bno);
getme(b, bp, 0, struct block);
if (vflag && (i<10 || vflag>1))
pblock(&b);
bp = b.next;
}
if (i>=10)
printf("(gave up) ");
if (nb > 0)
printf(" %d blocks\n", nb);
}
pblock(bp)
register struct block *bp;
{
register u_char *cp;
register i = 0;
u_char buf[1024];
printf(" %.3o:", bp->type);
cp = buf;
getme(buf[0], bp->rptr, 0, buf);
while (bp->rptr < bp->wptr) {
if (i >= 16) {
printf("\n ");
i = 0;
}
if (*cp<040 || *cp>=0177)
printf(" %.3o ", *cp);
else
printf("%c", *cp);
cp++;
bp->rptr++;
i++;
}
printf("\n");
}
flags(fp, w)
register struct flags *fp;
{
int any = 0;
while (fp->name) {
if (fp->flag&w) {
if (any)
printf(", ");
any++;
printf("%s", fp->name);
}
fp++;
}
}
_get(addr, off, size, loc)
unsigned long addr;
char *loc;
{
if (addr < 20)
addr = nl[addr].n_value;
addr += off*size;
lseek(mem, addr&0x7fffffff, 0);
read(mem, loc, size);
return(addr);
}
bfreecount()
{
struct block b;
struct block *bp;
register i;
for (i=0; i<3; i++) {
getme(bp, QFNL, i, struct block *);
while (bp) {
baccount(bp - (struct block *)nl[BLNL].n_value);
getme(b, bp, 0, struct block);
bp = b.next;
}
}
}
baccount(bno)
{
if (bno < 0 || bno >= Nblock)
printf("funny block %d\n", bno);
else if (ball[bno])
printf("dup block %d\n", bno);
else
ball[bno]++;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.