|
|
1.1 ! root 1: /* ! 2: ! 3: dcread.c ! 4: ! 5: This is an example how to use the dmsdos library. This program displays ! 6: a cluster on the screen in one of several formats (hexdump, text, etc.). ! 7: It can also search a file through the directories. ! 8: ! 9: Warning: This utility is not perfect. It does not check file end properly. ! 10: It does not even distinguish between files and directories. And the file ! 11: name conversion to 8.3 name space is far away from good. But example ! 12: code has never to be perfect :) ! 13: ! 14: There's also no documentation how to use this program except the usage ! 15: line. Example code never has documentation. Well, yes, you are expected ! 16: to read through the source code. :) ! 17: ! 18: */ ! 19: ! 20: #include<stdio.h> ! 21: #include<stdlib.h> ! 22: #include<string.h> ! 23: #include<ctype.h> ! 24: ! 25: #include"dmsdos.h" ! 26: #include"lib_interface.h" ! 27: ! 28: #define M_RAW 1 ! 29: #define M_HEX 0 ! 30: #define M_DIR 2 ! 31: #define M_TXT 3 ! 32: #define M_DISPLAYMASK 3 ! 33: #define M_VERBOSE 16 ! 34: ! 35: /*this is not good - but currently we have only one CVF open at a time*/ ! 36: struct super_block*sb; ! 37: Dblsb*dblsb; ! 38: ! 39: int scan(char*text) ! 40: { int v=0; ! 41: if(strncmp(text,"0x",2)==0||strncmp(text,"0X",2)==0) ! 42: sscanf(text+2,"%x",&v); ! 43: else ! 44: sscanf(text,"%d",&v); ! 45: return v; ! 46: } ! 47: ! 48: unsigned char* get_root_dir(void) ! 49: { unsigned char* data; ! 50: struct buffer_head*bh; ! 51: int i; ! 52: ! 53: data=malloc(dblsb->s_rootdirentries*32); ! 54: if(data==NULL)return NULL; ! 55: ! 56: for(i=0;i<dblsb->s_rootdirentries*32/512;++i) ! 57: { bh=raw_bread(sb,dblsb->s_rootdir+i); ! 58: if(bh==NULL){free(data);return NULL;} ! 59: memcpy(data+i*512,bh->b_data,512); ! 60: raw_brelse(sb,bh); ! 61: } ! 62: return data; ! 63: } ! 64: ! 65: int display_cluster(int nr, int mode) ! 66: { unsigned char*data; ! 67: int i,j; ! 68: ! 69: if(nr==0) ! 70: { data=get_root_dir(); ! 71: if(data==NULL)return -1; ! 72: i=dblsb->s_rootdirentries*32; ! 73: } ! 74: else ! 75: { data=malloc(dblsb->s_sectperclust*512); ! 76: if(data==NULL)return -1; ! 77: i=dmsdos_read_cluster(sb,data,nr); ! 78: if(i<0){free(data);return -1;} ! 79: } ! 80: ! 81: if(mode&M_VERBOSE)fprintf(stderr,"cluster %d has length %d\n",nr,i); ! 82: ! 83: switch(mode&M_DISPLAYMASK) ! 84: { case M_RAW: ! 85: for(j=0;j<dblsb->s_sectperclust*512;++j)printf("%c",data[j]); ! 86: break; ! 87: case M_HEX: ! 88: for(j=0;j<dblsb->s_sectperclust*512;j+=16) ! 89: { char buf[100]; ! 90: char str[100]; ! 91: ! 92: sprintf(str,"%04X:",j); ! 93: for(i=0;i<16;++i) ! 94: { sprintf(buf," %02X",data[j+i]); ! 95: strcat(str,buf); ! 96: } ! 97: strcat(str," "); ! 98: for(i=0;i<16;++i) ! 99: { if(data[i+j]>=32&&data[i+j]<=126)sprintf(buf,"%c",data[i+j]); ! 100: else strcpy(buf,"."); ! 101: strcat(str,buf); ! 102: } ! 103: ! 104: printf("%s\n",str); ! 105: } ! 106: break; ! 107: case M_DIR: ! 108: for(j=0;j<dblsb->s_sectperclust*512;j+=32) ! 109: { unsigned char*pp; ! 110: unsigned int x; ! 111: ! 112: if(data[j]==0)break; ! 113: if(data[j]==0xe5){printf("--DELETED--\n");continue;} ! 114: for(i=0;i<11;++i) ! 115: { if(i==8)printf(" "); ! 116: printf("%c",data[j+i]); ! 117: } ! 118: printf(" "); ! 119: if(data[j+11]&1)printf("R");else printf(" "); ! 120: if(data[j+11]&2)printf("H");else printf(" "); ! 121: if(data[j+11]&4)printf("S");else printf(" "); ! 122: if(data[j+11]&8)printf("V");else printf(" "); ! 123: if(data[j+11]&16)printf("D");else printf(" "); ! 124: if(data[j+11]&32)printf("A");else printf(" "); ! 125: if(data[j+11]&64)printf("?");else printf(" "); ! 126: if(data[j+11]&128)printf("?");else printf(" "); ! 127: ! 128: pp=&(data[j+22]); ! 129: x=CHS(pp); ! 130: printf(" %02d:%02d:%02d",x>>11,(x>>5)&63,(x&31)<<1); ! 131: ! 132: pp=&(data[j+24]); ! 133: x=CHS(pp); ! 134: printf(" %02d.%02d.%02d",x&31,(x>>5)&15,(x>>9)+80); ! 135: ! 136: pp=&(data[j+26]); ! 137: printf(" %5d",CHS(pp)); ! 138: ! 139: pp=&(data[j+28]); ! 140: printf(" %7lu\n",CHL(pp)); ! 141: } ! 142: break; ! 143: case M_TXT: ! 144: i=0; ! 145: for(j=0;j<dblsb->s_sectperclust*512;j++) ! 146: { if(data[j]==10) ! 147: { printf("\n"); ! 148: i=0; ! 149: continue; ! 150: } ! 151: if(data[j]>=32&&data[j]<=126)printf("%c",data[j]); ! 152: else printf("."); ! 153: ++i; ! 154: if(i==80&&j<511&&data[j+1]!=10) ! 155: { printf("\n"); ! 156: i=0; ! 157: } ! 158: } ! 159: if(i)printf("\n"); ! 160: break; ! 161: default: ! 162: fprintf(stderr,"display mode not implemented\n"); ! 163: free(data); ! 164: return -1; ! 165: } ! 166: ! 167: free(data); ! 168: return 0; ! 169: } ! 170: ! 171: int display_chain(int start, int mode) ! 172: { int i,next; ! 173: ! 174: if(start==0)return display_cluster(0,mode); ! 175: if(start==1||start<0||start>dblsb->s_max_cluster)return -1; ! 176: ! 177: do ! 178: { ! 179: next=dbl_fat_nextcluster(sb,start,NULL); ! 180: if(next==0&&(mode&M_VERBOSE)!=0) ! 181: fprintf(stderr,"warning: cluster %d is marked as unused in FAT\n",start); ! 182: i=display_cluster(start,mode); ! 183: if(i<0)return i; ! 184: start=next; ! 185: } ! 186: while(next>1&&next<=dblsb->s_max_cluster); ! 187: ! 188: if(next>=0) ! 189: { fprintf(stderr,"chain has no valid end in FAT\n"); ! 190: return -1; ! 191: } ! 192: ! 193: return 0; ! 194: } ! 195: ! 196: int scan_dir(char*entry,int start) ! 197: { char buf[]=" "; ! 198: /*12345678EXT*/ ! 199: int i; ! 200: int size; ! 201: unsigned char*data; ! 202: int next; ! 203: ! 204: if(strcmp(entry,".")==0)return start; ! 205: else if(strcmp(entry,"..")==0)strncpy(buf,"..",2); ! 206: else if(*entry=='.') return -1; ! 207: else ! 208: for(i=0;i<11;++i) ! 209: { if(*entry=='.'&&i<=7){i=7;++entry;continue;} ! 210: if(*entry=='.')break; ! 211: if(*entry=='\0')break; ! 212: buf[i]=toupper(*entry); ! 213: ++entry; ! 214: } ! 215: ! 216: do ! 217: { ! 218: printf("scan_dir: searching for %s in %d\n",buf,start); ! 219: ! 220: if(start==0) ! 221: { data=get_root_dir(); ! 222: size=dblsb->s_rootdirentries; ! 223: next=-1; ! 224: } ! 225: else ! 226: { data=malloc(dblsb->s_sectperclust*512); ! 227: if(data!=NULL) ! 228: { i=dmsdos_read_cluster(sb,data,start); ! 229: if(i<0){free(data);data=NULL;} ! 230: size=i/32; ! 231: next=dbl_fat_nextcluster(sb,start,NULL); ! 232: if(next==0) ! 233: fprintf(stderr,"warning: cluster %d is maked as unused in FAT\n", ! 234: next); ! 235: } ! 236: } ! 237: if(data==NULL)return -1; ! 238: ! 239: for(i=0;i<size;++i) ! 240: { if(strncmp(&(data[i*32]),buf,11)==0) ! 241: { unsigned char*pp; ! 242: int cluster; ! 243: ! 244: pp=&(data[i*32+26]); ! 245: cluster=CHS(pp); ! 246: free(data); ! 247: return cluster; ! 248: } ! 249: } ! 250: ! 251: free(data); ! 252: start=next; ! 253: } ! 254: while(next>0&&next<=dblsb->s_max_cluster); ! 255: return -1; ! 256: } ! 257: ! 258: int scan_path(char*path,int start) ! 259: { int i; ! 260: char*p; ! 261: ! 262: for(p=strtok(path,"/");p;p=strtok(NULL,"/")) ! 263: { i=scan_dir(p,start); ! 264: if(i<0) ! 265: { fprintf(stderr,"path component %s not found\n",p); ! 266: return -1; ! 267: } ! 268: start=i; ! 269: } ! 270: ! 271: return start; ! 272: } ! 273: ! 274: int main(int argc, char*argv[]) ! 275: { int mode=0; ! 276: int cluster; ! 277: int i; ! 278: ! 279: if(argc<3) ! 280: { fprintf(stderr,"usage: dcread CVF cluster|/path/to/file [raw|dir|hex|txt]\n"); ! 281: return 1; ! 282: } ! 283: ! 284: sb=open_cvf(argv[1],0/*read-only*/); ! 285: if(sb==NULL) ! 286: { printf("open CVF %s failed\n",argv[1]); ! 287: return 2; ! 288: } ! 289: dblsb=MSDOS_SB(sb)->private_data; ! 290: ! 291: if(*(argv[2])=='/') ! 292: { cluster=scan_path(argv[2]+1,0); ! 293: if(cluster<0) ! 294: { fprintf(stderr,"%s not found\n",argv[2]); ! 295: return 1; ! 296: } ! 297: } ! 298: else cluster=scan(argv[2]); ! 299: ! 300: if(argc==4) ! 301: { if(strcmp(argv[3],"raw")==0)mode=M_RAW; ! 302: else if(strcmp(argv[3],"dir")==0)mode=M_DIR; ! 303: else if(strcmp(argv[3],"hex")==0)mode=M_HEX; ! 304: else if(strcmp(argv[3],"txt")==0)mode=M_TXT; ! 305: else ! 306: { fprintf(stderr,"invalid argument %s\n",argv[3]); ! 307: close_cvf(sb); ! 308: return 1; ! 309: } ! 310: } ! 311: ! 312: i=display_chain(cluster,mode|M_VERBOSE); ! 313: ! 314: close_cvf(sb); ! 315: ! 316: return i; ! 317: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.