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