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

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: }

unix.superglobalmegacorp.com

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