Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * dump a 9660 cd image for a little while.
3
 * for debugging.
4
 */
5
#include <u.h>
6
#include <libc.h>
7
#include <bio.h>
8
#include <disk.h>
9
 
10
Biobuf *b;
11
 
12
#pragma varargck type "s" uchar*
13
#pragma varargck type "L" uchar*
14
#pragma varargck type "B" uchar*
15
#pragma varargck type "N" uchar*
16
#pragma varargck type "T" uchar*
17
#pragma varargck type "D" uchar*
18
 
19
typedef struct Voldesc Voldesc;
20
struct Voldesc {
21
	uchar	magic[8];	/* 0x01, "CD001", 0x01, 0x00 */
22
	uchar	systemid[32];	/* system identifier */
23
	uchar	volumeid[32];	/* volume identifier */
24
	uchar	unused[8];	/* character set in secondary desc */
25
	uchar	volsize[8];	/* volume size */
26
	uchar	charset[32];
27
	uchar	volsetsize[4];	/* volume set size = 1 */
28
	uchar	volseqnum[4];	/* volume sequence number = 1 */
29
	uchar	blocksize[4];	/* logical block size */
30
	uchar	pathsize[8];	/* path table size */
31
	uchar	lpathloc[4];	/* Lpath */
32
	uchar	olpathloc[4];	/* optional Lpath */
33
	uchar	mpathloc[4];	/* Mpath */
34
	uchar	ompathloc[4];	/* optional Mpath */
35
	uchar	rootdir[34];	/* root directory */
36
	uchar	volsetid[128];	/* volume set identifier */
37
	uchar	publisher[128];
38
	uchar	prepid[128];	/* data preparer identifier */
39
	uchar	applid[128];	/* application identifier */
40
	uchar	notice[37];	/* copyright notice file */
41
	uchar	abstract[37];	/* abstract file */
42
	uchar	biblio[37];	/* bibliographic file */
43
	uchar	cdate[17];	/* creation date */
44
	uchar	mdate[17];	/* modification date */
45
	uchar	xdate[17];	/* expiration date */
46
	uchar	edate[17];	/* effective date */
47
	uchar	fsvers;		/* file system version = 1 */
48
};
49
 
50
void
51
dumpbootvol(void *a)
52
{
53
	Voldesc *v;
54
 
55
	v = a;
56
	print("magic %.2ux %.5s %.2ux %2ux\n",
57
		v->magic[0], v->magic+1, v->magic[6], v->magic[7]);
58
	if(v->magic[0] == 0xFF)
59
		return;
60
 
61
	print("system %.32T\n", v->systemid);
62
	print("volume %.32T\n", v->volumeid);
63
	print("volume size %.4N\n", v->volsize);
64
	print("charset %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux\n",
65
		v->charset[0], v->charset[1], v->charset[2], v->charset[3],
66
		v->charset[4], v->charset[5], v->charset[6], v->charset[7]);
67
	print("volume set size %.2N\n", v->volsetsize);
68
	print("volume sequence number %.2N\n", v->volseqnum);
69
	print("logical block size %.2N\n", v->blocksize);
70
	print("path size %.4L\n", v->pathsize);
71
	print("lpath loc %.4L\n", v->lpathloc);
72
	print("opt lpath loc %.4L\n", v->olpathloc);
73
	print("mpath loc %.4B\n", v->mpathloc);
74
	print("opt mpath loc %.4B\n", v->ompathloc);
75
	print("rootdir %D\n", v->rootdir);
76
	print("volume set identifier %.128T\n", v->volsetid);
77
	print("publisher %.128T\n", v->publisher);
78
	print("preparer %.128T\n", v->prepid);
79
	print("application %.128T\n", v->applid);
80
	print("notice %.37T\n", v->notice);
81
	print("abstract %.37T\n", v->abstract);
82
	print("biblio %.37T\n", v->biblio);
83
	print("creation date %.17s\n", v->cdate);
84
	print("modification date %.17s\n", v->mdate);
85
	print("expiration date %.17s\n", v->xdate);
86
	print("effective date %.17s\n", v->edate);
87
	print("fs version %d\n", v->fsvers);
88
}
89
 
90
typedef struct Cdir Cdir;
91
struct Cdir {
92
	uchar	len;
93
	uchar	xlen;
94
	uchar	dloc[8];
95
	uchar	dlen[8];
96
	uchar	date[7];
97
	uchar	flags;
98
	uchar	unitsize;
99
	uchar	gapsize;
100
	uchar	volseqnum[4];
101
	uchar	namelen;
102
	uchar	name[1];	/* chumminess */
103
};
104
#pragma varargck type "D" Cdir*
105
 
106
int
107
Dfmt(Fmt *fmt)
108
{
109
	char buf[128];
110
	Cdir *c;
111
 
112
	c = va_arg(fmt->args, Cdir*);
113
	if(c->namelen == 1 && c->name[0] == '\0' || c->name[0] == '\001') {
114
		snprint(buf, sizeof buf, ".%s dloc %.4N dlen %.4N",
115
			c->name[0] ? "." : "", c->dloc, c->dlen);
116
	} else {
117
		snprint(buf, sizeof buf, "%.*T dloc %.4N dlen %.4N", c->namelen, c->name,
118
			c->dloc, c->dlen);
119
	}
120
	fmtstrcpy(fmt, buf);
121
	return 0;
122
}
123
 
124
typedef struct Path Path;
125
struct Path {
126
	uchar	namelen;
127
	uchar	xlen;
128
	uchar	dloc[4];
129
	uchar	parent[2];
130
	uchar	name[1];	/* chumminess */
131
};
132
#pragma varargck type "P" Path*
133
 
134
char longc, shortc;
135
void
136
bigend(void)
137
{
138
	longc = 'B';
139
}
140
 
141
void
142
littleend(void)
143
{
144
	longc = 'L';
145
}
146
 
147
int
148
Pfmt(Fmt *fmt)
149
{
150
	char xfmt[128], buf[128];
151
	Path *p;
152
 
153
	p = va_arg(fmt->args, Path*);
154
	sprint(xfmt, "data=%%.4%c up=%%.2%c name=%%.*T (%%d)", longc, longc);
155
	snprint(buf, sizeof buf, xfmt, p->dloc, p->parent, p->namelen, p->name, p->namelen);
156
	fmtstrcpy(fmt, buf);
157
	return 0;
158
}
159
 
160
ulong
161
big(void *a, int n)
162
{
163
	uchar *p;
164
	ulong v;
165
	int i;
166
 
167
	p = a;
168
	v = 0;
169
	for(i=0; i<n; i++)
170
		v = (v<<8) | *p++;
171
	return v;
172
}
173
 
174
ulong
175
little(void *a, int n)
176
{
177
	uchar *p;
178
	ulong v;
179
	int i;
180
 
181
	p = a;
182
	v = 0;
183
	for(i=0; i<n; i++)
184
		v |= (*p++<<(i*8));
185
	return v;
186
}
187
 
188
/* numbers in big or little endian. */
189
int
190
BLfmt(Fmt *fmt)
191
{
192
	ulong v;
193
	uchar *p;
194
	char buf[20];
195
 
196
	p = va_arg(fmt->args, uchar*);
197
 
198
	if(!(fmt->flags&FmtPrec)) {
199
		fmtstrcpy(fmt, "*BL*");
200
		return 0;
201
	}
202
 
203
	if(fmt->r == 'B')
204
		v = big(p, fmt->prec);
205
	else
206
		v = little(p, fmt->prec);
207
 
208
	sprint(buf, "0x%.*lux", fmt->prec*2, v);
209
	fmt->flags &= ~FmtPrec;
210
	fmtstrcpy(fmt, buf);
211
	return 0;
212
}
213
 
214
/* numbers in both little and big endian */
215
int
216
Nfmt(Fmt *fmt)
217
{
218
	char buf[100];
219
	uchar *p;
220
 
221
	p = va_arg(fmt->args, uchar*);
222
 
223
	sprint(buf, "%.*L %.*B", fmt->prec, p, fmt->prec, p+fmt->prec);
224
	fmt->flags &= ~FmtPrec;
225
	fmtstrcpy(fmt, buf);
226
	return 0;
227
}
228
 
229
int
230
asciiTfmt(Fmt *fmt)
231
{
232
	char *p, buf[256];
233
	int i;
234
 
235
	p = va_arg(fmt->args, char*);
236
	for(i=0; i<fmt->prec; i++)
237
		buf[i] = *p++;
238
	buf[i] = '\0';
239
	for(p=buf+strlen(buf); p>buf && p[-1]==' '; p--)
240
		;
241
	p[0] = '\0';
242
	fmt->flags &= ~FmtPrec;
243
	fmtstrcpy(fmt, buf);
244
	return 0;
245
}
246
 
247
int
248
runeTfmt(Fmt *fmt)
249
{
250
	Rune buf[256], *r;
251
	int i;
252
	uchar *p;
253
 
254
	p = va_arg(fmt->args, uchar*);
255
	for(i=0; i*2+2<=fmt->prec; i++, p+=2)
256
		buf[i] = (p[0]<<8)|p[1];
257
	buf[i] = L'\0';
258
	for(r=buf+i; r>buf && r[-1]==L' '; r--)
259
		;
260
	r[0] = L'\0';
261
	fmt->flags &= ~FmtPrec;
262
	return fmtprint(fmt, "%S", buf);
263
}
264
 
265
void
266
ascii(void)
267
{
268
	fmtinstall('T', asciiTfmt);
269
}
270
 
271
void
272
joliet(void)
273
{
274
	fmtinstall('T', runeTfmt);
275
}
276
 
277
void
278
getsect(uchar *buf, int n)
279
{
280
	if(Bseek(b, n*2048, 0) != n*2048 || Bread(b, buf, 2048) != 2048)
281
		sysfatal("reading block %ux", n);
282
}
283
 
284
void
285
pathtable(Voldesc *v, int islittle)
286
{
287
	int i, j, n, sz, addr;
288
	ulong (*word)(void*, int);
289
	uchar x[2048], *p, *ep;
290
	Path *pt;
291
 
292
	print(">>> entire %s path table\n", islittle ? "little" : "big");
293
	littleend();
294
	if(islittle) {
295
		littleend();
296
		word = little;
297
	}else{
298
		bigend();
299
		word = big;
300
	}
301
	sz = little(v->pathsize, 4);	/* little, not word */
302
	addr = word(islittle ? v->lpathloc : v->mpathloc, 4);
303
	j = 0;
304
	n = 1;
305
	while(sz > 0){
306
		getsect(x, addr);
307
		p = x;
308
		ep = x+sz;
309
		if(ep > x+2048)
310
			ep = x+2048;
311
		for(i=0; p<ep; i++) {
312
			pt = (Path*)p;
313
			if(pt->namelen==0)
314
				break;
315
			print("0x%.4x %4d+%-4ld %P\n", n, j, p-x, pt);
316
			n++;
317
			p += 8+pt->namelen+(pt->namelen&1);
318
		}
319
		sz -= 2048;
320
		addr++;
321
		j++;
322
	}
323
}
324
 
325
void
326
dump(void *root)
327
{
328
	Voldesc *v;
329
	Cdir *c;
330
	long rootdirloc;
331
	uchar x[2048];
332
	int i;
333
	uchar *p;
334
 
335
	dumpbootvol(root);
336
	v = (Voldesc*)root;
337
	c = (Cdir*)v->rootdir;
338
	rootdirloc = little(c->dloc, 4);
339
	print(">>> sed 5q root directory\n");
340
	getsect(x, rootdirloc);
341
	p = x;
342
	for(i=0; i<5 && (p-x)<little(c->dlen, 4); i++) {
343
		print("%D\n", p);
344
		p += ((Cdir*)p)->len;
345
	}
346
 
347
	pathtable(v, 1);
348
	pathtable(v, 0);
349
}
350
 
351
void
352
main(int argc, char **argv)
353
{
354
	uchar root[2048], jroot[2048];
355
 
356
	if(argc != 2)
357
		sysfatal("usage: %s file", argv[0]);
358
 
359
	b = Bopen(argv[1], OREAD);
360
	if(b == nil)
361
		sysfatal("bopen %r");
362
 
363
	fmtinstall('L', BLfmt);
364
	fmtinstall('B', BLfmt);
365
	fmtinstall('N', Nfmt);
366
	fmtinstall('D', Dfmt);
367
	fmtinstall('P', Pfmt);
368
 
369
	getsect(root, 16);
370
	ascii();
371
	dump(root);
372
 
373
	getsect(jroot, 17);
374
	joliet();
375
	dump(jroot);
376
	exits(0);
377
}