Annotation of dmsdos/src/dcread.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.