|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.