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