diff --git a/usr.sbin/makefs/cd9660.h b/usr.sbin/makefs/cd9660.h index b2db31460d02..c6f0e6472af3 100644 --- a/usr.sbin/makefs/cd9660.h +++ b/usr.sbin/makefs/cd9660.h @@ -1,327 +1,339 @@ /* $NetBSD: cd9660.h,v 1.21 2015/12/24 15:52:37 christos Exp $ */ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan * Perez-Rathke and Ram Vedam. All rights reserved. * * This code was written by Daniel Watt, Walter Deignan, Ryan Gabrys, * Alan Perez-Rathke and Ram Vedam. * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * THIS SOFTWARE IS PROVIDED BY DANIEL WATT, WALTER DEIGNAN, RYAN * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL DANIEL WATT, WALTER DEIGNAN, RYAN * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE,DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #ifndef _MAKEFS_CD9660_H #define _MAKEFS_CD9660_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include #include "makefs.h" #include "iso.h" #include "iso_rrip.h" #include "cd9660/cd9660_eltorito.h" #ifdef DEBUG #define INODE_WARNX(__x) warnx __x #else /* DEBUG */ #define INODE_WARNX(__x) #endif /* DEBUG */ /******** STRUCTURES **********/ #define ISO_VOLUME_DESCRIPTOR_STANDARD_ID "CD001" #define ISO_VOLUME_DESCRIPTOR_BOOT 0 #define ISO_VOLUME_DESCRIPTOR_PVD 1 #define ISO_VOLUME_DESCRIPTOR_TERMINATOR 255 /*30 for name and extension, as well as version number and padding bit*/ #define ISO_FILENAME_MAXLENGTH_BEFORE_VERSION 30 #define ISO_FILENAME_MAXLENGTH 38 #define ISO_FLAG_CLEAR 0x00 #define ISO_FLAG_HIDDEN 0x01 #define ISO_FLAG_DIRECTORY 0x02 #define ISO_FLAG_ASSOCIATED 0x04 #define ISO_FLAG_PERMISSIONS 0x08 #define ISO_FLAG_RESERVED5 0x10 #define ISO_FLAG_RESERVED6 0x20 #define ISO_FLAG_FINAL_RECORD 0x40 #define ISO_PATHTABLE_ENTRY_BASESIZE 8 #define ISO_RRIP_DEFAULT_MOVE_DIR_NAME "RR_MOVED" #define RRIP_DEFAULT_MOVE_DIR_NAME ".rr_moved" #define CD9660_BLOCKS(__sector_size, __bytes) \ howmany((__bytes), (__sector_size)) #define CD9660_MEM_ALLOC_ERROR(_F) \ err(EXIT_FAILURE, "%s, %s l. %d", _F, __FILE__, __LINE__) #define CD9660_TYPE_FILE 0x01 #define CD9660_TYPE_DIR 0x02 #define CD9660_TYPE_DOT 0x04 #define CD9660_TYPE_DOTDOT 0x08 #define CD9660_TYPE_VIRTUAL 0x80 #define CD9660_INODE_HASH_SIZE 1024 #define CD9660_SECTOR_SIZE 2048 #define CD9660_END_PADDING 150 /* Slight modification of the ISO structure in iso.h */ typedef struct _iso_directory_record_cd9660 { u_char length [ISODCL (1, 1)]; /* 711 */ u_char ext_attr_length [ISODCL (2, 2)]; /* 711 */ u_char extent [ISODCL (3, 10)]; /* 733 */ u_char size [ISODCL (11, 18)]; /* 733 */ u_char date [ISODCL (19, 25)]; /* 7 by 711 */ u_char flags [ISODCL (26, 26)]; u_char file_unit_size [ISODCL (27, 27)]; /* 711 */ u_char interleave [ISODCL (28, 28)]; /* 711 */ u_char volume_sequence_number [ISODCL (29, 32)]; /* 723 */ u_char name_len [ISODCL (33, 33)]; /* 711 */ char name [ISO_FILENAME_MAXLENGTH]; } iso_directory_record_cd9660; /* TODO: Lots of optimization of this structure */ typedef struct _cd9660node { u_char type;/* Used internally */ /* Tree structure */ struct _cd9660node *parent; /* parent (NULL if root) */ TAILQ_HEAD(cd9660_children_head, _cd9660node) cn_children; TAILQ_ENTRY(_cd9660node) cn_next_child; struct _cd9660node *dot_record; /* For directories, used mainly in RRIP */ struct _cd9660node *dot_dot_record; fsnode *node; /* pointer to fsnode */ struct _iso_directory_record_cd9660 *isoDirRecord; struct iso_extended_attributes *isoExtAttributes; /***** SIZE CALCULATION *****/ /*already stored in isoDirRecord, but this is an int version, and will be copied to isoDirRecord on writing*/ uint32_t fileDataSector; /* * same thing, though some notes: * If a file, this is the file size * If a directory, this is the size of all its children's * directory records * plus necessary padding */ int64_t fileDataLength; int64_t fileSectorsUsed; int fileRecordSize;/*copy of a variable, int for quicker calculations*/ /* Old name, used for renaming - needs to be optimized but low priority */ char o_name [ISO_FILENAME_MAXLENGTH]; /***** SPACE RESERVED FOR EXTENSIONS *****/ /* For memory efficiency's sake - we should move this to a separate struct and point to null if not needed */ /* For Rock Ridge */ struct _cd9660node *rr_real_parent, *rr_relocated; int64_t susp_entry_size; int64_t susp_dot_entry_size; int64_t susp_dot_dot_entry_size; /* Continuation area stuff */ int64_t susp_entry_ce_start; int64_t susp_dot_ce_start; int64_t susp_dot_dot_ce_start; int64_t susp_entry_ce_length; int64_t susp_dot_ce_length; int64_t susp_dot_dot_ce_length; /* Data to put at the end of the System Use field */ int64_t su_tail_size; char *su_tail_data; /*** PATH TABLE STUFF ***/ int level; /*depth*/ int ptnumber; struct _cd9660node *ptnext, *ptprev, *ptlast; /* SUSP entries */ TAILQ_HEAD(susp_linked_list, ISO_SUSP_ATTRIBUTES) head; } cd9660node; typedef struct _path_table_entry { u_char length[ISODCL (1, 1)]; u_char extended_attribute_length[ISODCL (2, 2)]; u_char first_sector[ISODCL (3, 6)]; u_char parent_number[ISODCL (7, 8)]; char name[ISO_FILENAME_MAXLENGTH]; } path_table_entry; typedef struct _volume_descriptor { u_char *volumeDescriptorData; /*ALWAYS 2048 bytes long*/ int64_t sector; struct _volume_descriptor *next; } volume_descriptor; +struct inode_map_node { + RB_ENTRY(inode_map_node) entry; + uint64_t key; + uint64_t value; +}; + typedef struct _iso9660_disk { int sectorSize; struct iso_primary_descriptor primaryDescriptor; struct iso_supplementary_descriptor supplementaryDescriptor; volume_descriptor *firstVolumeDescriptor; cd9660node *rootNode; /* Important sector numbers here */ /* primaryDescriptor.type_l_path_table*/ int64_t primaryBigEndianTableSector; /* primaryDescriptor.type_m_path_table*/ int64_t primaryLittleEndianTableSector; /* primaryDescriptor.opt_type_l_path_table*/ int64_t secondaryBigEndianTableSector; /* primaryDescriptor.opt_type_m_path_table*/ int64_t secondaryLittleEndianTableSector; /* primaryDescriptor.path_table_size*/ int pathTableLength; int64_t dataFirstSector; int64_t totalSectors; /* OPTIONS GO HERE */ int isoLevel; int include_padding_areas; int verbose_level; int keep_bad_images; /* SUSP options and variables */ int64_t susp_continuation_area_start_sector; int64_t susp_continuation_area_size; int64_t susp_continuation_area_current_free; int rock_ridge_enabled; /* Other Rock Ridge Variables */ char *rock_ridge_renamed_dir_name; unsigned rock_ridge_move_count; cd9660node *rr_moved_dir; + uint64_t rr_inode_next; + RB_HEAD(inode_map_tree, inode_map_node) rr_inode_map; + int chrp_boot; /* Spec breaking options */ u_char allow_deep_trees; u_char allow_start_dot; u_char allow_max_name; /* Allow 37 char filenames*/ u_char allow_illegal_chars; /* ~, !, # */ u_char allow_lowercase; u_char allow_multidot; u_char omit_trailing_period; /* BOOT INFORMATION HERE */ int has_generic_bootimage; /* Default to 0 */ char *generic_bootimage; int is_bootable;/* Default to 0 */ int64_t boot_catalog_sector; boot_volume_descriptor *boot_descriptor; char * boot_image_directory; TAILQ_HEAD(boot_image_list,cd9660_boot_image) boot_images; int image_serialno; LIST_HEAD(boot_catalog_entries,boot_catalog_entry) boot_entries; } iso9660_disk; +RB_PROTOTYPE(inode_map_tree, inode_map_node, entry, inode_map_node_cmp); + /************ FUNCTIONS **************/ int cd9660_valid_a_chars(const char *); int cd9660_valid_d_chars(const char *); void cd9660_uppercase_characters(char *, size_t); /* ISO Data Types */ void cd9660_721(uint16_t, unsigned char *); void cd9660_731(uint32_t, unsigned char *); void cd9660_722(uint16_t, unsigned char *); void cd9660_732(uint32_t, unsigned char *); void cd9660_bothendian_dword(uint32_t dw, unsigned char *); void cd9660_bothendian_word(uint16_t dw, unsigned char *); void cd9660_set_date(char *, time_t); void cd9660_time_8426(unsigned char *, time_t); void cd9660_time_915(unsigned char *, time_t); /*** Boot Functions ***/ int cd9660_write_generic_bootimage(FILE *); int cd9660_write_boot(iso9660_disk *, FILE *); int cd9660_add_boot_disk(iso9660_disk *, const char *); int cd9660_eltorito_add_boot_option(iso9660_disk *, const char *, const char *); int cd9660_setup_boot(iso9660_disk *, int); int cd9660_setup_boot_volume_descriptor(iso9660_disk *, volume_descriptor *); /*** Write Functions ***/ int cd9660_write_image(iso9660_disk *, const char *image); int cd9660_copy_file(iso9660_disk *, FILE *, off_t, const char *); void cd9660_compute_full_filename(cd9660node *, char *); int cd9660_compute_record_size(iso9660_disk *, cd9660node *); /* Debugging functions */ void debug_print_tree(iso9660_disk *, cd9660node *,int); void debug_print_path_tree(cd9660node *); void debug_print_volume_descriptor_information(iso9660_disk *); void debug_dump_to_xml_ptentry(path_table_entry *,int, int); void debug_dump_to_xml_path_table(FILE *, off_t, int, int); void debug_dump_to_xml(FILE *); int debug_get_encoded_number(const unsigned char *, int); void debug_dump_integer(const char *, const unsigned char *, int); void debug_dump_string(const char *, const unsigned char *, int); void debug_dump_directory_record_9_1(unsigned char *); void debug_dump_to_xml_volume_descriptor(unsigned char *,int); void cd9660_pad_string_spaces(char *, int); #endif diff --git a/usr.sbin/makefs/cd9660/iso9660_rrip.c b/usr.sbin/makefs/cd9660/iso9660_rrip.c index a4ce5c09b24b..e037f1db175f 100644 --- a/usr.sbin/makefs/cd9660/iso9660_rrip.c +++ b/usr.sbin/makefs/cd9660/iso9660_rrip.c @@ -1,837 +1,886 @@ /* $NetBSD: iso9660_rrip.c,v 1.14 2014/05/30 13:14:47 martin Exp $ */ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan * Perez-Rathke and Ram Vedam. All rights reserved. * * This code was written by Daniel Watt, Walter Deignan, Ryan Gabrys, * Alan Perez-Rathke and Ram Vedam. * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * THIS SOFTWARE IS PROVIDED BY DANIEL WATT, WALTER DEIGNAN, RYAN * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL DANIEL WATT, WALTER DEIGNAN, RYAN * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE,DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ /* This will hold all the function definitions * defined in iso9660_rrip.h */ #include #include #include #include #include "makefs.h" #include "cd9660.h" #include "iso9660_rrip.h" #include -static void cd9660_rrip_initialize_inode(cd9660node *); +static void cd9660_rrip_initialize_inode(iso9660_disk *, cd9660node *); static int cd9660_susp_handle_continuation(iso9660_disk *, cd9660node *); static int cd9660_susp_handle_continuation_common(iso9660_disk *, cd9660node *, int); int cd9660_susp_initialize(iso9660_disk *diskStructure, cd9660node *node, cd9660node *parent, cd9660node *grandparent) { cd9660node *cn; int r; /* Make sure the node is not NULL. If it is, there are major problems */ assert(node != NULL); if (!(node->type & CD9660_TYPE_DOT) && !(node->type & CD9660_TYPE_DOTDOT)) TAILQ_INIT(&(node->head)); if (node->dot_record != 0) TAILQ_INIT(&(node->dot_record->head)); if (node->dot_dot_record != 0) TAILQ_INIT(&(node->dot_dot_record->head)); + RB_INIT(&diskStructure->rr_inode_map); + diskStructure->rr_inode_next = 1; + /* SUSP specific entries here */ if ((r = cd9660_susp_initialize_node(diskStructure, node)) < 0) return r; /* currently called cd9660node_rrip_init_links */ r = cd9660_rrip_initialize_node(diskStructure, node, parent, grandparent); if (r < 0) return r; /* * See if we need a CE record, and set all of the * associated counters. * * This should be called after all extensions. After * this is called, no new records should be added. */ if ((r = cd9660_susp_handle_continuation(diskStructure, node)) < 0) return r; /* Recurse on children. */ TAILQ_FOREACH(cn, &node->cn_children, cn_next_child) { if ((r = cd9660_susp_initialize(diskStructure, cn, node, parent)) < 0) return 0; } return 1; } int cd9660_susp_finalize(iso9660_disk *diskStructure, cd9660node *node) { cd9660node *temp; + struct inode_map_node *mapnode, *mapnodetmp; int r; assert(node != NULL); if (node == diskStructure->rootNode) diskStructure->susp_continuation_area_current_free = 0; if ((r = cd9660_susp_finalize_node(diskStructure, node)) < 0) return r; if ((r = cd9660_rrip_finalize_node(node)) < 0) return r; TAILQ_FOREACH(temp, &node->cn_children, cn_next_child) { if ((r = cd9660_susp_finalize(diskStructure, temp)) < 0) return r; } + RB_FOREACH_SAFE(mapnode, inode_map_tree, + &(diskStructure->rr_inode_map), mapnodetmp) { + RB_REMOVE(inode_map_tree, &(diskStructure->rr_inode_map), + mapnode); + free(mapnode); + } return 1; } /* * If we really wanted to speed things up, we could have some sort of * lookup table on the SUSP entry type that calls a functor. Or, we could * combine the functions. These functions are kept separate to allow * easier addition of other extensions. * For the sake of simplicity and clarity, we won't be doing that for now. */ /* * SUSP needs to update the following types: * CE (continuation area) */ int cd9660_susp_finalize_node(iso9660_disk *diskStructure, cd9660node *node) { struct ISO_SUSP_ATTRIBUTES *t; /* Handle CE counters */ if (node->susp_entry_ce_length > 0) { node->susp_entry_ce_start = diskStructure->susp_continuation_area_current_free; diskStructure->susp_continuation_area_current_free += node->susp_entry_ce_length; } TAILQ_FOREACH(t, &node->head, rr_ll) { if (t->susp_type != SUSP_TYPE_SUSP || t->entry_type != SUSP_ENTRY_SUSP_CE) continue; cd9660_bothendian_dword( diskStructure-> susp_continuation_area_start_sector, t->attr.su_entry.CE.ca_sector); cd9660_bothendian_dword( diskStructure-> susp_continuation_area_start_sector, t->attr.su_entry.CE.ca_sector); cd9660_bothendian_dword(node->susp_entry_ce_start, t->attr.su_entry.CE.offset); cd9660_bothendian_dword(node->susp_entry_ce_length, t->attr.su_entry.CE.length); } return 0; } int cd9660_rrip_finalize_node(cd9660node *node) { struct ISO_SUSP_ATTRIBUTES *t; TAILQ_FOREACH(t, &node->head, rr_ll) { if (t->susp_type != SUSP_TYPE_RRIP) continue; switch (t->entry_type) { case SUSP_ENTRY_RRIP_CL: /* Look at rr_relocated*/ if (node->rr_relocated == NULL) return -1; cd9660_bothendian_dword( node->rr_relocated->fileDataSector, (unsigned char *) t->attr.rr_entry.CL.dir_loc); break; case SUSP_ENTRY_RRIP_PL: /* Look at rr_real_parent */ if (node->parent == NULL || node->parent->rr_real_parent == NULL) return -1; cd9660_bothendian_dword( node->parent->rr_real_parent->fileDataSector, (unsigned char *) t->attr.rr_entry.PL.dir_loc); break; } } return 0; } static int cd9660_susp_handle_continuation_common(iso9660_disk *diskStructure, cd9660node *node, int space) { int ca_used, susp_used, susp_used_pre_ce, working; struct ISO_SUSP_ATTRIBUTES *temp, *pre_ce, *last, *CE, *ST; pre_ce = last = NULL; working = 254 - space; if (node->su_tail_size > 0) /* Allow 4 bytes for "ST" record. */ working -= node->su_tail_size + 4; /* printf("There are %i bytes to work with\n",working); */ susp_used_pre_ce = susp_used = 0; ca_used = 0; TAILQ_FOREACH(temp, &node->head, rr_ll) { if (working < 0) break; /* * printf("SUSP Entry found, length is %i\n", * CD9660_SUSP_ENTRY_SIZE(temp)); */ working -= CD9660_SUSP_ENTRY_SIZE(temp); if (working >= 0) { last = temp; susp_used += CD9660_SUSP_ENTRY_SIZE(temp); } if (working >= 28) { /* * Remember the last entry after which we * could insert a "CE" entry. */ pre_ce = last; susp_used_pre_ce = susp_used; } } /* A CE entry is needed */ if (working <= 0) { CE = cd9660node_susp_create_node(SUSP_TYPE_SUSP, SUSP_ENTRY_SUSP_CE, "CE", SUSP_LOC_ENTRY); cd9660_susp_ce(CE, node); /* This will automatically insert at the appropriate location */ if (pre_ce != NULL) TAILQ_INSERT_AFTER(&node->head, pre_ce, CE, rr_ll); else TAILQ_INSERT_HEAD(&node->head, CE, rr_ll); last = CE; susp_used = susp_used_pre_ce + 28; /* Count how much CA data is necessary */ for (temp = TAILQ_NEXT(last, rr_ll); temp != NULL; temp = TAILQ_NEXT(temp, rr_ll)) { ca_used += CD9660_SUSP_ENTRY_SIZE(temp); } } /* An ST entry is needed */ if (node->su_tail_size > 0) { ST = cd9660node_susp_create_node(SUSP_TYPE_SUSP, SUSP_ENTRY_SUSP_ST, "ST", SUSP_LOC_ENTRY); cd9660_susp_st(ST, node); if (last != NULL) TAILQ_INSERT_AFTER(&node->head, last, ST, rr_ll); else TAILQ_INSERT_HEAD(&node->head, ST, rr_ll); last = ST; susp_used += 4; } if (last != NULL) last->last_in_suf = 1; node->susp_entry_size = susp_used; node->susp_entry_ce_length = ca_used; diskStructure->susp_continuation_area_size += ca_used; return 1; } /* See if a continuation entry is needed for each of the different types */ static int cd9660_susp_handle_continuation(iso9660_disk *diskStructure, cd9660node *node) { assert (node != NULL); /* Entry */ if (cd9660_susp_handle_continuation_common(diskStructure, node,(int)(node->isoDirRecord->length[0])) < 0) return 0; return 1; } int cd9660_susp_initialize_node(iso9660_disk *diskStructure, cd9660node *node) { struct ISO_SUSP_ATTRIBUTES *temp; /* * Requirements/notes: * CE: is added for us where needed * ST: not sure if it is even required, but if so, should be * handled by the CE code * PD: isn't needed (though might be added for testing) * SP: is stored ONLY on the . record of the root directory * ES: not sure */ /* Check for root directory, add SP and ER if needed. */ if (node->type & CD9660_TYPE_DOT) { if (node->parent == diskStructure->rootNode) { temp = cd9660node_susp_create_node(SUSP_TYPE_SUSP, SUSP_ENTRY_SUSP_SP, "SP", SUSP_LOC_DOT); cd9660_susp_sp(temp, node); /* Should be first entry. */ TAILQ_INSERT_HEAD(&node->head, temp, rr_ll); } } return 1; } static void -cd9660_rrip_initialize_inode(cd9660node *node) +cd9660_rrip_initialize_inode(iso9660_disk *diskStructure, cd9660node *node) { struct ISO_SUSP_ATTRIBUTES *attr; /* * Inode dependent values - this may change, * but for now virtual files and directories do * not have an inode structure */ if ((node->node != NULL) && (node->node->inode != NULL)) { /* PX - POSIX attributes */ attr = cd9660node_susp_create_node(SUSP_TYPE_RRIP, SUSP_ENTRY_RRIP_PX, "PX", SUSP_LOC_ENTRY); - cd9660node_rrip_px(attr, node->node); + cd9660node_rrip_px(diskStructure, attr, node->node); TAILQ_INSERT_TAIL(&node->head, attr, rr_ll); /* TF - timestamp */ attr = cd9660node_susp_create_node(SUSP_TYPE_RRIP, SUSP_ENTRY_RRIP_TF, "TF", SUSP_LOC_ENTRY); cd9660node_rrip_tf(attr, node->node); TAILQ_INSERT_TAIL(&node->head, attr, rr_ll); /* SL - Symbolic link */ /* ?????????? Dan - why is this here? */ if (TAILQ_EMPTY(&node->cn_children) && node->node->inode != NULL && S_ISLNK(node->node->inode->st.st_mode)) cd9660_createSL(node); /* PN - device number */ if (node->node->inode != NULL && ((S_ISCHR(node->node->inode->st.st_mode) || S_ISBLK(node->node->inode->st.st_mode)))) { attr = cd9660node_susp_create_node(SUSP_TYPE_RRIP, SUSP_ENTRY_RRIP_PN, "PN", SUSP_LOC_ENTRY); cd9660node_rrip_pn(attr, node->node); TAILQ_INSERT_TAIL(&node->head, attr, rr_ll); } } } int cd9660_rrip_initialize_node(iso9660_disk *diskStructure, cd9660node *node, cd9660node *parent, cd9660node *grandparent) { struct ISO_SUSP_ATTRIBUTES *current = NULL; assert(node != NULL); if (node->type & CD9660_TYPE_DOT) { /* * Handle ER - should be the only entry to appear on * a "." record */ if (node->parent == diskStructure->rootNode) { cd9660_susp_ER(node, 1, SUSP_RRIP_ER_EXT_ID, SUSP_RRIP_ER_EXT_DES, SUSP_RRIP_ER_EXT_SRC); } if (parent != NULL && parent->node != NULL && parent->node->inode != NULL) { /* PX - POSIX attributes */ current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, SUSP_ENTRY_RRIP_PX, "PX", SUSP_LOC_ENTRY); - cd9660node_rrip_px(current, parent->node); + cd9660node_rrip_px(diskStructure, current, + parent->node); TAILQ_INSERT_TAIL(&node->head, current, rr_ll); /* TF - timestamp */ current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, SUSP_ENTRY_RRIP_TF, "TF", SUSP_LOC_ENTRY); cd9660node_rrip_tf(current, parent->node); TAILQ_INSERT_TAIL(&node->head, current, rr_ll); } } else if (node->type & CD9660_TYPE_DOTDOT) { if (grandparent != NULL && grandparent->node != NULL && grandparent->node->inode != NULL) { /* PX - POSIX attributes */ current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, SUSP_ENTRY_RRIP_PX, "PX", SUSP_LOC_ENTRY); - cd9660node_rrip_px(current, grandparent->node); + cd9660node_rrip_px(diskStructure, current, + grandparent->node); TAILQ_INSERT_TAIL(&node->head, current, rr_ll); /* TF - timestamp */ current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, SUSP_ENTRY_RRIP_TF, "TF", SUSP_LOC_ENTRY); cd9660node_rrip_tf(current, grandparent->node); TAILQ_INSERT_TAIL(&node->head, current, rr_ll); } /* Handle PL */ if (parent != NULL && parent->rr_real_parent != NULL) { current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, SUSP_ENTRY_RRIP_PL, "PL", SUSP_LOC_DOTDOT); cd9660_rrip_PL(current,node); TAILQ_INSERT_TAIL(&node->head, current, rr_ll); } } else { - cd9660_rrip_initialize_inode(node); + cd9660_rrip_initialize_inode(diskStructure, node); if (node == diskStructure->rr_moved_dir) { cd9660_rrip_add_NM(node, RRIP_DEFAULT_MOVE_DIR_NAME); } else if (node->node != NULL) { cd9660_rrip_NM(node); } /* Rock ridge directory relocation code here. */ /* First handle the CL for the placeholder file. */ if (node->rr_relocated != NULL) { current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, SUSP_ENTRY_RRIP_CL, "CL", SUSP_LOC_ENTRY); cd9660_rrip_CL(current, node); TAILQ_INSERT_TAIL(&node->head, current, rr_ll); } /* Handle RE*/ if (node->rr_real_parent != NULL) { current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, SUSP_ENTRY_RRIP_RE, "RE", SUSP_LOC_ENTRY); cd9660_rrip_RE(current,node); TAILQ_INSERT_TAIL(&node->head, current, rr_ll); } } return 1; } struct ISO_SUSP_ATTRIBUTES* cd9660node_susp_create_node(int susp_type, int entry_type, const char *type_id, int write_loc) { struct ISO_SUSP_ATTRIBUTES* temp; temp = emalloc(sizeof(*temp)); temp->susp_type = susp_type; temp->entry_type = entry_type; temp->last_in_suf = 0; /* Phase this out */ temp->type_of[0] = type_id[0]; temp->type_of[1] = type_id[1]; temp->write_location = write_loc; /* * Since the first four bytes is common, lets go ahead and * set the type identifier, since we are passing that to this * function anyhow. */ temp->attr.su_entry.SP.h.type[0] = type_id[0]; temp->attr.su_entry.SP.h.type[1] = type_id[1]; return temp; } int cd9660_rrip_PL(struct ISO_SUSP_ATTRIBUTES* p, cd9660node *node __unused) { p->attr.rr_entry.PL.h.length[0] = 12; p->attr.rr_entry.PL.h.version[0] = 1; return 1; } int cd9660_rrip_CL(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *node __unused) { p->attr.rr_entry.CL.h.length[0] = 12; p->attr.rr_entry.CL.h.version[0] = 1; return 1; } int cd9660_rrip_RE(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *node __unused) { p->attr.rr_entry.RE.h.length[0] = 4; p->attr.rr_entry.RE.h.version[0] = 1; return 1; } void cd9660_createSL(cd9660node *node) { struct ISO_SUSP_ATTRIBUTES* current; int path_count, dir_count, done, i, j, dir_copied; char temp_cr[255]; char temp_sl[255]; /* used in copying continuation entry*/ char* sl_ptr; sl_ptr = node->node->symlink; done = 0; path_count = 0; dir_count = 0; dir_copied = 0; current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, SUSP_ENTRY_RRIP_SL, "SL", SUSP_LOC_ENTRY); current->attr.rr_entry.SL.h.version[0] = 1; current->attr.rr_entry.SL.flags[0] = SL_FLAGS_NONE; if (*sl_ptr == '/') { temp_cr[0] = SL_FLAGS_ROOT; temp_cr[1] = 0; memcpy(current->attr.rr_entry.SL.component + path_count, temp_cr, 2); path_count += 2; sl_ptr++; } for (i = 0; i < (dir_count + 2); i++) temp_cr[i] = '\0'; while (!done) { while ((*sl_ptr != '/') && (*sl_ptr != '\0')) { dir_copied = 1; if (*sl_ptr == '.') { if ((*(sl_ptr + 1) == '/') || (*(sl_ptr + 1) == '\0')) { temp_cr[0] = SL_FLAGS_CURRENT; sl_ptr++; } else if(*(sl_ptr + 1) == '.') { if ((*(sl_ptr + 2) == '/') || (*(sl_ptr + 2) == '\0')) { temp_cr[0] = SL_FLAGS_PARENT; sl_ptr += 2; } } else { temp_cr[dir_count+2] = *sl_ptr; sl_ptr++; dir_count++; } } else { temp_cr[dir_count + 2] = *sl_ptr; sl_ptr++; dir_count++; } } if ((path_count + dir_count) >= 249) { current->attr.rr_entry.SL.flags[0] |= SL_FLAGS_CONTINUE; j = 0; if (path_count <= 249) { while(j != (249 - path_count)) { temp_sl[j] = temp_cr[j]; j++; } temp_sl[0] = SL_FLAGS_CONTINUE; temp_sl[1] = j - 2; memcpy( current->attr.rr_entry.SL.component + path_count, temp_sl, j); } path_count += j; current->attr.rr_entry.SL.h.length[0] = path_count + 5; TAILQ_INSERT_TAIL(&node->head, current, rr_ll); current= cd9660node_susp_create_node(SUSP_TYPE_RRIP, SUSP_ENTRY_RRIP_SL, "SL", SUSP_LOC_ENTRY); current->attr.rr_entry.SL.h.version[0] = 1; current->attr.rr_entry.SL.flags[0] = SL_FLAGS_NONE; path_count = 0; if (dir_count > 2) { while (j != dir_count + 2) { current->attr.rr_entry.SL.component[ path_count + 2] = temp_cr[j]; j++; path_count++; } current->attr.rr_entry.SL.component[1] = path_count; path_count+= 2; } else { while(j != dir_count) { current->attr.rr_entry.SL.component[ path_count+2] = temp_cr[j]; j++; path_count++; } } } else { if (dir_copied == 1) { temp_cr[1] = dir_count; memcpy(current->attr.rr_entry.SL.component + path_count, temp_cr, dir_count + 2); path_count += dir_count + 2; } } if (*sl_ptr == '\0') { done = 1; current->attr.rr_entry.SL.h.length[0] = path_count + 5; TAILQ_INSERT_TAIL(&node->head, current, rr_ll); } else { sl_ptr++; dir_count = 0; dir_copied = 0; for(i = 0; i < 255; i++) { temp_cr[i] = '\0'; } } } } +static int +inode_map_node_cmp(struct inode_map_node *a, struct inode_map_node *b) +{ + if (a->key < b->key) + return (-1); + if (a->key > b->key) + return (1); + return (0); +} + +RB_GENERATE(inode_map_tree, inode_map_node, entry, inode_map_node_cmp); + +static uint64_t +inode_map(iso9660_disk *diskStructure, uint64_t in) +{ + struct inode_map_node lookup = { .key = in }; + struct inode_map_node *node; + + /* + * Always assign an inode number if src inode unset. mtree mode leaves + * src inode unset for files with st_nlink == 1. + */ + if (in != 0) { + node = RB_FIND(inode_map_tree, &(diskStructure->rr_inode_map), + &lookup); + if (node != 0) + return (node->value); + } + + node = emalloc(sizeof(struct inode_map_node)); + node->key = in; + node->value = diskStructure->rr_inode_next++; + RB_INSERT(inode_map_tree, &(diskStructure->rr_inode_map), node); + return (node->value); +} + int -cd9660node_rrip_px(struct ISO_SUSP_ATTRIBUTES *v, fsnode *pxinfo) +cd9660node_rrip_px(iso9660_disk *diskStructure, struct ISO_SUSP_ATTRIBUTES *v, + fsnode *pxinfo) { v->attr.rr_entry.PX.h.length[0] = 44; v->attr.rr_entry.PX.h.version[0] = 1; cd9660_bothendian_dword(pxinfo->inode->st.st_mode, v->attr.rr_entry.PX.mode); cd9660_bothendian_dword(pxinfo->inode->st.st_nlink, v->attr.rr_entry.PX.links); cd9660_bothendian_dword(pxinfo->inode->st.st_uid, v->attr.rr_entry.PX.uid); cd9660_bothendian_dword(pxinfo->inode->st.st_gid, v->attr.rr_entry.PX.gid); - cd9660_bothendian_dword(pxinfo->inode->st.st_ino, - v->attr.rr_entry.PX.serial); + cd9660_bothendian_dword(inode_map(diskStructure, + pxinfo->inode->st.st_ino), v->attr.rr_entry.PX.serial); return 1; } int cd9660node_rrip_pn(struct ISO_SUSP_ATTRIBUTES *pn_field, fsnode *fnode) { pn_field->attr.rr_entry.PN.h.length[0] = 20; pn_field->attr.rr_entry.PN.h.version[0] = 1; if (sizeof (fnode->inode->st.st_rdev) > 4) cd9660_bothendian_dword( (uint64_t)fnode->inode->st.st_rdev >> 32, pn_field->attr.rr_entry.PN.high); else cd9660_bothendian_dword(0, pn_field->attr.rr_entry.PN.high); cd9660_bothendian_dword(fnode->inode->st.st_rdev & 0xffffffff, pn_field->attr.rr_entry.PN.low); return 1; } #if 0 int cd9660node_rrip_nm(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *file_node) { int nm_length = strlen(file_node->isoDirRecord->name) + 5; p->attr.rr_entry.NM.h.type[0] = 'N'; p->attr.rr_entry.NM.h.type[1] = 'M'; sprintf(p->attr.rr_entry.NM.altname, "%s", file_node->isoDirRecord->name); p->attr.rr_entry.NM.h.length[0] = (unsigned char)nm_length; p->attr.rr_entry.NM.h.version[0] = (unsigned char)1; p->attr.rr_entry.NM.flags[0] = (unsigned char) NM_PARENT; return 1; } #endif int cd9660node_rrip_tf(struct ISO_SUSP_ATTRIBUTES *p, fsnode *_node) { p->attr.rr_entry.TF.flags[0] = TF_MODIFY | TF_ACCESS | TF_ATTRIBUTES; p->attr.rr_entry.TF.h.length[0] = 5; p->attr.rr_entry.TF.h.version[0] = 1; /* * Need to add creation time, backup time, * expiration time, and effective time. */ cd9660_time_915(p->attr.rr_entry.TF.timestamp, _node->inode->st.st_mtime); p->attr.rr_entry.TF.h.length[0] += 7; cd9660_time_915(p->attr.rr_entry.TF.timestamp + 7, _node->inode->st.st_atime); p->attr.rr_entry.TF.h.length[0] += 7; cd9660_time_915(p->attr.rr_entry.TF.timestamp + 14, _node->inode->st.st_ctime); p->attr.rr_entry.TF.h.length[0] += 7; return 1; } int cd9660_susp_sp(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *spinfo __unused) { p->attr.su_entry.SP.h.length[0] = 7; p->attr.su_entry.SP.h.version[0] = 1; p->attr.su_entry.SP.check[0] = 0xBE; p->attr.su_entry.SP.check[1] = 0xEF; p->attr.su_entry.SP.len_skp[0] = 0; return 1; } int cd9660_susp_st(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *stinfo __unused) { p->attr.su_entry.ST.h.type[0] = 'S'; p->attr.su_entry.ST.h.type[1] = 'T'; p->attr.su_entry.ST.h.length[0] = 4; p->attr.su_entry.ST.h.version[0] = 1; return 1; } int cd9660_susp_ce(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *spinfo __unused) { p->attr.su_entry.CE.h.length[0] = 28; p->attr.su_entry.CE.h.version[0] = 1; /* Other attributes dont matter right now, will be updated later */ return 1; } int cd9660_susp_pd(struct ISO_SUSP_ATTRIBUTES *p __unused, int length __unused) { return 1; } void cd9660_rrip_add_NM(cd9660node *node, const char *name) { int working,len; const char *p; struct ISO_SUSP_ATTRIBUTES *r; /* * Each NM record has 254 bytes to work with. This means that * the name data itself only has 249 bytes to work with. So, a * name with 251 characters would require two nm records. */ p = name; working = 1; while (working) { r = cd9660node_susp_create_node(SUSP_TYPE_RRIP, SUSP_ENTRY_RRIP_NM, "NM", SUSP_LOC_ENTRY); r->attr.rr_entry.NM.h.version[0] = 1; r->attr.rr_entry.NM.flags[0] = RRIP_NM_FLAGS_NONE; len = strlen(p); if (len > 249) { len = 249; r->attr.rr_entry.NM.flags[0] = RRIP_NM_FLAGS_CONTINUE; } else { working = 0; } memcpy(r->attr.rr_entry.NM.altname, p, len); r->attr.rr_entry.NM.h.length[0] = 5 + len; TAILQ_INSERT_TAIL(&node->head, r, rr_ll); p += len; } } void cd9660_rrip_NM(cd9660node *node) { cd9660_rrip_add_NM(node, node->node->name); } struct ISO_SUSP_ATTRIBUTES* cd9660_susp_ER(cd9660node *node, u_char ext_version, const char* ext_id, const char* ext_des, const char* ext_src) { int l; struct ISO_SUSP_ATTRIBUTES *r; r = cd9660node_susp_create_node(SUSP_TYPE_SUSP, SUSP_ENTRY_SUSP_ER, "ER", SUSP_LOC_DOT); /* Fixed data is 8 bytes */ r->attr.su_entry.ER.h.length[0] = 8; r->attr.su_entry.ER.h.version[0] = 1; r->attr.su_entry.ER.len_id[0] = (u_char)strlen(ext_id); r->attr.su_entry.ER.len_des[0] = (u_char)strlen(ext_des); r->attr.su_entry.ER.len_src[0] = (u_char)strlen(ext_src); l = r->attr.su_entry.ER.len_id[0] + r->attr.su_entry.ER.len_src[0] + r->attr.su_entry.ER.len_des[0]; /* Everything must fit. */ assert(l + r->attr.su_entry.ER.h.length[0] <= 254); r->attr.su_entry.ER.h.length[0] += (u_char)l; r->attr.su_entry.ER.ext_ver[0] = ext_version; memcpy(r->attr.su_entry.ER.ext_data, ext_id, (int)r->attr.su_entry.ER.len_id[0]); l = (int) r->attr.su_entry.ER.len_id[0]; memcpy(r->attr.su_entry.ER.ext_data + l,ext_des, (int)r->attr.su_entry.ER.len_des[0]); l += (int)r->attr.su_entry.ER.len_des[0]; memcpy(r->attr.su_entry.ER.ext_data + l,ext_src, (int)r->attr.su_entry.ER.len_src[0]); TAILQ_INSERT_TAIL(&node->head, r, rr_ll); return r; } struct ISO_SUSP_ATTRIBUTES* cd9660_susp_ES(struct ISO_SUSP_ATTRIBUTES *last __unused, cd9660node *node __unused) { return NULL; } diff --git a/usr.sbin/makefs/cd9660/iso9660_rrip.h b/usr.sbin/makefs/cd9660/iso9660_rrip.h index 5e1e8b5130f0..4c738d27ba45 100644 --- a/usr.sbin/makefs/cd9660/iso9660_rrip.h +++ b/usr.sbin/makefs/cd9660/iso9660_rrip.h @@ -1,292 +1,292 @@ /* $NetBSD: iso9660_rrip.h,v 1.5 2009/01/10 22:06:29 bjh21 Exp $ */ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan * Perez-Rathke and Ram Vedam. All rights reserved. * * This code was written by Daniel Watt, Walter Deignan, Ryan Gabrys, * Alan Perez-Rathke and Ram Vedam. * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * THIS SOFTWARE IS PROVIDED BY DANIEL WATT, WALTER DEIGNAN, RYAN * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL DANIEL WATT, WALTER DEIGNAN, RYAN * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE,DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #ifndef __ISO9660_RRIP_H__ #define __ISO9660_RRIP_H__ /* * This will hold all the functions needed to * write an ISO 9660 image with Rock Ridge Extensions */ /* For writing must use ISO_RRIP_EXTREF structure */ #include "makefs.h" #include #include "cd9660.h" #include #define PX_LENGTH 0x2C #define PN_LENGTH 0x14 #define TF_CREATION 0x01 #define TF_MODIFY 0x02 #define TF_ACCESS 0x04 #define TF_ATTRIBUTES 0x08 #define TF_BACKUP 0x10 #define TF_EXPIRATION 0x20 #define TF_EFFECTIVE 0x40 #define TF_LONG_FORM 0x80 #define NM_CONTINUE 0x01 #define NM_CURRENT 0x02 #define NM_PARENT 0x04 #define SUSP_LOC_ENTRY 0x01 #define SUSP_LOC_DOT 0x02 #define SUSP_LOC_DOTDOT 0x04 #define SUSP_TYPE_SUSP 1 #define SUSP_TYPE_RRIP 2 #define SUSP_ENTRY_SUSP_CE 1 #define SUSP_ENTRY_SUSP_PD 2 #define SUSP_ENTRY_SUSP_SP 3 #define SUSP_ENTRY_SUSP_ST 4 #define SUSP_ENTRY_SUSP_ER 5 #define SUSP_ENTRY_SUSP_ES 6 #define SUSP_ENTRY_RRIP_PX 1 #define SUSP_ENTRY_RRIP_PN 2 #define SUSP_ENTRY_RRIP_SL 3 #define SUSP_ENTRY_RRIP_NM 4 #define SUSP_ENTRY_RRIP_CL 5 #define SUSP_ENTRY_RRIP_PL 6 #define SUSP_ENTRY_RRIP_RE 7 #define SUSP_ENTRY_RRIP_TF 8 #define SUSP_ENTRY_RRIP_SF 9 #define SUSP_RRIP_ER_EXT_ID "IEEE_P1282" #define SUSP_RRIP_ER_EXT_DES "THE IEEE P1282 PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS." #define SUSP_RRIP_ER_EXT_SRC "PLEASE CONTACT THE IEEE STANDARDS DEPARTMENT, PISCATAWAY, NJ, USA FOR THE P1282 SPECIFICATION." #define SL_FLAGS_NONE 0 #define SL_FLAGS_CONTINUE 1 #define SL_FLAGS_CURRENT 2 #define SL_FLAGS_PARENT 4 #define SL_FLAGS_ROOT 8 typedef struct { ISO_SUSP_HEADER h; u_char mode [ISODCL(5,12)]; u_char links [ISODCL(13,20)]; u_char uid [ISODCL(21,28)]; u_char gid [ISODCL(29,36)]; u_char serial [ISODCL(37,44)]; } ISO_RRIP_PX; typedef struct { ISO_SUSP_HEADER h; u_char high [ISODCL(5,12)]; u_char low [ISODCL(13,20)]; } ISO_RRIP_PN; typedef struct { ISO_SUSP_HEADER h; u_char flags [ISODCL ( 4, 4)]; u_char component [ISODCL ( 4, 256)]; u_int nBytes; } ISO_RRIP_SL; typedef struct { ISO_SUSP_HEADER h; u_char flags [ISODCL ( 4, 4)]; u_char timestamp [ISODCL ( 5, 256)]; } ISO_RRIP_TF; #define RRIP_NM_FLAGS_NONE 0x00 #define RRIP_NM_FLAGS_CONTINUE 0x01 #define RRIP_NM_FLAGS_CURRENT 0x02 #define RRIP_NM_FLAGS_PARENT 0x04 typedef struct { ISO_SUSP_HEADER h; u_char flags [ISODCL ( 4, 4)]; u_char altname [ISODCL ( 4, 256)]; } ISO_RRIP_NM; /* Note that this is the same structure as cd9660_rrip.h : ISO_RRIP_CONT */ typedef struct { ISO_SUSP_HEADER h; u_char ca_sector [ISODCL ( 5, 12)]; u_char offset [ISODCL ( 13, 20)]; u_char length [ISODCL ( 21, 28)]; } ISO_SUSP_CE; typedef struct { ISO_SUSP_HEADER h; u_char padding_area [ISODCL ( 4, 256)]; } ISO_SUSP_PD; typedef struct { ISO_SUSP_HEADER h; u_char check [ISODCL ( 4, 5)]; u_char len_skp [ISODCL ( 6, 6)]; } ISO_SUSP_SP; typedef struct { ISO_SUSP_HEADER h; } ISO_SUSP_ST; typedef struct { ISO_SUSP_HEADER h; u_char len_id [ISODCL ( 4, 4)]; u_char len_des [ISODCL ( 5, 5)]; u_char len_src [ISODCL ( 6, 6)]; u_char ext_ver [ISODCL ( 7, 7)]; u_char ext_data [ISODCL (8,256)]; /* u_char ext_id [ISODCL ( 8, 256)]; u_char ext_des [ISODCL ( 257, 513)]; u_char ext_src [ISODCL ( 514, 770)];*/ } ISO_SUSP_ER; typedef struct { ISO_SUSP_HEADER h; u_char ext_seq [ISODCL ( 4, 4)]; } ISO_SUSP_ES; typedef union { ISO_RRIP_PX PX; ISO_RRIP_PN PN; ISO_RRIP_SL SL; ISO_RRIP_NM NM; ISO_RRIP_CLINK CL; ISO_RRIP_PLINK PL; ISO_RRIP_RELDIR RE; ISO_RRIP_TF TF; } rrip_entry; typedef union { ISO_SUSP_CE CE; ISO_SUSP_PD PD; ISO_SUSP_SP SP; ISO_SUSP_ST ST; ISO_SUSP_ER ER; ISO_SUSP_ES ES; } susp_entry; typedef union { susp_entry su_entry; rrip_entry rr_entry; } SUSP_ENTRIES; struct ISO_SUSP_ATTRIBUTES { SUSP_ENTRIES attr; int type; char type_of[2]; char last_in_suf; /* last entry in the System Use Field? */ /* Dan's addons - will merge later. This allows use of a switch */ char susp_type; /* SUSP or RRIP */ char entry_type; /* Record type */ char write_location; TAILQ_ENTRY(ISO_SUSP_ATTRIBUTES) rr_ll; }; #define CD9660_SUSP_ENTRY_SIZE(entry)\ ((int) ((entry)->attr.su_entry.SP.h.length[0])) /* Recursive function - move later to func pointer code*/ int cd9660_susp_finalize(iso9660_disk *, cd9660node *); /* These two operate on single nodes */ int cd9660_susp_finalize_node(iso9660_disk *, cd9660node *); int cd9660_rrip_finalize_node(cd9660node *); /* POSIX File attribute */ -int cd9660node_rrip_px(struct ISO_SUSP_ATTRIBUTES *, fsnode *); +int cd9660node_rrip_px(iso9660_disk *, struct ISO_SUSP_ATTRIBUTES *, fsnode *); /* Device number */ int cd9660node_rrip_pn(struct ISO_SUSP_ATTRIBUTES *, fsnode *); /* Symbolic link */ int cd9660node_rrip_SL(struct ISO_SUSP_ATTRIBUTES *, fsnode *); /* Alternate Name function */ void cd9660_rrip_NM(cd9660node *); void cd9660_rrip_add_NM(cd9660node *,const char *); /* Parent and child link function */ int cd9660_rrip_PL(struct ISO_SUSP_ATTRIBUTES *, cd9660node *); int cd9660_rrip_CL(struct ISO_SUSP_ATTRIBUTES *, cd9660node *); int cd9660_rrip_RE(struct ISO_SUSP_ATTRIBUTES *, cd9660node *); int cd9660node_rrip_tf(struct ISO_SUSP_ATTRIBUTES *, fsnode *); /* * Relocation directory function. I'm not quite sure what * sort of parameters are needed, but personally I don't think * any parameters are needed except for the memory address where * the information needs to be put in */ int cd9660node_rrip_re(void *, fsnode *); /* * Don't know if this function is needed because it apparently is an * optional feature that does not really need to be implemented but I * thought I should add it anyway. */ int cd9660_susp_ce (struct ISO_SUSP_ATTRIBUTES *, cd9660node *); int cd9660_susp_pd (struct ISO_SUSP_ATTRIBUTES *, int); int cd9660_susp_sp (struct ISO_SUSP_ATTRIBUTES *, cd9660node *); int cd9660_susp_st (struct ISO_SUSP_ATTRIBUTES *, cd9660node *); struct ISO_SUSP_ATTRIBUTES *cd9660_susp_ER(cd9660node *, u_char, const char *, const char *, const char *); struct ISO_SUSP_ATTRIBUTES *cd9660_susp_ES(struct ISO_SUSP_ATTRIBUTES*, cd9660node *); /* Helper functions */ /* Common SUSP/RRIP functions */ int cd9660_susp_initialize(iso9660_disk *, cd9660node *, cd9660node *, cd9660node *); int cd9660_susp_initialize_node(iso9660_disk *, cd9660node *); struct ISO_SUSP_ATTRIBUTES *cd9660node_susp_create_node(int, int, const char *, int); struct ISO_SUSP_ATTRIBUTES *cd9660node_susp_add_entry(cd9660node *, struct ISO_SUSP_ATTRIBUTES *, struct ISO_SUSP_ATTRIBUTES *, int); /* RRIP specific functions */ int cd9660_rrip_initialize_node(iso9660_disk *, cd9660node *, cd9660node *, cd9660node *); void cd9660_createSL(cd9660node *); /* Functions that probably can be removed */ /* int cd9660node_initialize_node(int, char *); */ #endif