/* Format and interpret the error log file */ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/utsname.h> #ifdef vax #include <sys/mba.h> #endif #include <sys/map.h> #include <sys/elog.h> #include <sys/err.h> #include <sys/erec.h> #include <time.h> #define writout() ((page<=limit) && (mode==PRINT)) #define major(x) (int)((unsigned)(x>>8)&0377) #define minor(x) ((int)x&0377) #define araysz(x) ((sizeof(x)/sizeof(x[0]))-1) #define readrec(x) (fread(&ercd.ebb.block,\ (e_hdr.e_len - sizeof(struct errhdr)),1,x) ) char Nl [1]; #ifdef vax #define FORM "%08X" #define FORM2 "%08X\n" #else #define FORM "%06o" #define FORM2 "%16lo\n" #endif #define NULS Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl #define INAUG "0301080077" /* roughly the inception of error logging [mmddhhmmyy] */ #define WDLEN 16 #define MINREC 8 #define MAXREC 74 #define DEVADR ((physadr)(0160000)) #define MAXLEN 66 #define MAXSTR 40 #define NMAJOR 16 #define PGLEN 60 #define MBAREG 5 #define INT 15 #define MEM 14 #define YES 1 #define NO 0 #define PRINT 1 #define NOPRINT 0 #define DSEC 3 /* 2**DSEC is the number of logical partitions on RP03/4/5/6 as defined in the device driver. */ /* Space needed for each block device in detail report. */ int pneed[9] = {31,31,31,24,25,29,25,28,31}; /* NMAJOR devices of 9 possible logical units */ struct sums { long soft; long hard; long totalio; long misc; long missing; } sums[NMAJOR][9]; union ercd { struct estart start; struct eend end; struct etimchg timchg; struct econfchg confchg; struct estray stray; struct eparity parity; struct eb { struct eblock block; unsigned short reginf [30]; } ebb; } ercd; struct errhdr e_hdr; int dmsize []; int MAJ; int MIN; int page=1; int print; int mode = NOPRINT; int line; int n = 0; int aflg; int dflg; int fflg; int Unix = 1; int parsum; int straysum; int limit = 10000; int optdev = 0; long readerr = 0; FILE *file; time_t atime; time_t stime = 0L; time_t etime = 017777777777L; time_t fftime = 017777777777L; time_t ltime = 0L; char interp [MAXSTR]; char choice [MAXSTR]; long tloc; char cbuf[]; #ifdef vax struct vaxreg { char *regnam; char *bitcod [WDLEN*2]; }; #endif struct regs { char *regname; char *bitcode [WDLEN]; }; char *htime[20]; char *header = "SYSTEM ERROR REPORT"; char *hd1 = "System Error Report - Selected Items"; char *hd2 = "Summary Error Report"; /* Must be same order as "true" major device numbers */ char *dev[] = { "RK05", "RP03", "RF11", "TU10", "TC11", "RP04/5/6", "TU16", "RS03/4", "RL01", 0 }; /* Register names and bit mnemonics for each */ /* register and bit to be interpreted on detail report. */ struct regs rkregs [] = { "RKDS",Nl,Nl,Nl,Nl,Nl,"WPS",Nl,Nl,Nl,"SIN","DRU", Nl,Nl,Nl,Nl,Nl, "RKER","WCE","CSE","","","","NXS","NXC","NXD","TE","DLT", "NXM","PGE","SKE","WLO","OVR","DRE", "RKCS",NULS, "RKWC",NULS, "RKBA",NULS, "RKDA",NULS, 0 }; struct regs rpregs[] = { "RPDS",Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,"SUFU",Nl, "SUSI","HNF",Nl,Nl,Nl, "RPER","DSKERR","EOP","NXME","WCE","TIMEE","CSME", "WPE","LPE","MODE","FMTE","PROG","NXS","NXT","NXC","FUV","WPV", "RPCS",NULS, "RPWC",NULS, "RPBA",NULS, "RPCA",NULS, "RPDA",NULS, 0 }; struct regs rfregs[] = { "RFCS",Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,"MXF","WLO", "NED","DPE","WCE",Nl,Nl, "RFWC",NULS, "RFBA",NULS, "RFDA",NULS, "RFDAE",Nl,Nl,Nl,Nl,Nl,"DAOVFL",Nl,"DRL",Nl,Nl,"NEM", "CTER","BTER","ATER","APE", 0 }; struct regs tmregs [] = { "TMER",Nl,Nl,"WRL",Nl,Nl,Nl,Nl,"NXM","BTE","RLE","EOT", "BGL","PAE","CRE",Nl,"ILL", "TMCS",NULS, "TMBC",NULS, "TMBA",NULS, "Z ",NULS, "Z ",NULS, 0 }; struct regs tcregs [] = { "TCCSR",Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,"NEX","DATM","BLKM", "SELE","ILO","MTE","PAR",Nl, "TCCM",NULS, "TCWC",NULS, "TCBA",NULS, "Z ",NULS, 0 }; #ifdef vax struct regs hpregs[] = { "HPCS1","GO","F0","F1","F2","F3","F4",Nl,Nl, Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl, "HPDS",Nl,Nl,Nl,Nl,Nl,Nl,"VV","DRY", "DPR",Nl,Nl,Nl,"MOL","PIP","ERR","ATA", "HPER1",NULS, "HPMR",NULS, "HPAS","ATA0","ATA1","ATA2","ATA3","ATA4","ATA5","ATA6","ATA7", Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl, "HPDA",NULS, "HPDT",NULS, "HPLA",NULS, "Z ",NULS, "HPOF",NULS, "HPDC",NULS, "HPCC",NULS, "HPER2",NULS, "HPER3",NULS, "HPEC1",NULS, "HPEC2",NULS, 0 }; struct regs htregs[] = { "HTCS1","GO","F0","F1","F2","F3","F4",Nl,Nl, Nl,Nl,Nl,"DVA",Nl,Nl,Nl,Nl, "HTDS","SLA","BOT","TM","IDB","SDWN","PES","SSC","DRY", "DPR",Nl,"EOT","WRL","MOL","PIP","ERR","ATA", "HTER1","ILF","ILR","RMR","CPAR","FMT","DPAR","INC/VPE", "PER/LRC","NSG","FCE","CS/ITM","NEF","DTE","OPI","UNS", "COR/CRC", "HTMR",NULS, "HTAS","ATA0","ATA1","ATA2","ATA3","ATA4","ATA5","ATA6", "ATA7",Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl, "HTFC",NULS, "HTDT",Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,"SPR",Nl,Nl,Nl,Nl,Nl, "HTCK",NULS, "HTSN",NULS, "HTTC","SS0","SS1","SS2","EVPAR","FMT0","FMT1","FMT2", "FMT3","DEN0","DEN1","DEN2",Nl,"EAODTE","TCW","FCS", "ACCL", 0 }; struct vaxreg mbareg[] = { "MBACSR",NULS,Nl,Nl,Nl,Nl,Nl,"OTMP","APU","APD",Nl,Nl, "XDF","MXE",Nl,"UXRDE","WDSE","SBIPE", "MBACR","INIT","ABRT","IE","MM",Nl,Nl,Nl,Nl,Nl,Nl,Nl, Nl,Nl,Nl,Nl,Nl,NULS, "MBASR","RDTO","IFSQTO","RDSUB","ERCON","UNVMP","MPPAR","MBDPAR", "MBEXC","MXF","WCLE","WCVE","DTL","DTABT","DTCOMP",Nl, Nl,"MATA","MCWE","NED","PGE",Nl,Nl,Nl,Nl,Nl,Nl, Nl,Nl,Nl,"CRD","NRC","DTB", "MBAVAR",NULS,NULS, "MBABCR",NULS,NULS, 0 }; #else struct regs hpregs[] = { "HPCS1",Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl, Nl,Nl,"MCPE","TRE",Nl, "HPWC",NULS, "HPBA",NULS, "HPDA",NULS, "HPCS2",Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,"MDPE","MXF","PGE", "NEM","NED","PE","WCE","DLT", "HPDS",Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl, Nl,Nl,"WRL","MOL",Nl,Nl,Nl, "HPER1","ILF","ILR","RMR","PAR","FER","WCF","ECH","HCE", "HCRC","AOE","IAE","WLE","DTE","OPI","UNS","DCK", "HPAS",NULS, "Z ",NULS, "HPDB",NULS, "HPMR",NULS, "HPDT",NULS, "Z ",NULS, "HPOF",NULS, "HPDC",NULS, "HPCC",NULS, "HPER2",NULS, "HPER3",NULS, "HPEC1",NULS, "HPEC2",NULS, "HPBAE",NULS, "HPCS3",Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl, Nl,Nl,Nl,Nl,"APE", 0 }; struct regs htregs [] = { "HTCS1",Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl, Nl,Nl,Nl,"MCPE","TRE",Nl, "HTWC",NULS, "HTBA",NULS, "HTFC",NULS, "HTCS2",Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,"MDPE","MXF","PGE", "NEM","NED","PE","WCE","DLT", "HTDS",Nl,"BOT",Nl,Nl,Nl,Nl,Nl,Nl, Nl,Nl,"EOT","WRL","MOL",Nl,Nl,Nl, "HTER","ILF","ILR","RMR","CPAR","FMT","DPAR", "INC/VPE","PEF/LRC","NSG","FCE","CS/ITM","NEF", "DTE","OPI","UNS","COR/CRC", "HTAS",NULS, "HTCK",NULS, "HTDB",NULS, "HTMR",NULS, "HTDT",NULS, "Z ",NULS, "HTTC",Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,"NRZ", "PE",Nl,Nl,Nl,Nl,Nl, "HTBAE",NULS, "HTCS3",Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl, Nl,Nl,Nl,Nl,"APE", 0 }; #endif struct regs hsregs[] = { "HSCS1",Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl, Nl,Nl,"MCPE","TRE","SC", "HSWC",NULS, "HSBA",NULS, "HSDA",NULS, "HSCS2",Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,"MDPE","MXF","PGE", "NEM","NED","PE","WCE","DLT", "HSDS",Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl, Nl,Nl,Nl,"WRL","MOL",Nl,Nl,Nl, "HSER","ILF","ILR","RMR","PAR",Nl,Nl,Nl,Nl,Nl,"AO", "IAE","WLE","DTE","OPI","UNS","DCK", "HSAS",NULS, "Z ",NULS, "HSDB",NULS, "HSMR",NULS, "Z ",NULS, "HSBAE",NULS, "HSCS3",Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl, Nl,Nl,Nl,Nl,Nl,"APE", 0 }; struct regs rlregs[] = { "RLCS",Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,Nl,"OPI","CRC","DLT/HNF","NXM","DE",Nl, "RLBS",NULS, "RLDA",NULS, "RLMP",Nl,Nl,Nl,"BH","HO","CO","HS",Nl,"DSE","VC","WGE","SPE", "SKTO","WL","CHE","WDE", 0 }; int rkblk(); int rpblk(); int rfblk(); int tmblk(); int tcblk(); int hpblk(); int htblk(); int hsblk(); int rlblk(); /* Device specification functions */ /* Must remain in same order as true major device numbers */ int (*func[]) () = { rkblk, rpblk, rfblk, tmblk, tcblk, hpblk, htblk, hsblk, rlblk, 0 }; struct regs *devregs[] = { rkregs, rpregs, rfregs, tmregs, tcregs, hpregs, htregs, hsregs, rlregs, 0 }; struct pos { unsigned flg; unsigned unit; unsigned cyl; unsigned trk; unsigned sector; } pos; /* Array order directed by MMR3 */ char *msg[] = { "User D Space Enabled", "Supervisor D Space Enabled", "Kernel D Space Enabled", Nl, "22 bit mapping Enabled", "UNIBUS MAP relocation Enabled", 0 }; char *lines [] = { /* 0*/ "\n", /* 1*/ "%s ERROR LOGGED ON %s\n", /* 2*/ " Physical Device %u\n", /* 3*/ " Logical Device %d (%2.2o)\n", /* 4*/ " Device Address ", /* 5*/ " Retry Count %u\n", /* 6*/ " Error Diagnosis %s\n", /* 7*/ " Simultaneous Bus Activity ", /* 8*/ " Registers at Error time\n", /* 9*/ " %s ", /*10*/ " Physical Buffer Start Address ", /*11*/ " Transfer Size in Bytes %11u\n", /*12*/ " Type of Transfer %8s\n", /*13*/ " Block No. in Logical File System %16ld\n", /*14*/ " I/O Type %8s\n", /*15*/ " Cylinder Requested %11u\n", /*16*/ " Track Requested %11u\n", /*17*/ " Sector Requested %11u\n", /*18*/ " Statistics on Device to date:\n", /*19*/ " No. of R/W Operations %16ld\n", /*20*/ " No. of Other Operations %16ld\n", /*21*/ " No. of Unrecorded Errors %11u\n", /*9b*/ "%o ", /*23*/ " Sector Requested %4u-%u\n", /*24*/ " Unibus Map Utilization? %3.3s\n", 0 }; char *xlines [] = { /* 0*/ "\n\nDEVICE CONFIGURATION CHANGE - %s\n", /* 1*/ " DEVICE: %s - %s\n", /* 2*/ "\n\nSTRAY INTERRUPT on %s\n", /* 3*/ " For Controller at - ", /* 4*/ " At Location ", /* 5*/ "\n\nMEMORY PARITY ERROR at %s\n", /* 6*/ " Memory Address of Error - %lo (cycle %d)\n\n", /* 7*/ " MSER %06o", /* 8*/ " MSCR %06o", /* 9*/ "\n\nTIME CHANGE ***** FROM %s", /*10*/ "\t\t TO %s \n\n\n\n", /*11*/ "\nERROR LOGGING SYSTEM SHUTDOWN - %s\n\n\n", /*12*/ "\nERROR LOGGING SYSTEM STARTED - %s \n", /*13*/ "\n\n System Profile:\n\n", /*14*/ " 11/%d Processor\n", /*15*/ "\t System Memory Size - %ld Bytes\n", /*16*/ "\n Configured with:", /*17*/ " UNIX/%s Operating System (%s)\n", /*18*/ " %s \n", 0 }; char *sumlines [] = { /* 0*/ "\n\n", /* 1*/ "%s UNIT %d \n", /* 2*/ " Hard Errors - %ld\n", /* 3*/ " Soft Errors - %ld\n", /* 4*/ " Total I/O Operations - %ld\n", /* 5*/ " Total Misc. Operations - %ld\n", /* 6*/ " No. of Errors Missed - %ld\n", /* 7*/ " Total Read Errors - %ld\n", /* 8*/ " Total Memory Parity Errors - %d\n", /* 9*/ " Total Stray Interrupts - %d\n", /*10*/ " Date of Earliest Entry: %s", /*11*/ " Date of Latest Entry: %s", /*12*/ " Error Types: %s\n", /*13*/ " Limitations: ", /*14*/ " ", 0 }; /* Correspondence of input requests to major device defines */ struct tab { char *devname ; int devnum; }; struct tab dtab[] = { "rk",RK0, "RK",RK0, "RK05",RK0, "rk05",RK0, "rp",RP0, "RP",RP0, "RP03",RP0, "rp03",RP0, "rf",RF0, "rf11",RF0, "RF",RF0, "RF11",RF0, "tm",TM0, "TM",TM0, "tu",TM0, "TU10",TM0, "mt",TM0, "tu10",TM0, "tc",TC0, "TC",TC0, "tc11",TC0, "TC11",TC0, "hp",HP0, "HP",HP0, "RP04",HP0, "rp04",HP0, "rp05",HP0, "RP05",HP0, "RP06",HP0, "rp06",HP0, "ht",HT0, "HT",HT0, "TU16",HT0, "tu16",HT0, "TJU16",HT0, "hs",HS0, "HS",HS0, "rs03",HS0, "RS03",HS0, "RS04",HS0, "rs04",HS0, "rs",HS0, "RS",HS0, "rl",RL0, "RL",RL0, "rl01",RL0, "RL01",RL0, "MEM",MEM, "mem",MEM, "int",INT, "INT",INT, 0,0 }; char *ctime(); main (argc,argv) char *argv[]; int argc; { register i,j; print = NO; while (--argc>0 && **++argv =='-') { switch (*++*argv) { case 's': /* starting at a specified time */ header = hd1; if((--argc <=0) || (**++argv == '-')) error("Date required for -s option",(char *)NULL); if(gtime(&stime,*argv)) error("Invalid Start time",*argv); break; case 'e': /* ending at a specified time */ header = hd1; if((--argc<=0) || (**++argv =='-')) error("Date required for -e option\n",(char *)NULL); if(gtime(&etime,*argv)) error("Invalid End time.",(char *)NULL); break; case 'a': /* print all devices*/ aflg++; mode = PRINT; break; case 'p': /* limit total no. of pages */ if((--argc<=0) || (**++argv == '-')) error("Page limit not supplied.\n",(char *)NULL); limit = atoi(*argv); break; case 'f': /* fatal errors */ header = hd1; fflg++; break; default: if(j=encode(*argv)) { optdev = (optdev |= j); dflg++; header = hd1; mode = PRINT; if(strlen(choice)) concat(",",choice); concat(*argv,choice); } else fprintf(stderr,"%s?\n",argv); } } for(i=0;i<NMAJOR;i++) { for(j=0;j<9;j++) { sums[i][j].hard = 0; sums[i][j].soft = 0; sums[i][j].totalio = 0; sums[i][j].misc = 0; sums[i][j].missing = 0; } } parsum=0; straysum=0; if(gtime(&atime,INAUG)) error("Invalid INAUG time",INAUG); if (argc ==0) report("/usr/adm/errfile"); else while(argc--) report(*argv++); printsum(); putft(); exit(0); } report(fp) char *fp; { if((file = fopen(fp,"r"))== NULL) { fprintf(stderr,"Cannot open %s\n",fp); return; } inithdng(); if(writout()) puthead(header); putdata(); if(writout()) putft(); return; } putdata() { while(fread(&e_hdr.e_type,sizeof(struct errhdr),1,file)) { newtry: switch(e_hdr.e_type) { case E_GOTS: setime(); up(); break; case E_GORT: setime(); up(); break; case E_STOP: setime(); down(); break; case E_TCHG: setime(); timecg(); break; case E_BLK: setime(); blk(); break; case E_STRAY: setime(); stray(); break; case E_PRTY: setime(); party(); break; case E_CCHG: cconfig(); setime(); break; default: fprintf(stderr,"%d\n",e_hdr.e_len); fprintf(stderr,"%d\n",e_hdr.e_type); readerr++; if(recov()) { goto newtry; } fprintf (stderr,"Unrecovered read error.\n"); } } return; } /* System Startup Record */ up() { register int i; if (!readrec(file)) { fprintf(stderr,"at up = %o\n",ercd.start.e_cpu); fprintf(stderr,"%o\n",ercd.start.e_mmr3); fprintf(stderr,"%ld\n",ercd.start.e_name.release); fprintf(stderr,"%s %s\n",ercd.start.e_name.release,ercd.start.e_name.sysname); readerr++; return; } if(writout()) { need(14+araysz(msg)); printf(xlines[12],ctime(&e_hdr.e_time)); printf(xlines[13]); printf(xlines[17],ercd.start.e_name.release,ercd.start.e_name.sysname); printf(xlines[14],ercd.start.e_cpu); if(ercd.start.e_syssize) { printf(xlines[15],ercd.start.e_syssize); } else line--; for(i=0;i<=araysz(msg);i++) { if(ercd.start.e_mmr3 & (1<<i)){ printf(xlines[18],msg[i]); } else line--; } printf(xlines[16]); afix(araysz(dev),(unsigned) ercd.start.e_bconf,dev); printf(lines[0]); } } /* System Shutdown Record */ down() { if(writout()) { need(5); printf(xlines[11],ctime(&e_hdr.e_time)); } } /* Time Change Record */ timecg() { if(!readrec(file)) { readerr++; return; } if(writout()) { need(8); printf(xlines[9],ctime(&e_hdr.e_time)); printf(xlines[10],ctime(&ercd.timchg.e_ntime)); } } /* Handle a MERT configuration change */ cconfig() { if (!readrec(file)) { readerr++; return; } if(writout()) { need(7); printf(xlines[0],ctime(&e_hdr.e_time)); printf(lines[0]); printf(xlines[1],dev[ercd.confchg.e_trudev], ercd.confchg.e_cflag?"Attached":"Detached"); printf(lines[0]); } } /* Stray Interrupt Record */ stray() { if (!readrec(file)) { readerr++; return; } if(!wanted()) return; if(print==YES) { need(7); if(page<=limit) { printf(xlines[2],ctime(&e_hdr.e_time)); if(ercd.stray.e_saddr < DEVADR) printf(xlines[4]); else printf(xlines[3]); printf(FORM,ercd.stray.e_saddr); printf(lines[0]); printf(lines[7]); if(ercd.stray.e_sbacty == 0) printf("None\n"); else afix(araysz(dev),(unsigned) ercd.stray.e_sbacty,dev); } } straysum++; } /* Memory Parity Record */ party() { if (!readrec(file)) { readerr++; return; } if(!wanted()) return; if(print==YES) { need(9); if(page<=limit) { printf(xlines[5],ctime(&e_hdr.e_time)); printf(xlines[6],(((long)(ercd.parity.e_parreg[1]&077))<<WDLEN) + ((long)((unsigned) ercd.parity.e_parreg[0])), (ercd.parity.e_parreg[1]>>14)&03); printf(lines[8]); printf(xlines[7],ercd.parity.e_parreg[2]); printf(lines[0]); printf(xlines[8],ercd.parity.e_parreg[3]); printf(lines[0]); } } parsum++; } /* Device Error Record */ blk() { register union ercd *z; register int i; struct regs *p; int *mbar; struct vaxreg *q; pos.flg = 0; if (!readrec(file)) { readerr++; return; } z = &ercd; MAJ=major(ercd.ebb.block.e_dev); MIN=minor(ercd.ebb.block.e_dev); if((MAJ>araysz(func)) | MAJ<0) return; if(!wanted()) return; (*func[MAJ])(); /* Increment summary totals */ if(ercd.ebb.block.e_bflags &E_ERROR) sums[MAJ][pos.unit].hard++; else sums[MAJ][pos.unit].soft++; sums[MAJ][pos.unit].totalio = ercd.ebb.block.e_stats.io_ops; sums[MAJ][pos.unit].misc = ercd.ebb.block.e_stats.io_misc; sums[MAJ][pos.unit].missing = ercd.ebb.block.e_stats.io_unlog; if(print==NO) return; need(pneed[MAJ]+ercd.ebb.block.e_nreg); if(page <= limit) { printf(lines[0]); printf(lines[1],dev[MAJ],ctime(&e_hdr.e_time)); printf(lines[2],pos.unit); printf(lines[3],MIN,MIN); printf(lines[4]); printf(FORM,ercd.ebb.block.e_regloc); printf(lines[0]); printf(lines[5],ercd.ebb.block.e_rtry); printf(lines[6],ercd.ebb.block.e_bflags&E_ERROR? "Unrecovered":"Recovered"); printf(lines[7]); if(ercd.ebb.block.e_bacty == 0) printf("None\n"); else afix(araysz(dev),(unsigned) ercd.ebb.block.e_bacty,dev); printf(lines[0]); printf(lines[8]); #ifdef vax mbar = ((int *) &z-> e_mba); q=mbareg; for(i=0;i<MBAREG;i++,mbar++,q++) { printf("\t %-6.6s %08X",q->regnam,*mbar); afix(WDLEN*2,*mbar,q->bitcod); } #endif p=devregs[MAJ]; for(i=0;i<ercd.ebb.block.e_nreg;i++,p++) { if(*p->regname != 'Z') { printf("\t %-5.5s ",p->regname); printf(FORM,ercd.ebb.reginf[i]); afix(WDLEN,ercd.ebb.reginf[i],p->bitcode); } } printf(lines[0]); printf(lines[10]); printf(FORM2,ercd.ebb.block.e_memadd); printf(lines[11],ercd.ebb.block.e_bytes); i=ercd.ebb.block.e_bflags; printf(lines[12], (i&E_NOIO)?"No-op":((i&E_READ)?"Read":"Write")); printf(lines[13],ercd.ebb.block.e_bnum); if(Unix) printf(lines[14], i&E_PHYS? "Physical":"Buffered"); else line--; /* Not valid in this implementation; the line following is inserted in its place. printf(lines[24],i&E_MAP?"Yes":"No"); */ line--; printf(lines[0]); if(pos.flg) { printf(lines[0]); if(MAJ != HS0) printf(lines[15],pos.cyl); printf(lines[16],pos.trk); if(MAJ==HS0) printf(lines[23],pos.sector,pos.sector+n); else printf(lines[17],pos.sector); printf(lines[0]); } printf(lines[0]); printf(lines[18]); printf(lines[19],ercd.ebb.block.e_stats.io_ops); printf(lines[20],ercd.ebb.block.e_stats.io_misc); printf(lines[21],ercd.ebb.block.e_stats.io_unlog); printf(lines[0]); } } rkblk() { register int m; daddr_t d; pos.flg = 1; m = MIN - 7; if(m<=0) { d = ercd.ebb.block.e_bnum; pos.unit = MIN; } else { d = (ercd.ebb.block.e_bnum/m); pos.unit = (ercd.ebb.block.e_bnum%m); } pos.cyl = d/24; pos.trk = (d%24)/12; pos.sector = (d%24)%12; } rpblk() { pos.flg=1; pos.unit = (MIN>>DSEC); pos.cyl=ercd.ebb.block.e_cyloff; pos.cyl += (ercd.ebb.block.e_bnum/(20*10)); pos.trk = (ercd.ebb.block.e_bnum%(20*10))/10; pos.sector = ((ercd.ebb.block.e_bnum%(20*10))%10); } rfblk() { pos.flg=1; pos.unit=(ercd.ebb.block.e_bnum/1024); pos.trk=((ercd.ebb.block.e_bnum%1024)/8); pos.cyl=0; pos.sector=((ercd.ebb.block.e_bnum%1024)%8); } tmblk() { pos.unit = (MIN&03); } tcblk() { pos.unit = (MIN&07); } hpblk() { pos.flg = 1; pos.unit=(MIN>>DSEC); pos.cyl = ercd.ebb.block.e_cyloff; pos.cyl += (ercd.ebb.block.e_bnum/(19*22)); pos.trk = ((ercd.ebb.block.e_bnum%(19*22))/22); pos.sector=((ercd.ebb.block.e_bnum%(19*22))%22); } htblk() { pos.unit=(MIN&03); } hsblk() { register div; if(MIN & 010) { div=32L; n=1; } else { div=16L; n=3; } pos.flg = 1; pos.cyl=0; pos.unit=MIN&07; pos.trk = (ercd.ebb.block.e_bnum/div); pos.sector = ercd.ebb.block.e_bnum%div; pos.sector *= (n+1); } rlblk() { pos.flg = 1; pos.unit = MIN; pos.trk = (ercd.ebb.block.e_bnum/(20*256)); pos.cyl = ((ercd.ebb.block.e_bnum)%(20*256))/20; pos.sector = ((ercd.ebb.block.e_bnum)%(20*256))%20; pos.sector *= 2; } cleanse(p,q) register char *p; register int q; { while(q--) *p++='\0'; } afix(a,b,c) int a; unsigned b; char **c; { register i; cleanse(interp,MAXSTR); for(i=0;i<a;i++) { if((b & (1<<i)) && (*c[i])) { if((strlen(c[i])+strlen(interp))>=MAXSTR) { concat(",",interp); printf(" %s\n\t\t\t",interp); line++; cleanse(interp,MAXSTR); } else { if(strlen(interp)) concat(",",interp); } concat(c[i],interp); } } printf(" %s\n",interp); } puthead(h) char *h; { printf("\n\n %s Prepared on %s Page %d\n\n\n\n", h,htime,page); line = 6; } inithdng() { time(&tloc); ctime(&tloc); cbuf[16] = '\0'; strcpy(htime,cbuf+4); } putft() { while (line++<MAXLEN) { putchar('\n'); } page++; } trnpg() { if( line >= MAXLEN) page++; else putft(); if(page<=limit) puthead(header); } need(a) /* acts like ".ne" command of nroff */ int a; { if( line>(PGLEN-a)) trnpg(); line += a; } gtime(tptr,pt) char *pt; time_t *tptr; { register int i; register int y, t; int d, h, m; extern int dmsize []; extern int *localtime(); extern long timezone; extern long timezone; int nt[2]; t = gpair(pt++); if(t<1 || t>12) return(1); pt++; d = gpair(pt++); if(d<1 || d>31) return (1); pt++; h = gpair(pt++); if(h == 24) { h = 0; d++; } pt++; m = gpair(pt++); if(m<0 || m>59) return (1); pt++; y = gpair(pt++); if (y<0) { time(nt); y = localtime(nt)[5]; } *tptr = 0; y += 1900; for(i=1970; i<y; i++) *tptr += dysize(i); /* Leap year */ if (dysize(y)==366 && t >= 3) *tptr += 1; while(--t) *tptr += dmsize[t-1]; *tptr += (d-1); *tptr = (*tptr *24) + h; *tptr = (*tptr*60) + m; *tptr *= 60; *tptr += timezone; if(localtime(tptr)->tm_isdst) *tptr -= 60*60; return(0); } gpair(pt) char *pt; { register int c, d; register char *cp; cp = pt; if(*cp == 0) return(-1); c = (*cp++ - '0') * 10; if (c<0 || c>100) return(-1); if(*cp == 0) return(-1); if ((d = *cp++ - '0') < 0 || d > 9) return(-1); return (c+d); } wanted () { /* Starting - ending limitations? */ if(e_hdr.e_time <stime ) return (0); if(e_hdr.e_time > etime) return (0); /* Only fatal error flag? */ if((fflg) && (e_hdr.e_type==E_BLK) && !(ercd.ebb.block.e_bflags&E_ERROR)) return(0); /* Stray interrupts or parity errors to be considered */ if((aflg) || ((e_hdr.e_type==E_STRAY)&&(optdev&(1<<INT))) || ((e_hdr.e_type==E_PRTY)&&(optdev&(1<<MEM)))) { print=YES; return (1); } /* Device chosen for consideration or printing? */ if(dflg == 0) { print=NO; return(1); } if((1<<MAJ)&optdev) { print=YES; return(1); } print=NO; return(0); } error(s1,s2) char *s1, *s2; { fprintf(stderr,"errpt:%s %s \n",s1,s2); exit(16); } recov() { struct errhdr *p,*q; int i; for(;;) { p = q = &e_hdr; q++; for(i=0;i<((sizeof(struct errhdr) /2)-1);i++) *p++ = *q++; fread(p,2,1,file); if(feof(file))return(0); if(valid()) return (1); } } valid() { switch(e_hdr.e_type) { default: return(0); case E_GOTS: case E_GORT: case E_STOP: case E_TCHG: case E_BLK: case E_STRAY: case E_CCHG: case E_PRTY: if((e_hdr.e_len <MINREC) || (e_hdr.e_len > MAXREC) ) return (0); if((e_hdr.e_time < atime) || (e_hdr.e_time > tloc)) return(0); return (1); } } printsum() { int i; header = hd2; page = 1; puthead(header); need(11); printf(sumlines[12],choice[0]?choice:"All"); printf(sumlines[13]); if(stime) { printf("On or after %s",ctime(&stime)); printf(sumlines[14]); } else line--; if(etime!=017777777777L) { printf("On or before %s",ctime(&etime)); printf(sumlines[14]); } else line--; if(fflg) { printf("Only fatal errors are printed.\n"); printf(sumlines[14]); } else line--; if(limit != 10000) printf("Printing suppressed after page %d.\n",limit); else line--; printf(lines[0]); printf(sumlines[10],ctime(&fftime)); printf(sumlines[11],ctime(<ime)); printf(lines[0]); if(readerr) printf(sumlines[7],readerr); else printf(lines[0]); printf(lines[0]); if((optdev&(1<<14)) || !(dflg) || (aflg)) { need(3); printf(lines[0]); printf(sumlines[9],straysum); printf(lines[0]); } if((optdev&(1<<13)) || !(dflg) || (aflg)) { need(3); printf(lines[0]); printf(sumlines[8],parsum); printf(lines[0]); } if ((dflg == 0)||(aflg)) { for(i=0;i<NMAJOR;i++) (prsum(i)); } else for(i=0;i<NMAJOR;i++) if(optdev & (1<<i)) prsum(i); if(line == 7) printf("No errors for this report\n"); } prsum(i) register int i; { register int j; for(j=0;j<8;j++) { if(sums[i][j].totalio) { need(10); printf(sumlines[1],dev[i],j); printf(sumlines[0]); printf(sumlines[2],sums[i][j].hard); printf(sumlines[3],sums[i][j].soft); printf(sumlines[4],sums[i][j].totalio); printf(sumlines[5],sums[i][j].misc); printf(sumlines[6],sums[i][j].missing); printf(sumlines[0]); } } } /* Associate typed name with a specific bit in "optdev" */ encode(p) char *p; { register struct tab *q; for(q=dtab;q->devname;q++) { if (!strcmp(q->devname,p)) return(1<<(q->devnum)); } return(0); } concat(a,b) register char *a,*b; { while (*b) b++; while (*b++ = *a++); } setime() { if(e_hdr.e_time < fftime) fftime = e_hdr.e_time; if(e_hdr.e_time > ltime) ltime = e_hdr.e_time; }