/* Program to massage a captured DMP file into a .DSK (or other binary) file. To make the dump, use a terminal program to capture the output from the following RSX command sequence: >INS $DMP >DMO ddu:/DEV/LOCK=V (only needed if ddu: is system disk) >MOU ddu:/FOR (needed if ddu: is *not* the system disk) >DMP TI:=ddu:/BL:0/WD By John Wilson . 03/07/99 JMBW Created (for reading octal dumps via E11 console). 07/19/99 JMBW Modified for DMP /WD (word hex dump, nice & concise). 07/31/99 JMBW Cleaned up for release. */ #include char lbuf[81]; unsigned char obuf[8192]; int optr=0; FILE *in, *out; /* parse octal value from next n chars */ unsigned long octal(char **p,int n) { unsigned long v=0UL; char c; while(n--) { c=*((*p)++); /* get next dig */ if(c<'0'||c>'7') { /* must be octal */ *p=NULL; return(0UL); } v=(v<<3)|(c-'0'); /* add it in */ } return(v); } /* as above, variable size field */ unsigned long voctal(char **p) { unsigned long v=0UL; char c; int ok=0; for(;;) { c=**p; /* get next dig */ if(c<'0'||c>'7') { /* must be octal */ if(ok) break; *p=NULL; return(0UL); } v=(v<<3)|(c-'0'); /* add it in */ (*p)++; ok=1; /* got a digit */ } return(v); } /* parse hex value from next n chars */ unsigned long hex(char **p,int n) { unsigned long v=0UL; char c; while(n--) { c=*((*p)++); /* get next dig */ if(c>='0'&&c<='9') /* digit */ v=(v<<4)|(c-'0'); /* add it in */ else if(c>='A'&&c<='F') /* letter A-F (*not* LC) */ v=(v<<4)|(c-'A'+0x0A); else { /* something else, illegal */ *p=NULL; return(0UL); } } return(v); } /* make sure next n characters match a fixed string */ int match(char **p,char *q) { register char c; while(*q) { c=*((*p)++); /* get next char */ if(c>='a'&&c<='z') c&=~040; /* convert to UC */ if(c!=*q++) return(0); /* no match */ } return(1); /* made it all the way through */ } main(int argc,char **argv) { unsigned long addr, data, block, line, temp; static unsigned char bytes[16]; int n; char *p; if(argc!=3) { fprintf(stderr,"Usage: %s infile outfile\n",argv[0]); exit(1); } /* open input file */ if((in=fopen(argv[1],"r"))==NULL) { perror("opening input file"); exit(1); } /* open output file */ if((out=fopen(argv[2],"wb"))==NULL) { perror("opening output file"); exit(1); } line=0UL; /* nothing read yet */ block=0UL; /* assume block 0 */ addr=0UL; /* start of block */ for(;;) { /* get next line */ if(fgets(lbuf,sizeof(lbuf),in)==NULL) { if(ferror(in)) { fprintf(stderr, "?File read error at line %ld\n", line); goto err; } else break; } line++; /* try it as a block heading */ p=lbuf; if(match(&p,"\t\t LOGICAL BLOCK ")) { /* looks good, parse block number */ temp=voctal(&p); if(p==NULL) goto next; if(!match(&p,",")) goto next; temp=(temp<<16)|octal(&p,6); if(p==NULL) goto next; /* should be the next block in sequence */ if(temp!=block) { fprintf(stderr, "?Block sequence error at line %ld\n", line); goto err; } /* should have finished all 512 bytes of prev blk */ if(addr!=0) { fprintf(stderr, "?Incomplete preceding block at line %ldn", line); goto err; } } else { /* nope, try it as 8 hex words and a hex address */ p=lbuf; for(n=16;n;n-=2) { temp=hex(&p,4); /* get a # */ if(p==NULL) goto next; bytes[n-2]=temp&0xFF; /* save 2 bytes */ bytes[n-1]=temp>>8; if(!match(&p," ")) /* blank follows */ goto next; /* (even on 8th) */ } if(!match(&p,"\t")) /* tab */ goto next; temp=hex(&p,4); /* addr follows */ if(p==NULL) goto next; /* make sure it's the next line in sequence */ if(temp!=addr) { fprintf(stderr, "?Data sequence error at line %ld\n", line); goto err; } /* write the 16 bytes to output file buffer */ for(n=0;n<16;n++) { obuf[optr++]=bytes[n]; if(optr==sizeof(obuf)) { if(fwrite(obuf,1,optr,out)!=optr) { perror("?Error writing file"); goto err; } optr=0; } } /* prepare for next data line */ addr+=0x10; /* bump to next line */ if(addr==512) { /* wrap past end of block */ addr=0; block++; } } next: ; } /* should have ended on a block boundary */ if(addr!=0) { fprintf(stderr, "?Incomplete final block (next seq = %04lX, blk=%ld)\n", addr,block); exit(1); } /* tell them what happened */ fprintf(stderr,"Total blocks written: %ld\n",block); /* flush buffer */ if(optr) { if(fwrite(obuf,1,optr,out)!=optr) { perror("fwrite"); exit(1); } } fclose(in); fclose(out); exit(0); err: fclose(in); fclose(out); exit(1); }