]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/disk/rd9660.c
disk/format: removed 9fat magic VOLID value
[plan9front.git] / sys / src / cmd / disk / rd9660.c
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 }