xref: /minix3/usr.sbin/makefs/cd9660/iso9660_rrip.c (revision 3472022b8bc03355d7d3c40541b929ab4122de1a)
1*3472022bSJean-Baptiste Boric /*	$NetBSD: iso9660_rrip.c,v 1.14 2014/05/30 13:14:47 martin Exp $	*/
29f988b79SJean-Baptiste Boric 
39f988b79SJean-Baptiste Boric /*
49f988b79SJean-Baptiste Boric  * Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan
59f988b79SJean-Baptiste Boric  * Perez-Rathke and Ram Vedam.  All rights reserved.
69f988b79SJean-Baptiste Boric  *
79f988b79SJean-Baptiste Boric  * This code was written by Daniel Watt, Walter Deignan, Ryan Gabrys,
89f988b79SJean-Baptiste Boric  * Alan Perez-Rathke and Ram Vedam.
99f988b79SJean-Baptiste Boric  *
109f988b79SJean-Baptiste Boric  * Redistribution and use in source and binary forms, with or
119f988b79SJean-Baptiste Boric  * without modification, are permitted provided that the following
129f988b79SJean-Baptiste Boric  * conditions are met:
139f988b79SJean-Baptiste Boric  * 1. Redistributions of source code must retain the above copyright
149f988b79SJean-Baptiste Boric  *    notice, this list of conditions and the following disclaimer.
159f988b79SJean-Baptiste Boric  * 2. Redistributions in binary form must reproduce the above
169f988b79SJean-Baptiste Boric  *    copyright notice, this list of conditions and the following
179f988b79SJean-Baptiste Boric  *    disclaimer in the documentation and/or other materials provided
189f988b79SJean-Baptiste Boric  *    with the distribution.
199f988b79SJean-Baptiste Boric  *
209f988b79SJean-Baptiste Boric  * THIS SOFTWARE IS PROVIDED BY DANIEL WATT, WALTER DEIGNAN, RYAN
219f988b79SJean-Baptiste Boric  * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM ``AS IS'' AND ANY EXPRESS OR
229f988b79SJean-Baptiste Boric  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
239f988b79SJean-Baptiste Boric  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
249f988b79SJean-Baptiste Boric  * DISCLAIMED.  IN NO EVENT SHALL DANIEL WATT, WALTER DEIGNAN, RYAN
259f988b79SJean-Baptiste Boric  * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM BE LIABLE FOR ANY DIRECT, INDIRECT,
269f988b79SJean-Baptiste Boric  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
279f988b79SJean-Baptiste Boric  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
289f988b79SJean-Baptiste Boric  * USE,DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
299f988b79SJean-Baptiste Boric  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
309f988b79SJean-Baptiste Boric  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
319f988b79SJean-Baptiste Boric  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
329f988b79SJean-Baptiste Boric  * OF SUCH DAMAGE.
339f988b79SJean-Baptiste Boric  */
349f988b79SJean-Baptiste Boric /* This will hold all the function definitions
359f988b79SJean-Baptiste Boric  * defined in iso9660_rrip.h
369f988b79SJean-Baptiste Boric  */
379f988b79SJean-Baptiste Boric 
389f988b79SJean-Baptiste Boric #include "makefs.h"
399f988b79SJean-Baptiste Boric #include "cd9660.h"
409f988b79SJean-Baptiste Boric #include "iso9660_rrip.h"
419f988b79SJean-Baptiste Boric #include <sys/queue.h>
429f988b79SJean-Baptiste Boric #include <stdio.h>
439f988b79SJean-Baptiste Boric #include <util.h>
449f988b79SJean-Baptiste Boric 
459f988b79SJean-Baptiste Boric #include <sys/cdefs.h>
469f988b79SJean-Baptiste Boric #if defined(__RCSID) && !defined(__lint)
47*3472022bSJean-Baptiste Boric __RCSID("$NetBSD: iso9660_rrip.c,v 1.14 2014/05/30 13:14:47 martin Exp $");
489f988b79SJean-Baptiste Boric #endif  /* !__lint */
499f988b79SJean-Baptiste Boric 
509f988b79SJean-Baptiste Boric static void cd9660_rrip_initialize_inode(cd9660node *);
519f988b79SJean-Baptiste Boric static int cd9660_susp_handle_continuation(iso9660_disk *, cd9660node *);
529f988b79SJean-Baptiste Boric static int cd9660_susp_handle_continuation_common(iso9660_disk *, cd9660node *,
539f988b79SJean-Baptiste Boric     int);
549f988b79SJean-Baptiste Boric 
559f988b79SJean-Baptiste Boric int
cd9660_susp_initialize(iso9660_disk * diskStructure,cd9660node * node,cd9660node * parent,cd9660node * grandparent)569f988b79SJean-Baptiste Boric cd9660_susp_initialize(iso9660_disk *diskStructure, cd9660node *node,
579f988b79SJean-Baptiste Boric     cd9660node *parent, cd9660node *grandparent)
589f988b79SJean-Baptiste Boric {
599f988b79SJean-Baptiste Boric 	cd9660node *cn;
609f988b79SJean-Baptiste Boric 	int r;
619f988b79SJean-Baptiste Boric 
629f988b79SJean-Baptiste Boric 	/* Make sure the node is not NULL. If it is, there are major problems */
639f988b79SJean-Baptiste Boric 	assert(node != NULL);
649f988b79SJean-Baptiste Boric 
659f988b79SJean-Baptiste Boric 	if (!(node->type & CD9660_TYPE_DOT) &&
669f988b79SJean-Baptiste Boric 	    !(node->type & CD9660_TYPE_DOTDOT))
679f988b79SJean-Baptiste Boric 		TAILQ_INIT(&(node->head));
689f988b79SJean-Baptiste Boric 	if (node->dot_record != 0)
699f988b79SJean-Baptiste Boric 		TAILQ_INIT(&(node->dot_record->head));
709f988b79SJean-Baptiste Boric 	if (node->dot_dot_record != 0)
719f988b79SJean-Baptiste Boric 		TAILQ_INIT(&(node->dot_dot_record->head));
729f988b79SJean-Baptiste Boric 
739f988b79SJean-Baptiste Boric 	 /* SUSP specific entries here */
749f988b79SJean-Baptiste Boric 	if ((r = cd9660_susp_initialize_node(diskStructure, node)) < 0)
759f988b79SJean-Baptiste Boric 		return r;
769f988b79SJean-Baptiste Boric 
779f988b79SJean-Baptiste Boric 	/* currently called cd9660node_rrip_init_links */
789f988b79SJean-Baptiste Boric 	r = cd9660_rrip_initialize_node(diskStructure, node, parent, grandparent);
799f988b79SJean-Baptiste Boric 	if (r < 0)
809f988b79SJean-Baptiste Boric 		return r;
819f988b79SJean-Baptiste Boric 
829f988b79SJean-Baptiste Boric 	/*
839f988b79SJean-Baptiste Boric 	 * See if we need a CE record, and set all of the
849f988b79SJean-Baptiste Boric 	 * associated counters.
859f988b79SJean-Baptiste Boric 	 *
869f988b79SJean-Baptiste Boric 	 * This should be called after all extensions. After
879f988b79SJean-Baptiste Boric 	 * this is called, no new records should be added.
889f988b79SJean-Baptiste Boric 	 */
899f988b79SJean-Baptiste Boric 	if ((r = cd9660_susp_handle_continuation(diskStructure, node)) < 0)
909f988b79SJean-Baptiste Boric 		return r;
919f988b79SJean-Baptiste Boric 
929f988b79SJean-Baptiste Boric 	/* Recurse on children. */
939f988b79SJean-Baptiste Boric 	TAILQ_FOREACH(cn, &node->cn_children, cn_next_child) {
949f988b79SJean-Baptiste Boric 		if ((r = cd9660_susp_initialize(diskStructure, cn, node, parent)) < 0)
959f988b79SJean-Baptiste Boric 			return 0;
969f988b79SJean-Baptiste Boric 	}
979f988b79SJean-Baptiste Boric 	return 1;
989f988b79SJean-Baptiste Boric }
999f988b79SJean-Baptiste Boric 
1009f988b79SJean-Baptiste Boric int
cd9660_susp_finalize(iso9660_disk * diskStructure,cd9660node * node)1019f988b79SJean-Baptiste Boric cd9660_susp_finalize(iso9660_disk *diskStructure, cd9660node *node)
1029f988b79SJean-Baptiste Boric {
1039f988b79SJean-Baptiste Boric 	cd9660node *temp;
1049f988b79SJean-Baptiste Boric 	int r;
1059f988b79SJean-Baptiste Boric 
1069f988b79SJean-Baptiste Boric 	assert(node != NULL);
1079f988b79SJean-Baptiste Boric 
1089f988b79SJean-Baptiste Boric 	if (node == diskStructure->rootNode)
1099f988b79SJean-Baptiste Boric 		diskStructure->susp_continuation_area_current_free = 0;
1109f988b79SJean-Baptiste Boric 
1119f988b79SJean-Baptiste Boric 	if ((r = cd9660_susp_finalize_node(diskStructure, node)) < 0)
1129f988b79SJean-Baptiste Boric 		return r;
1139f988b79SJean-Baptiste Boric 	if ((r = cd9660_rrip_finalize_node(diskStructure, node)) < 0)
1149f988b79SJean-Baptiste Boric 		return r;
1159f988b79SJean-Baptiste Boric 
1169f988b79SJean-Baptiste Boric 	TAILQ_FOREACH(temp, &node->cn_children, cn_next_child) {
1179f988b79SJean-Baptiste Boric 		if ((r = cd9660_susp_finalize(diskStructure, temp)) < 0)
1189f988b79SJean-Baptiste Boric 			return r;
1199f988b79SJean-Baptiste Boric 	}
1209f988b79SJean-Baptiste Boric 	return 1;
1219f988b79SJean-Baptiste Boric }
1229f988b79SJean-Baptiste Boric 
1239f988b79SJean-Baptiste Boric /*
1249f988b79SJean-Baptiste Boric  * If we really wanted to speed things up, we could have some sort of
1259f988b79SJean-Baptiste Boric  * lookup table on the SUSP entry type that calls a functor. Or, we could
1269f988b79SJean-Baptiste Boric  * combine the functions. These functions are kept separate to allow
1279f988b79SJean-Baptiste Boric  * easier addition of other extensions.
1289f988b79SJean-Baptiste Boric 
1299f988b79SJean-Baptiste Boric  * For the sake of simplicity and clarity, we won't be doing that for now.
1309f988b79SJean-Baptiste Boric  */
1319f988b79SJean-Baptiste Boric 
1329f988b79SJean-Baptiste Boric /*
1339f988b79SJean-Baptiste Boric  * SUSP needs to update the following types:
1349f988b79SJean-Baptiste Boric  * CE (continuation area)
1359f988b79SJean-Baptiste Boric  */
1369f988b79SJean-Baptiste Boric int
cd9660_susp_finalize_node(iso9660_disk * diskStructure,cd9660node * node)1379f988b79SJean-Baptiste Boric cd9660_susp_finalize_node(iso9660_disk *diskStructure, cd9660node *node)
1389f988b79SJean-Baptiste Boric {
1399f988b79SJean-Baptiste Boric 	struct ISO_SUSP_ATTRIBUTES *t;
1409f988b79SJean-Baptiste Boric 
1419f988b79SJean-Baptiste Boric 	/* Handle CE counters */
1429f988b79SJean-Baptiste Boric 	if (node->susp_entry_ce_length > 0) {
1439f988b79SJean-Baptiste Boric 		node->susp_entry_ce_start =
1449f988b79SJean-Baptiste Boric 		    diskStructure->susp_continuation_area_current_free;
1459f988b79SJean-Baptiste Boric 		diskStructure->susp_continuation_area_current_free +=
1469f988b79SJean-Baptiste Boric 		    node->susp_entry_ce_length;
1479f988b79SJean-Baptiste Boric 	}
1489f988b79SJean-Baptiste Boric 
1499f988b79SJean-Baptiste Boric 	TAILQ_FOREACH(t, &node->head, rr_ll) {
1509f988b79SJean-Baptiste Boric 		if (t->susp_type != SUSP_TYPE_SUSP ||
1519f988b79SJean-Baptiste Boric 		    t->entry_type != SUSP_ENTRY_SUSP_CE)
1529f988b79SJean-Baptiste Boric 			continue;
1539f988b79SJean-Baptiste Boric 		cd9660_bothendian_dword(
1549f988b79SJean-Baptiste Boric 			diskStructure->
1559f988b79SJean-Baptiste Boric 			  susp_continuation_area_start_sector,
1569f988b79SJean-Baptiste Boric 			t->attr.su_entry.CE.ca_sector);
1579f988b79SJean-Baptiste Boric 
1589f988b79SJean-Baptiste Boric 		cd9660_bothendian_dword(
1599f988b79SJean-Baptiste Boric 			diskStructure->
1609f988b79SJean-Baptiste Boric 			  susp_continuation_area_start_sector,
1619f988b79SJean-Baptiste Boric 			t->attr.su_entry.CE.ca_sector);
1629f988b79SJean-Baptiste Boric 		cd9660_bothendian_dword(node->susp_entry_ce_start,
1639f988b79SJean-Baptiste Boric 			t->attr.su_entry.CE.offset);
1649f988b79SJean-Baptiste Boric 		cd9660_bothendian_dword(node->susp_entry_ce_length,
1659f988b79SJean-Baptiste Boric 			t->attr.su_entry.CE.length);
1669f988b79SJean-Baptiste Boric 	}
1679f988b79SJean-Baptiste Boric 	return 0;
1689f988b79SJean-Baptiste Boric }
1699f988b79SJean-Baptiste Boric 
1709f988b79SJean-Baptiste Boric int
cd9660_rrip_finalize_node(iso9660_disk * diskStructure __unused,cd9660node * node)1719f988b79SJean-Baptiste Boric cd9660_rrip_finalize_node(iso9660_disk *diskStructure __unused,
1729f988b79SJean-Baptiste Boric     cd9660node *node)
1739f988b79SJean-Baptiste Boric {
1749f988b79SJean-Baptiste Boric 	struct ISO_SUSP_ATTRIBUTES *t;
1759f988b79SJean-Baptiste Boric 
1769f988b79SJean-Baptiste Boric 	TAILQ_FOREACH(t, &node->head, rr_ll) {
1779f988b79SJean-Baptiste Boric 		if (t->susp_type != SUSP_TYPE_RRIP)
1789f988b79SJean-Baptiste Boric 			continue;
1799f988b79SJean-Baptiste Boric 		switch (t->entry_type) {
1809f988b79SJean-Baptiste Boric 		case SUSP_ENTRY_RRIP_CL:
1819f988b79SJean-Baptiste Boric 			/* Look at rr_relocated*/
1829f988b79SJean-Baptiste Boric 			if (node->rr_relocated == NULL)
1839f988b79SJean-Baptiste Boric 				return -1;
1849f988b79SJean-Baptiste Boric 			cd9660_bothendian_dword(
1859f988b79SJean-Baptiste Boric 				node->rr_relocated->fileDataSector,
1869f988b79SJean-Baptiste Boric 				(unsigned char *)
1879f988b79SJean-Baptiste Boric 				    t->attr.rr_entry.CL.dir_loc);
1889f988b79SJean-Baptiste Boric 			break;
1899f988b79SJean-Baptiste Boric 		case SUSP_ENTRY_RRIP_PL:
1909f988b79SJean-Baptiste Boric 			/* Look at rr_real_parent */
1919f988b79SJean-Baptiste Boric 			if (node->parent == NULL ||
1929f988b79SJean-Baptiste Boric 			    node->parent->rr_real_parent == NULL)
1939f988b79SJean-Baptiste Boric 				return -1;
1949f988b79SJean-Baptiste Boric 			cd9660_bothendian_dword(
1959f988b79SJean-Baptiste Boric 				node->parent->rr_real_parent->fileDataSector,
1969f988b79SJean-Baptiste Boric 				(unsigned char *)
1979f988b79SJean-Baptiste Boric 				    t->attr.rr_entry.PL.dir_loc);
1989f988b79SJean-Baptiste Boric 			break;
1999f988b79SJean-Baptiste Boric 		}
2009f988b79SJean-Baptiste Boric 	}
2019f988b79SJean-Baptiste Boric 	return 0;
2029f988b79SJean-Baptiste Boric }
2039f988b79SJean-Baptiste Boric 
2049f988b79SJean-Baptiste Boric static int
cd9660_susp_handle_continuation_common(iso9660_disk * diskStructure,cd9660node * node,int space)2059f988b79SJean-Baptiste Boric cd9660_susp_handle_continuation_common(iso9660_disk *diskStructure,
2069f988b79SJean-Baptiste Boric     cd9660node *node, int space)
2079f988b79SJean-Baptiste Boric {
2089f988b79SJean-Baptiste Boric 	int ca_used, susp_used, susp_used_pre_ce, working;
2099f988b79SJean-Baptiste Boric 	struct ISO_SUSP_ATTRIBUTES *temp, *pre_ce, *last, *CE, *ST;
2109f988b79SJean-Baptiste Boric 
2119f988b79SJean-Baptiste Boric 	pre_ce = last = NULL;
2129f988b79SJean-Baptiste Boric 	working = 254 - space;
2139f988b79SJean-Baptiste Boric 	if (node->su_tail_size > 0)
2149f988b79SJean-Baptiste Boric 		/* Allow 4 bytes for "ST" record. */
2159f988b79SJean-Baptiste Boric 		working -= node->su_tail_size + 4;
2169f988b79SJean-Baptiste Boric 	/* printf("There are %i bytes to work with\n",working); */
2179f988b79SJean-Baptiste Boric 
2189f988b79SJean-Baptiste Boric 	susp_used_pre_ce = susp_used = 0;
2199f988b79SJean-Baptiste Boric 	ca_used = 0;
2209f988b79SJean-Baptiste Boric 	TAILQ_FOREACH(temp, &node->head, rr_ll) {
2219f988b79SJean-Baptiste Boric 		if (working < 0)
2229f988b79SJean-Baptiste Boric 			break;
2239f988b79SJean-Baptiste Boric 		/*
2249f988b79SJean-Baptiste Boric 		 * printf("SUSP Entry found, length is %i\n",
2259f988b79SJean-Baptiste Boric 		 * CD9660_SUSP_ENTRY_SIZE(temp));
2269f988b79SJean-Baptiste Boric 		 */
2279f988b79SJean-Baptiste Boric 		working -= CD9660_SUSP_ENTRY_SIZE(temp);
2289f988b79SJean-Baptiste Boric 		if (working >= 0) {
2299f988b79SJean-Baptiste Boric 			last = temp;
2309f988b79SJean-Baptiste Boric 			susp_used += CD9660_SUSP_ENTRY_SIZE(temp);
2319f988b79SJean-Baptiste Boric 		}
2329f988b79SJean-Baptiste Boric 		if (working >= 28) {
2339f988b79SJean-Baptiste Boric 			/*
2349f988b79SJean-Baptiste Boric 			 * Remember the last entry after which we
2359f988b79SJean-Baptiste Boric 			 * could insert a "CE" entry.
2369f988b79SJean-Baptiste Boric 			 */
2379f988b79SJean-Baptiste Boric 			pre_ce = last;
2389f988b79SJean-Baptiste Boric 			susp_used_pre_ce = susp_used;
2399f988b79SJean-Baptiste Boric 		}
2409f988b79SJean-Baptiste Boric 	}
2419f988b79SJean-Baptiste Boric 
2429f988b79SJean-Baptiste Boric 	/* A CE entry is needed */
2439f988b79SJean-Baptiste Boric 	if (working <= 0) {
2449f988b79SJean-Baptiste Boric 		CE = cd9660node_susp_create_node(SUSP_TYPE_SUSP,
2459f988b79SJean-Baptiste Boric 			SUSP_ENTRY_SUSP_CE, "CE", SUSP_LOC_ENTRY);
2469f988b79SJean-Baptiste Boric 		cd9660_susp_ce(CE, node);
2479f988b79SJean-Baptiste Boric 		/* This will automatically insert at the appropriate location */
2489f988b79SJean-Baptiste Boric 		if (pre_ce != NULL)
2499f988b79SJean-Baptiste Boric 			TAILQ_INSERT_AFTER(&node->head, pre_ce, CE, rr_ll);
2509f988b79SJean-Baptiste Boric 		else
2519f988b79SJean-Baptiste Boric 			TAILQ_INSERT_HEAD(&node->head, CE, rr_ll);
2529f988b79SJean-Baptiste Boric 		last = CE;
2539f988b79SJean-Baptiste Boric 		susp_used = susp_used_pre_ce + 28;
2549f988b79SJean-Baptiste Boric 		/* Count how much CA data is necessary */
2559f988b79SJean-Baptiste Boric 		for (temp = TAILQ_NEXT(last, rr_ll); temp != NULL;
2569f988b79SJean-Baptiste Boric 		     temp = TAILQ_NEXT(temp, rr_ll)) {
2579f988b79SJean-Baptiste Boric 			ca_used += CD9660_SUSP_ENTRY_SIZE(temp);
2589f988b79SJean-Baptiste Boric 		}
2599f988b79SJean-Baptiste Boric 	}
2609f988b79SJean-Baptiste Boric 
2619f988b79SJean-Baptiste Boric 	/* An ST entry is needed */
2629f988b79SJean-Baptiste Boric 	if (node->su_tail_size > 0) {
2639f988b79SJean-Baptiste Boric 		ST = cd9660node_susp_create_node(SUSP_TYPE_SUSP,
2649f988b79SJean-Baptiste Boric 		    SUSP_ENTRY_SUSP_ST, "ST", SUSP_LOC_ENTRY);
2659f988b79SJean-Baptiste Boric 		cd9660_susp_st(ST, node);
2669f988b79SJean-Baptiste Boric 		if (last != NULL)
2679f988b79SJean-Baptiste Boric 			TAILQ_INSERT_AFTER(&node->head, last, ST, rr_ll);
2689f988b79SJean-Baptiste Boric 		else
2699f988b79SJean-Baptiste Boric 			TAILQ_INSERT_HEAD(&node->head, ST, rr_ll);
2709f988b79SJean-Baptiste Boric 		last = ST;
2719f988b79SJean-Baptiste Boric 		susp_used += 4;
2729f988b79SJean-Baptiste Boric 	}
2739f988b79SJean-Baptiste Boric 	if (last != NULL)
2749f988b79SJean-Baptiste Boric 		last->last_in_suf = 1;
2759f988b79SJean-Baptiste Boric 
2769f988b79SJean-Baptiste Boric 	node->susp_entry_size = susp_used;
2779f988b79SJean-Baptiste Boric 	node->susp_entry_ce_length = ca_used;
2789f988b79SJean-Baptiste Boric 
2799f988b79SJean-Baptiste Boric 	diskStructure->susp_continuation_area_size += ca_used;
2809f988b79SJean-Baptiste Boric 	return 1;
2819f988b79SJean-Baptiste Boric }
2829f988b79SJean-Baptiste Boric 
2839f988b79SJean-Baptiste Boric /* See if a continuation entry is needed for each of the different types */
2849f988b79SJean-Baptiste Boric static int
cd9660_susp_handle_continuation(iso9660_disk * diskStructure,cd9660node * node)2859f988b79SJean-Baptiste Boric cd9660_susp_handle_continuation(iso9660_disk *diskStructure, cd9660node *node)
2869f988b79SJean-Baptiste Boric {
2879f988b79SJean-Baptiste Boric 	assert (node != NULL);
2889f988b79SJean-Baptiste Boric 
2899f988b79SJean-Baptiste Boric 	/* Entry */
2909f988b79SJean-Baptiste Boric 	if (cd9660_susp_handle_continuation_common(diskStructure,
2919f988b79SJean-Baptiste Boric 		node,(int)(node->isoDirRecord->length[0])) < 0)
2929f988b79SJean-Baptiste Boric 		return 0;
2939f988b79SJean-Baptiste Boric 
2949f988b79SJean-Baptiste Boric 	return 1;
2959f988b79SJean-Baptiste Boric }
2969f988b79SJean-Baptiste Boric 
2979f988b79SJean-Baptiste Boric int
cd9660_susp_initialize_node(iso9660_disk * diskStructure,cd9660node * node)2989f988b79SJean-Baptiste Boric cd9660_susp_initialize_node(iso9660_disk *diskStructure, cd9660node *node)
2999f988b79SJean-Baptiste Boric {
3009f988b79SJean-Baptiste Boric 	struct ISO_SUSP_ATTRIBUTES *temp;
3019f988b79SJean-Baptiste Boric 
3029f988b79SJean-Baptiste Boric 	/*
3039f988b79SJean-Baptiste Boric 	 * Requirements/notes:
3049f988b79SJean-Baptiste Boric 	 * CE: is added for us where needed
3059f988b79SJean-Baptiste Boric 	 * ST: not sure if it is even required, but if so, should be
3069f988b79SJean-Baptiste Boric 	 *     handled by the CE code
3079f988b79SJean-Baptiste Boric 	 * PD: isnt needed (though might be added for testing)
3089f988b79SJean-Baptiste Boric 	 * SP: is stored ONLY on the . record of the root directory
3099f988b79SJean-Baptiste Boric 	 * ES: not sure
3109f988b79SJean-Baptiste Boric 	 */
3119f988b79SJean-Baptiste Boric 
3129f988b79SJean-Baptiste Boric 	/* Check for root directory, add SP and ER if needed. */
3139f988b79SJean-Baptiste Boric 	if (node->type & CD9660_TYPE_DOT) {
3149f988b79SJean-Baptiste Boric 		if (node->parent == diskStructure->rootNode) {
3159f988b79SJean-Baptiste Boric 			temp = cd9660node_susp_create_node(SUSP_TYPE_SUSP,
3169f988b79SJean-Baptiste Boric 				SUSP_ENTRY_SUSP_SP, "SP", SUSP_LOC_DOT);
3179f988b79SJean-Baptiste Boric 			cd9660_susp_sp(temp, node);
3189f988b79SJean-Baptiste Boric 
3199f988b79SJean-Baptiste Boric 			/* Should be first entry. */
3209f988b79SJean-Baptiste Boric 			TAILQ_INSERT_HEAD(&node->head, temp, rr_ll);
3219f988b79SJean-Baptiste Boric 		}
3229f988b79SJean-Baptiste Boric 	}
3239f988b79SJean-Baptiste Boric 	return 1;
3249f988b79SJean-Baptiste Boric }
3259f988b79SJean-Baptiste Boric 
3269f988b79SJean-Baptiste Boric static void
cd9660_rrip_initialize_inode(cd9660node * node)3279f988b79SJean-Baptiste Boric cd9660_rrip_initialize_inode(cd9660node *node)
3289f988b79SJean-Baptiste Boric {
3299f988b79SJean-Baptiste Boric 	struct ISO_SUSP_ATTRIBUTES *attr;
3309f988b79SJean-Baptiste Boric 
3319f988b79SJean-Baptiste Boric 	/*
3329f988b79SJean-Baptiste Boric 	 * Inode dependent values - this may change,
3339f988b79SJean-Baptiste Boric 	 * but for now virtual files and directories do
3349f988b79SJean-Baptiste Boric 	 * not have an inode structure
3359f988b79SJean-Baptiste Boric 	 */
3369f988b79SJean-Baptiste Boric 
3379f988b79SJean-Baptiste Boric 	if ((node->node != NULL) && (node->node->inode != NULL)) {
3389f988b79SJean-Baptiste Boric 		/* PX - POSIX attributes */
3399f988b79SJean-Baptiste Boric 		attr = cd9660node_susp_create_node(SUSP_TYPE_RRIP,
3409f988b79SJean-Baptiste Boric 			SUSP_ENTRY_RRIP_PX, "PX", SUSP_LOC_ENTRY);
3419f988b79SJean-Baptiste Boric 		cd9660node_rrip_px(attr, node->node);
3429f988b79SJean-Baptiste Boric 
3439f988b79SJean-Baptiste Boric 		TAILQ_INSERT_TAIL(&node->head, attr, rr_ll);
3449f988b79SJean-Baptiste Boric 
3459f988b79SJean-Baptiste Boric 		/* TF - timestamp */
3469f988b79SJean-Baptiste Boric 		attr = cd9660node_susp_create_node(SUSP_TYPE_RRIP,
3479f988b79SJean-Baptiste Boric 			SUSP_ENTRY_RRIP_TF, "TF", SUSP_LOC_ENTRY);
3489f988b79SJean-Baptiste Boric 		cd9660node_rrip_tf(attr, node->node);
3499f988b79SJean-Baptiste Boric 		TAILQ_INSERT_TAIL(&node->head, attr, rr_ll);
3509f988b79SJean-Baptiste Boric 
3519f988b79SJean-Baptiste Boric 		/* SL - Symbolic link */
3529f988b79SJean-Baptiste Boric 		/* ?????????? Dan - why is this here? */
3539f988b79SJean-Baptiste Boric 		if (TAILQ_EMPTY(&node->cn_children) &&
3549f988b79SJean-Baptiste Boric 		    node->node->inode != NULL &&
3559f988b79SJean-Baptiste Boric 		    S_ISLNK(node->node->inode->st.st_mode))
3569f988b79SJean-Baptiste Boric 			cd9660_createSL(node);
3579f988b79SJean-Baptiste Boric 
3589f988b79SJean-Baptiste Boric 		/* PN - device number */
3599f988b79SJean-Baptiste Boric 		if (node->node->inode != NULL &&
3609f988b79SJean-Baptiste Boric 		    ((S_ISCHR(node->node->inode->st.st_mode) ||
3619f988b79SJean-Baptiste Boric 		     S_ISBLK(node->node->inode->st.st_mode)))) {
3629f988b79SJean-Baptiste Boric 			attr =
3639f988b79SJean-Baptiste Boric 			    cd9660node_susp_create_node(SUSP_TYPE_RRIP,
3649f988b79SJean-Baptiste Boric 				SUSP_ENTRY_RRIP_PN, "PN",
3659f988b79SJean-Baptiste Boric 				SUSP_LOC_ENTRY);
3669f988b79SJean-Baptiste Boric 			cd9660node_rrip_pn(attr, node->node);
3679f988b79SJean-Baptiste Boric 			TAILQ_INSERT_TAIL(&node->head, attr, rr_ll);
3689f988b79SJean-Baptiste Boric 		}
3699f988b79SJean-Baptiste Boric 	}
3709f988b79SJean-Baptiste Boric }
3719f988b79SJean-Baptiste Boric 
3729f988b79SJean-Baptiste Boric int
cd9660_rrip_initialize_node(iso9660_disk * diskStructure,cd9660node * node,cd9660node * parent,cd9660node * grandparent)3739f988b79SJean-Baptiste Boric cd9660_rrip_initialize_node(iso9660_disk *diskStructure, cd9660node *node,
3749f988b79SJean-Baptiste Boric     cd9660node *parent, cd9660node *grandparent)
3759f988b79SJean-Baptiste Boric {
3769f988b79SJean-Baptiste Boric 	struct ISO_SUSP_ATTRIBUTES *current = NULL;
3779f988b79SJean-Baptiste Boric 
3789f988b79SJean-Baptiste Boric 	assert(node != NULL);
3799f988b79SJean-Baptiste Boric 
3809f988b79SJean-Baptiste Boric 	if (node->type & CD9660_TYPE_DOT) {
3819f988b79SJean-Baptiste Boric 		/*
3829f988b79SJean-Baptiste Boric 		 * Handle ER - should be the only entry to appear on
3839f988b79SJean-Baptiste Boric 		 * a "." record
3849f988b79SJean-Baptiste Boric 		 */
3859f988b79SJean-Baptiste Boric 		if (node->parent == diskStructure->rootNode) {
3869f988b79SJean-Baptiste Boric 			cd9660_susp_ER(node, 1, SUSP_RRIP_ER_EXT_ID,
3879f988b79SJean-Baptiste Boric 				SUSP_RRIP_ER_EXT_DES, SUSP_RRIP_ER_EXT_SRC);
3889f988b79SJean-Baptiste Boric 		}
3899f988b79SJean-Baptiste Boric 		if (parent != NULL && parent->node != NULL &&
3909f988b79SJean-Baptiste Boric 		    parent->node->inode != NULL) {
3919f988b79SJean-Baptiste Boric 			/* PX - POSIX attributes */
3929f988b79SJean-Baptiste Boric 			current = cd9660node_susp_create_node(SUSP_TYPE_RRIP,
3939f988b79SJean-Baptiste Boric 				SUSP_ENTRY_RRIP_PX, "PX", SUSP_LOC_ENTRY);
3949f988b79SJean-Baptiste Boric 			cd9660node_rrip_px(current, parent->node);
3959f988b79SJean-Baptiste Boric 			TAILQ_INSERT_TAIL(&node->head, current, rr_ll);
3969f988b79SJean-Baptiste Boric 		}
3979f988b79SJean-Baptiste Boric 	} else if (node->type & CD9660_TYPE_DOTDOT) {
3989f988b79SJean-Baptiste Boric 		if (grandparent != NULL && grandparent->node != NULL &&
3999f988b79SJean-Baptiste Boric 		    grandparent->node->inode != NULL) {
4009f988b79SJean-Baptiste Boric 			/* PX - POSIX attributes */
4019f988b79SJean-Baptiste Boric 			current = cd9660node_susp_create_node(SUSP_TYPE_RRIP,
4029f988b79SJean-Baptiste Boric 				SUSP_ENTRY_RRIP_PX, "PX", SUSP_LOC_ENTRY);
4039f988b79SJean-Baptiste Boric 			cd9660node_rrip_px(current, grandparent->node);
4049f988b79SJean-Baptiste Boric 			TAILQ_INSERT_TAIL(&node->head, current, rr_ll);
4059f988b79SJean-Baptiste Boric 		}
4069f988b79SJean-Baptiste Boric 		/* Handle PL */
4079f988b79SJean-Baptiste Boric 		if (parent != NULL && parent->rr_real_parent != NULL) {
4089f988b79SJean-Baptiste Boric 			current = cd9660node_susp_create_node(SUSP_TYPE_RRIP,
4099f988b79SJean-Baptiste Boric 			    SUSP_ENTRY_RRIP_PL, "PL", SUSP_LOC_DOTDOT);
4109f988b79SJean-Baptiste Boric 			cd9660_rrip_PL(current,node);
4119f988b79SJean-Baptiste Boric 			TAILQ_INSERT_TAIL(&node->head, current, rr_ll);
4129f988b79SJean-Baptiste Boric 		}
4139f988b79SJean-Baptiste Boric 	} else {
4149f988b79SJean-Baptiste Boric 		cd9660_rrip_initialize_inode(node);
4159f988b79SJean-Baptiste Boric 
4169f988b79SJean-Baptiste Boric 		/*
4179f988b79SJean-Baptiste Boric 		 * Not every node needs a NM set - only if the name is
4189f988b79SJean-Baptiste Boric 		 * actually different. IE: If a file is TEST -> TEST,
4199f988b79SJean-Baptiste Boric 		 * no NM. test -> TEST, need a NM
4209f988b79SJean-Baptiste Boric 		 *
4219f988b79SJean-Baptiste Boric 		 * The rr_moved_dir needs to be assigned a NM record as well.
4229f988b79SJean-Baptiste Boric 		 */
4239f988b79SJean-Baptiste Boric 		if (node == diskStructure->rr_moved_dir) {
4249f988b79SJean-Baptiste Boric 			cd9660_rrip_add_NM(node, RRIP_DEFAULT_MOVE_DIR_NAME);
4259f988b79SJean-Baptiste Boric 		}
4269f988b79SJean-Baptiste Boric 		else if ((node->node != NULL) &&
4279f988b79SJean-Baptiste Boric 			((strlen(node->node->name) !=
4289f988b79SJean-Baptiste Boric 			    (uint8_t)node->isoDirRecord->name_len[0]) ||
4299f988b79SJean-Baptiste Boric 			(memcmp(node->node->name,node->isoDirRecord->name,
4309f988b79SJean-Baptiste Boric 				(uint8_t)node->isoDirRecord->name_len[0]) != 0))) {
4319f988b79SJean-Baptiste Boric 			cd9660_rrip_NM(node);
4329f988b79SJean-Baptiste Boric 		}
4339f988b79SJean-Baptiste Boric 
4349f988b79SJean-Baptiste Boric 
4359f988b79SJean-Baptiste Boric 
4369f988b79SJean-Baptiste Boric 		/* Rock ridge directory relocation code here. */
4379f988b79SJean-Baptiste Boric 
4389f988b79SJean-Baptiste Boric 		/* First handle the CL for the placeholder file. */
4399f988b79SJean-Baptiste Boric 		if (node->rr_relocated != NULL) {
4409f988b79SJean-Baptiste Boric 			current = cd9660node_susp_create_node(SUSP_TYPE_RRIP,
4419f988b79SJean-Baptiste Boric 				SUSP_ENTRY_RRIP_CL, "CL", SUSP_LOC_ENTRY);
4429f988b79SJean-Baptiste Boric 			cd9660_rrip_CL(current, node);
4439f988b79SJean-Baptiste Boric 			TAILQ_INSERT_TAIL(&node->head, current, rr_ll);
4449f988b79SJean-Baptiste Boric 		}
4459f988b79SJean-Baptiste Boric 
4469f988b79SJean-Baptiste Boric 		/* Handle RE*/
4479f988b79SJean-Baptiste Boric 		if (node->rr_real_parent != NULL) {
4489f988b79SJean-Baptiste Boric 			current = cd9660node_susp_create_node(SUSP_TYPE_RRIP,
4499f988b79SJean-Baptiste Boric 				SUSP_ENTRY_RRIP_RE, "RE", SUSP_LOC_ENTRY);
4509f988b79SJean-Baptiste Boric 			cd9660_rrip_RE(current,node);
4519f988b79SJean-Baptiste Boric 			TAILQ_INSERT_TAIL(&node->head, current, rr_ll);
4529f988b79SJean-Baptiste Boric 		}
4539f988b79SJean-Baptiste Boric 	}
4549f988b79SJean-Baptiste Boric 	return 1;
4559f988b79SJean-Baptiste Boric }
4569f988b79SJean-Baptiste Boric 
4579f988b79SJean-Baptiste Boric struct ISO_SUSP_ATTRIBUTES*
cd9660node_susp_create_node(int susp_type,int entry_type,const char * type_id,int write_loc)4589f988b79SJean-Baptiste Boric cd9660node_susp_create_node(int susp_type, int entry_type, const char *type_id,
4599f988b79SJean-Baptiste Boric 			    int write_loc)
4609f988b79SJean-Baptiste Boric {
4619f988b79SJean-Baptiste Boric 	struct ISO_SUSP_ATTRIBUTES* temp;
4629f988b79SJean-Baptiste Boric 
4639f988b79SJean-Baptiste Boric 	temp = emalloc(sizeof(*temp));
4649f988b79SJean-Baptiste Boric 	temp->susp_type = susp_type;
4659f988b79SJean-Baptiste Boric 	temp->entry_type = entry_type;
4669f988b79SJean-Baptiste Boric 	temp->last_in_suf = 0;
4679f988b79SJean-Baptiste Boric 	/* Phase this out */
4689f988b79SJean-Baptiste Boric 	temp->type_of[0] = type_id[0];
4699f988b79SJean-Baptiste Boric 	temp->type_of[1] = type_id[1];
4709f988b79SJean-Baptiste Boric 	temp->write_location = write_loc;
4719f988b79SJean-Baptiste Boric 
4729f988b79SJean-Baptiste Boric 	/*
4739f988b79SJean-Baptiste Boric 	 * Since the first four bytes is common, lets go ahead and
4749f988b79SJean-Baptiste Boric 	 * set the type identifier, since we are passing that to this
4759f988b79SJean-Baptiste Boric 	 * function anyhow.
4769f988b79SJean-Baptiste Boric 	 */
4779f988b79SJean-Baptiste Boric 	temp->attr.su_entry.SP.h.type[0] = type_id[0];
4789f988b79SJean-Baptiste Boric 	temp->attr.su_entry.SP.h.type[1] = type_id[1];
4799f988b79SJean-Baptiste Boric 	return temp;
4809f988b79SJean-Baptiste Boric }
4819f988b79SJean-Baptiste Boric 
4829f988b79SJean-Baptiste Boric int
cd9660_rrip_PL(struct ISO_SUSP_ATTRIBUTES * p,cd9660node * node __unused)4839f988b79SJean-Baptiste Boric cd9660_rrip_PL(struct ISO_SUSP_ATTRIBUTES* p, cd9660node *node __unused)
4849f988b79SJean-Baptiste Boric {
4859f988b79SJean-Baptiste Boric 	p->attr.rr_entry.PL.h.length[0] = 12;
4869f988b79SJean-Baptiste Boric 	p->attr.rr_entry.PL.h.version[0] = 1;
4879f988b79SJean-Baptiste Boric 	return 1;
4889f988b79SJean-Baptiste Boric }
4899f988b79SJean-Baptiste Boric 
4909f988b79SJean-Baptiste Boric int
cd9660_rrip_CL(struct ISO_SUSP_ATTRIBUTES * p,cd9660node * node __unused)4919f988b79SJean-Baptiste Boric cd9660_rrip_CL(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *node __unused)
4929f988b79SJean-Baptiste Boric {
4939f988b79SJean-Baptiste Boric 	p->attr.rr_entry.CL.h.length[0] = 12;
4949f988b79SJean-Baptiste Boric 	p->attr.rr_entry.CL.h.version[0] = 1;
4959f988b79SJean-Baptiste Boric 	return 1;
4969f988b79SJean-Baptiste Boric }
4979f988b79SJean-Baptiste Boric 
4989f988b79SJean-Baptiste Boric int
cd9660_rrip_RE(struct ISO_SUSP_ATTRIBUTES * p,cd9660node * node __unused)4999f988b79SJean-Baptiste Boric cd9660_rrip_RE(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *node __unused)
5009f988b79SJean-Baptiste Boric {
5019f988b79SJean-Baptiste Boric 	p->attr.rr_entry.RE.h.length[0] = 4;
5029f988b79SJean-Baptiste Boric 	p->attr.rr_entry.RE.h.version[0] = 1;
5039f988b79SJean-Baptiste Boric 	return 1;
5049f988b79SJean-Baptiste Boric }
5059f988b79SJean-Baptiste Boric 
5069f988b79SJean-Baptiste Boric void
cd9660_createSL(cd9660node * node)5079f988b79SJean-Baptiste Boric cd9660_createSL(cd9660node *node)
5089f988b79SJean-Baptiste Boric {
5099f988b79SJean-Baptiste Boric 	struct ISO_SUSP_ATTRIBUTES* current;
5109f988b79SJean-Baptiste Boric 	int path_count, dir_count, done, i, j, dir_copied;
5119f988b79SJean-Baptiste Boric 	char temp_cr[255];
5129f988b79SJean-Baptiste Boric 	char temp_sl[255]; /* used in copying continuation entry*/
5139f988b79SJean-Baptiste Boric 	char* sl_ptr;
5149f988b79SJean-Baptiste Boric 
5159f988b79SJean-Baptiste Boric 	sl_ptr = node->node->symlink;
5169f988b79SJean-Baptiste Boric 
5179f988b79SJean-Baptiste Boric 	done = 0;
5189f988b79SJean-Baptiste Boric 	path_count = 0;
5199f988b79SJean-Baptiste Boric 	dir_count = 0;
5209f988b79SJean-Baptiste Boric 	dir_copied = 0;
5219f988b79SJean-Baptiste Boric 	current = cd9660node_susp_create_node(SUSP_TYPE_RRIP,
5229f988b79SJean-Baptiste Boric 	    SUSP_ENTRY_RRIP_SL, "SL", SUSP_LOC_ENTRY);
5239f988b79SJean-Baptiste Boric 
5249f988b79SJean-Baptiste Boric 	current->attr.rr_entry.SL.h.version[0] = 1;
5259f988b79SJean-Baptiste Boric 	current->attr.rr_entry.SL.flags[0] = SL_FLAGS_NONE;
5269f988b79SJean-Baptiste Boric 
5279f988b79SJean-Baptiste Boric 	if (*sl_ptr == '/') {
5289f988b79SJean-Baptiste Boric 		temp_cr[0] = SL_FLAGS_ROOT;
5299f988b79SJean-Baptiste Boric 		temp_cr[1] = 0;
5309f988b79SJean-Baptiste Boric 		memcpy(current->attr.rr_entry.SL.component + path_count,
5319f988b79SJean-Baptiste Boric 		    temp_cr, 2);
5329f988b79SJean-Baptiste Boric 		path_count += 2;
5339f988b79SJean-Baptiste Boric 		sl_ptr++;
5349f988b79SJean-Baptiste Boric 	}
5359f988b79SJean-Baptiste Boric 
5369f988b79SJean-Baptiste Boric 	for (i = 0; i < (dir_count + 2); i++)
5379f988b79SJean-Baptiste Boric 		temp_cr[i] = '\0';
5389f988b79SJean-Baptiste Boric 
5399f988b79SJean-Baptiste Boric 	while (!done) {
5409f988b79SJean-Baptiste Boric 		while ((*sl_ptr != '/') && (*sl_ptr != '\0')) {
5419f988b79SJean-Baptiste Boric 			dir_copied = 1;
5429f988b79SJean-Baptiste Boric 			if (*sl_ptr == '.') {
5439f988b79SJean-Baptiste Boric 				if ((*(sl_ptr + 1) == '/') || (*(sl_ptr + 1)
5449f988b79SJean-Baptiste Boric 				     == '\0')) {
5459f988b79SJean-Baptiste Boric 					temp_cr[0] = SL_FLAGS_CURRENT;
5469f988b79SJean-Baptiste Boric 					sl_ptr++;
5479f988b79SJean-Baptiste Boric 				} else if(*(sl_ptr + 1) == '.') {
5489f988b79SJean-Baptiste Boric 					if ((*(sl_ptr + 2) == '/') ||
5499f988b79SJean-Baptiste Boric 					    (*(sl_ptr + 2) == '\0')) {
5509f988b79SJean-Baptiste Boric 						temp_cr[0] = SL_FLAGS_PARENT;
5519f988b79SJean-Baptiste Boric 						sl_ptr += 2;
5529f988b79SJean-Baptiste Boric 					}
5539f988b79SJean-Baptiste Boric 				} else {
5549f988b79SJean-Baptiste Boric 					temp_cr[dir_count+2] = *sl_ptr;
5559f988b79SJean-Baptiste Boric 					sl_ptr++;
5569f988b79SJean-Baptiste Boric 					dir_count++;
5579f988b79SJean-Baptiste Boric 				}
5589f988b79SJean-Baptiste Boric 			} else {
5599f988b79SJean-Baptiste Boric 				temp_cr[dir_count + 2] = *sl_ptr;
5609f988b79SJean-Baptiste Boric 				sl_ptr++;
5619f988b79SJean-Baptiste Boric 				dir_count++;
5629f988b79SJean-Baptiste Boric 			}
5639f988b79SJean-Baptiste Boric 		}
5649f988b79SJean-Baptiste Boric 
5659f988b79SJean-Baptiste Boric 		if ((path_count + dir_count) >= 249) {
5669f988b79SJean-Baptiste Boric 			current->attr.rr_entry.SL.flags[0] |= SL_FLAGS_CONTINUE;
5679f988b79SJean-Baptiste Boric 
5689f988b79SJean-Baptiste Boric 			j = 0;
5699f988b79SJean-Baptiste Boric 
5709f988b79SJean-Baptiste Boric 			if (path_count <= 249) {
5719f988b79SJean-Baptiste Boric 				while(j != (249 - path_count)) {
5729f988b79SJean-Baptiste Boric 					temp_sl[j] = temp_cr[j];
5739f988b79SJean-Baptiste Boric 					j++;
5749f988b79SJean-Baptiste Boric 				}
5759f988b79SJean-Baptiste Boric 				temp_sl[0] = SL_FLAGS_CONTINUE;
5769f988b79SJean-Baptiste Boric 				temp_sl[1] = j - 2;
5779f988b79SJean-Baptiste Boric 				memcpy(
5789f988b79SJean-Baptiste Boric 				    current->attr.rr_entry.SL.component +
5799f988b79SJean-Baptiste Boric 					path_count,
5809f988b79SJean-Baptiste Boric 				    temp_sl, j);
5819f988b79SJean-Baptiste Boric 			}
5829f988b79SJean-Baptiste Boric 
5839f988b79SJean-Baptiste Boric 			path_count += j;
5849f988b79SJean-Baptiste Boric 			current->attr.rr_entry.SL.h.length[0] = path_count + 5;
5859f988b79SJean-Baptiste Boric 			TAILQ_INSERT_TAIL(&node->head, current, rr_ll);
5869f988b79SJean-Baptiste Boric 			current= cd9660node_susp_create_node(SUSP_TYPE_RRIP,
5879f988b79SJean-Baptiste Boric 			       SUSP_ENTRY_RRIP_SL, "SL", SUSP_LOC_ENTRY);
5889f988b79SJean-Baptiste Boric 			current->attr.rr_entry.SL.h.version[0] = 1;
5899f988b79SJean-Baptiste Boric 			current->attr.rr_entry.SL.flags[0] = SL_FLAGS_NONE;
5909f988b79SJean-Baptiste Boric 
5919f988b79SJean-Baptiste Boric 			path_count = 0;
5929f988b79SJean-Baptiste Boric 
5939f988b79SJean-Baptiste Boric 			if (dir_count > 2) {
5949f988b79SJean-Baptiste Boric 				while (j != dir_count + 2) {
5959f988b79SJean-Baptiste Boric 					current->attr.rr_entry.SL.component[
5969f988b79SJean-Baptiste Boric 					    path_count + 2] = temp_cr[j];
5979f988b79SJean-Baptiste Boric 					j++;
5989f988b79SJean-Baptiste Boric 					path_count++;
5999f988b79SJean-Baptiste Boric 				}
6009f988b79SJean-Baptiste Boric 				current->attr.rr_entry.SL.component[1]
6019f988b79SJean-Baptiste Boric 				    = path_count;
6029f988b79SJean-Baptiste Boric 				path_count+= 2;
6039f988b79SJean-Baptiste Boric 			} else {
6049f988b79SJean-Baptiste Boric 				while(j != dir_count) {
6059f988b79SJean-Baptiste Boric 					current->attr.rr_entry.SL.component[
6069f988b79SJean-Baptiste Boric 					    path_count+2] = temp_cr[j];
6079f988b79SJean-Baptiste Boric 					j++;
6089f988b79SJean-Baptiste Boric 					path_count++;
6099f988b79SJean-Baptiste Boric 				}
6109f988b79SJean-Baptiste Boric 			}
6119f988b79SJean-Baptiste Boric 		} else {
6129f988b79SJean-Baptiste Boric 			if (dir_copied == 1) {
6139f988b79SJean-Baptiste Boric 				temp_cr[1] = dir_count;
6149f988b79SJean-Baptiste Boric 				memcpy(current->attr.rr_entry.SL.component +
6159f988b79SJean-Baptiste Boric 					path_count,
6169f988b79SJean-Baptiste Boric 				    temp_cr, dir_count + 2);
6179f988b79SJean-Baptiste Boric 				path_count += dir_count + 2;
6189f988b79SJean-Baptiste Boric 			}
6199f988b79SJean-Baptiste Boric 		}
6209f988b79SJean-Baptiste Boric 
6219f988b79SJean-Baptiste Boric 		if (*sl_ptr == '\0') {
6229f988b79SJean-Baptiste Boric 			done = 1;
6239f988b79SJean-Baptiste Boric 			current->attr.rr_entry.SL.h.length[0] = path_count + 5;
6249f988b79SJean-Baptiste Boric 			TAILQ_INSERT_TAIL(&node->head, current, rr_ll);
6259f988b79SJean-Baptiste Boric 		} else {
6269f988b79SJean-Baptiste Boric 			sl_ptr++;
6279f988b79SJean-Baptiste Boric 			dir_count = 0;
6289f988b79SJean-Baptiste Boric 			dir_copied = 0;
6299f988b79SJean-Baptiste Boric 			for(i = 0; i < 255; i++) {
6309f988b79SJean-Baptiste Boric 				temp_cr[i] = '\0';
6319f988b79SJean-Baptiste Boric 			}
6329f988b79SJean-Baptiste Boric 		}
6339f988b79SJean-Baptiste Boric 	}
6349f988b79SJean-Baptiste Boric }
6359f988b79SJean-Baptiste Boric 
6369f988b79SJean-Baptiste Boric int
cd9660node_rrip_px(struct ISO_SUSP_ATTRIBUTES * v,fsnode * pxinfo)6379f988b79SJean-Baptiste Boric cd9660node_rrip_px(struct ISO_SUSP_ATTRIBUTES *v, fsnode *pxinfo)
6389f988b79SJean-Baptiste Boric {
6399f988b79SJean-Baptiste Boric 	v->attr.rr_entry.PX.h.length[0] = 36;
6409f988b79SJean-Baptiste Boric 	v->attr.rr_entry.PX.h.version[0] = 1;
6419f988b79SJean-Baptiste Boric 	cd9660_bothendian_dword(pxinfo->inode->st.st_mode,
6429f988b79SJean-Baptiste Boric 	    v->attr.rr_entry.PX.mode);
6439f988b79SJean-Baptiste Boric 	cd9660_bothendian_dword(pxinfo->inode->st.st_nlink,
6449f988b79SJean-Baptiste Boric 	    v->attr.rr_entry.PX.links);
6459f988b79SJean-Baptiste Boric 	cd9660_bothendian_dword(pxinfo->inode->st.st_uid,
6469f988b79SJean-Baptiste Boric 	    v->attr.rr_entry.PX.uid);
6479f988b79SJean-Baptiste Boric 	cd9660_bothendian_dword(pxinfo->inode->st.st_gid,
6489f988b79SJean-Baptiste Boric 	    v->attr.rr_entry.PX.gid);
6499f988b79SJean-Baptiste Boric 
6509f988b79SJean-Baptiste Boric 	/* Ignoring the serial number for now */
6519f988b79SJean-Baptiste Boric 	return 1;
6529f988b79SJean-Baptiste Boric }
6539f988b79SJean-Baptiste Boric 
6549f988b79SJean-Baptiste Boric int
cd9660node_rrip_pn(struct ISO_SUSP_ATTRIBUTES * pn_field,fsnode * fnode)6559f988b79SJean-Baptiste Boric cd9660node_rrip_pn(struct ISO_SUSP_ATTRIBUTES *pn_field, fsnode *fnode)
6569f988b79SJean-Baptiste Boric {
6579f988b79SJean-Baptiste Boric 	pn_field->attr.rr_entry.PN.h.length[0] = 20;
6589f988b79SJean-Baptiste Boric 	pn_field->attr.rr_entry.PN.h.version[0] = 1;
6599f988b79SJean-Baptiste Boric 
660*3472022bSJean-Baptiste Boric 	if (sizeof (fnode->inode->st.st_rdev) > 4)
661*3472022bSJean-Baptiste Boric 		cd9660_bothendian_dword(
662*3472022bSJean-Baptiste Boric 		    (uint64_t)fnode->inode->st.st_rdev >> 32,
6639f988b79SJean-Baptiste Boric 		    pn_field->attr.rr_entry.PN.high);
6649f988b79SJean-Baptiste Boric 	else
6659f988b79SJean-Baptiste Boric 		cd9660_bothendian_dword(0, pn_field->attr.rr_entry.PN.high);
6669f988b79SJean-Baptiste Boric 
667*3472022bSJean-Baptiste Boric 	cd9660_bothendian_dword(fnode->inode->st.st_rdev & 0xffffffff,
6689f988b79SJean-Baptiste Boric 		pn_field->attr.rr_entry.PN.low);
6699f988b79SJean-Baptiste Boric 	return 1;
6709f988b79SJean-Baptiste Boric }
6719f988b79SJean-Baptiste Boric 
6729f988b79SJean-Baptiste Boric #if 0
6739f988b79SJean-Baptiste Boric int
6749f988b79SJean-Baptiste Boric cd9660node_rrip_nm(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *file_node)
6759f988b79SJean-Baptiste Boric {
6769f988b79SJean-Baptiste Boric 	int nm_length = strlen(file_node->isoDirRecord->name) + 5;
6779f988b79SJean-Baptiste Boric         p->attr.rr_entry.NM.h.type[0] = 'N';
6789f988b79SJean-Baptiste Boric 	p->attr.rr_entry.NM.h.type[1] = 'M';
6799f988b79SJean-Baptiste Boric 	sprintf(p->attr.rr_entry.NM.altname, "%s", file_node->isoDirRecord->name);
6809f988b79SJean-Baptiste Boric 	p->attr.rr_entry.NM.h.length[0] = (unsigned char)nm_length;
6819f988b79SJean-Baptiste Boric 	p->attr.rr_entry.NM.h.version[0] = (unsigned char)1;
6829f988b79SJean-Baptiste Boric 	p->attr.rr_entry.NM.flags[0] = (unsigned char) NM_PARENT;
6839f988b79SJean-Baptiste Boric 	return 1;
6849f988b79SJean-Baptiste Boric }
6859f988b79SJean-Baptiste Boric #endif
6869f988b79SJean-Baptiste Boric 
6879f988b79SJean-Baptiste Boric int
cd9660node_rrip_tf(struct ISO_SUSP_ATTRIBUTES * p,fsnode * _node)6889f988b79SJean-Baptiste Boric cd9660node_rrip_tf(struct ISO_SUSP_ATTRIBUTES *p, fsnode *_node)
6899f988b79SJean-Baptiste Boric {
6909f988b79SJean-Baptiste Boric 	p->attr.rr_entry.TF.flags[0] = TF_MODIFY | TF_ACCESS | TF_ATTRIBUTES;
6919f988b79SJean-Baptiste Boric 	p->attr.rr_entry.TF.h.length[0] = 5;
6929f988b79SJean-Baptiste Boric 	p->attr.rr_entry.TF.h.version[0] = 1;
6939f988b79SJean-Baptiste Boric 
6949f988b79SJean-Baptiste Boric 	/*
6959f988b79SJean-Baptiste Boric 	 * Need to add creation time, backup time,
6969f988b79SJean-Baptiste Boric 	 * expiration time, and effective time.
6979f988b79SJean-Baptiste Boric 	 */
6989f988b79SJean-Baptiste Boric 
6999f988b79SJean-Baptiste Boric 	cd9660_time_915(p->attr.rr_entry.TF.timestamp,
7009f988b79SJean-Baptiste Boric 		_node->inode->st.st_atime);
7019f988b79SJean-Baptiste Boric 	p->attr.rr_entry.TF.h.length[0] += 7;
7029f988b79SJean-Baptiste Boric 
7039f988b79SJean-Baptiste Boric 	cd9660_time_915(p->attr.rr_entry.TF.timestamp + 7,
7049f988b79SJean-Baptiste Boric 		_node->inode->st.st_mtime);
7059f988b79SJean-Baptiste Boric 	p->attr.rr_entry.TF.h.length[0] += 7;
7069f988b79SJean-Baptiste Boric 
7079f988b79SJean-Baptiste Boric 	cd9660_time_915(p->attr.rr_entry.TF.timestamp + 14,
7089f988b79SJean-Baptiste Boric 		_node->inode->st.st_ctime);
7099f988b79SJean-Baptiste Boric 	p->attr.rr_entry.TF.h.length[0] += 7;
7109f988b79SJean-Baptiste Boric 	return 1;
7119f988b79SJean-Baptiste Boric }
7129f988b79SJean-Baptiste Boric 
7139f988b79SJean-Baptiste Boric int
cd9660_susp_sp(struct ISO_SUSP_ATTRIBUTES * p,cd9660node * spinfo __unused)7149f988b79SJean-Baptiste Boric cd9660_susp_sp(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *spinfo __unused)
7159f988b79SJean-Baptiste Boric {
7169f988b79SJean-Baptiste Boric 	p->attr.su_entry.SP.h.length[0] = 7;
7179f988b79SJean-Baptiste Boric 	p->attr.su_entry.SP.h.version[0] = 1;
7189f988b79SJean-Baptiste Boric 	p->attr.su_entry.SP.check[0] = 0xBE;
7199f988b79SJean-Baptiste Boric 	p->attr.su_entry.SP.check[1] = 0xEF;
7209f988b79SJean-Baptiste Boric 	p->attr.su_entry.SP.len_skp[0] = 0;
7219f988b79SJean-Baptiste Boric 	return 1;
7229f988b79SJean-Baptiste Boric }
7239f988b79SJean-Baptiste Boric 
7249f988b79SJean-Baptiste Boric int
cd9660_susp_st(struct ISO_SUSP_ATTRIBUTES * p,cd9660node * stinfo __unused)7259f988b79SJean-Baptiste Boric cd9660_susp_st(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *stinfo __unused)
7269f988b79SJean-Baptiste Boric {
7279f988b79SJean-Baptiste Boric 	p->attr.su_entry.ST.h.type[0] = 'S';
7289f988b79SJean-Baptiste Boric 	p->attr.su_entry.ST.h.type[1] = 'T';
7299f988b79SJean-Baptiste Boric 	p->attr.su_entry.ST.h.length[0] = 4;
7309f988b79SJean-Baptiste Boric 	p->attr.su_entry.ST.h.version[0] = 1;
7319f988b79SJean-Baptiste Boric 	return 1;
7329f988b79SJean-Baptiste Boric }
7339f988b79SJean-Baptiste Boric 
7349f988b79SJean-Baptiste Boric int
cd9660_susp_ce(struct ISO_SUSP_ATTRIBUTES * p,cd9660node * spinfo __unused)7359f988b79SJean-Baptiste Boric cd9660_susp_ce(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *spinfo __unused)
7369f988b79SJean-Baptiste Boric {
7379f988b79SJean-Baptiste Boric 	p->attr.su_entry.CE.h.length[0] = 28;
7389f988b79SJean-Baptiste Boric 	p->attr.su_entry.CE.h.version[0] = 1;
7399f988b79SJean-Baptiste Boric 	/* Other attributes dont matter right now, will be updated later */
7409f988b79SJean-Baptiste Boric 	return 1;
7419f988b79SJean-Baptiste Boric }
7429f988b79SJean-Baptiste Boric 
7439f988b79SJean-Baptiste Boric int
cd9660_susp_pd(struct ISO_SUSP_ATTRIBUTES * p __unused,int length __unused)7449f988b79SJean-Baptiste Boric cd9660_susp_pd(struct ISO_SUSP_ATTRIBUTES *p __unused, int length __unused)
7459f988b79SJean-Baptiste Boric {
7469f988b79SJean-Baptiste Boric 	return 1;
7479f988b79SJean-Baptiste Boric }
7489f988b79SJean-Baptiste Boric 
7499f988b79SJean-Baptiste Boric void
cd9660_rrip_add_NM(cd9660node * node,const char * name)7509f988b79SJean-Baptiste Boric cd9660_rrip_add_NM(cd9660node *node, const char *name)
7519f988b79SJean-Baptiste Boric {
7529f988b79SJean-Baptiste Boric 	int working,len;
7539f988b79SJean-Baptiste Boric 	const char *p;
7549f988b79SJean-Baptiste Boric 	struct ISO_SUSP_ATTRIBUTES *r;
7559f988b79SJean-Baptiste Boric 
7569f988b79SJean-Baptiste Boric 	/*
7579f988b79SJean-Baptiste Boric 	 * Each NM record has 254 byes to work with. This means that
7589f988b79SJean-Baptiste Boric 	 * the name data itself only has 249 bytes to work with. So, a
7599f988b79SJean-Baptiste Boric 	 * name with 251 characters would require two nm records.
7609f988b79SJean-Baptiste Boric 	 */
7619f988b79SJean-Baptiste Boric 	p = name;
7629f988b79SJean-Baptiste Boric 	working = 1;
7639f988b79SJean-Baptiste Boric 	while (working) {
7649f988b79SJean-Baptiste Boric 		r = cd9660node_susp_create_node(SUSP_TYPE_RRIP,
7659f988b79SJean-Baptiste Boric 		    SUSP_ENTRY_RRIP_NM, "NM", SUSP_LOC_ENTRY);
7669f988b79SJean-Baptiste Boric 		r->attr.rr_entry.NM.h.version[0] = 1;
7679f988b79SJean-Baptiste Boric 		r->attr.rr_entry.NM.flags[0] = RRIP_NM_FLAGS_NONE;
7689f988b79SJean-Baptiste Boric 		len = strlen(p);
7699f988b79SJean-Baptiste Boric 
7709f988b79SJean-Baptiste Boric 		if (len > 249) {
7719f988b79SJean-Baptiste Boric 			len = 249;
7729f988b79SJean-Baptiste Boric 			r->attr.rr_entry.NM.flags[0] = RRIP_NM_FLAGS_CONTINUE;
7739f988b79SJean-Baptiste Boric 		} else {
7749f988b79SJean-Baptiste Boric 			working = 0;
7759f988b79SJean-Baptiste Boric 		}
7769f988b79SJean-Baptiste Boric 		memcpy(r->attr.rr_entry.NM.altname, p, len);
7779f988b79SJean-Baptiste Boric 		r->attr.rr_entry.NM.h.length[0] = 5 + len;
7789f988b79SJean-Baptiste Boric 
7799f988b79SJean-Baptiste Boric 		TAILQ_INSERT_TAIL(&node->head, r, rr_ll);
7809f988b79SJean-Baptiste Boric 
7819f988b79SJean-Baptiste Boric 		p += len;
7829f988b79SJean-Baptiste Boric 	}
7839f988b79SJean-Baptiste Boric }
7849f988b79SJean-Baptiste Boric 
7859f988b79SJean-Baptiste Boric void
cd9660_rrip_NM(cd9660node * node)7869f988b79SJean-Baptiste Boric cd9660_rrip_NM(cd9660node *node)
7879f988b79SJean-Baptiste Boric {
7889f988b79SJean-Baptiste Boric 	cd9660_rrip_add_NM(node, node->node->name);
7899f988b79SJean-Baptiste Boric }
7909f988b79SJean-Baptiste Boric 
7919f988b79SJean-Baptiste Boric 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)7929f988b79SJean-Baptiste Boric cd9660_susp_ER(cd9660node *node,
7939f988b79SJean-Baptiste Boric 	       u_char ext_version, const char* ext_id, const char* ext_des,
7949f988b79SJean-Baptiste Boric 	       const char* ext_src)
7959f988b79SJean-Baptiste Boric {
7969f988b79SJean-Baptiste Boric 	int l;
7979f988b79SJean-Baptiste Boric 	struct ISO_SUSP_ATTRIBUTES *r;
7989f988b79SJean-Baptiste Boric 
7999f988b79SJean-Baptiste Boric 	r = cd9660node_susp_create_node(SUSP_TYPE_SUSP,
8009f988b79SJean-Baptiste Boric 			SUSP_ENTRY_SUSP_ER, "ER", SUSP_LOC_DOT);
8019f988b79SJean-Baptiste Boric 
8029f988b79SJean-Baptiste Boric 	/* Fixed data is 8 bytes */
8039f988b79SJean-Baptiste Boric 	r->attr.su_entry.ER.h.length[0] = 8;
8049f988b79SJean-Baptiste Boric 	r->attr.su_entry.ER.h.version[0] = 1;
8059f988b79SJean-Baptiste Boric 
8069f988b79SJean-Baptiste Boric 	r->attr.su_entry.ER.len_id[0] = (u_char)strlen(ext_id);
8079f988b79SJean-Baptiste Boric 	r->attr.su_entry.ER.len_des[0] = (u_char)strlen(ext_des);
8089f988b79SJean-Baptiste Boric 	r->attr.su_entry.ER.len_src[0] = (u_char)strlen(ext_src);
8099f988b79SJean-Baptiste Boric 
8109f988b79SJean-Baptiste Boric 	l = r->attr.su_entry.ER.len_id[0] +
8119f988b79SJean-Baptiste Boric 		r->attr.su_entry.ER.len_src[0] +
8129f988b79SJean-Baptiste Boric 		r->attr.su_entry.ER.len_des[0];
8139f988b79SJean-Baptiste Boric 
8149f988b79SJean-Baptiste Boric 	/* Everything must fit. */
8159f988b79SJean-Baptiste Boric 	assert(l + r->attr.su_entry.ER.h.length[0] <= 254);
8169f988b79SJean-Baptiste Boric 
8179f988b79SJean-Baptiste Boric 	r->attr.su_entry.ER.h.length[0] += (u_char)l;
8189f988b79SJean-Baptiste Boric 
8199f988b79SJean-Baptiste Boric 
8209f988b79SJean-Baptiste Boric 	r->attr.su_entry.ER.ext_ver[0] = ext_version;
8219f988b79SJean-Baptiste Boric 	memcpy(r->attr.su_entry.ER.ext_data, ext_id,
8229f988b79SJean-Baptiste Boric 		(int)r->attr.su_entry.ER.len_id[0]);
8239f988b79SJean-Baptiste Boric 	l = (int) r->attr.su_entry.ER.len_id[0];
8249f988b79SJean-Baptiste Boric 	memcpy(r->attr.su_entry.ER.ext_data + l,ext_des,
8259f988b79SJean-Baptiste Boric 		(int)r->attr.su_entry.ER.len_des[0]);
8269f988b79SJean-Baptiste Boric 
8279f988b79SJean-Baptiste Boric 	l += (int)r->attr.su_entry.ER.len_des[0];
8289f988b79SJean-Baptiste Boric 	memcpy(r->attr.su_entry.ER.ext_data + l,ext_src,
8299f988b79SJean-Baptiste Boric 		(int)r->attr.su_entry.ER.len_src[0]);
8309f988b79SJean-Baptiste Boric 
8319f988b79SJean-Baptiste Boric 	TAILQ_INSERT_TAIL(&node->head, r, rr_ll);
8329f988b79SJean-Baptiste Boric 	return r;
8339f988b79SJean-Baptiste Boric }
8349f988b79SJean-Baptiste Boric 
8359f988b79SJean-Baptiste Boric struct ISO_SUSP_ATTRIBUTES*
cd9660_susp_ES(struct ISO_SUSP_ATTRIBUTES * last __unused,cd9660node * node __unused)8369f988b79SJean-Baptiste Boric cd9660_susp_ES(struct ISO_SUSP_ATTRIBUTES *last __unused, cd9660node *node __unused)
8379f988b79SJean-Baptiste Boric {
8389f988b79SJean-Baptiste Boric 	return NULL;
8399f988b79SJean-Baptiste Boric }
840