|
|
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.