Annotation of dmsdos/src/dcread.c, revision 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.