/******************************************************************************* * Dump.cpp Dump contents of old HP640000 floppy disks * T.Barnaby, BEAM Ltd, 30/4/04 ******************************************************************************* */ #include #include #include #include #include #include #include #pragma pack(1) #define BLKSIZE 2048 struct Block { unsigned short prevBlk; unsigned char data[2044]; unsigned short nextBlk; }; struct DirEntry { unsigned char mode; char name[15]; unsigned short v2; unsigned short blk; unsigned short va[6]; }; class FileSys { public: FileSys(); ~FileSys(); // High level routines int open(char* fileName); int lsDir(); int copyFiles(); // Low level routines int copyFile(int blkNo, char* name); int getBlock(int blkNo, Block& blk); int read(int pos, void* buf, int bytes); void printBlock(int blkno); // Data members char* obuf; int obufSize; }; void convName(char* name){ while(*name){ if(*name == ' ') *name = '_'; name++; } // Remove trailing spaces name--; while(*name == '_'){ *name = '\0'; name--; } } FileSys::FileSys(){ obuf = 0; obufSize = 0; } FileSys::~FileSys(){ delete obuf; obuf = 0; } int FileSys::open(char* fileName){ int b; FILE* file; int nblks = 160; obufSize = nblks * BLKSIZE; obuf = new char [obufSize]; if((file = fopen(fileName, "r")) == NULL){ fprintf(stderr, "Unable to open: %s\n", fileName); return 1; } for(b = 0; b < nblks; b++){ if(fread(&obuf[b*BLKSIZE], 1, BLKSIZE, file) != BLKSIZE){ fprintf(stderr, "File read error: %s\n", fileName); return 1; } } printf("Read: %d blocks\n", b); return 0; } int FileSys::read(int pos, void* buf, int nbytes){ // printf("ReadPos: %d\n", pos); memcpy(buf, &obuf[pos], nbytes); return nbytes; } void FileSys::printBlock(int blkno){ Block block; unsigned char* p = block.data; unsigned char abuf[32]; int n; getBlock(blkno, block); printf("Loc: %x Blk: %d Prev: %d Next: %d\n", blkno * BLKSIZE, blkno, block.prevBlk, block.nextBlk); #ifndef ZAP for(n = 0; n < sizeof(block.data); n++, p++){ printf("%2.2x ", *p); if(isprint(*p)) abuf[n % 16] = *p; else abuf[n % 16] = '.'; if((n % 16) == 15){ abuf[16] = '\0'; printf("\t%s\n", abuf); } } abuf[(n % 16)] = '\0'; printf("\t\t\t%s\n", abuf); #else for(n = 0; n < sizeof(block.data); n++, p++){ printf("%c", *p); } #endif } int FileSys::getBlock(int blkNo, Block& blk){ int err; err = read((blkNo) * BLKSIZE, &blk, BLKSIZE); blk.prevBlk = ntohs(blk.prevBlk); blk.nextBlk = ntohs(blk.nextBlk); return err; } int FileSys::copyFile(int blkNo, char* name){ Block blk; unsigned char* p = blk.data; int nbytes; FILE* file; if((file = fopen(name, "w")) == NULL){ fprintf(stderr, "Unable to open: %s for writing\n", name); return 1; } getBlock(blkNo, blk); // printBlock(blkNo); p++; nbytes = *p++ * 2; while(nbytes){ while(nbytes--){ if(p >= &blk.data[sizeof(blk.data)]){ if(blk.nextBlk == 0xFFFF){ fprintf(stderr, "File read error\n"); return 1; } getBlock(blk.nextBlk, blk); // printBlock(blk.nextBlk); p = blk.data; } fwrite(p++, 1, 1, file); } if(p >= &blk.data[sizeof(blk.data)]){ if(blk.nextBlk == 0xFFFF){ fprintf(stderr, "File read error\n"); return 1; } getBlock(blk.nextBlk, blk); // printBlock(blk.nextBlk); p = blk.data; } p++; nbytes = *p++ * 2; fwrite("\n", 1, 1, file); } } int FileSys::lsDir(){ int err; DirEntry dir[192]; DirEntry* de = dir; int n; char name[16]; read(68 * BLKSIZE, dir, sizeof(dir)); for(n = 0; n < 192; n++){ if(de->mode){ strncpy(name, de->name, sizeof(name)); name[sizeof(name) - 1] = '\0'; convName(name); printf("Mode: %x Name: %-16s Blk: %d\n", de->mode, name, ntohs(de->blk)); } de++; } return err; } int FileSys::copyFiles(){ int err; DirEntry dir[192]; DirEntry* de = dir; int n; char name[16]; read(68 * BLKSIZE, dir, sizeof(dir)); for(n = 0; n < 192; n++){ if(de->mode){ strncpy(name, de->name, sizeof(name)); name[sizeof(name) - 1] = '\0'; convName(name); printf("Mode: %x Name: %-16s Blk: %d\n", de->mode, name, ntohs(de->blk)); copyFile(ntohs(de->blk), name); } de++; } return err; } void scanFile(FileSys& fileSys, int blkNo){ Block blk; int b = blkNo; // Scan back while(b != 0xFFFF){ fileSys.getBlock(b, blk); printf("ReadBlkPrev: %d Prev: %d Next: %d\n", b, blk.prevBlk, blk.nextBlk); b = blk.prevBlk; } // Scan forward b = blkNo; while(b != 0xFFFF){ fileSys.getBlock(b, blk); printf("ReadBlk: %d Prev: %d Next: %d\n", b, blk.prevBlk, blk.nextBlk); b = blk.nextBlk; } } void usage(){ fprintf(stderr, "Usage: hp64000Copy \n"); } int main(int argc, char** argv){ char* fileName; FileSys fileSys; if(argc != 2){ usage(); return 1; } fileName = argv[1]; printf("\nAccessing HP64000 FileSystem in: %s\n", fileName); fileSys.open(fileName); // Normal operation fileSys.copyFiles(); // Test routines // fileSys.printBlock(8); // fileSys.printBlock(123); // fileSys.printBlock(21); // fileSys.lsDir(); // fileSys.copyFile(123, "t"); // scanFile(fileSys, 8); // fileSys.printBlock(8); // fileSys.dirList("/", ""); // fileSys.dirList("/", "out"); return 0; }