1fc002adaSEnji Cooper /* $NetBSD: iso9660_rrip.c,v 1.14 2014/05/30 13:14:47 martin Exp $ */ 201a0f853SOlivier Houchard 31de7b4b8SPedro F. Giffuni /*- 41de7b4b8SPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-NetBSD 51de7b4b8SPedro F. Giffuni * 601a0f853SOlivier Houchard * Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan 701a0f853SOlivier Houchard * Perez-Rathke and Ram Vedam. All rights reserved. 801a0f853SOlivier Houchard * 901a0f853SOlivier Houchard * This code was written by Daniel Watt, Walter Deignan, Ryan Gabrys, 1001a0f853SOlivier Houchard * Alan Perez-Rathke and Ram Vedam. 1101a0f853SOlivier Houchard * 1201a0f853SOlivier Houchard * Redistribution and use in source and binary forms, with or 1301a0f853SOlivier Houchard * without modification, are permitted provided that the following 1401a0f853SOlivier Houchard * conditions are met: 1501a0f853SOlivier Houchard * 1. Redistributions of source code must retain the above copyright 1601a0f853SOlivier Houchard * notice, this list of conditions and the following disclaimer. 1701a0f853SOlivier Houchard * 2. Redistributions in binary form must reproduce the above 1801a0f853SOlivier Houchard * copyright notice, this list of conditions and the following 1901a0f853SOlivier Houchard * disclaimer in the documentation and/or other materials provided 2001a0f853SOlivier Houchard * with the distribution. 2101a0f853SOlivier Houchard * 2201a0f853SOlivier Houchard * THIS SOFTWARE IS PROVIDED BY DANIEL WATT, WALTER DEIGNAN, RYAN 2301a0f853SOlivier Houchard * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM ``AS IS'' AND ANY EXPRESS OR 2401a0f853SOlivier Houchard * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2501a0f853SOlivier Houchard * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 2601a0f853SOlivier Houchard * DISCLAIMED. IN NO EVENT SHALL DANIEL WATT, WALTER DEIGNAN, RYAN 2701a0f853SOlivier Houchard * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM BE LIABLE FOR ANY DIRECT, INDIRECT, 2801a0f853SOlivier Houchard * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2901a0f853SOlivier Houchard * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 3001a0f853SOlivier Houchard * USE,DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 3101a0f853SOlivier Houchard * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 3201a0f853SOlivier Houchard * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3301a0f853SOlivier Houchard * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 3401a0f853SOlivier Houchard * OF SUCH DAMAGE. 3501a0f853SOlivier Houchard */ 3601a0f853SOlivier Houchard /* This will hold all the function definitions 3701a0f853SOlivier Houchard * defined in iso9660_rrip.h 3801a0f853SOlivier Houchard */ 3901a0f853SOlivier Houchard 405d71efbeSMarcel Moolenaar #include <sys/cdefs.h> 415d71efbeSMarcel Moolenaar __FBSDID("$FreeBSD$"); 425d71efbeSMarcel Moolenaar 435d71efbeSMarcel Moolenaar #include <sys/queue.h> 445d71efbeSMarcel Moolenaar #include <sys/types.h> 455d71efbeSMarcel Moolenaar #include <stdio.h> 465d71efbeSMarcel Moolenaar 4701a0f853SOlivier Houchard #include "makefs.h" 4801a0f853SOlivier Houchard #include "cd9660.h" 4901a0f853SOlivier Houchard #include "iso9660_rrip.h" 505f5598b1SEd Maste #include <util.h> 5101a0f853SOlivier Houchard 5201a0f853SOlivier Houchard static void cd9660_rrip_initialize_inode(cd9660node *); 531631d42aSEd Maste static int cd9660_susp_handle_continuation(iso9660_disk *, cd9660node *); 541631d42aSEd Maste static int cd9660_susp_handle_continuation_common(iso9660_disk *, cd9660node *, 551631d42aSEd Maste int); 5601a0f853SOlivier Houchard 5701a0f853SOlivier Houchard int 581631d42aSEd Maste cd9660_susp_initialize(iso9660_disk *diskStructure, cd9660node *node, 591631d42aSEd Maste cd9660node *parent, cd9660node *grandparent) 6001a0f853SOlivier Houchard { 6101a0f853SOlivier Houchard cd9660node *cn; 6201a0f853SOlivier Houchard int r; 6301a0f853SOlivier Houchard 6401a0f853SOlivier Houchard /* Make sure the node is not NULL. If it is, there are major problems */ 6501a0f853SOlivier Houchard assert(node != NULL); 6601a0f853SOlivier Houchard 6701a0f853SOlivier Houchard if (!(node->type & CD9660_TYPE_DOT) && 6801a0f853SOlivier Houchard !(node->type & CD9660_TYPE_DOTDOT)) 6901a0f853SOlivier Houchard TAILQ_INIT(&(node->head)); 7001a0f853SOlivier Houchard if (node->dot_record != 0) 7101a0f853SOlivier Houchard TAILQ_INIT(&(node->dot_record->head)); 7201a0f853SOlivier Houchard if (node->dot_dot_record != 0) 7301a0f853SOlivier Houchard TAILQ_INIT(&(node->dot_dot_record->head)); 7401a0f853SOlivier Houchard 7501a0f853SOlivier Houchard /* SUSP specific entries here */ 761631d42aSEd Maste if ((r = cd9660_susp_initialize_node(diskStructure, node)) < 0) 7701a0f853SOlivier Houchard return r; 7801a0f853SOlivier Houchard 7901a0f853SOlivier Houchard /* currently called cd9660node_rrip_init_links */ 801631d42aSEd Maste r = cd9660_rrip_initialize_node(diskStructure, node, parent, grandparent); 8101a0f853SOlivier Houchard if (r < 0) 8201a0f853SOlivier Houchard return r; 8301a0f853SOlivier Houchard 8401a0f853SOlivier Houchard /* 8501a0f853SOlivier Houchard * See if we need a CE record, and set all of the 8601a0f853SOlivier Houchard * associated counters. 8701a0f853SOlivier Houchard * 8801a0f853SOlivier Houchard * This should be called after all extensions. After 8901a0f853SOlivier Houchard * this is called, no new records should be added. 9001a0f853SOlivier Houchard */ 911631d42aSEd Maste if ((r = cd9660_susp_handle_continuation(diskStructure, node)) < 0) 9201a0f853SOlivier Houchard return r; 9301a0f853SOlivier Houchard 9401a0f853SOlivier Houchard /* Recurse on children. */ 9501a0f853SOlivier Houchard TAILQ_FOREACH(cn, &node->cn_children, cn_next_child) { 961631d42aSEd Maste if ((r = cd9660_susp_initialize(diskStructure, cn, node, parent)) < 0) 9701a0f853SOlivier Houchard return 0; 9801a0f853SOlivier Houchard } 9901a0f853SOlivier Houchard return 1; 10001a0f853SOlivier Houchard } 10101a0f853SOlivier Houchard 10201a0f853SOlivier Houchard int 1031631d42aSEd Maste cd9660_susp_finalize(iso9660_disk *diskStructure, cd9660node *node) 10401a0f853SOlivier Houchard { 10501a0f853SOlivier Houchard cd9660node *temp; 10601a0f853SOlivier Houchard int r; 10701a0f853SOlivier Houchard 10801a0f853SOlivier Houchard assert(node != NULL); 10901a0f853SOlivier Houchard 1101631d42aSEd Maste if (node == diskStructure->rootNode) 1111631d42aSEd Maste diskStructure->susp_continuation_area_current_free = 0; 11201a0f853SOlivier Houchard 1131631d42aSEd Maste if ((r = cd9660_susp_finalize_node(diskStructure, node)) < 0) 11401a0f853SOlivier Houchard return r; 11501a0f853SOlivier Houchard if ((r = cd9660_rrip_finalize_node(node)) < 0) 11601a0f853SOlivier Houchard return r; 11701a0f853SOlivier Houchard 11801a0f853SOlivier Houchard TAILQ_FOREACH(temp, &node->cn_children, cn_next_child) { 1191631d42aSEd Maste if ((r = cd9660_susp_finalize(diskStructure, temp)) < 0) 12001a0f853SOlivier Houchard return r; 12101a0f853SOlivier Houchard } 12201a0f853SOlivier Houchard return 1; 12301a0f853SOlivier Houchard } 12401a0f853SOlivier Houchard 12501a0f853SOlivier Houchard /* 12601a0f853SOlivier Houchard * If we really wanted to speed things up, we could have some sort of 12701a0f853SOlivier Houchard * lookup table on the SUSP entry type that calls a functor. Or, we could 12801a0f853SOlivier Houchard * combine the functions. These functions are kept separate to allow 12901a0f853SOlivier Houchard * easier addition of other extensions. 13001a0f853SOlivier Houchard 13101a0f853SOlivier Houchard * For the sake of simplicity and clarity, we won't be doing that for now. 13201a0f853SOlivier Houchard */ 13301a0f853SOlivier Houchard 13401a0f853SOlivier Houchard /* 13501a0f853SOlivier Houchard * SUSP needs to update the following types: 13601a0f853SOlivier Houchard * CE (continuation area) 13701a0f853SOlivier Houchard */ 13801a0f853SOlivier Houchard int 1391631d42aSEd Maste cd9660_susp_finalize_node(iso9660_disk *diskStructure, cd9660node *node) 14001a0f853SOlivier Houchard { 14101a0f853SOlivier Houchard struct ISO_SUSP_ATTRIBUTES *t; 14201a0f853SOlivier Houchard 14301a0f853SOlivier Houchard /* Handle CE counters */ 14401a0f853SOlivier Houchard if (node->susp_entry_ce_length > 0) { 14501a0f853SOlivier Houchard node->susp_entry_ce_start = 1461631d42aSEd Maste diskStructure->susp_continuation_area_current_free; 1471631d42aSEd Maste diskStructure->susp_continuation_area_current_free += 14801a0f853SOlivier Houchard node->susp_entry_ce_length; 14901a0f853SOlivier Houchard } 15001a0f853SOlivier Houchard 15101a0f853SOlivier Houchard TAILQ_FOREACH(t, &node->head, rr_ll) { 15201a0f853SOlivier Houchard if (t->susp_type != SUSP_TYPE_SUSP || 15301a0f853SOlivier Houchard t->entry_type != SUSP_ENTRY_SUSP_CE) 15401a0f853SOlivier Houchard continue; 15501a0f853SOlivier Houchard cd9660_bothendian_dword( 1561631d42aSEd Maste diskStructure-> 15701a0f853SOlivier Houchard susp_continuation_area_start_sector, 15801a0f853SOlivier Houchard t->attr.su_entry.CE.ca_sector); 15901a0f853SOlivier Houchard 16001a0f853SOlivier Houchard cd9660_bothendian_dword( 1611631d42aSEd Maste diskStructure-> 16201a0f853SOlivier Houchard susp_continuation_area_start_sector, 16301a0f853SOlivier Houchard t->attr.su_entry.CE.ca_sector); 16401a0f853SOlivier Houchard cd9660_bothendian_dword(node->susp_entry_ce_start, 16501a0f853SOlivier Houchard t->attr.su_entry.CE.offset); 16601a0f853SOlivier Houchard cd9660_bothendian_dword(node->susp_entry_ce_length, 16701a0f853SOlivier Houchard t->attr.su_entry.CE.length); 16801a0f853SOlivier Houchard } 16901a0f853SOlivier Houchard return 0; 17001a0f853SOlivier Houchard } 17101a0f853SOlivier Houchard 17201a0f853SOlivier Houchard int 17301a0f853SOlivier Houchard cd9660_rrip_finalize_node(cd9660node *node) 17401a0f853SOlivier Houchard { 17501a0f853SOlivier Houchard struct ISO_SUSP_ATTRIBUTES *t; 17601a0f853SOlivier Houchard 17701a0f853SOlivier Houchard TAILQ_FOREACH(t, &node->head, rr_ll) { 17801a0f853SOlivier Houchard if (t->susp_type != SUSP_TYPE_RRIP) 17901a0f853SOlivier Houchard continue; 18001a0f853SOlivier Houchard switch (t->entry_type) { 18101a0f853SOlivier Houchard case SUSP_ENTRY_RRIP_CL: 18201a0f853SOlivier Houchard /* Look at rr_relocated*/ 18301a0f853SOlivier Houchard if (node->rr_relocated == NULL) 18401a0f853SOlivier Houchard return -1; 18501a0f853SOlivier Houchard cd9660_bothendian_dword( 18601a0f853SOlivier Houchard node->rr_relocated->fileDataSector, 18701a0f853SOlivier Houchard (unsigned char *) 18801a0f853SOlivier Houchard t->attr.rr_entry.CL.dir_loc); 18901a0f853SOlivier Houchard break; 19001a0f853SOlivier Houchard case SUSP_ENTRY_RRIP_PL: 19101a0f853SOlivier Houchard /* Look at rr_real_parent */ 192852f933dSMarius Strobl if (node->parent == NULL || 193852f933dSMarius Strobl node->parent->rr_real_parent == NULL) 19401a0f853SOlivier Houchard return -1; 19501a0f853SOlivier Houchard cd9660_bothendian_dword( 196852f933dSMarius Strobl node->parent->rr_real_parent->fileDataSector, 19701a0f853SOlivier Houchard (unsigned char *) 19801a0f853SOlivier Houchard t->attr.rr_entry.PL.dir_loc); 19901a0f853SOlivier Houchard break; 20001a0f853SOlivier Houchard } 20101a0f853SOlivier Houchard } 20201a0f853SOlivier Houchard return 0; 20301a0f853SOlivier Houchard } 20401a0f853SOlivier Houchard 20501a0f853SOlivier Houchard static int 2061631d42aSEd Maste cd9660_susp_handle_continuation_common(iso9660_disk *diskStructure, 2071631d42aSEd Maste cd9660node *node, int space) 20801a0f853SOlivier Houchard { 20901a0f853SOlivier Houchard int ca_used, susp_used, susp_used_pre_ce, working; 21001a0f853SOlivier Houchard struct ISO_SUSP_ATTRIBUTES *temp, *pre_ce, *last, *CE, *ST; 21101a0f853SOlivier Houchard 21201a0f853SOlivier Houchard pre_ce = last = NULL; 21301a0f853SOlivier Houchard working = 254 - space; 21401a0f853SOlivier Houchard if (node->su_tail_size > 0) 21501a0f853SOlivier Houchard /* Allow 4 bytes for "ST" record. */ 21601a0f853SOlivier Houchard working -= node->su_tail_size + 4; 21701a0f853SOlivier Houchard /* printf("There are %i bytes to work with\n",working); */ 21801a0f853SOlivier Houchard 21901a0f853SOlivier Houchard susp_used_pre_ce = susp_used = 0; 22001a0f853SOlivier Houchard ca_used = 0; 22101a0f853SOlivier Houchard TAILQ_FOREACH(temp, &node->head, rr_ll) { 22201a0f853SOlivier Houchard if (working < 0) 22301a0f853SOlivier Houchard break; 22401a0f853SOlivier Houchard /* 22501a0f853SOlivier Houchard * printf("SUSP Entry found, length is %i\n", 22601a0f853SOlivier Houchard * CD9660_SUSP_ENTRY_SIZE(temp)); 22701a0f853SOlivier Houchard */ 22801a0f853SOlivier Houchard working -= CD9660_SUSP_ENTRY_SIZE(temp); 22901a0f853SOlivier Houchard if (working >= 0) { 23001a0f853SOlivier Houchard last = temp; 23101a0f853SOlivier Houchard susp_used += CD9660_SUSP_ENTRY_SIZE(temp); 23201a0f853SOlivier Houchard } 23301a0f853SOlivier Houchard if (working >= 28) { 23401a0f853SOlivier Houchard /* 23501a0f853SOlivier Houchard * Remember the last entry after which we 23601a0f853SOlivier Houchard * could insert a "CE" entry. 23701a0f853SOlivier Houchard */ 23801a0f853SOlivier Houchard pre_ce = last; 23901a0f853SOlivier Houchard susp_used_pre_ce = susp_used; 24001a0f853SOlivier Houchard } 24101a0f853SOlivier Houchard } 24201a0f853SOlivier Houchard 24301a0f853SOlivier Houchard /* A CE entry is needed */ 24401a0f853SOlivier Houchard if (working <= 0) { 24501a0f853SOlivier Houchard CE = cd9660node_susp_create_node(SUSP_TYPE_SUSP, 24601a0f853SOlivier Houchard SUSP_ENTRY_SUSP_CE, "CE", SUSP_LOC_ENTRY); 24701a0f853SOlivier Houchard cd9660_susp_ce(CE, node); 24801a0f853SOlivier Houchard /* This will automatically insert at the appropriate location */ 24901a0f853SOlivier Houchard if (pre_ce != NULL) 25001a0f853SOlivier Houchard TAILQ_INSERT_AFTER(&node->head, pre_ce, CE, rr_ll); 25101a0f853SOlivier Houchard else 25201a0f853SOlivier Houchard TAILQ_INSERT_HEAD(&node->head, CE, rr_ll); 25301a0f853SOlivier Houchard last = CE; 25401a0f853SOlivier Houchard susp_used = susp_used_pre_ce + 28; 25501a0f853SOlivier Houchard /* Count how much CA data is necessary */ 25601a0f853SOlivier Houchard for (temp = TAILQ_NEXT(last, rr_ll); temp != NULL; 25701a0f853SOlivier Houchard temp = TAILQ_NEXT(temp, rr_ll)) { 25801a0f853SOlivier Houchard ca_used += CD9660_SUSP_ENTRY_SIZE(temp); 25901a0f853SOlivier Houchard } 26001a0f853SOlivier Houchard } 26101a0f853SOlivier Houchard 26201a0f853SOlivier Houchard /* An ST entry is needed */ 26301a0f853SOlivier Houchard if (node->su_tail_size > 0) { 26401a0f853SOlivier Houchard ST = cd9660node_susp_create_node(SUSP_TYPE_SUSP, 26501a0f853SOlivier Houchard SUSP_ENTRY_SUSP_ST, "ST", SUSP_LOC_ENTRY); 26601a0f853SOlivier Houchard cd9660_susp_st(ST, node); 26701a0f853SOlivier Houchard if (last != NULL) 26801a0f853SOlivier Houchard TAILQ_INSERT_AFTER(&node->head, last, ST, rr_ll); 26901a0f853SOlivier Houchard else 27001a0f853SOlivier Houchard TAILQ_INSERT_HEAD(&node->head, ST, rr_ll); 27101a0f853SOlivier Houchard last = ST; 27201a0f853SOlivier Houchard susp_used += 4; 27301a0f853SOlivier Houchard } 27401a0f853SOlivier Houchard if (last != NULL) 27501a0f853SOlivier Houchard last->last_in_suf = 1; 27601a0f853SOlivier Houchard 27701a0f853SOlivier Houchard node->susp_entry_size = susp_used; 27801a0f853SOlivier Houchard node->susp_entry_ce_length = ca_used; 27901a0f853SOlivier Houchard 2801631d42aSEd Maste diskStructure->susp_continuation_area_size += ca_used; 28101a0f853SOlivier Houchard return 1; 28201a0f853SOlivier Houchard } 28301a0f853SOlivier Houchard 28401a0f853SOlivier Houchard /* See if a continuation entry is needed for each of the different types */ 28501a0f853SOlivier Houchard static int 2861631d42aSEd Maste cd9660_susp_handle_continuation(iso9660_disk *diskStructure, cd9660node *node) 28701a0f853SOlivier Houchard { 28801a0f853SOlivier Houchard assert (node != NULL); 28901a0f853SOlivier Houchard 29001a0f853SOlivier Houchard /* Entry */ 2911631d42aSEd Maste if (cd9660_susp_handle_continuation_common(diskStructure, 29201a0f853SOlivier Houchard node,(int)(node->isoDirRecord->length[0])) < 0) 29301a0f853SOlivier Houchard return 0; 29401a0f853SOlivier Houchard 29501a0f853SOlivier Houchard return 1; 29601a0f853SOlivier Houchard } 29701a0f853SOlivier Houchard 29801a0f853SOlivier Houchard int 2991631d42aSEd Maste cd9660_susp_initialize_node(iso9660_disk *diskStructure, cd9660node *node) 30001a0f853SOlivier Houchard { 30101a0f853SOlivier Houchard struct ISO_SUSP_ATTRIBUTES *temp; 30201a0f853SOlivier Houchard 30301a0f853SOlivier Houchard /* 30401a0f853SOlivier Houchard * Requirements/notes: 30501a0f853SOlivier Houchard * CE: is added for us where needed 30601a0f853SOlivier Houchard * ST: not sure if it is even required, but if so, should be 30701a0f853SOlivier Houchard * handled by the CE code 3083df5ecacSUlrich Spörlein * PD: isn't needed (though might be added for testing) 30901a0f853SOlivier Houchard * SP: is stored ONLY on the . record of the root directory 31001a0f853SOlivier Houchard * ES: not sure 31101a0f853SOlivier Houchard */ 31201a0f853SOlivier Houchard 31301a0f853SOlivier Houchard /* Check for root directory, add SP and ER if needed. */ 31401a0f853SOlivier Houchard if (node->type & CD9660_TYPE_DOT) { 3151631d42aSEd Maste if (node->parent == diskStructure->rootNode) { 31601a0f853SOlivier Houchard temp = cd9660node_susp_create_node(SUSP_TYPE_SUSP, 31701a0f853SOlivier Houchard SUSP_ENTRY_SUSP_SP, "SP", SUSP_LOC_DOT); 31801a0f853SOlivier Houchard cd9660_susp_sp(temp, node); 31901a0f853SOlivier Houchard 32001a0f853SOlivier Houchard /* Should be first entry. */ 32101a0f853SOlivier Houchard TAILQ_INSERT_HEAD(&node->head, temp, rr_ll); 32201a0f853SOlivier Houchard } 32301a0f853SOlivier Houchard } 32401a0f853SOlivier Houchard return 1; 32501a0f853SOlivier Houchard } 32601a0f853SOlivier Houchard 32701a0f853SOlivier Houchard static void 32801a0f853SOlivier Houchard cd9660_rrip_initialize_inode(cd9660node *node) 32901a0f853SOlivier Houchard { 33001a0f853SOlivier Houchard struct ISO_SUSP_ATTRIBUTES *attr; 33101a0f853SOlivier Houchard 33201a0f853SOlivier Houchard /* 33301a0f853SOlivier Houchard * Inode dependent values - this may change, 33401a0f853SOlivier Houchard * but for now virtual files and directories do 33501a0f853SOlivier Houchard * not have an inode structure 33601a0f853SOlivier Houchard */ 33701a0f853SOlivier Houchard 33801a0f853SOlivier Houchard if ((node->node != NULL) && (node->node->inode != NULL)) { 33901a0f853SOlivier Houchard /* PX - POSIX attributes */ 34001a0f853SOlivier Houchard attr = cd9660node_susp_create_node(SUSP_TYPE_RRIP, 34101a0f853SOlivier Houchard SUSP_ENTRY_RRIP_PX, "PX", SUSP_LOC_ENTRY); 34201a0f853SOlivier Houchard cd9660node_rrip_px(attr, node->node); 34301a0f853SOlivier Houchard 34401a0f853SOlivier Houchard TAILQ_INSERT_TAIL(&node->head, attr, rr_ll); 34501a0f853SOlivier Houchard 34601a0f853SOlivier Houchard /* TF - timestamp */ 34701a0f853SOlivier Houchard attr = cd9660node_susp_create_node(SUSP_TYPE_RRIP, 34801a0f853SOlivier Houchard SUSP_ENTRY_RRIP_TF, "TF", SUSP_LOC_ENTRY); 34901a0f853SOlivier Houchard cd9660node_rrip_tf(attr, node->node); 35001a0f853SOlivier Houchard TAILQ_INSERT_TAIL(&node->head, attr, rr_ll); 35101a0f853SOlivier Houchard 35201a0f853SOlivier Houchard /* SL - Symbolic link */ 35301a0f853SOlivier Houchard /* ?????????? Dan - why is this here? */ 35401a0f853SOlivier Houchard if (TAILQ_EMPTY(&node->cn_children) && 35501a0f853SOlivier Houchard node->node->inode != NULL && 35601a0f853SOlivier Houchard S_ISLNK(node->node->inode->st.st_mode)) 35701a0f853SOlivier Houchard cd9660_createSL(node); 35801a0f853SOlivier Houchard 35901a0f853SOlivier Houchard /* PN - device number */ 36001a0f853SOlivier Houchard if (node->node->inode != NULL && 36101a0f853SOlivier Houchard ((S_ISCHR(node->node->inode->st.st_mode) || 36201a0f853SOlivier Houchard S_ISBLK(node->node->inode->st.st_mode)))) { 36301a0f853SOlivier Houchard attr = 36401a0f853SOlivier Houchard cd9660node_susp_create_node(SUSP_TYPE_RRIP, 36501a0f853SOlivier Houchard SUSP_ENTRY_RRIP_PN, "PN", 36601a0f853SOlivier Houchard SUSP_LOC_ENTRY); 36701a0f853SOlivier Houchard cd9660node_rrip_pn(attr, node->node); 36801a0f853SOlivier Houchard TAILQ_INSERT_TAIL(&node->head, attr, rr_ll); 36901a0f853SOlivier Houchard } 37001a0f853SOlivier Houchard } 37101a0f853SOlivier Houchard } 37201a0f853SOlivier Houchard 37301a0f853SOlivier Houchard int 3741631d42aSEd Maste cd9660_rrip_initialize_node(iso9660_disk *diskStructure, cd9660node *node, 3751631d42aSEd Maste cd9660node *parent, cd9660node *grandparent) 37601a0f853SOlivier Houchard { 37701a0f853SOlivier Houchard struct ISO_SUSP_ATTRIBUTES *current = NULL; 37801a0f853SOlivier Houchard 37901a0f853SOlivier Houchard assert(node != NULL); 38001a0f853SOlivier Houchard 38101a0f853SOlivier Houchard if (node->type & CD9660_TYPE_DOT) { 38201a0f853SOlivier Houchard /* 38301a0f853SOlivier Houchard * Handle ER - should be the only entry to appear on 38401a0f853SOlivier Houchard * a "." record 38501a0f853SOlivier Houchard */ 3861631d42aSEd Maste if (node->parent == diskStructure->rootNode) { 38701a0f853SOlivier Houchard cd9660_susp_ER(node, 1, SUSP_RRIP_ER_EXT_ID, 38801a0f853SOlivier Houchard SUSP_RRIP_ER_EXT_DES, SUSP_RRIP_ER_EXT_SRC); 38901a0f853SOlivier Houchard } 39001a0f853SOlivier Houchard if (parent != NULL && parent->node != NULL && 39101a0f853SOlivier Houchard parent->node->inode != NULL) { 39201a0f853SOlivier Houchard /* PX - POSIX attributes */ 39301a0f853SOlivier Houchard current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, 39401a0f853SOlivier Houchard SUSP_ENTRY_RRIP_PX, "PX", SUSP_LOC_ENTRY); 39501a0f853SOlivier Houchard cd9660node_rrip_px(current, parent->node); 39601a0f853SOlivier Houchard TAILQ_INSERT_TAIL(&node->head, current, rr_ll); 39701a0f853SOlivier Houchard } 39801a0f853SOlivier Houchard } else if (node->type & CD9660_TYPE_DOTDOT) { 39901a0f853SOlivier Houchard if (grandparent != NULL && grandparent->node != NULL && 40001a0f853SOlivier Houchard grandparent->node->inode != NULL) { 40101a0f853SOlivier Houchard /* PX - POSIX attributes */ 40201a0f853SOlivier Houchard current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, 40301a0f853SOlivier Houchard SUSP_ENTRY_RRIP_PX, "PX", SUSP_LOC_ENTRY); 40401a0f853SOlivier Houchard cd9660node_rrip_px(current, grandparent->node); 40501a0f853SOlivier Houchard TAILQ_INSERT_TAIL(&node->head, current, rr_ll); 40601a0f853SOlivier Houchard } 407852f933dSMarius Strobl /* Handle PL */ 408852f933dSMarius Strobl if (parent != NULL && parent->rr_real_parent != NULL) { 409852f933dSMarius Strobl current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, 410852f933dSMarius Strobl SUSP_ENTRY_RRIP_PL, "PL", SUSP_LOC_DOTDOT); 411852f933dSMarius Strobl cd9660_rrip_PL(current,node); 412852f933dSMarius Strobl TAILQ_INSERT_TAIL(&node->head, current, rr_ll); 413852f933dSMarius Strobl } 41401a0f853SOlivier Houchard } else { 41501a0f853SOlivier Houchard cd9660_rrip_initialize_inode(node); 41601a0f853SOlivier Houchard 41701a0f853SOlivier Houchard /* 41801a0f853SOlivier Houchard * Not every node needs a NM set - only if the name is 41901a0f853SOlivier Houchard * actually different. IE: If a file is TEST -> TEST, 42001a0f853SOlivier Houchard * no NM. test -> TEST, need a NM 42101a0f853SOlivier Houchard * 42201a0f853SOlivier Houchard * The rr_moved_dir needs to be assigned a NM record as well. 42301a0f853SOlivier Houchard */ 4241631d42aSEd Maste if (node == diskStructure->rr_moved_dir) { 42501a0f853SOlivier Houchard cd9660_rrip_add_NM(node, RRIP_DEFAULT_MOVE_DIR_NAME); 42601a0f853SOlivier Houchard } 42701a0f853SOlivier Houchard else if ((node->node != NULL) && 42801a0f853SOlivier Houchard ((strlen(node->node->name) != 4291bce1a74SMarius Strobl (uint8_t)node->isoDirRecord->name_len[0]) || 43001a0f853SOlivier Houchard (memcmp(node->node->name,node->isoDirRecord->name, 4311bce1a74SMarius Strobl (uint8_t)node->isoDirRecord->name_len[0]) != 0))) { 43201a0f853SOlivier Houchard cd9660_rrip_NM(node); 43301a0f853SOlivier Houchard } 43401a0f853SOlivier Houchard 43501a0f853SOlivier Houchard 43601a0f853SOlivier Houchard 43701a0f853SOlivier Houchard /* Rock ridge directory relocation code here. */ 43801a0f853SOlivier Houchard 43901a0f853SOlivier Houchard /* First handle the CL for the placeholder file. */ 44001a0f853SOlivier Houchard if (node->rr_relocated != NULL) { 44101a0f853SOlivier Houchard current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, 44201a0f853SOlivier Houchard SUSP_ENTRY_RRIP_CL, "CL", SUSP_LOC_ENTRY); 44301a0f853SOlivier Houchard cd9660_rrip_CL(current, node); 44401a0f853SOlivier Houchard TAILQ_INSERT_TAIL(&node->head, current, rr_ll); 44501a0f853SOlivier Houchard } 44601a0f853SOlivier Houchard 44701a0f853SOlivier Houchard /* Handle RE*/ 44801a0f853SOlivier Houchard if (node->rr_real_parent != NULL) { 44901a0f853SOlivier Houchard current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, 45001a0f853SOlivier Houchard SUSP_ENTRY_RRIP_RE, "RE", SUSP_LOC_ENTRY); 45101a0f853SOlivier Houchard cd9660_rrip_RE(current,node); 45201a0f853SOlivier Houchard TAILQ_INSERT_TAIL(&node->head, current, rr_ll); 45301a0f853SOlivier Houchard } 45401a0f853SOlivier Houchard } 45501a0f853SOlivier Houchard return 1; 45601a0f853SOlivier Houchard } 45701a0f853SOlivier Houchard 45801a0f853SOlivier Houchard struct ISO_SUSP_ATTRIBUTES* 45901a0f853SOlivier Houchard cd9660node_susp_create_node(int susp_type, int entry_type, const char *type_id, 46001a0f853SOlivier Houchard int write_loc) 46101a0f853SOlivier Houchard { 46201a0f853SOlivier Houchard struct ISO_SUSP_ATTRIBUTES* temp; 46301a0f853SOlivier Houchard 4645f5598b1SEd Maste temp = emalloc(sizeof(*temp)); 46501a0f853SOlivier Houchard temp->susp_type = susp_type; 46601a0f853SOlivier Houchard temp->entry_type = entry_type; 46701a0f853SOlivier Houchard temp->last_in_suf = 0; 46801a0f853SOlivier Houchard /* Phase this out */ 46901a0f853SOlivier Houchard temp->type_of[0] = type_id[0]; 47001a0f853SOlivier Houchard temp->type_of[1] = type_id[1]; 47101a0f853SOlivier Houchard temp->write_location = write_loc; 47201a0f853SOlivier Houchard 47301a0f853SOlivier Houchard /* 47401a0f853SOlivier Houchard * Since the first four bytes is common, lets go ahead and 47501a0f853SOlivier Houchard * set the type identifier, since we are passing that to this 47601a0f853SOlivier Houchard * function anyhow. 47701a0f853SOlivier Houchard */ 47801a0f853SOlivier Houchard temp->attr.su_entry.SP.h.type[0] = type_id[0]; 47901a0f853SOlivier Houchard temp->attr.su_entry.SP.h.type[1] = type_id[1]; 48001a0f853SOlivier Houchard return temp; 48101a0f853SOlivier Houchard } 48201a0f853SOlivier Houchard 48301a0f853SOlivier Houchard int 48401a0f853SOlivier Houchard cd9660_rrip_PL(struct ISO_SUSP_ATTRIBUTES* p, cd9660node *node __unused) 48501a0f853SOlivier Houchard { 48601a0f853SOlivier Houchard p->attr.rr_entry.PL.h.length[0] = 12; 48701a0f853SOlivier Houchard p->attr.rr_entry.PL.h.version[0] = 1; 48801a0f853SOlivier Houchard return 1; 48901a0f853SOlivier Houchard } 49001a0f853SOlivier Houchard 49101a0f853SOlivier Houchard int 49201a0f853SOlivier Houchard cd9660_rrip_CL(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *node __unused) 49301a0f853SOlivier Houchard { 49401a0f853SOlivier Houchard p->attr.rr_entry.CL.h.length[0] = 12; 49501a0f853SOlivier Houchard p->attr.rr_entry.CL.h.version[0] = 1; 49601a0f853SOlivier Houchard return 1; 49701a0f853SOlivier Houchard } 49801a0f853SOlivier Houchard 49901a0f853SOlivier Houchard int 50001a0f853SOlivier Houchard cd9660_rrip_RE(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *node __unused) 50101a0f853SOlivier Houchard { 502852f933dSMarius Strobl p->attr.rr_entry.RE.h.length[0] = 4; 50301a0f853SOlivier Houchard p->attr.rr_entry.RE.h.version[0] = 1; 50401a0f853SOlivier Houchard return 1; 50501a0f853SOlivier Houchard } 50601a0f853SOlivier Houchard 50701a0f853SOlivier Houchard void 50801a0f853SOlivier Houchard cd9660_createSL(cd9660node *node) 50901a0f853SOlivier Houchard { 51001a0f853SOlivier Houchard struct ISO_SUSP_ATTRIBUTES* current; 51101a0f853SOlivier Houchard int path_count, dir_count, done, i, j, dir_copied; 51201a0f853SOlivier Houchard char temp_cr[255]; 51301a0f853SOlivier Houchard char temp_sl[255]; /* used in copying continuation entry*/ 51401a0f853SOlivier Houchard char* sl_ptr; 51501a0f853SOlivier Houchard 51601a0f853SOlivier Houchard sl_ptr = node->node->symlink; 51701a0f853SOlivier Houchard 51801a0f853SOlivier Houchard done = 0; 51901a0f853SOlivier Houchard path_count = 0; 52001a0f853SOlivier Houchard dir_count = 0; 52101a0f853SOlivier Houchard dir_copied = 0; 52201a0f853SOlivier Houchard current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, 52301a0f853SOlivier Houchard SUSP_ENTRY_RRIP_SL, "SL", SUSP_LOC_ENTRY); 52401a0f853SOlivier Houchard 52501a0f853SOlivier Houchard current->attr.rr_entry.SL.h.version[0] = 1; 52601a0f853SOlivier Houchard current->attr.rr_entry.SL.flags[0] = SL_FLAGS_NONE; 52701a0f853SOlivier Houchard 52801a0f853SOlivier Houchard if (*sl_ptr == '/') { 52901a0f853SOlivier Houchard temp_cr[0] = SL_FLAGS_ROOT; 53001a0f853SOlivier Houchard temp_cr[1] = 0; 53101a0f853SOlivier Houchard memcpy(current->attr.rr_entry.SL.component + path_count, 53201a0f853SOlivier Houchard temp_cr, 2); 53301a0f853SOlivier Houchard path_count += 2; 53401a0f853SOlivier Houchard sl_ptr++; 53501a0f853SOlivier Houchard } 53601a0f853SOlivier Houchard 53701a0f853SOlivier Houchard for (i = 0; i < (dir_count + 2); i++) 53801a0f853SOlivier Houchard temp_cr[i] = '\0'; 53901a0f853SOlivier Houchard 54001a0f853SOlivier Houchard while (!done) { 54101a0f853SOlivier Houchard while ((*sl_ptr != '/') && (*sl_ptr != '\0')) { 54201a0f853SOlivier Houchard dir_copied = 1; 54301a0f853SOlivier Houchard if (*sl_ptr == '.') { 54401a0f853SOlivier Houchard if ((*(sl_ptr + 1) == '/') || (*(sl_ptr + 1) 54501a0f853SOlivier Houchard == '\0')) { 54601a0f853SOlivier Houchard temp_cr[0] = SL_FLAGS_CURRENT; 54701a0f853SOlivier Houchard sl_ptr++; 54801a0f853SOlivier Houchard } else if(*(sl_ptr + 1) == '.') { 54901a0f853SOlivier Houchard if ((*(sl_ptr + 2) == '/') || 55001a0f853SOlivier Houchard (*(sl_ptr + 2) == '\0')) { 55101a0f853SOlivier Houchard temp_cr[0] = SL_FLAGS_PARENT; 55201a0f853SOlivier Houchard sl_ptr += 2; 55301a0f853SOlivier Houchard } 55401a0f853SOlivier Houchard } else { 55501a0f853SOlivier Houchard temp_cr[dir_count+2] = *sl_ptr; 55601a0f853SOlivier Houchard sl_ptr++; 55701a0f853SOlivier Houchard dir_count++; 55801a0f853SOlivier Houchard } 55901a0f853SOlivier Houchard } else { 56001a0f853SOlivier Houchard temp_cr[dir_count + 2] = *sl_ptr; 56101a0f853SOlivier Houchard sl_ptr++; 56201a0f853SOlivier Houchard dir_count++; 56301a0f853SOlivier Houchard } 56401a0f853SOlivier Houchard } 56501a0f853SOlivier Houchard 56601a0f853SOlivier Houchard if ((path_count + dir_count) >= 249) { 56701a0f853SOlivier Houchard current->attr.rr_entry.SL.flags[0] |= SL_FLAGS_CONTINUE; 56801a0f853SOlivier Houchard 56901a0f853SOlivier Houchard j = 0; 57001a0f853SOlivier Houchard 57101a0f853SOlivier Houchard if (path_count <= 249) { 57201a0f853SOlivier Houchard while(j != (249 - path_count)) { 57301a0f853SOlivier Houchard temp_sl[j] = temp_cr[j]; 57401a0f853SOlivier Houchard j++; 57501a0f853SOlivier Houchard } 57601a0f853SOlivier Houchard temp_sl[0] = SL_FLAGS_CONTINUE; 57701a0f853SOlivier Houchard temp_sl[1] = j - 2; 57801a0f853SOlivier Houchard memcpy( 57901a0f853SOlivier Houchard current->attr.rr_entry.SL.component + 58001a0f853SOlivier Houchard path_count, 58101a0f853SOlivier Houchard temp_sl, j); 58201a0f853SOlivier Houchard } 58301a0f853SOlivier Houchard 58401a0f853SOlivier Houchard path_count += j; 58501a0f853SOlivier Houchard current->attr.rr_entry.SL.h.length[0] = path_count + 5; 58601a0f853SOlivier Houchard TAILQ_INSERT_TAIL(&node->head, current, rr_ll); 58701a0f853SOlivier Houchard current= cd9660node_susp_create_node(SUSP_TYPE_RRIP, 58801a0f853SOlivier Houchard SUSP_ENTRY_RRIP_SL, "SL", SUSP_LOC_ENTRY); 58901a0f853SOlivier Houchard current->attr.rr_entry.SL.h.version[0] = 1; 59001a0f853SOlivier Houchard current->attr.rr_entry.SL.flags[0] = SL_FLAGS_NONE; 59101a0f853SOlivier Houchard 59201a0f853SOlivier Houchard path_count = 0; 59301a0f853SOlivier Houchard 59401a0f853SOlivier Houchard if (dir_count > 2) { 59501a0f853SOlivier Houchard while (j != dir_count + 2) { 59601a0f853SOlivier Houchard current->attr.rr_entry.SL.component[ 59701a0f853SOlivier Houchard path_count + 2] = temp_cr[j]; 59801a0f853SOlivier Houchard j++; 59901a0f853SOlivier Houchard path_count++; 60001a0f853SOlivier Houchard } 60101a0f853SOlivier Houchard current->attr.rr_entry.SL.component[1] 60201a0f853SOlivier Houchard = path_count; 60301a0f853SOlivier Houchard path_count+= 2; 60401a0f853SOlivier Houchard } else { 60501a0f853SOlivier Houchard while(j != dir_count) { 60601a0f853SOlivier Houchard current->attr.rr_entry.SL.component[ 60701a0f853SOlivier Houchard path_count+2] = temp_cr[j]; 60801a0f853SOlivier Houchard j++; 60901a0f853SOlivier Houchard path_count++; 61001a0f853SOlivier Houchard } 61101a0f853SOlivier Houchard } 61201a0f853SOlivier Houchard } else { 61301a0f853SOlivier Houchard if (dir_copied == 1) { 61401a0f853SOlivier Houchard temp_cr[1] = dir_count; 61501a0f853SOlivier Houchard memcpy(current->attr.rr_entry.SL.component + 61601a0f853SOlivier Houchard path_count, 61701a0f853SOlivier Houchard temp_cr, dir_count + 2); 61801a0f853SOlivier Houchard path_count += dir_count + 2; 61901a0f853SOlivier Houchard } 62001a0f853SOlivier Houchard } 62101a0f853SOlivier Houchard 62201a0f853SOlivier Houchard if (*sl_ptr == '\0') { 62301a0f853SOlivier Houchard done = 1; 62401a0f853SOlivier Houchard current->attr.rr_entry.SL.h.length[0] = path_count + 5; 62501a0f853SOlivier Houchard TAILQ_INSERT_TAIL(&node->head, current, rr_ll); 62601a0f853SOlivier Houchard } else { 62701a0f853SOlivier Houchard sl_ptr++; 62801a0f853SOlivier Houchard dir_count = 0; 62901a0f853SOlivier Houchard dir_copied = 0; 63001a0f853SOlivier Houchard for(i = 0; i < 255; i++) { 63101a0f853SOlivier Houchard temp_cr[i] = '\0'; 63201a0f853SOlivier Houchard } 63301a0f853SOlivier Houchard } 63401a0f853SOlivier Houchard } 63501a0f853SOlivier Houchard } 63601a0f853SOlivier Houchard 63701a0f853SOlivier Houchard int 63801a0f853SOlivier Houchard cd9660node_rrip_px(struct ISO_SUSP_ATTRIBUTES *v, fsnode *pxinfo) 63901a0f853SOlivier Houchard { 640516e0168SMarius Strobl v->attr.rr_entry.PX.h.length[0] = 44; 64101a0f853SOlivier Houchard v->attr.rr_entry.PX.h.version[0] = 1; 64201a0f853SOlivier Houchard cd9660_bothendian_dword(pxinfo->inode->st.st_mode, 64301a0f853SOlivier Houchard v->attr.rr_entry.PX.mode); 64401a0f853SOlivier Houchard cd9660_bothendian_dword(pxinfo->inode->st.st_nlink, 64501a0f853SOlivier Houchard v->attr.rr_entry.PX.links); 64601a0f853SOlivier Houchard cd9660_bothendian_dword(pxinfo->inode->st.st_uid, 64701a0f853SOlivier Houchard v->attr.rr_entry.PX.uid); 64801a0f853SOlivier Houchard cd9660_bothendian_dword(pxinfo->inode->st.st_gid, 64901a0f853SOlivier Houchard v->attr.rr_entry.PX.gid); 650516e0168SMarius Strobl cd9660_bothendian_dword(pxinfo->inode->st.st_ino, 651516e0168SMarius Strobl v->attr.rr_entry.PX.serial); 65201a0f853SOlivier Houchard 65301a0f853SOlivier Houchard return 1; 65401a0f853SOlivier Houchard } 65501a0f853SOlivier Houchard 65601a0f853SOlivier Houchard int 65701a0f853SOlivier Houchard cd9660node_rrip_pn(struct ISO_SUSP_ATTRIBUTES *pn_field, fsnode *fnode) 65801a0f853SOlivier Houchard { 65901a0f853SOlivier Houchard pn_field->attr.rr_entry.PN.h.length[0] = 20; 66001a0f853SOlivier Houchard pn_field->attr.rr_entry.PN.h.version[0] = 1; 66101a0f853SOlivier Houchard 662fc002adaSEnji Cooper if (sizeof (fnode->inode->st.st_rdev) > 4) 663fc002adaSEnji Cooper cd9660_bothendian_dword( 664fc002adaSEnji Cooper (uint64_t)fnode->inode->st.st_rdev >> 32, 66501a0f853SOlivier Houchard pn_field->attr.rr_entry.PN.high); 66601a0f853SOlivier Houchard else 66701a0f853SOlivier Houchard cd9660_bothendian_dword(0, pn_field->attr.rr_entry.PN.high); 66801a0f853SOlivier Houchard 669fc002adaSEnji Cooper cd9660_bothendian_dword(fnode->inode->st.st_rdev & 0xffffffff, 67001a0f853SOlivier Houchard pn_field->attr.rr_entry.PN.low); 67101a0f853SOlivier Houchard return 1; 67201a0f853SOlivier Houchard } 67301a0f853SOlivier Houchard 67401a0f853SOlivier Houchard #if 0 67501a0f853SOlivier Houchard int 67601a0f853SOlivier Houchard cd9660node_rrip_nm(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *file_node) 67701a0f853SOlivier Houchard { 67801a0f853SOlivier Houchard int nm_length = strlen(file_node->isoDirRecord->name) + 5; 67901a0f853SOlivier Houchard p->attr.rr_entry.NM.h.type[0] = 'N'; 68001a0f853SOlivier Houchard p->attr.rr_entry.NM.h.type[1] = 'M'; 68101a0f853SOlivier Houchard sprintf(p->attr.rr_entry.NM.altname, "%s", file_node->isoDirRecord->name); 68201a0f853SOlivier Houchard p->attr.rr_entry.NM.h.length[0] = (unsigned char)nm_length; 68301a0f853SOlivier Houchard p->attr.rr_entry.NM.h.version[0] = (unsigned char)1; 68401a0f853SOlivier Houchard p->attr.rr_entry.NM.flags[0] = (unsigned char) NM_PARENT; 68501a0f853SOlivier Houchard return 1; 68601a0f853SOlivier Houchard } 68701a0f853SOlivier Houchard #endif 68801a0f853SOlivier Houchard 68901a0f853SOlivier Houchard int 69001a0f853SOlivier Houchard cd9660node_rrip_tf(struct ISO_SUSP_ATTRIBUTES *p, fsnode *_node) 69101a0f853SOlivier Houchard { 69201a0f853SOlivier Houchard p->attr.rr_entry.TF.flags[0] = TF_MODIFY | TF_ACCESS | TF_ATTRIBUTES; 6931bce1a74SMarius Strobl p->attr.rr_entry.TF.h.length[0] = 5; 69401a0f853SOlivier Houchard p->attr.rr_entry.TF.h.version[0] = 1; 69501a0f853SOlivier Houchard 69601a0f853SOlivier Houchard /* 69701a0f853SOlivier Houchard * Need to add creation time, backup time, 69801a0f853SOlivier Houchard * expiration time, and effective time. 69901a0f853SOlivier Houchard */ 70001a0f853SOlivier Houchard 70101a0f853SOlivier Houchard cd9660_time_915(p->attr.rr_entry.TF.timestamp, 70201a0f853SOlivier Houchard _node->inode->st.st_atime); 70301a0f853SOlivier Houchard p->attr.rr_entry.TF.h.length[0] += 7; 70401a0f853SOlivier Houchard 70501a0f853SOlivier Houchard cd9660_time_915(p->attr.rr_entry.TF.timestamp + 7, 70601a0f853SOlivier Houchard _node->inode->st.st_mtime); 70701a0f853SOlivier Houchard p->attr.rr_entry.TF.h.length[0] += 7; 70801a0f853SOlivier Houchard 70901a0f853SOlivier Houchard cd9660_time_915(p->attr.rr_entry.TF.timestamp + 14, 71001a0f853SOlivier Houchard _node->inode->st.st_ctime); 71101a0f853SOlivier Houchard p->attr.rr_entry.TF.h.length[0] += 7; 71201a0f853SOlivier Houchard return 1; 71301a0f853SOlivier Houchard } 71401a0f853SOlivier Houchard 71501a0f853SOlivier Houchard int 71601a0f853SOlivier Houchard cd9660_susp_sp(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *spinfo __unused) 71701a0f853SOlivier Houchard { 71801a0f853SOlivier Houchard p->attr.su_entry.SP.h.length[0] = 7; 71901a0f853SOlivier Houchard p->attr.su_entry.SP.h.version[0] = 1; 72001a0f853SOlivier Houchard p->attr.su_entry.SP.check[0] = 0xBE; 72101a0f853SOlivier Houchard p->attr.su_entry.SP.check[1] = 0xEF; 72201a0f853SOlivier Houchard p->attr.su_entry.SP.len_skp[0] = 0; 72301a0f853SOlivier Houchard return 1; 72401a0f853SOlivier Houchard } 72501a0f853SOlivier Houchard 72601a0f853SOlivier Houchard int 72701a0f853SOlivier Houchard cd9660_susp_st(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *stinfo __unused) 72801a0f853SOlivier Houchard { 72901a0f853SOlivier Houchard p->attr.su_entry.ST.h.type[0] = 'S'; 73001a0f853SOlivier Houchard p->attr.su_entry.ST.h.type[1] = 'T'; 73101a0f853SOlivier Houchard p->attr.su_entry.ST.h.length[0] = 4; 73201a0f853SOlivier Houchard p->attr.su_entry.ST.h.version[0] = 1; 73301a0f853SOlivier Houchard return 1; 73401a0f853SOlivier Houchard } 73501a0f853SOlivier Houchard 73601a0f853SOlivier Houchard int 73701a0f853SOlivier Houchard cd9660_susp_ce(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *spinfo __unused) 73801a0f853SOlivier Houchard { 73901a0f853SOlivier Houchard p->attr.su_entry.CE.h.length[0] = 28; 74001a0f853SOlivier Houchard p->attr.su_entry.CE.h.version[0] = 1; 74101a0f853SOlivier Houchard /* Other attributes dont matter right now, will be updated later */ 74201a0f853SOlivier Houchard return 1; 74301a0f853SOlivier Houchard } 74401a0f853SOlivier Houchard 74501a0f853SOlivier Houchard int 74601a0f853SOlivier Houchard cd9660_susp_pd(struct ISO_SUSP_ATTRIBUTES *p __unused, int length __unused) 74701a0f853SOlivier Houchard { 74801a0f853SOlivier Houchard return 1; 74901a0f853SOlivier Houchard } 75001a0f853SOlivier Houchard 75101a0f853SOlivier Houchard void 75201a0f853SOlivier Houchard cd9660_rrip_add_NM(cd9660node *node, const char *name) 75301a0f853SOlivier Houchard { 75401a0f853SOlivier Houchard int working,len; 75501a0f853SOlivier Houchard const char *p; 75601a0f853SOlivier Houchard struct ISO_SUSP_ATTRIBUTES *r; 75701a0f853SOlivier Houchard 75801a0f853SOlivier Houchard /* 7595f285d55SGordon Bergling * Each NM record has 254 bytes to work with. This means that 76001a0f853SOlivier Houchard * the name data itself only has 249 bytes to work with. So, a 76101a0f853SOlivier Houchard * name with 251 characters would require two nm records. 76201a0f853SOlivier Houchard */ 76301a0f853SOlivier Houchard p = name; 76401a0f853SOlivier Houchard working = 1; 76501a0f853SOlivier Houchard while (working) { 76601a0f853SOlivier Houchard r = cd9660node_susp_create_node(SUSP_TYPE_RRIP, 76701a0f853SOlivier Houchard SUSP_ENTRY_RRIP_NM, "NM", SUSP_LOC_ENTRY); 76801a0f853SOlivier Houchard r->attr.rr_entry.NM.h.version[0] = 1; 76901a0f853SOlivier Houchard r->attr.rr_entry.NM.flags[0] = RRIP_NM_FLAGS_NONE; 77001a0f853SOlivier Houchard len = strlen(p); 77101a0f853SOlivier Houchard 77201a0f853SOlivier Houchard if (len > 249) { 77301a0f853SOlivier Houchard len = 249; 77401a0f853SOlivier Houchard r->attr.rr_entry.NM.flags[0] = RRIP_NM_FLAGS_CONTINUE; 77501a0f853SOlivier Houchard } else { 77601a0f853SOlivier Houchard working = 0; 77701a0f853SOlivier Houchard } 77801a0f853SOlivier Houchard memcpy(r->attr.rr_entry.NM.altname, p, len); 77901a0f853SOlivier Houchard r->attr.rr_entry.NM.h.length[0] = 5 + len; 78001a0f853SOlivier Houchard 78101a0f853SOlivier Houchard TAILQ_INSERT_TAIL(&node->head, r, rr_ll); 78201a0f853SOlivier Houchard 78301a0f853SOlivier Houchard p += len; 78401a0f853SOlivier Houchard } 78501a0f853SOlivier Houchard } 78601a0f853SOlivier Houchard 78701a0f853SOlivier Houchard void 78801a0f853SOlivier Houchard cd9660_rrip_NM(cd9660node *node) 78901a0f853SOlivier Houchard { 79001a0f853SOlivier Houchard cd9660_rrip_add_NM(node, node->node->name); 79101a0f853SOlivier Houchard } 79201a0f853SOlivier Houchard 79301a0f853SOlivier Houchard struct ISO_SUSP_ATTRIBUTES* 79401a0f853SOlivier Houchard cd9660_susp_ER(cd9660node *node, 79501a0f853SOlivier Houchard u_char ext_version, const char* ext_id, const char* ext_des, 79601a0f853SOlivier Houchard const char* ext_src) 79701a0f853SOlivier Houchard { 79801a0f853SOlivier Houchard int l; 79901a0f853SOlivier Houchard struct ISO_SUSP_ATTRIBUTES *r; 80001a0f853SOlivier Houchard 80101a0f853SOlivier Houchard r = cd9660node_susp_create_node(SUSP_TYPE_SUSP, 80201a0f853SOlivier Houchard SUSP_ENTRY_SUSP_ER, "ER", SUSP_LOC_DOT); 80301a0f853SOlivier Houchard 80401a0f853SOlivier Houchard /* Fixed data is 8 bytes */ 80501a0f853SOlivier Houchard r->attr.su_entry.ER.h.length[0] = 8; 80601a0f853SOlivier Houchard r->attr.su_entry.ER.h.version[0] = 1; 80701a0f853SOlivier Houchard 80801a0f853SOlivier Houchard r->attr.su_entry.ER.len_id[0] = (u_char)strlen(ext_id); 80901a0f853SOlivier Houchard r->attr.su_entry.ER.len_des[0] = (u_char)strlen(ext_des); 81001a0f853SOlivier Houchard r->attr.su_entry.ER.len_src[0] = (u_char)strlen(ext_src); 81101a0f853SOlivier Houchard 81201a0f853SOlivier Houchard l = r->attr.su_entry.ER.len_id[0] + 81301a0f853SOlivier Houchard r->attr.su_entry.ER.len_src[0] + 81401a0f853SOlivier Houchard r->attr.su_entry.ER.len_des[0]; 81501a0f853SOlivier Houchard 81601a0f853SOlivier Houchard /* Everything must fit. */ 81701a0f853SOlivier Houchard assert(l + r->attr.su_entry.ER.h.length[0] <= 254); 81801a0f853SOlivier Houchard 81901a0f853SOlivier Houchard r->attr.su_entry.ER.h.length[0] += (u_char)l; 82001a0f853SOlivier Houchard 82101a0f853SOlivier Houchard 82201a0f853SOlivier Houchard r->attr.su_entry.ER.ext_ver[0] = ext_version; 82301a0f853SOlivier Houchard memcpy(r->attr.su_entry.ER.ext_data, ext_id, 82401a0f853SOlivier Houchard (int)r->attr.su_entry.ER.len_id[0]); 82501a0f853SOlivier Houchard l = (int) r->attr.su_entry.ER.len_id[0]; 82601a0f853SOlivier Houchard memcpy(r->attr.su_entry.ER.ext_data + l,ext_des, 82701a0f853SOlivier Houchard (int)r->attr.su_entry.ER.len_des[0]); 82801a0f853SOlivier Houchard 82901a0f853SOlivier Houchard l += (int)r->attr.su_entry.ER.len_des[0]; 83001a0f853SOlivier Houchard memcpy(r->attr.su_entry.ER.ext_data + l,ext_src, 83101a0f853SOlivier Houchard (int)r->attr.su_entry.ER.len_src[0]); 83201a0f853SOlivier Houchard 83301a0f853SOlivier Houchard TAILQ_INSERT_TAIL(&node->head, r, rr_ll); 83401a0f853SOlivier Houchard return r; 83501a0f853SOlivier Houchard } 83601a0f853SOlivier Houchard 83701a0f853SOlivier Houchard struct ISO_SUSP_ATTRIBUTES* 83801a0f853SOlivier Houchard cd9660_susp_ES(struct ISO_SUSP_ATTRIBUTES *last __unused, cd9660node *node __unused) 83901a0f853SOlivier Houchard { 84001a0f853SOlivier Houchard return NULL; 84101a0f853SOlivier Houchard } 842