1 /* $NetBSD: cd9660_debug.c,v 1.9 2009/01/08 22:28:45 bjh21 Exp $ */
2
3 /*
4 * Copyright (c) 2009
5 * Thorsten Glaser <tg@mirbsd.org>
6 * Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan
7 * Perez-Rathke and Ram Vedam. All rights reserved.
8 *
9 * This code was written by Daniel Watt, Walter Deignan, Ryan Gabrys,
10 * Alan Perez-Rathke and Ram Vedam.
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above
18 * copyright notice, this list of conditions and the following
19 * disclaimer in the documentation and/or other materials provided
20 * with the distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY DANIEL WATT, WALTER DEIGNAN, RYAN
23 * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL DANIEL WATT, WALTER DEIGNAN, RYAN
27 * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30 * USE,DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
34 * OF SUCH DAMAGE.
35 */
36
37 #if HAVE_NBTOOL_CONFIG_H
38 #include "nbtool_config.h"
39 #endif
40
41 #include <sys/cdefs.h>
42 #include <sys/param.h>
43
44 #if defined(__RCSID) && !defined(__lint)
45 __IDSTRING(mbsdid, "$MirOS: src/usr.sbin/makefs/cd9660/cd9660_debug.c,v 1.4 2010/03/06 23:24:16 tg Exp $");
46 __RCSID("$NetBSD: cd9660_debug.c,v 1.9 2009/01/08 22:28:45 bjh21 Exp $");
47 #endif /* !__lint */
48
49 #if !HAVE_NBTOOL_CONFIG_H
50 #include <sys/mount.h>
51 #endif
52
53 #include "makefs.h"
54 #include "cd9660.h"
55 #include "iso9660_rrip.h"
56
57 static void debug_print_susp_attrs(cd9660node *, int);
58 static void debug_dump_to_xml_padded_hex_output(const char *, unsigned char *,
59 int);
60
61 static inline void
print_n_tabs(int n)62 print_n_tabs(int n)
63 {
64 int i;
65
66 for (i = 1; i <= n; i ++)
67 printf("\t");
68 }
69
70 #if 0
71 void
72 debug_print_rrip_info(n)
73 cd9660node *n;
74 {
75 struct ISO_SUSP_ATTRIBUTES *t;
76 TAILQ_FOREACH(t, &node->head, rr_ll) {
77
78 }
79 }
80 #endif
81
82 static void
debug_print_susp_attrs(cd9660node * n,int indent)83 debug_print_susp_attrs(cd9660node *n, int indent)
84 {
85 struct ISO_SUSP_ATTRIBUTES *t;
86
87 TAILQ_FOREACH(t, &n->head, rr_ll) {
88 print_n_tabs(indent);
89 printf("-");
90 printf("%c%c: L:%i",t->attr.su_entry.SP.h.type[0],
91 t->attr.su_entry.SP.h.type[1],
92 (int)t->attr.su_entry.SP.h.length[0]);
93 printf("\n");
94 }
95 }
96
97 void
debug_print_tree(cd9660node * node,int level)98 debug_print_tree(cd9660node *node, int level)
99 {
100 #if !HAVE_NBTOOL_CONFIG_H
101 cd9660node *cn;
102
103 print_n_tabs(level);
104 if (node->type & CD9660_TYPE_DOT) {
105 printf(". (%i)\n",
106 isonum_733(node->isoDirRecord->extent));
107 } else if (node->type & CD9660_TYPE_DOTDOT) {
108 printf("..(%i)\n",
109 isonum_733(node->isoDirRecord->extent));
110 } else if (node->isoDirRecord->name[0]=='\0') {
111 printf("(ROOT) (%i to %i)\n",
112 node->fileDataSector,
113 node->fileDataSector +
114 node->fileSectorsUsed - 1);
115 } else {
116 printf("%s (%s) (%i to %i)\n",
117 node->isoDirRecord->name,
118 (node->isoDirRecord->flags[0]
119 & ISO_FLAG_DIRECTORY) ? "DIR" : "FILE",
120 node->fileDataSector,
121 (node->fileSectorsUsed == 0) ?
122 node->fileDataSector :
123 node->fileDataSector
124 + node->fileSectorsUsed - 1);
125 }
126 if (diskStructure.rock_ridge_enabled)
127 debug_print_susp_attrs(node, level + 1);
128 TAILQ_FOREACH(cn, &node->cn_children, cn_next_child)
129 debug_print_tree(cn, level + 1);
130 #else
131 printf("Sorry, debugging is not supported in host-tools mode.\n");
132 #endif
133 }
134
135 void
debug_print_path_tree(cd9660node * n)136 debug_print_path_tree(cd9660node *n)
137 {
138 cd9660node *iterator = n;
139
140 /* Only display this message when called with the root node */
141 if (n->parent == NULL)
142 printf("debug_print_path_table: Dumping path table contents\n");
143
144 while (iterator != NULL) {
145 if (iterator->isoDirRecord->name[0] == '\0')
146 printf("0) (ROOT)\n");
147 else
148 printf("%i) %s\n", iterator->level,
149 iterator->isoDirRecord->name);
150
151 iterator = iterator->ptnext;
152 }
153 }
154
155 void
debug_print_volume_descriptor_information(void)156 debug_print_volume_descriptor_information(void)
157 {
158 volume_descriptor *tmp = diskStructure.firstVolumeDescriptor;
159 char temp[2048];
160
161 printf("==Listing Volume Descriptors==\n");
162
163 while (tmp != NULL) {
164 memset(temp, 0, 2048);
165 memcpy(temp, tmp->volumeDescriptorData + 1, 5);
166 printf("Volume descriptor in sector %i: type %i, ID %s\n",
167 tmp->sector, tmp->volumeDescriptorData[0], temp);
168 switch(tmp->volumeDescriptorData[0]) {
169 case 0:/*boot record*/
170 break;
171
172 case 1: /* PVD */
173 break;
174
175 case 2: /* SVD */
176 break;
177
178 case 3: /* Volume Partition Descriptor */
179 break;
180
181 case 255: /* terminator */
182 break;
183 }
184 tmp = tmp->next;
185 }
186
187 printf("==Done Listing Volume Descriptors==\n");
188 }
189
190 void
debug_dump_to_xml_ptentry(path_table_entry * pttemp,int num,int mode)191 debug_dump_to_xml_ptentry(path_table_entry *pttemp, int num, int mode)
192 {
193 printf("<ptentry num=\"%i\">\n" ,num);
194 printf("<length>%i</length>\n", pttemp->length[0]);
195 printf("<extended_attribute_length>%i</extended_attribute_length>\n",
196 pttemp->extended_attribute_length[0]);
197 printf("<parent_number>%i</parent_number>\n",
198 debug_get_encoded_number(pttemp->parent_number,mode));
199 debug_dump_to_xml_padded_hex_output("name",
200 pttemp->name, pttemp->length[0]);
201 printf("</ptentry>\n");
202 }
203
204 void
debug_dump_to_xml_path_table(FILE * fd,int sector,int size,int mode)205 debug_dump_to_xml_path_table(FILE *fd, int sector, int size, int mode)
206 {
207 path_table_entry pttemp;
208 int t = 0;
209 int n = 0;
210
211 fseek(fd, 2048 * sector, SEEK_SET);
212
213 while (t < size) {
214 /* Read fixed data first */
215 fread(&pttemp, 1, 8, fd);
216 t += 8;
217 /* Read variable */
218 fread(((unsigned char*)&pttemp) + 8, 1, pttemp.length[0], fd);
219 t += pttemp.length[0];
220 debug_dump_to_xml_ptentry(&pttemp, n, mode);
221 n++;
222 }
223
224 }
225
226 /*
227 * XML Debug output functions
228 * Dump hierarchy of CD, as well as volume info, to XML
229 * Can be used later to diff against a standard,
230 * or just provide easy to read detailed debug output
231 */
232 void
debug_dump_to_xml(FILE * fd)233 debug_dump_to_xml(FILE *fd)
234 {
235 unsigned char buf[2048];
236 int sector;
237 int t, t2;
238 struct iso_primary_descriptor primaryVD;
239 struct _boot_volume_descriptor bootVD;
240
241 printf("<cd9660dump>\n");
242
243 /* Display Volume Descriptors */
244 sector = 16;
245 do {
246 fseek(fd, 2048*sector, SEEK_SET);
247 fread(buf, 1, 2048, fd);
248 t = (int)((unsigned char)buf[0]);
249 switch (t) {
250 case 0:
251 memcpy(&bootVD, buf, 2048);
252 break;
253 case 1:
254 memcpy(&primaryVD, buf, 2048);
255 break;
256 }
257 debug_dump_to_xml_volume_descriptor(buf, sector);
258 sector++;
259 } while (t != 255);
260
261 t = debug_get_encoded_number((u_char *)primaryVD.type_l_path_table,
262 731);
263 t2 = debug_get_encoded_number((u_char *)primaryVD.path_table_size, 733);
264 printf("Path table 1 located at sector %i and is %i bytes long\n",
265 t,t2);
266 debug_dump_to_xml_path_table(fd, t, t2, 721);
267
268 t = debug_get_encoded_number((u_char *)primaryVD.type_m_path_table,
269 731);
270 debug_dump_to_xml_path_table(fd, t, t2, 722);
271
272 printf("</cd9660dump>\n");
273 }
274
275 static void
debug_dump_to_xml_padded_hex_output(const char * element,unsigned char * buf,int len)276 debug_dump_to_xml_padded_hex_output(const char *element, unsigned char *buf,
277 int len)
278 {
279 int i;
280 int t;
281
282 printf("<%s>",element);
283 for (i = 0; i < len; i++) {
284 t = (unsigned char)buf[i];
285 if (t >= 32 && t < 127)
286 printf("%c",t);
287 }
288 printf("</%s>\n",element);
289
290 printf("<%s:hex>",element);
291 for (i = 0; i < len; i++) {
292 t = (unsigned char)buf[i];
293 printf(" %x",t);
294 }
295 printf("</%s:hex>\n",element);
296 }
297
298 int
debug_get_encoded_number(unsigned char * buf,int mode)299 debug_get_encoded_number(unsigned char* buf, int mode)
300 {
301 #if !HAVE_NBTOOL_CONFIG_H
302 switch (mode) {
303 /* 711: Single bite */
304 case 711:
305 return isonum_711(buf);
306
307 /* 712: Single signed byte */
308 case 712:
309 return isonum_712((char *)buf);
310
311 /* 721: 16 bit LE */
312 case 721:
313 return isonum_721(buf);
314
315 /* 731: 32 bit LE */
316 case 731:
317 return isonum_731(buf);
318
319 /* 722: 16 bit BE */
320 case 722:
321 return isonum_722(buf);
322
323 /* 732: 32 bit BE */
324 case 732:
325 return isonum_732(buf);
326
327 /* 723: 16 bit bothE */
328 case 723:
329 return isonum_723(buf);
330
331 /* 733: 32 bit bothE */
332 case 733:
333 return isonum_733(buf);
334 }
335 #endif
336 return 0;
337 }
338
339 void
debug_dump_integer(const char * element,char * buf,int mode)340 debug_dump_integer(const char *element, char* buf, int mode)
341 {
342 printf("<%s>%i</%s>\n", element,
343 debug_get_encoded_number((unsigned char *)buf, mode), element);
344 }
345
346 void
debug_dump_string(const char * element __unused,unsigned char * buf __unused,int len __unused)347 debug_dump_string(const char *element __unused, unsigned char *buf __unused, int len __unused)
348 {
349
350 }
351
352 void
debug_dump_directory_record_9_1(unsigned char * buf)353 debug_dump_directory_record_9_1(unsigned char* buf)
354 {
355 printf("<directoryrecord>\n");
356 debug_dump_integer("length",
357 ((struct iso_directory_record*) buf)->length, 711);
358 debug_dump_integer("ext_attr_length",
359 ((struct iso_directory_record*) buf)->ext_attr_length,711);
360 debug_dump_integer("extent",
361 (char *)((struct iso_directory_record*) buf)->extent, 733);
362 debug_dump_integer("size",
363 (char *)((struct iso_directory_record*) buf)->size, 733);
364 debug_dump_integer("flags",
365 ((struct iso_directory_record*) buf)->flags, 711);
366 debug_dump_integer("file_unit_size",
367 ((struct iso_directory_record*) buf)->file_unit_size,711);
368 debug_dump_integer("interleave",
369 ((struct iso_directory_record*) buf)->interleave, 711);
370 debug_dump_integer("volume_sequence_number",
371 ((struct iso_directory_record*) buf)->volume_sequence_number,
372 723);
373 debug_dump_integer("name_len",
374 ((struct iso_directory_record*) buf)->name_len, 711);
375 debug_dump_to_xml_padded_hex_output("name",
376 (u_char *)((struct iso_directory_record*) buf)->name,
377 debug_get_encoded_number((u_char *)
378 ((struct iso_directory_record*) buf)->length, 711));
379 printf("</directoryrecord>\n");
380 }
381
382
383 void
debug_dump_to_xml_volume_descriptor(unsigned char * buf,int sector)384 debug_dump_to_xml_volume_descriptor(unsigned char* buf, int sector)
385 {
386 printf("<volumedescriptor sector=\"%i\">\n", sector);
387 printf("<vdtype>");
388 switch(buf[0]) {
389 case 0:
390 printf("boot");
391 break;
392
393 case 1:
394 printf("primary");
395 break;
396
397 case 2:
398 printf("supplementary");
399 break;
400
401 case 3:
402 printf("volume partition descriptor");
403 break;
404
405 case 255:
406 printf("terminator");
407 break;
408 }
409
410 printf("</vdtype>\n");
411 switch(buf[0]) {
412 case 1:
413 debug_dump_integer("type",
414 ((struct iso_primary_descriptor*)buf)->type, 711);
415 debug_dump_to_xml_padded_hex_output("id",
416 (u_char *)((struct iso_primary_descriptor*) buf)->id,
417 ISODCL ( 2, 6));
418 debug_dump_integer("version",
419 ((struct iso_primary_descriptor*)buf)->version,
420 711);
421 debug_dump_to_xml_padded_hex_output("system_id",
422 (u_char *)((struct iso_primary_descriptor*)buf)->system_id,
423 ISODCL(9,40));
424 debug_dump_to_xml_padded_hex_output("volume_id",
425 (u_char *)((struct iso_primary_descriptor*)buf)->volume_id,
426 ISODCL(41,72));
427 debug_dump_integer("volume_space_size",
428 ((struct iso_primary_descriptor*)buf)->volume_space_size,
429 733);
430 debug_dump_integer("volume_set_size",
431 ((struct iso_primary_descriptor*)buf)->volume_set_size,
432 733);
433 debug_dump_integer("volume_sequence_number",
434 ((struct iso_primary_descriptor*)buf)->volume_sequence_number,
435 723);
436 debug_dump_integer("logical_block_size",
437 ((struct iso_primary_descriptor*)buf)->logical_block_size,
438 723);
439 debug_dump_integer("path_table_size",
440 ((struct iso_primary_descriptor*)buf)->path_table_size,
441 733);
442 debug_dump_integer("type_l_path_table",
443 ((struct iso_primary_descriptor*)buf)->type_l_path_table,
444 731);
445 debug_dump_integer("opt_type_l_path_table",
446 ((struct iso_primary_descriptor*)buf)->opt_type_l_path_table,
447 731);
448 debug_dump_integer("type_m_path_table",
449 ((struct iso_primary_descriptor*)buf)->type_m_path_table,
450 732);
451 debug_dump_integer("opt_type_m_path_table",
452 ((struct iso_primary_descriptor*)buf)->opt_type_m_path_table,732);
453 debug_dump_directory_record_9_1(
454 (u_char *)((struct iso_primary_descriptor*)buf)->root_directory_record);
455 debug_dump_to_xml_padded_hex_output("volume_set_id",
456 (u_char *)((struct iso_primary_descriptor*) buf)->volume_set_id,
457 ISODCL (191, 318));
458 debug_dump_to_xml_padded_hex_output("publisher_id",
459 (u_char *)((struct iso_primary_descriptor*) buf)->publisher_id,
460 ISODCL (319, 446));
461 debug_dump_to_xml_padded_hex_output("preparer_id",
462 (u_char *)((struct iso_primary_descriptor*) buf)->preparer_id,
463 ISODCL (447, 574));
464 debug_dump_to_xml_padded_hex_output("application_id",
465 (u_char *)((struct iso_primary_descriptor*) buf)->application_id,
466 ISODCL (575, 702));
467 debug_dump_to_xml_padded_hex_output("copyright_file_id",
468 (u_char *)((struct iso_primary_descriptor*) buf)->copyright_file_id,
469 ISODCL (703, 739));
470 debug_dump_to_xml_padded_hex_output("abstract_file_id",
471 (u_char *)((struct iso_primary_descriptor*) buf)->abstract_file_id,
472 ISODCL (740, 776));
473 debug_dump_to_xml_padded_hex_output("bibliographic_file_id",
474 (u_char *)((struct iso_primary_descriptor*) buf)->bibliographic_file_id,
475 ISODCL (777, 813));
476
477 debug_dump_to_xml_padded_hex_output("creation_date",
478 (u_char *)((struct iso_primary_descriptor*) buf)->creation_date,
479 ISODCL (814, 830));
480 debug_dump_to_xml_padded_hex_output("modification_date",
481 (u_char *)((struct iso_primary_descriptor*) buf)->modification_date,
482 ISODCL (831, 847));
483 debug_dump_to_xml_padded_hex_output("expiration_date",
484 (u_char *)((struct iso_primary_descriptor*) buf)->expiration_date,
485 ISODCL (848, 864));
486 debug_dump_to_xml_padded_hex_output("effective_date",
487 (u_char *)((struct iso_primary_descriptor*) buf)->effective_date,
488 ISODCL (865, 881));
489
490 debug_dump_to_xml_padded_hex_output("file_structure_version",
491 (u_char *)((struct iso_primary_descriptor*) buf)->file_structure_version,
492 ISODCL(882,882));
493 break;
494 }
495 printf("</volumedescriptor>\n");
496 }
497
498