1214921Scognet/* $NetBSD: cd9660_debug.c,v 1.11 2010/10/27 18:51:35 christos Exp $ */ 2214921Scognet 3214921Scognet/* 4214921Scognet * Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan 5214921Scognet * Perez-Rathke and Ram Vedam. All rights reserved. 6214921Scognet * 7214921Scognet * This code was written by Daniel Watt, Walter Deignan, Ryan Gabrys, 8214921Scognet * Alan Perez-Rathke and Ram Vedam. 9214921Scognet * 10214921Scognet * Redistribution and use in source and binary forms, with or 11214921Scognet * without modification, are permitted provided that the following 12214921Scognet * conditions are met: 13214921Scognet * 1. Redistributions of source code must retain the above copyright 14214921Scognet * notice, this list of conditions and the following disclaimer. 15214921Scognet * 2. Redistributions in binary form must reproduce the above 16214921Scognet * copyright notice, this list of conditions and the following 17214921Scognet * disclaimer in the documentation and/or other materials provided 18214921Scognet * with the distribution. 19214921Scognet * 20214921Scognet * THIS SOFTWARE IS PROVIDED BY DANIEL WATT, WALTER DEIGNAN, RYAN 21214921Scognet * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM ``AS IS'' AND ANY EXPRESS OR 22214921Scognet * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23214921Scognet * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24214921Scognet * DISCLAIMED. IN NO EVENT SHALL DANIEL WATT, WALTER DEIGNAN, RYAN 25214921Scognet * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM BE LIABLE FOR ANY DIRECT, INDIRECT, 26214921Scognet * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27214921Scognet * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 28214921Scognet * USE,DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29214921Scognet * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30214921Scognet * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31214921Scognet * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 32214921Scognet * OF SUCH DAMAGE. 33214921Scognet */ 34214921Scognet 35214921Scognet#include <sys/cdefs.h> 36214921Scognet__FBSDID("$FreeBSD$"); 37214921Scognet#include <sys/param.h> 38214921Scognet 39214921Scognet#include <sys/mount.h> 40214921Scognet 41214921Scognet#include "makefs.h" 42214921Scognet#include "cd9660.h" 43214921Scognet#include "iso9660_rrip.h" 44214921Scognet 45214921Scognetstatic void debug_print_susp_attrs(cd9660node *, int); 46214921Scognetstatic void debug_dump_to_xml_padded_hex_output(const char *, unsigned char *, 47214921Scognet int); 48214921Scognet 49214921Scognetstatic inline void 50214921Scognetprint_n_tabs(int n) 51214921Scognet{ 52214921Scognet int i; 53214921Scognet 54214921Scognet for (i = 1; i <= n; i ++) 55214921Scognet printf("\t"); 56214921Scognet} 57214921Scognet 58214921Scognet#if 0 59214921Scognetvoid 60214921Scognetdebug_print_rrip_info(n) 61214921Scognetcd9660node *n; 62214921Scognet{ 63214921Scognet struct ISO_SUSP_ATTRIBUTES *t; 64214921Scognet TAILQ_FOREACH(t, &node->head, rr_ll) { 65214921Scognet 66214921Scognet } 67214921Scognet} 68214921Scognet#endif 69214921Scognet 70214921Scognetstatic void 71214921Scognetdebug_print_susp_attrs(cd9660node *n, int indent) 72214921Scognet{ 73214921Scognet struct ISO_SUSP_ATTRIBUTES *t; 74214921Scognet 75214921Scognet TAILQ_FOREACH(t, &n->head, rr_ll) { 76214921Scognet print_n_tabs(indent); 77214921Scognet printf("-"); 78214921Scognet printf("%c%c: L:%i",t->attr.su_entry.SP.h.type[0], 79214921Scognet t->attr.su_entry.SP.h.type[1], 80214921Scognet (int)t->attr.su_entry.SP.h.length[0]); 81214921Scognet printf("\n"); 82214921Scognet } 83214921Scognet} 84214921Scognet 85214921Scognetvoid 86214921Scognetdebug_print_tree(cd9660node *node, int level) 87214921Scognet{ 88214921Scognet#if !HAVE_NBTOOL_CONFIG_H 89214921Scognet cd9660node *cn; 90214921Scognet 91214921Scognet print_n_tabs(level); 92214921Scognet if (node->type & CD9660_TYPE_DOT) { 93214921Scognet printf(". (%i)\n", 94214921Scognet isonum_733(node->isoDirRecord->extent)); 95214921Scognet } else if (node->type & CD9660_TYPE_DOTDOT) { 96214921Scognet printf("..(%i)\n", 97214921Scognet isonum_733(node->isoDirRecord->extent)); 98214921Scognet } else if (node->isoDirRecord->name[0]=='\0') { 99214921Scognet printf("(ROOT) (%" PRIu32 " to %" PRId64 ")\n", 100214921Scognet node->fileDataSector, 101214921Scognet node->fileDataSector + 102214921Scognet node->fileSectorsUsed - 1); 103214921Scognet } else { 104214921Scognet printf("%s (%s) (%" PRIu32 " to %" PRId64 ")\n", 105214921Scognet node->isoDirRecord->name, 106214921Scognet (node->isoDirRecord->flags[0] 107214921Scognet & ISO_FLAG_DIRECTORY) ? "DIR" : "FILE", 108214921Scognet node->fileDataSector, 109214921Scognet (node->fileSectorsUsed == 0) ? 110214921Scognet node->fileDataSector : 111214921Scognet node->fileDataSector 112214921Scognet + node->fileSectorsUsed - 1); 113214921Scognet } 114214921Scognet if (diskStructure.rock_ridge_enabled) 115214921Scognet debug_print_susp_attrs(node, level + 1); 116214921Scognet TAILQ_FOREACH(cn, &node->cn_children, cn_next_child) 117214921Scognet debug_print_tree(cn, level + 1); 118214921Scognet#else 119214921Scognet printf("Sorry, debugging is not supported in host-tools mode.\n"); 120214921Scognet#endif 121214921Scognet} 122214921Scognet 123214921Scognetvoid 124214921Scognetdebug_print_path_tree(cd9660node *n) 125214921Scognet{ 126214921Scognet cd9660node *iterator = n; 127214921Scognet 128214921Scognet /* Only display this message when called with the root node */ 129214921Scognet if (n->parent == NULL) 130214921Scognet printf("debug_print_path_table: Dumping path table contents\n"); 131214921Scognet 132214921Scognet while (iterator != NULL) { 133214921Scognet if (iterator->isoDirRecord->name[0] == '\0') 134214921Scognet printf("0) (ROOT)\n"); 135214921Scognet else 136214921Scognet printf("%i) %s\n", iterator->level, 137214921Scognet iterator->isoDirRecord->name); 138214921Scognet 139214921Scognet iterator = iterator->ptnext; 140214921Scognet } 141214921Scognet} 142214921Scognet 143214921Scognetvoid 144214921Scognetdebug_print_volume_descriptor_information(void) 145214921Scognet{ 146214921Scognet volume_descriptor *tmp = diskStructure.firstVolumeDescriptor; 147214921Scognet char temp[CD9660_SECTOR_SIZE]; 148214921Scognet 149214921Scognet printf("==Listing Volume Descriptors==\n"); 150214921Scognet 151214921Scognet while (tmp != NULL) { 152214921Scognet memset(temp, 0, CD9660_SECTOR_SIZE); 153214921Scognet memcpy(temp, tmp->volumeDescriptorData + 1, 5); 154214921Scognet printf("Volume descriptor in sector %" PRId64 155214921Scognet ": type %i, ID %s\n", 156214921Scognet tmp->sector, tmp->volumeDescriptorData[0], temp); 157214921Scognet switch(tmp->volumeDescriptorData[0]) { 158214921Scognet case 0:/*boot record*/ 159214921Scognet break; 160214921Scognet 161214921Scognet case 1: /* PVD */ 162214921Scognet break; 163214921Scognet 164214921Scognet case 2: /* SVD */ 165214921Scognet break; 166214921Scognet 167214921Scognet case 3: /* Volume Partition Descriptor */ 168214921Scognet break; 169214921Scognet 170214921Scognet case 255: /* terminator */ 171214921Scognet break; 172214921Scognet } 173214921Scognet tmp = tmp->next; 174214921Scognet } 175214921Scognet 176214921Scognet printf("==Done Listing Volume Descriptors==\n"); 177214921Scognet} 178214921Scognet 179214921Scognetvoid 180214921Scognetdebug_dump_to_xml_ptentry(path_table_entry *pttemp, int num, int mode) 181214921Scognet{ 182214921Scognet printf("<ptentry num=\"%i\">\n" ,num); 183214921Scognet printf("<length>%i</length>\n", pttemp->length[0]); 184214921Scognet printf("<extended_attribute_length>%i</extended_attribute_length>\n", 185214921Scognet pttemp->extended_attribute_length[0]); 186214921Scognet printf("<parent_number>%i</parent_number>\n", 187214921Scognet debug_get_encoded_number(pttemp->parent_number,mode)); 188214921Scognet debug_dump_to_xml_padded_hex_output("name", 189214921Scognet pttemp->name, pttemp->length[0]); 190214921Scognet printf("</ptentry>\n"); 191214921Scognet} 192214921Scognet 193214921Scognetvoid 194214921Scognetdebug_dump_to_xml_path_table(FILE *fd, off_t sector, int size, int mode) 195214921Scognet{ 196214921Scognet path_table_entry pttemp; 197214921Scognet int t = 0; 198214921Scognet int n = 0; 199214921Scognet 200214921Scognet if (fseeko(fd, CD9660_SECTOR_SIZE * sector, SEEK_SET) == -1) 201214921Scognet err(1, "fseeko"); 202214921Scognet 203214921Scognet while (t < size) { 204214921Scognet /* Read fixed data first */ 205214921Scognet fread(&pttemp, 1, 8, fd); 206214921Scognet t += 8; 207214921Scognet /* Read variable */ 208214921Scognet fread(((unsigned char*)&pttemp) + 8, 1, pttemp.length[0], fd); 209214921Scognet t += pttemp.length[0]; 210214921Scognet debug_dump_to_xml_ptentry(&pttemp, n, mode); 211214921Scognet n++; 212214921Scognet } 213214921Scognet 214214921Scognet} 215214921Scognet 216214921Scognet/* 217214921Scognet * XML Debug output functions 218214921Scognet * Dump hierarchy of CD, as well as volume info, to XML 219214921Scognet * Can be used later to diff against a standard, 220214921Scognet * or just provide easy to read detailed debug output 221214921Scognet */ 222214921Scognetvoid 223214921Scognetdebug_dump_to_xml(FILE *fd) 224214921Scognet{ 225214921Scognet unsigned char buf[CD9660_SECTOR_SIZE]; 226214921Scognet off_t sector; 227214921Scognet int t, t2; 228214921Scognet struct iso_primary_descriptor primaryVD; 229214921Scognet struct _boot_volume_descriptor bootVD; 230214921Scognet 231214921Scognet printf("<cd9660dump>\n"); 232214921Scognet 233214921Scognet /* Display Volume Descriptors */ 234214921Scognet sector = 16; 235214921Scognet do { 236214921Scognet if (fseeko(fd, CD9660_SECTOR_SIZE * sector, SEEK_SET) == -1) 237214921Scognet err(1, "fseeko"); 238214921Scognet fread(buf, 1, CD9660_SECTOR_SIZE, fd); 239214921Scognet t = (int)((unsigned char)buf[0]); 240214921Scognet switch (t) { 241214921Scognet case 0: 242214921Scognet memcpy(&bootVD, buf, CD9660_SECTOR_SIZE); 243214921Scognet break; 244214921Scognet case 1: 245214921Scognet memcpy(&primaryVD, buf, CD9660_SECTOR_SIZE); 246214921Scognet break; 247214921Scognet } 248214921Scognet debug_dump_to_xml_volume_descriptor(buf, sector); 249214921Scognet sector++; 250214921Scognet } while (t != 255); 251214921Scognet 252214921Scognet t = debug_get_encoded_number((u_char *)primaryVD.type_l_path_table, 253214921Scognet 731); 254214921Scognet t2 = debug_get_encoded_number((u_char *)primaryVD.path_table_size, 733); 255214921Scognet printf("Path table 1 located at sector %i and is %i bytes long\n", 256214921Scognet t,t2); 257214921Scognet debug_dump_to_xml_path_table(fd, t, t2, 721); 258214921Scognet 259214921Scognet t = debug_get_encoded_number((u_char *)primaryVD.type_m_path_table, 260214921Scognet 731); 261214921Scognet debug_dump_to_xml_path_table(fd, t, t2, 722); 262214921Scognet 263214921Scognet printf("</cd9660dump>\n"); 264214921Scognet} 265214921Scognet 266214921Scognetstatic void 267214921Scognetdebug_dump_to_xml_padded_hex_output(const char *element, unsigned char *buf, 268214921Scognet int len) 269214921Scognet{ 270214921Scognet int i; 271214921Scognet int t; 272214921Scognet 273214921Scognet printf("<%s>",element); 274214921Scognet for (i = 0; i < len; i++) { 275214921Scognet t = (unsigned char)buf[i]; 276214921Scognet if (t >= 32 && t < 127) 277214921Scognet printf("%c",t); 278214921Scognet } 279214921Scognet printf("</%s>\n",element); 280214921Scognet 281214921Scognet printf("<%s:hex>",element); 282214921Scognet for (i = 0; i < len; i++) { 283214921Scognet t = (unsigned char)buf[i]; 284214921Scognet printf(" %x",t); 285214921Scognet } 286214921Scognet printf("</%s:hex>\n",element); 287214921Scognet} 288214921Scognet 289214921Scognetint 290214921Scognetdebug_get_encoded_number(unsigned char* buf, int mode) 291214921Scognet{ 292214921Scognet#if !HAVE_NBTOOL_CONFIG_H 293214921Scognet switch (mode) { 294214921Scognet /* 711: Single bite */ 295214921Scognet case 711: 296214921Scognet return isonum_711(buf); 297214921Scognet 298214921Scognet /* 712: Single signed byte */ 299214921Scognet case 712: 300214921Scognet return isonum_712((signed char *)buf); 301214921Scognet 302214921Scognet /* 721: 16 bit LE */ 303214921Scognet case 721: 304214921Scognet return isonum_721(buf); 305214921Scognet 306214921Scognet /* 731: 32 bit LE */ 307214921Scognet case 731: 308214921Scognet return isonum_731(buf); 309214921Scognet 310214921Scognet /* 722: 16 bit BE */ 311214921Scognet case 722: 312214921Scognet return isonum_722(buf); 313214921Scognet 314214921Scognet /* 732: 32 bit BE */ 315214921Scognet case 732: 316214921Scognet return isonum_732(buf); 317214921Scognet 318214921Scognet /* 723: 16 bit bothE */ 319214921Scognet case 723: 320214921Scognet return isonum_723(buf); 321214921Scognet 322214921Scognet /* 733: 32 bit bothE */ 323214921Scognet case 733: 324214921Scognet return isonum_733(buf); 325214921Scognet } 326214921Scognet#endif 327214921Scognet return 0; 328214921Scognet} 329214921Scognet 330214921Scognetvoid 331214921Scognetdebug_dump_integer(const char *element, char* buf, int mode) 332214921Scognet{ 333214921Scognet printf("<%s>%i</%s>\n", element, 334214921Scognet debug_get_encoded_number((unsigned char *)buf, mode), element); 335214921Scognet} 336214921Scognet 337214921Scognetvoid 338214921Scognetdebug_dump_string(const char *element __unused, unsigned char *buf __unused, int len __unused) 339214921Scognet{ 340214921Scognet 341214921Scognet} 342214921Scognet 343214921Scognetvoid 344214921Scognetdebug_dump_directory_record_9_1(unsigned char* buf) 345214921Scognet{ 346214921Scognet printf("<directoryrecord>\n"); 347214921Scognet debug_dump_integer("length", 348214921Scognet ((struct iso_directory_record*) buf)->length, 711); 349214921Scognet debug_dump_integer("ext_attr_length", 350214921Scognet ((struct iso_directory_record*) buf)->ext_attr_length,711); 351214921Scognet debug_dump_integer("extent", 352214921Scognet (char *)((struct iso_directory_record*) buf)->extent, 733); 353214921Scognet debug_dump_integer("size", 354214921Scognet (char *)((struct iso_directory_record*) buf)->size, 733); 355214921Scognet debug_dump_integer("flags", 356214921Scognet ((struct iso_directory_record*) buf)->flags, 711); 357214921Scognet debug_dump_integer("file_unit_size", 358214921Scognet ((struct iso_directory_record*) buf)->file_unit_size,711); 359214921Scognet debug_dump_integer("interleave", 360214921Scognet ((struct iso_directory_record*) buf)->interleave, 711); 361214921Scognet debug_dump_integer("volume_sequence_number", 362214921Scognet ((struct iso_directory_record*) buf)->volume_sequence_number, 363214921Scognet 723); 364214921Scognet debug_dump_integer("name_len", 365214921Scognet ((struct iso_directory_record*) buf)->name_len, 711); 366214921Scognet debug_dump_to_xml_padded_hex_output("name", 367214921Scognet (u_char *)((struct iso_directory_record*) buf)->name, 368214921Scognet debug_get_encoded_number((u_char *) 369214921Scognet ((struct iso_directory_record*) buf)->length, 711)); 370214921Scognet printf("</directoryrecord>\n"); 371214921Scognet} 372214921Scognet 373214921Scognet 374214921Scognetvoid 375214921Scognetdebug_dump_to_xml_volume_descriptor(unsigned char* buf, int sector) 376214921Scognet{ 377214921Scognet printf("<volumedescriptor sector=\"%i\">\n", sector); 378214921Scognet printf("<vdtype>"); 379214921Scognet switch(buf[0]) { 380214921Scognet case 0: 381214921Scognet printf("boot"); 382214921Scognet break; 383214921Scognet 384214921Scognet case 1: 385214921Scognet printf("primary"); 386214921Scognet break; 387214921Scognet 388214921Scognet case 2: 389214921Scognet printf("supplementary"); 390214921Scognet break; 391214921Scognet 392214921Scognet case 3: 393214921Scognet printf("volume partition descriptor"); 394214921Scognet break; 395214921Scognet 396214921Scognet case 255: 397214921Scognet printf("terminator"); 398214921Scognet break; 399214921Scognet } 400214921Scognet 401214921Scognet printf("</vdtype>\n"); 402214921Scognet switch(buf[0]) { 403214921Scognet case 1: 404214921Scognet debug_dump_integer("type", 405214921Scognet ((struct iso_primary_descriptor*)buf)->type, 711); 406214921Scognet debug_dump_to_xml_padded_hex_output("id", 407214921Scognet (u_char *)((struct iso_primary_descriptor*) buf)->id, 408214921Scognet ISODCL ( 2, 6)); 409214921Scognet debug_dump_integer("version", 410214921Scognet ((struct iso_primary_descriptor*)buf)->version, 411214921Scognet 711); 412214921Scognet debug_dump_to_xml_padded_hex_output("system_id", 413214921Scognet (u_char *)((struct iso_primary_descriptor*)buf)->system_id, 414214921Scognet ISODCL(9,40)); 415214921Scognet debug_dump_to_xml_padded_hex_output("volume_id", 416214921Scognet (u_char *)((struct iso_primary_descriptor*)buf)->volume_id, 417214921Scognet ISODCL(41,72)); 418214921Scognet debug_dump_integer("volume_space_size", 419214921Scognet ((struct iso_primary_descriptor*)buf)->volume_space_size, 420214921Scognet 733); 421214921Scognet debug_dump_integer("volume_set_size", 422214921Scognet ((struct iso_primary_descriptor*)buf)->volume_set_size, 423214921Scognet 733); 424214921Scognet debug_dump_integer("volume_sequence_number", 425214921Scognet ((struct iso_primary_descriptor*)buf)->volume_sequence_number, 426214921Scognet 723); 427214921Scognet debug_dump_integer("logical_block_size", 428214921Scognet ((struct iso_primary_descriptor*)buf)->logical_block_size, 429214921Scognet 723); 430214921Scognet debug_dump_integer("path_table_size", 431214921Scognet ((struct iso_primary_descriptor*)buf)->path_table_size, 432214921Scognet 733); 433214921Scognet debug_dump_integer("type_l_path_table", 434214921Scognet ((struct iso_primary_descriptor*)buf)->type_l_path_table, 435214921Scognet 731); 436214921Scognet debug_dump_integer("opt_type_l_path_table", 437214921Scognet ((struct iso_primary_descriptor*)buf)->opt_type_l_path_table, 438214921Scognet 731); 439214921Scognet debug_dump_integer("type_m_path_table", 440214921Scognet ((struct iso_primary_descriptor*)buf)->type_m_path_table, 441214921Scognet 732); 442214921Scognet debug_dump_integer("opt_type_m_path_table", 443214921Scognet ((struct iso_primary_descriptor*)buf)->opt_type_m_path_table,732); 444214921Scognet debug_dump_directory_record_9_1( 445214921Scognet (u_char *)((struct iso_primary_descriptor*)buf)->root_directory_record); 446214921Scognet debug_dump_to_xml_padded_hex_output("volume_set_id", 447214921Scognet (u_char *)((struct iso_primary_descriptor*) buf)->volume_set_id, 448214921Scognet ISODCL (191, 318)); 449214921Scognet debug_dump_to_xml_padded_hex_output("publisher_id", 450214921Scognet (u_char *)((struct iso_primary_descriptor*) buf)->publisher_id, 451214921Scognet ISODCL (319, 446)); 452214921Scognet debug_dump_to_xml_padded_hex_output("preparer_id", 453214921Scognet (u_char *)((struct iso_primary_descriptor*) buf)->preparer_id, 454214921Scognet ISODCL (447, 574)); 455214921Scognet debug_dump_to_xml_padded_hex_output("application_id", 456214921Scognet (u_char *)((struct iso_primary_descriptor*) buf)->application_id, 457214921Scognet ISODCL (575, 702)); 458214921Scognet debug_dump_to_xml_padded_hex_output("copyright_file_id", 459214921Scognet (u_char *)((struct iso_primary_descriptor*) buf)->copyright_file_id, 460214921Scognet ISODCL (703, 739)); 461214921Scognet debug_dump_to_xml_padded_hex_output("abstract_file_id", 462214921Scognet (u_char *)((struct iso_primary_descriptor*) buf)->abstract_file_id, 463214921Scognet ISODCL (740, 776)); 464214921Scognet debug_dump_to_xml_padded_hex_output("bibliographic_file_id", 465214921Scognet (u_char *)((struct iso_primary_descriptor*) buf)->bibliographic_file_id, 466214921Scognet ISODCL (777, 813)); 467214921Scognet 468214921Scognet debug_dump_to_xml_padded_hex_output("creation_date", 469214921Scognet (u_char *)((struct iso_primary_descriptor*) buf)->creation_date, 470214921Scognet ISODCL (814, 830)); 471214921Scognet debug_dump_to_xml_padded_hex_output("modification_date", 472214921Scognet (u_char *)((struct iso_primary_descriptor*) buf)->modification_date, 473214921Scognet ISODCL (831, 847)); 474214921Scognet debug_dump_to_xml_padded_hex_output("expiration_date", 475214921Scognet (u_char *)((struct iso_primary_descriptor*) buf)->expiration_date, 476214921Scognet ISODCL (848, 864)); 477214921Scognet debug_dump_to_xml_padded_hex_output("effective_date", 478214921Scognet (u_char *)((struct iso_primary_descriptor*) buf)->effective_date, 479214921Scognet ISODCL (865, 881)); 480214921Scognet 481214921Scognet debug_dump_to_xml_padded_hex_output("file_structure_version", 482214921Scognet (u_char *)((struct iso_primary_descriptor*) buf)->file_structure_version, 483214921Scognet ISODCL(882,882)); 484214921Scognet break; 485214921Scognet } 486214921Scognet printf("</volumedescriptor>\n"); 487214921Scognet} 488214921Scognet 489