| @@ -1,839 +1,825 @@ | | | @@ -1,839 +1,825 @@ |
1 | /* $NetBSD: iso9660_rrip.c,v 1.15 2023/04/18 22:56:41 christos Exp $ */ | | 1 | /* $NetBSD: iso9660_rrip.c,v 1.16 2023/04/18 23:02:51 christos Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan | | 4 | * Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan |
5 | * Perez-Rathke and Ram Vedam. All rights reserved. | | 5 | * Perez-Rathke and Ram Vedam. All rights reserved. |
6 | * | | 6 | * |
7 | * This code was written by Daniel Watt, Walter Deignan, Ryan Gabrys, | | 7 | * This code was written by Daniel Watt, Walter Deignan, Ryan Gabrys, |
8 | * Alan Perez-Rathke and Ram Vedam. | | 8 | * Alan Perez-Rathke and Ram Vedam. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or | | 10 | * Redistribution and use in source and binary forms, with or |
11 | * without modification, are permitted provided that the following | | 11 | * without modification, are permitted provided that the following |
12 | * conditions are met: | | 12 | * conditions are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
15 | * 2. Redistributions in binary form must reproduce the above | | 15 | * 2. Redistributions in binary form must reproduce the above |
16 | * copyright notice, this list of conditions and the following | | 16 | * copyright notice, this list of conditions and the following |
17 | * disclaimer in the documentation and/or other materials provided | | 17 | * disclaimer in the documentation and/or other materials provided |
18 | * with the distribution. | | 18 | * with the distribution. |
19 | * | | 19 | * |
20 | * THIS SOFTWARE IS PROVIDED BY DANIEL WATT, WALTER DEIGNAN, RYAN | | 20 | * THIS SOFTWARE IS PROVIDED BY DANIEL WATT, WALTER DEIGNAN, RYAN |
21 | * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM ``AS IS'' AND ANY EXPRESS OR | | 21 | * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM ``AS IS'' AND ANY EXPRESS OR |
22 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 22 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
23 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | | 23 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
24 | * DISCLAIMED. IN NO EVENT SHALL DANIEL WATT, WALTER DEIGNAN, RYAN | | 24 | * DISCLAIMED. IN NO EVENT SHALL DANIEL WATT, WALTER DEIGNAN, RYAN |
25 | * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM BE LIABLE FOR ANY DIRECT, INDIRECT, | | 25 | * GABRYS, ALAN PEREZ-RATHKE AND RAM VEDAM BE LIABLE FOR ANY DIRECT, INDIRECT, |
26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | | 26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
27 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | | 27 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
28 | * USE,DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | | 28 | * USE,DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
29 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 29 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
30 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 30 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY | | 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY |
32 | * OF SUCH DAMAGE. | | 32 | * OF SUCH DAMAGE. |
33 | */ | | 33 | */ |
34 | /* This will hold all the function definitions | | 34 | /* This will hold all the function definitions |
35 | * defined in iso9660_rrip.h | | 35 | * defined in iso9660_rrip.h |
36 | */ | | 36 | */ |
37 | | | 37 | |
38 | #include "makefs.h" | | 38 | #include "makefs.h" |
39 | #include "cd9660.h" | | 39 | #include "cd9660.h" |
40 | #include "iso9660_rrip.h" | | 40 | #include "iso9660_rrip.h" |
41 | #include <sys/queue.h> | | 41 | #include <sys/queue.h> |
42 | #include <stdio.h> | | 42 | #include <stdio.h> |
43 | #include <util.h> | | 43 | #include <util.h> |
44 | | | 44 | |
45 | #include <sys/cdefs.h> | | 45 | #include <sys/cdefs.h> |
46 | #if defined(__RCSID) && !defined(__lint) | | 46 | #if defined(__RCSID) && !defined(__lint) |
47 | __RCSID("$NetBSD: iso9660_rrip.c,v 1.15 2023/04/18 22:56:41 christos Exp $"); | | 47 | __RCSID("$NetBSD: iso9660_rrip.c,v 1.16 2023/04/18 23:02:51 christos Exp $"); |
48 | #endif /* !__lint */ | | 48 | #endif /* !__lint */ |
49 | | | 49 | |
50 | static void cd9660_rrip_initialize_inode(cd9660node *); | | 50 | static void cd9660_rrip_initialize_inode(cd9660node *); |
51 | static int cd9660_susp_handle_continuation(iso9660_disk *, cd9660node *); | | 51 | static int cd9660_susp_handle_continuation(iso9660_disk *, cd9660node *); |
52 | static int cd9660_susp_handle_continuation_common(iso9660_disk *, cd9660node *, | | 52 | static int cd9660_susp_handle_continuation_common(iso9660_disk *, cd9660node *, |
53 | int); | | 53 | int); |
54 | | | 54 | |
55 | int | | 55 | int |
56 | cd9660_susp_initialize(iso9660_disk *diskStructure, cd9660node *node, | | 56 | cd9660_susp_initialize(iso9660_disk *diskStructure, cd9660node *node, |
57 | cd9660node *parent, cd9660node *grandparent) | | 57 | cd9660node *parent, cd9660node *grandparent) |
58 | { | | 58 | { |
59 | cd9660node *cn; | | 59 | cd9660node *cn; |
60 | int r; | | 60 | int r; |
61 | | | 61 | |
62 | /* Make sure the node is not NULL. If it is, there are major problems */ | | 62 | /* Make sure the node is not NULL. If it is, there are major problems */ |
63 | assert(node != NULL); | | 63 | assert(node != NULL); |
64 | | | 64 | |
65 | if (!(node->type & CD9660_TYPE_DOT) && | | 65 | if (!(node->type & CD9660_TYPE_DOT) && |
66 | !(node->type & CD9660_TYPE_DOTDOT)) | | 66 | !(node->type & CD9660_TYPE_DOTDOT)) |
67 | TAILQ_INIT(&(node->head)); | | 67 | TAILQ_INIT(&(node->head)); |
68 | if (node->dot_record != 0) | | 68 | if (node->dot_record != 0) |
69 | TAILQ_INIT(&(node->dot_record->head)); | | 69 | TAILQ_INIT(&(node->dot_record->head)); |
70 | if (node->dot_dot_record != 0) | | 70 | if (node->dot_dot_record != 0) |
71 | TAILQ_INIT(&(node->dot_dot_record->head)); | | 71 | TAILQ_INIT(&(node->dot_dot_record->head)); |
72 | | | 72 | |
73 | /* SUSP specific entries here */ | | 73 | /* SUSP specific entries here */ |
74 | if ((r = cd9660_susp_initialize_node(diskStructure, node)) < 0) | | 74 | if ((r = cd9660_susp_initialize_node(diskStructure, node)) < 0) |
75 | return r; | | 75 | return r; |
76 | | | 76 | |
77 | /* currently called cd9660node_rrip_init_links */ | | 77 | /* currently called cd9660node_rrip_init_links */ |
78 | r = cd9660_rrip_initialize_node(diskStructure, node, parent, grandparent); | | 78 | r = cd9660_rrip_initialize_node(diskStructure, node, parent, grandparent); |
79 | if (r < 0) | | 79 | if (r < 0) |
80 | return r; | | 80 | return r; |
81 | | | 81 | |
82 | /* | | 82 | /* |
83 | * See if we need a CE record, and set all of the | | 83 | * See if we need a CE record, and set all of the |
84 | * associated counters. | | 84 | * associated counters. |
85 | * | | 85 | * |
86 | * This should be called after all extensions. After | | 86 | * This should be called after all extensions. After |
87 | * this is called, no new records should be added. | | 87 | * this is called, no new records should be added. |
88 | */ | | 88 | */ |
89 | if ((r = cd9660_susp_handle_continuation(diskStructure, node)) < 0) | | 89 | if ((r = cd9660_susp_handle_continuation(diskStructure, node)) < 0) |
90 | return r; | | 90 | return r; |
91 | | | 91 | |
92 | /* Recurse on children. */ | | 92 | /* Recurse on children. */ |
93 | TAILQ_FOREACH(cn, &node->cn_children, cn_next_child) { | | 93 | TAILQ_FOREACH(cn, &node->cn_children, cn_next_child) { |
94 | if ((r = cd9660_susp_initialize(diskStructure, cn, node, parent)) < 0) | | 94 | if ((r = cd9660_susp_initialize(diskStructure, cn, node, parent)) < 0) |
95 | return 0; | | 95 | return 0; |
96 | } | | 96 | } |
97 | return 1; | | 97 | return 1; |
98 | } | | 98 | } |
99 | | | 99 | |
100 | int | | 100 | int |
101 | cd9660_susp_finalize(iso9660_disk *diskStructure, cd9660node *node) | | 101 | cd9660_susp_finalize(iso9660_disk *diskStructure, cd9660node *node) |
102 | { | | 102 | { |
103 | cd9660node *temp; | | 103 | cd9660node *temp; |
104 | int r; | | 104 | int r; |
105 | | | 105 | |
106 | assert(node != NULL); | | 106 | assert(node != NULL); |
107 | | | 107 | |
108 | if (node == diskStructure->rootNode) | | 108 | if (node == diskStructure->rootNode) |
109 | diskStructure->susp_continuation_area_current_free = 0; | | 109 | diskStructure->susp_continuation_area_current_free = 0; |
110 | | | 110 | |
111 | if ((r = cd9660_susp_finalize_node(diskStructure, node)) < 0) | | 111 | if ((r = cd9660_susp_finalize_node(diskStructure, node)) < 0) |
112 | return r; | | 112 | return r; |
113 | if ((r = cd9660_rrip_finalize_node(diskStructure, node)) < 0) | | 113 | if ((r = cd9660_rrip_finalize_node(diskStructure, node)) < 0) |
114 | return r; | | 114 | return r; |
115 | | | 115 | |
116 | TAILQ_FOREACH(temp, &node->cn_children, cn_next_child) { | | 116 | TAILQ_FOREACH(temp, &node->cn_children, cn_next_child) { |
117 | if ((r = cd9660_susp_finalize(diskStructure, temp)) < 0) | | 117 | if ((r = cd9660_susp_finalize(diskStructure, temp)) < 0) |
118 | return r; | | 118 | return r; |
119 | } | | 119 | } |
120 | return 1; | | 120 | return 1; |
121 | } | | 121 | } |
122 | | | 122 | |
123 | /* | | 123 | /* |
124 | * If we really wanted to speed things up, we could have some sort of | | 124 | * If we really wanted to speed things up, we could have some sort of |
125 | * lookup table on the SUSP entry type that calls a functor. Or, we could | | 125 | * lookup table on the SUSP entry type that calls a functor. Or, we could |
126 | * combine the functions. These functions are kept separate to allow | | 126 | * combine the functions. These functions are kept separate to allow |
127 | * easier addition of other extensions. | | 127 | * easier addition of other extensions. |
128 | | | 128 | |
129 | * For the sake of simplicity and clarity, we won't be doing that for now. | | 129 | * For the sake of simplicity and clarity, we won't be doing that for now. |
130 | */ | | 130 | */ |
131 | | | 131 | |
132 | /* | | 132 | /* |
133 | * SUSP needs to update the following types: | | 133 | * SUSP needs to update the following types: |
134 | * CE (continuation area) | | 134 | * CE (continuation area) |
135 | */ | | 135 | */ |
136 | int | | 136 | int |
137 | cd9660_susp_finalize_node(iso9660_disk *diskStructure, cd9660node *node) | | 137 | cd9660_susp_finalize_node(iso9660_disk *diskStructure, cd9660node *node) |
138 | { | | 138 | { |
139 | struct ISO_SUSP_ATTRIBUTES *t; | | 139 | struct ISO_SUSP_ATTRIBUTES *t; |
140 | | | 140 | |
141 | /* Handle CE counters */ | | 141 | /* Handle CE counters */ |
142 | if (node->susp_entry_ce_length > 0) { | | 142 | if (node->susp_entry_ce_length > 0) { |
143 | node->susp_entry_ce_start = | | 143 | node->susp_entry_ce_start = |
144 | diskStructure->susp_continuation_area_current_free; | | 144 | diskStructure->susp_continuation_area_current_free; |
145 | diskStructure->susp_continuation_area_current_free += | | 145 | diskStructure->susp_continuation_area_current_free += |
146 | node->susp_entry_ce_length; | | 146 | node->susp_entry_ce_length; |
147 | } | | 147 | } |
148 | | | 148 | |
149 | TAILQ_FOREACH(t, &node->head, rr_ll) { | | 149 | TAILQ_FOREACH(t, &node->head, rr_ll) { |
150 | if (t->susp_type != SUSP_TYPE_SUSP || | | 150 | if (t->susp_type != SUSP_TYPE_SUSP || |
151 | t->entry_type != SUSP_ENTRY_SUSP_CE) | | 151 | t->entry_type != SUSP_ENTRY_SUSP_CE) |
152 | continue; | | 152 | continue; |
153 | cd9660_bothendian_dword( | | 153 | cd9660_bothendian_dword( |
154 | diskStructure-> | | 154 | diskStructure-> |
155 | susp_continuation_area_start_sector, | | 155 | susp_continuation_area_start_sector, |
156 | t->attr.su_entry.CE.ca_sector); | | 156 | t->attr.su_entry.CE.ca_sector); |
157 | | | 157 | |
158 | cd9660_bothendian_dword( | | 158 | cd9660_bothendian_dword( |
159 | diskStructure-> | | 159 | diskStructure-> |
160 | susp_continuation_area_start_sector, | | 160 | susp_continuation_area_start_sector, |
161 | t->attr.su_entry.CE.ca_sector); | | 161 | t->attr.su_entry.CE.ca_sector); |
162 | cd9660_bothendian_dword(node->susp_entry_ce_start, | | 162 | cd9660_bothendian_dword(node->susp_entry_ce_start, |
163 | t->attr.su_entry.CE.offset); | | 163 | t->attr.su_entry.CE.offset); |
164 | cd9660_bothendian_dword(node->susp_entry_ce_length, | | 164 | cd9660_bothendian_dword(node->susp_entry_ce_length, |
165 | t->attr.su_entry.CE.length); | | 165 | t->attr.su_entry.CE.length); |
166 | } | | 166 | } |
167 | return 0; | | 167 | return 0; |
168 | } | | 168 | } |
169 | | | 169 | |
170 | int | | 170 | int |
171 | cd9660_rrip_finalize_node(iso9660_disk *diskStructure __unused, | | 171 | cd9660_rrip_finalize_node(iso9660_disk *diskStructure __unused, |
172 | cd9660node *node) | | 172 | cd9660node *node) |
173 | { | | 173 | { |
174 | struct ISO_SUSP_ATTRIBUTES *t; | | 174 | struct ISO_SUSP_ATTRIBUTES *t; |
175 | | | 175 | |
176 | TAILQ_FOREACH(t, &node->head, rr_ll) { | | 176 | TAILQ_FOREACH(t, &node->head, rr_ll) { |
177 | if (t->susp_type != SUSP_TYPE_RRIP) | | 177 | if (t->susp_type != SUSP_TYPE_RRIP) |
178 | continue; | | 178 | continue; |
179 | switch (t->entry_type) { | | 179 | switch (t->entry_type) { |
180 | case SUSP_ENTRY_RRIP_CL: | | 180 | case SUSP_ENTRY_RRIP_CL: |
181 | /* Look at rr_relocated*/ | | 181 | /* Look at rr_relocated*/ |
182 | if (node->rr_relocated == NULL) | | 182 | if (node->rr_relocated == NULL) |
183 | return -1; | | 183 | return -1; |
184 | cd9660_bothendian_dword( | | 184 | cd9660_bothendian_dword( |
185 | node->rr_relocated->fileDataSector, | | 185 | node->rr_relocated->fileDataSector, |
186 | (unsigned char *) | | 186 | (unsigned char *) |
187 | t->attr.rr_entry.CL.dir_loc); | | 187 | t->attr.rr_entry.CL.dir_loc); |
188 | break; | | 188 | break; |
189 | case SUSP_ENTRY_RRIP_PL: | | 189 | case SUSP_ENTRY_RRIP_PL: |
190 | /* Look at rr_real_parent */ | | 190 | /* Look at rr_real_parent */ |
191 | if (node->parent == NULL || | | 191 | if (node->parent == NULL || |
192 | node->parent->rr_real_parent == NULL) | | 192 | node->parent->rr_real_parent == NULL) |
193 | return -1; | | 193 | return -1; |
194 | cd9660_bothendian_dword( | | 194 | cd9660_bothendian_dword( |
195 | node->parent->rr_real_parent->fileDataSector, | | 195 | node->parent->rr_real_parent->fileDataSector, |
196 | (unsigned char *) | | 196 | (unsigned char *) |
197 | t->attr.rr_entry.PL.dir_loc); | | 197 | t->attr.rr_entry.PL.dir_loc); |
198 | break; | | 198 | break; |
199 | } | | 199 | } |
200 | } | | 200 | } |
201 | return 0; | | 201 | return 0; |
202 | } | | 202 | } |
203 | | | 203 | |
204 | static int | | 204 | static int |
205 | cd9660_susp_handle_continuation_common(iso9660_disk *diskStructure, | | 205 | cd9660_susp_handle_continuation_common(iso9660_disk *diskStructure, |
206 | cd9660node *node, int space) | | 206 | cd9660node *node, int space) |
207 | { | | 207 | { |
208 | int ca_used, susp_used, susp_used_pre_ce, working; | | 208 | int ca_used, susp_used, susp_used_pre_ce, working; |
209 | struct ISO_SUSP_ATTRIBUTES *temp, *pre_ce, *last, *CE, *ST; | | 209 | struct ISO_SUSP_ATTRIBUTES *temp, *pre_ce, *last, *CE, *ST; |
210 | | | 210 | |
211 | pre_ce = last = NULL; | | 211 | pre_ce = last = NULL; |
212 | working = 254 - space; | | 212 | working = 254 - space; |
213 | if (node->su_tail_size > 0) | | 213 | if (node->su_tail_size > 0) |
214 | /* Allow 4 bytes for "ST" record. */ | | 214 | /* Allow 4 bytes for "ST" record. */ |
215 | working -= node->su_tail_size + 4; | | 215 | working -= node->su_tail_size + 4; |
216 | /* printf("There are %i bytes to work with\n",working); */ | | 216 | /* printf("There are %i bytes to work with\n",working); */ |
217 | | | 217 | |
218 | susp_used_pre_ce = susp_used = 0; | | 218 | susp_used_pre_ce = susp_used = 0; |
219 | ca_used = 0; | | 219 | ca_used = 0; |
220 | TAILQ_FOREACH(temp, &node->head, rr_ll) { | | 220 | TAILQ_FOREACH(temp, &node->head, rr_ll) { |
221 | if (working < 0) | | 221 | if (working < 0) |
222 | break; | | 222 | break; |
223 | /* | | 223 | /* |
224 | * printf("SUSP Entry found, length is %i\n", | | 224 | * printf("SUSP Entry found, length is %i\n", |
225 | * CD9660_SUSP_ENTRY_SIZE(temp)); | | 225 | * CD9660_SUSP_ENTRY_SIZE(temp)); |
226 | */ | | 226 | */ |
227 | working -= CD9660_SUSP_ENTRY_SIZE(temp); | | 227 | working -= CD9660_SUSP_ENTRY_SIZE(temp); |
228 | if (working >= 0) { | | 228 | if (working >= 0) { |
229 | last = temp; | | 229 | last = temp; |
230 | susp_used += CD9660_SUSP_ENTRY_SIZE(temp); | | 230 | susp_used += CD9660_SUSP_ENTRY_SIZE(temp); |
231 | } | | 231 | } |
232 | if (working >= 28) { | | 232 | if (working >= 28) { |
233 | /* | | 233 | /* |
234 | * Remember the last entry after which we | | 234 | * Remember the last entry after which we |
235 | * could insert a "CE" entry. | | 235 | * could insert a "CE" entry. |
236 | */ | | 236 | */ |
237 | pre_ce = last; | | 237 | pre_ce = last; |
238 | susp_used_pre_ce = susp_used; | | 238 | susp_used_pre_ce = susp_used; |
239 | } | | 239 | } |
240 | } | | 240 | } |
241 | | | 241 | |
242 | /* A CE entry is needed */ | | 242 | /* A CE entry is needed */ |
243 | if (working <= 0) { | | 243 | if (working <= 0) { |
244 | CE = cd9660node_susp_create_node(SUSP_TYPE_SUSP, | | 244 | CE = cd9660node_susp_create_node(SUSP_TYPE_SUSP, |
245 | SUSP_ENTRY_SUSP_CE, "CE", SUSP_LOC_ENTRY); | | 245 | SUSP_ENTRY_SUSP_CE, "CE", SUSP_LOC_ENTRY); |
246 | cd9660_susp_ce(CE, node); | | 246 | cd9660_susp_ce(CE, node); |
247 | /* This will automatically insert at the appropriate location */ | | 247 | /* This will automatically insert at the appropriate location */ |
248 | if (pre_ce != NULL) | | 248 | if (pre_ce != NULL) |
249 | TAILQ_INSERT_AFTER(&node->head, pre_ce, CE, rr_ll); | | 249 | TAILQ_INSERT_AFTER(&node->head, pre_ce, CE, rr_ll); |
250 | else | | 250 | else |
251 | TAILQ_INSERT_HEAD(&node->head, CE, rr_ll); | | 251 | TAILQ_INSERT_HEAD(&node->head, CE, rr_ll); |
252 | last = CE; | | 252 | last = CE; |
253 | susp_used = susp_used_pre_ce + 28; | | 253 | susp_used = susp_used_pre_ce + 28; |
254 | /* Count how much CA data is necessary */ | | 254 | /* Count how much CA data is necessary */ |
255 | for (temp = TAILQ_NEXT(last, rr_ll); temp != NULL; | | 255 | for (temp = TAILQ_NEXT(last, rr_ll); temp != NULL; |
256 | temp = TAILQ_NEXT(temp, rr_ll)) { | | 256 | temp = TAILQ_NEXT(temp, rr_ll)) { |
257 | ca_used += CD9660_SUSP_ENTRY_SIZE(temp); | | 257 | ca_used += CD9660_SUSP_ENTRY_SIZE(temp); |
258 | } | | 258 | } |
259 | } | | 259 | } |
260 | | | 260 | |
261 | /* An ST entry is needed */ | | 261 | /* An ST entry is needed */ |
262 | if (node->su_tail_size > 0) { | | 262 | if (node->su_tail_size > 0) { |
263 | ST = cd9660node_susp_create_node(SUSP_TYPE_SUSP, | | 263 | ST = cd9660node_susp_create_node(SUSP_TYPE_SUSP, |
264 | SUSP_ENTRY_SUSP_ST, "ST", SUSP_LOC_ENTRY); | | 264 | SUSP_ENTRY_SUSP_ST, "ST", SUSP_LOC_ENTRY); |
265 | cd9660_susp_st(ST, node); | | 265 | cd9660_susp_st(ST, node); |
266 | if (last != NULL) | | 266 | if (last != NULL) |
267 | TAILQ_INSERT_AFTER(&node->head, last, ST, rr_ll); | | 267 | TAILQ_INSERT_AFTER(&node->head, last, ST, rr_ll); |
268 | else | | 268 | else |
269 | TAILQ_INSERT_HEAD(&node->head, ST, rr_ll); | | 269 | TAILQ_INSERT_HEAD(&node->head, ST, rr_ll); |
270 | last = ST; | | 270 | last = ST; |
271 | susp_used += 4; | | 271 | susp_used += 4; |
272 | } | | 272 | } |
273 | if (last != NULL) | | 273 | if (last != NULL) |
274 | last->last_in_suf = 1; | | 274 | last->last_in_suf = 1; |
275 | | | 275 | |
276 | node->susp_entry_size = susp_used; | | 276 | node->susp_entry_size = susp_used; |
277 | node->susp_entry_ce_length = ca_used; | | 277 | node->susp_entry_ce_length = ca_used; |
278 | | | 278 | |
279 | diskStructure->susp_continuation_area_size += ca_used; | | 279 | diskStructure->susp_continuation_area_size += ca_used; |
280 | return 1; | | 280 | return 1; |
281 | } | | 281 | } |
282 | | | 282 | |
283 | /* See if a continuation entry is needed for each of the different types */ | | 283 | /* See if a continuation entry is needed for each of the different types */ |
284 | static int | | 284 | static int |
285 | cd9660_susp_handle_continuation(iso9660_disk *diskStructure, cd9660node *node) | | 285 | cd9660_susp_handle_continuation(iso9660_disk *diskStructure, cd9660node *node) |
286 | { | | 286 | { |
287 | assert (node != NULL); | | 287 | assert (node != NULL); |
288 | | | 288 | |
289 | /* Entry */ | | 289 | /* Entry */ |
290 | if (cd9660_susp_handle_continuation_common(diskStructure, | | 290 | if (cd9660_susp_handle_continuation_common(diskStructure, |
291 | node,(int)(node->isoDirRecord->length[0])) < 0) | | 291 | node,(int)(node->isoDirRecord->length[0])) < 0) |
292 | return 0; | | 292 | return 0; |
293 | | | 293 | |
294 | return 1; | | 294 | return 1; |
295 | } | | 295 | } |
296 | | | 296 | |
297 | int | | 297 | int |
298 | cd9660_susp_initialize_node(iso9660_disk *diskStructure, cd9660node *node) | | 298 | cd9660_susp_initialize_node(iso9660_disk *diskStructure, cd9660node *node) |
299 | { | | 299 | { |
300 | struct ISO_SUSP_ATTRIBUTES *temp; | | 300 | struct ISO_SUSP_ATTRIBUTES *temp; |
301 | | | 301 | |
302 | /* | | 302 | /* |
303 | * Requirements/notes: | | 303 | * Requirements/notes: |
304 | * CE: is added for us where needed | | 304 | * CE: is added for us where needed |
305 | * ST: not sure if it is even required, but if so, should be | | 305 | * ST: not sure if it is even required, but if so, should be |
306 | * handled by the CE code | | 306 | * handled by the CE code |
307 | * PD: isnt needed (though might be added for testing) | | 307 | * PD: isnt needed (though might be added for testing) |
308 | * SP: is stored ONLY on the . record of the root directory | | 308 | * SP: is stored ONLY on the . record of the root directory |
309 | * ES: not sure | | 309 | * ES: not sure |
310 | */ | | 310 | */ |
311 | | | 311 | |
312 | /* Check for root directory, add SP and ER if needed. */ | | 312 | /* Check for root directory, add SP and ER if needed. */ |
313 | if (node->type & CD9660_TYPE_DOT) { | | 313 | if (node->type & CD9660_TYPE_DOT) { |
314 | if (node->parent == diskStructure->rootNode) { | | 314 | if (node->parent == diskStructure->rootNode) { |
315 | temp = cd9660node_susp_create_node(SUSP_TYPE_SUSP, | | 315 | temp = cd9660node_susp_create_node(SUSP_TYPE_SUSP, |
316 | SUSP_ENTRY_SUSP_SP, "SP", SUSP_LOC_DOT); | | 316 | SUSP_ENTRY_SUSP_SP, "SP", SUSP_LOC_DOT); |
317 | cd9660_susp_sp(temp, node); | | 317 | cd9660_susp_sp(temp, node); |
318 | | | 318 | |
319 | /* Should be first entry. */ | | 319 | /* Should be first entry. */ |
320 | TAILQ_INSERT_HEAD(&node->head, temp, rr_ll); | | 320 | TAILQ_INSERT_HEAD(&node->head, temp, rr_ll); |
321 | } | | 321 | } |
322 | } | | 322 | } |
323 | return 1; | | 323 | return 1; |
324 | } | | 324 | } |
325 | | | 325 | |
326 | static void | | 326 | static void |
327 | cd9660_rrip_initialize_inode(cd9660node *node) | | 327 | cd9660_rrip_initialize_inode(cd9660node *node) |
328 | { | | 328 | { |
329 | struct ISO_SUSP_ATTRIBUTES *attr; | | 329 | struct ISO_SUSP_ATTRIBUTES *attr; |
330 | | | 330 | |
331 | /* | | 331 | /* |
332 | * Inode dependent values - this may change, | | 332 | * Inode dependent values - this may change, |
333 | * but for now virtual files and directories do | | 333 | * but for now virtual files and directories do |
334 | * not have an inode structure | | 334 | * not have an inode structure |
335 | */ | | 335 | */ |
336 | | | 336 | |
337 | if ((node->node != NULL) && (node->node->inode != NULL)) { | | 337 | if ((node->node != NULL) && (node->node->inode != NULL)) { |
338 | /* PX - POSIX attributes */ | | 338 | /* PX - POSIX attributes */ |
339 | attr = cd9660node_susp_create_node(SUSP_TYPE_RRIP, | | 339 | attr = cd9660node_susp_create_node(SUSP_TYPE_RRIP, |
340 | SUSP_ENTRY_RRIP_PX, "PX", SUSP_LOC_ENTRY); | | 340 | SUSP_ENTRY_RRIP_PX, "PX", SUSP_LOC_ENTRY); |
341 | cd9660node_rrip_px(attr, node->node); | | 341 | cd9660node_rrip_px(attr, node->node); |
342 | | | 342 | |
343 | TAILQ_INSERT_TAIL(&node->head, attr, rr_ll); | | 343 | TAILQ_INSERT_TAIL(&node->head, attr, rr_ll); |
344 | | | 344 | |
345 | /* TF - timestamp */ | | 345 | /* TF - timestamp */ |
346 | attr = cd9660node_susp_create_node(SUSP_TYPE_RRIP, | | 346 | attr = cd9660node_susp_create_node(SUSP_TYPE_RRIP, |
347 | SUSP_ENTRY_RRIP_TF, "TF", SUSP_LOC_ENTRY); | | 347 | SUSP_ENTRY_RRIP_TF, "TF", SUSP_LOC_ENTRY); |
348 | cd9660node_rrip_tf(attr, node->node); | | 348 | cd9660node_rrip_tf(attr, node->node); |
349 | TAILQ_INSERT_TAIL(&node->head, attr, rr_ll); | | 349 | TAILQ_INSERT_TAIL(&node->head, attr, rr_ll); |
350 | | | 350 | |
351 | /* SL - Symbolic link */ | | 351 | /* SL - Symbolic link */ |
352 | /* ?????????? Dan - why is this here? */ | | 352 | /* ?????????? Dan - why is this here? */ |
353 | if (TAILQ_EMPTY(&node->cn_children) && | | 353 | if (TAILQ_EMPTY(&node->cn_children) && |
354 | node->node->inode != NULL && | | 354 | node->node->inode != NULL && |
355 | S_ISLNK(node->node->inode->st.st_mode)) | | 355 | S_ISLNK(node->node->inode->st.st_mode)) |
356 | cd9660_createSL(node); | | 356 | cd9660_createSL(node); |
357 | | | 357 | |
358 | /* PN - device number */ | | 358 | /* PN - device number */ |
359 | if (node->node->inode != NULL && | | 359 | if (node->node->inode != NULL && |
360 | ((S_ISCHR(node->node->inode->st.st_mode) || | | 360 | ((S_ISCHR(node->node->inode->st.st_mode) || |
361 | S_ISBLK(node->node->inode->st.st_mode)))) { | | 361 | S_ISBLK(node->node->inode->st.st_mode)))) { |
362 | attr = | | 362 | attr = |
363 | cd9660node_susp_create_node(SUSP_TYPE_RRIP, | | 363 | cd9660node_susp_create_node(SUSP_TYPE_RRIP, |
364 | SUSP_ENTRY_RRIP_PN, "PN", | | 364 | SUSP_ENTRY_RRIP_PN, "PN", |
365 | SUSP_LOC_ENTRY); | | 365 | SUSP_LOC_ENTRY); |
366 | cd9660node_rrip_pn(attr, node->node); | | 366 | cd9660node_rrip_pn(attr, node->node); |
367 | TAILQ_INSERT_TAIL(&node->head, attr, rr_ll); | | 367 | TAILQ_INSERT_TAIL(&node->head, attr, rr_ll); |
368 | } | | 368 | } |
369 | } | | 369 | } |
370 | } | | 370 | } |
371 | | | 371 | |
372 | int | | 372 | int |
373 | cd9660_rrip_initialize_node(iso9660_disk *diskStructure, cd9660node *node, | | 373 | cd9660_rrip_initialize_node(iso9660_disk *diskStructure, cd9660node *node, |
374 | cd9660node *parent, cd9660node *grandparent) | | 374 | cd9660node *parent, cd9660node *grandparent) |
375 | { | | 375 | { |
376 | struct ISO_SUSP_ATTRIBUTES *current = NULL; | | 376 | struct ISO_SUSP_ATTRIBUTES *current = NULL; |
377 | | | 377 | |
378 | assert(node != NULL); | | 378 | assert(node != NULL); |
379 | | | 379 | |
380 | if (node->type & CD9660_TYPE_DOT) { | | 380 | if (node->type & CD9660_TYPE_DOT) { |
381 | /* | | 381 | /* |
382 | * Handle ER - should be the only entry to appear on | | 382 | * Handle ER - should be the only entry to appear on |
383 | * a "." record | | 383 | * a "." record |
384 | */ | | 384 | */ |
385 | if (node->parent == diskStructure->rootNode) { | | 385 | if (node->parent == diskStructure->rootNode) { |
386 | cd9660_susp_ER(node, 1, SUSP_RRIP_ER_EXT_ID, | | 386 | cd9660_susp_ER(node, 1, SUSP_RRIP_ER_EXT_ID, |
387 | SUSP_RRIP_ER_EXT_DES, SUSP_RRIP_ER_EXT_SRC); | | 387 | SUSP_RRIP_ER_EXT_DES, SUSP_RRIP_ER_EXT_SRC); |
388 | } | | 388 | } |
389 | if (parent != NULL && parent->node != NULL && | | 389 | if (parent != NULL && parent->node != NULL && |
390 | parent->node->inode != NULL) { | | 390 | parent->node->inode != NULL) { |
391 | /* PX - POSIX attributes */ | | 391 | /* PX - POSIX attributes */ |
392 | current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, | | 392 | current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, |
393 | SUSP_ENTRY_RRIP_PX, "PX", SUSP_LOC_ENTRY); | | 393 | SUSP_ENTRY_RRIP_PX, "PX", SUSP_LOC_ENTRY); |
394 | cd9660node_rrip_px(current, parent->node); | | 394 | cd9660node_rrip_px(current, parent->node); |
395 | TAILQ_INSERT_TAIL(&node->head, current, rr_ll); | | 395 | TAILQ_INSERT_TAIL(&node->head, current, rr_ll); |
396 | } | | 396 | } |
397 | } else if (node->type & CD9660_TYPE_DOTDOT) { | | 397 | } else if (node->type & CD9660_TYPE_DOTDOT) { |
398 | if (grandparent != NULL && grandparent->node != NULL && | | 398 | if (grandparent != NULL && grandparent->node != NULL && |
399 | grandparent->node->inode != NULL) { | | 399 | grandparent->node->inode != NULL) { |
400 | /* PX - POSIX attributes */ | | 400 | /* PX - POSIX attributes */ |
401 | current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, | | 401 | current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, |
402 | SUSP_ENTRY_RRIP_PX, "PX", SUSP_LOC_ENTRY); | | 402 | SUSP_ENTRY_RRIP_PX, "PX", SUSP_LOC_ENTRY); |
403 | cd9660node_rrip_px(current, grandparent->node); | | 403 | cd9660node_rrip_px(current, grandparent->node); |
404 | TAILQ_INSERT_TAIL(&node->head, current, rr_ll); | | 404 | TAILQ_INSERT_TAIL(&node->head, current, rr_ll); |
405 | } | | 405 | } |
406 | /* Handle PL */ | | 406 | /* Handle PL */ |
407 | if (parent != NULL && parent->rr_real_parent != NULL) { | | 407 | if (parent != NULL && parent->rr_real_parent != NULL) { |
408 | current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, | | 408 | current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, |
409 | SUSP_ENTRY_RRIP_PL, "PL", SUSP_LOC_DOTDOT); | | 409 | SUSP_ENTRY_RRIP_PL, "PL", SUSP_LOC_DOTDOT); |
410 | cd9660_rrip_PL(current,node); | | 410 | cd9660_rrip_PL(current,node); |
411 | TAILQ_INSERT_TAIL(&node->head, current, rr_ll); | | 411 | TAILQ_INSERT_TAIL(&node->head, current, rr_ll); |
412 | } | | 412 | } |
413 | } else { | | 413 | } else { |
414 | cd9660_rrip_initialize_inode(node); | | 414 | cd9660_rrip_initialize_inode(node); |
415 | | | 415 | |
416 | /* | | | |
417 | * Not every node needs a NM set - only if the name is | | | |
418 | * actually different. IE: If a file is TEST -> TEST, | | | |
419 | * no NM. test -> TEST, need a NM | | | |
420 | * | | | |
421 | * The rr_moved_dir needs to be assigned a NM record as well. | | | |
422 | */ | | | |
423 | if (node == diskStructure->rr_moved_dir) { | | 416 | if (node == diskStructure->rr_moved_dir) { |
424 | cd9660_rrip_add_NM(node, RRIP_DEFAULT_MOVE_DIR_NAME); | | 417 | cd9660_rrip_add_NM(node, RRIP_DEFAULT_MOVE_DIR_NAME); |
425 | } | | 418 | } else if (node->node != NULL) { |
426 | else if ((node->node != NULL) && | | | |
427 | ((strlen(node->node->name) != | | | |
428 | (uint8_t)node->isoDirRecord->name_len[0]) || | | | |
429 | (memcmp(node->node->name,node->isoDirRecord->name, | | | |
430 | (uint8_t)node->isoDirRecord->name_len[0]) != 0))) { | | | |
431 | cd9660_rrip_NM(node); | | 419 | cd9660_rrip_NM(node); |
432 | } | | 420 | } |
433 | | | 421 | |
434 | | | | |
435 | | | | |
436 | /* Rock ridge directory relocation code here. */ | | 422 | /* Rock ridge directory relocation code here. */ |
437 | | | 423 | |
438 | /* First handle the CL for the placeholder file. */ | | 424 | /* First handle the CL for the placeholder file. */ |
439 | if (node->rr_relocated != NULL) { | | 425 | if (node->rr_relocated != NULL) { |
440 | current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, | | 426 | current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, |
441 | SUSP_ENTRY_RRIP_CL, "CL", SUSP_LOC_ENTRY); | | 427 | SUSP_ENTRY_RRIP_CL, "CL", SUSP_LOC_ENTRY); |
442 | cd9660_rrip_CL(current, node); | | 428 | cd9660_rrip_CL(current, node); |
443 | TAILQ_INSERT_TAIL(&node->head, current, rr_ll); | | 429 | TAILQ_INSERT_TAIL(&node->head, current, rr_ll); |
444 | } | | 430 | } |
445 | | | 431 | |
446 | /* Handle RE*/ | | 432 | /* Handle RE*/ |
447 | if (node->rr_real_parent != NULL) { | | 433 | if (node->rr_real_parent != NULL) { |
448 | current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, | | 434 | current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, |
449 | SUSP_ENTRY_RRIP_RE, "RE", SUSP_LOC_ENTRY); | | 435 | SUSP_ENTRY_RRIP_RE, "RE", SUSP_LOC_ENTRY); |
450 | cd9660_rrip_RE(current,node); | | 436 | cd9660_rrip_RE(current,node); |
451 | TAILQ_INSERT_TAIL(&node->head, current, rr_ll); | | 437 | TAILQ_INSERT_TAIL(&node->head, current, rr_ll); |
452 | } | | 438 | } |
453 | } | | 439 | } |
454 | return 1; | | 440 | return 1; |
455 | } | | 441 | } |
456 | | | 442 | |
457 | struct ISO_SUSP_ATTRIBUTES* | | 443 | struct ISO_SUSP_ATTRIBUTES* |
458 | cd9660node_susp_create_node(int susp_type, int entry_type, const char *type_id, | | 444 | cd9660node_susp_create_node(int susp_type, int entry_type, const char *type_id, |
459 | int write_loc) | | 445 | int write_loc) |
460 | { | | 446 | { |
461 | struct ISO_SUSP_ATTRIBUTES* temp; | | 447 | struct ISO_SUSP_ATTRIBUTES* temp; |
462 | | | 448 | |
463 | temp = emalloc(sizeof(*temp)); | | 449 | temp = emalloc(sizeof(*temp)); |
464 | temp->susp_type = susp_type; | | 450 | temp->susp_type = susp_type; |
465 | temp->entry_type = entry_type; | | 451 | temp->entry_type = entry_type; |
466 | temp->last_in_suf = 0; | | 452 | temp->last_in_suf = 0; |
467 | /* Phase this out */ | | 453 | /* Phase this out */ |
468 | temp->type_of[0] = type_id[0]; | | 454 | temp->type_of[0] = type_id[0]; |
469 | temp->type_of[1] = type_id[1]; | | 455 | temp->type_of[1] = type_id[1]; |
470 | temp->write_location = write_loc; | | 456 | temp->write_location = write_loc; |
471 | | | 457 | |
472 | /* | | 458 | /* |
473 | * Since the first four bytes is common, lets go ahead and | | 459 | * Since the first four bytes is common, lets go ahead and |
474 | * set the type identifier, since we are passing that to this | | 460 | * set the type identifier, since we are passing that to this |
475 | * function anyhow. | | 461 | * function anyhow. |
476 | */ | | 462 | */ |
477 | temp->attr.su_entry.SP.h.type[0] = type_id[0]; | | 463 | temp->attr.su_entry.SP.h.type[0] = type_id[0]; |
478 | temp->attr.su_entry.SP.h.type[1] = type_id[1]; | | 464 | temp->attr.su_entry.SP.h.type[1] = type_id[1]; |
479 | return temp; | | 465 | return temp; |
480 | } | | 466 | } |
481 | | | 467 | |
482 | int | | 468 | int |
483 | cd9660_rrip_PL(struct ISO_SUSP_ATTRIBUTES* p, cd9660node *node __unused) | | 469 | cd9660_rrip_PL(struct ISO_SUSP_ATTRIBUTES* p, cd9660node *node __unused) |
484 | { | | 470 | { |
485 | p->attr.rr_entry.PL.h.length[0] = 12; | | 471 | p->attr.rr_entry.PL.h.length[0] = 12; |
486 | p->attr.rr_entry.PL.h.version[0] = 1; | | 472 | p->attr.rr_entry.PL.h.version[0] = 1; |
487 | return 1; | | 473 | return 1; |
488 | } | | 474 | } |
489 | | | 475 | |
490 | int | | 476 | int |
491 | cd9660_rrip_CL(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *node __unused) | | 477 | cd9660_rrip_CL(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *node __unused) |
492 | { | | 478 | { |
493 | p->attr.rr_entry.CL.h.length[0] = 12; | | 479 | p->attr.rr_entry.CL.h.length[0] = 12; |
494 | p->attr.rr_entry.CL.h.version[0] = 1; | | 480 | p->attr.rr_entry.CL.h.version[0] = 1; |
495 | return 1; | | 481 | return 1; |
496 | } | | 482 | } |
497 | | | 483 | |
498 | int | | 484 | int |
499 | cd9660_rrip_RE(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *node __unused) | | 485 | cd9660_rrip_RE(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *node __unused) |
500 | { | | 486 | { |
501 | p->attr.rr_entry.RE.h.length[0] = 4; | | 487 | p->attr.rr_entry.RE.h.length[0] = 4; |
502 | p->attr.rr_entry.RE.h.version[0] = 1; | | 488 | p->attr.rr_entry.RE.h.version[0] = 1; |
503 | return 1; | | 489 | return 1; |
504 | } | | 490 | } |
505 | | | 491 | |
506 | void | | 492 | void |
507 | cd9660_createSL(cd9660node *node) | | 493 | cd9660_createSL(cd9660node *node) |
508 | { | | 494 | { |
509 | struct ISO_SUSP_ATTRIBUTES* current; | | 495 | struct ISO_SUSP_ATTRIBUTES* current; |
510 | int path_count, dir_count, done, i, j, dir_copied; | | 496 | int path_count, dir_count, done, i, j, dir_copied; |
511 | char temp_cr[255]; | | 497 | char temp_cr[255]; |
512 | char temp_sl[255]; /* used in copying continuation entry*/ | | 498 | char temp_sl[255]; /* used in copying continuation entry*/ |
513 | char* sl_ptr; | | 499 | char* sl_ptr; |
514 | | | 500 | |
515 | sl_ptr = node->node->symlink; | | 501 | sl_ptr = node->node->symlink; |
516 | | | 502 | |
517 | done = 0; | | 503 | done = 0; |
518 | path_count = 0; | | 504 | path_count = 0; |
519 | dir_count = 0; | | 505 | dir_count = 0; |
520 | dir_copied = 0; | | 506 | dir_copied = 0; |
521 | current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, | | 507 | current = cd9660node_susp_create_node(SUSP_TYPE_RRIP, |
522 | SUSP_ENTRY_RRIP_SL, "SL", SUSP_LOC_ENTRY); | | 508 | SUSP_ENTRY_RRIP_SL, "SL", SUSP_LOC_ENTRY); |
523 | | | 509 | |
524 | current->attr.rr_entry.SL.h.version[0] = 1; | | 510 | current->attr.rr_entry.SL.h.version[0] = 1; |
525 | current->attr.rr_entry.SL.flags[0] = SL_FLAGS_NONE; | | 511 | current->attr.rr_entry.SL.flags[0] = SL_FLAGS_NONE; |
526 | | | 512 | |
527 | if (*sl_ptr == '/') { | | 513 | if (*sl_ptr == '/') { |
528 | temp_cr[0] = SL_FLAGS_ROOT; | | 514 | temp_cr[0] = SL_FLAGS_ROOT; |
529 | temp_cr[1] = 0; | | 515 | temp_cr[1] = 0; |
530 | memcpy(current->attr.rr_entry.SL.component + path_count, | | 516 | memcpy(current->attr.rr_entry.SL.component + path_count, |
531 | temp_cr, 2); | | 517 | temp_cr, 2); |
532 | path_count += 2; | | 518 | path_count += 2; |
533 | sl_ptr++; | | 519 | sl_ptr++; |
534 | } | | 520 | } |
535 | | | 521 | |
536 | for (i = 0; i < (dir_count + 2); i++) | | 522 | for (i = 0; i < (dir_count + 2); i++) |
537 | temp_cr[i] = '\0'; | | 523 | temp_cr[i] = '\0'; |
538 | | | 524 | |
539 | while (!done) { | | 525 | while (!done) { |
540 | while ((*sl_ptr != '/') && (*sl_ptr != '\0')) { | | 526 | while ((*sl_ptr != '/') && (*sl_ptr != '\0')) { |
541 | dir_copied = 1; | | 527 | dir_copied = 1; |
542 | if (*sl_ptr == '.') { | | 528 | if (*sl_ptr == '.') { |
543 | if ((*(sl_ptr + 1) == '/') || (*(sl_ptr + 1) | | 529 | if ((*(sl_ptr + 1) == '/') || (*(sl_ptr + 1) |
544 | == '\0')) { | | 530 | == '\0')) { |
545 | temp_cr[0] = SL_FLAGS_CURRENT; | | 531 | temp_cr[0] = SL_FLAGS_CURRENT; |
546 | sl_ptr++; | | 532 | sl_ptr++; |
547 | } else if(*(sl_ptr + 1) == '.') { | | 533 | } else if(*(sl_ptr + 1) == '.') { |
548 | if ((*(sl_ptr + 2) == '/') || | | 534 | if ((*(sl_ptr + 2) == '/') || |
549 | (*(sl_ptr + 2) == '\0')) { | | 535 | (*(sl_ptr + 2) == '\0')) { |
550 | temp_cr[0] = SL_FLAGS_PARENT; | | 536 | temp_cr[0] = SL_FLAGS_PARENT; |
551 | sl_ptr += 2; | | 537 | sl_ptr += 2; |
552 | } | | 538 | } |
553 | } else { | | 539 | } else { |
554 | temp_cr[dir_count+2] = *sl_ptr; | | 540 | temp_cr[dir_count+2] = *sl_ptr; |
555 | sl_ptr++; | | 541 | sl_ptr++; |
556 | dir_count++; | | 542 | dir_count++; |
557 | } | | 543 | } |
558 | } else { | | 544 | } else { |
559 | temp_cr[dir_count + 2] = *sl_ptr; | | 545 | temp_cr[dir_count + 2] = *sl_ptr; |
560 | sl_ptr++; | | 546 | sl_ptr++; |
561 | dir_count++; | | 547 | dir_count++; |
562 | } | | 548 | } |
563 | } | | 549 | } |
564 | | | 550 | |
565 | if ((path_count + dir_count) >= 249) { | | 551 | if ((path_count + dir_count) >= 249) { |
566 | current->attr.rr_entry.SL.flags[0] |= SL_FLAGS_CONTINUE; | | 552 | current->attr.rr_entry.SL.flags[0] |= SL_FLAGS_CONTINUE; |
567 | | | 553 | |
568 | j = 0; | | 554 | j = 0; |
569 | | | 555 | |
570 | if (path_count <= 249) { | | 556 | if (path_count <= 249) { |
571 | while(j != (249 - path_count)) { | | 557 | while(j != (249 - path_count)) { |
572 | temp_sl[j] = temp_cr[j]; | | 558 | temp_sl[j] = temp_cr[j]; |
573 | j++; | | 559 | j++; |
574 | } | | 560 | } |
575 | temp_sl[0] = SL_FLAGS_CONTINUE; | | 561 | temp_sl[0] = SL_FLAGS_CONTINUE; |
576 | temp_sl[1] = j - 2; | | 562 | temp_sl[1] = j - 2; |
577 | memcpy( | | 563 | memcpy( |
578 | current->attr.rr_entry.SL.component + | | 564 | current->attr.rr_entry.SL.component + |
579 | path_count, | | 565 | path_count, |
580 | temp_sl, j); | | 566 | temp_sl, j); |
581 | } | | 567 | } |
582 | | | 568 | |
583 | path_count += j; | | 569 | path_count += j; |
584 | current->attr.rr_entry.SL.h.length[0] = path_count + 5; | | 570 | current->attr.rr_entry.SL.h.length[0] = path_count + 5; |
585 | TAILQ_INSERT_TAIL(&node->head, current, rr_ll); | | 571 | TAILQ_INSERT_TAIL(&node->head, current, rr_ll); |
586 | current= cd9660node_susp_create_node(SUSP_TYPE_RRIP, | | 572 | current= cd9660node_susp_create_node(SUSP_TYPE_RRIP, |
587 | SUSP_ENTRY_RRIP_SL, "SL", SUSP_LOC_ENTRY); | | 573 | SUSP_ENTRY_RRIP_SL, "SL", SUSP_LOC_ENTRY); |
588 | current->attr.rr_entry.SL.h.version[0] = 1; | | 574 | current->attr.rr_entry.SL.h.version[0] = 1; |
589 | current->attr.rr_entry.SL.flags[0] = SL_FLAGS_NONE; | | 575 | current->attr.rr_entry.SL.flags[0] = SL_FLAGS_NONE; |
590 | | | 576 | |
591 | path_count = 0; | | 577 | path_count = 0; |
592 | | | 578 | |
593 | if (dir_count > 2) { | | 579 | if (dir_count > 2) { |
594 | while (j != dir_count + 2) { | | 580 | while (j != dir_count + 2) { |
595 | current->attr.rr_entry.SL.component[ | | 581 | current->attr.rr_entry.SL.component[ |
596 | path_count + 2] = temp_cr[j]; | | 582 | path_count + 2] = temp_cr[j]; |
597 | j++; | | 583 | j++; |
598 | path_count++; | | 584 | path_count++; |
599 | } | | 585 | } |
600 | current->attr.rr_entry.SL.component[1] | | 586 | current->attr.rr_entry.SL.component[1] |
601 | = path_count; | | 587 | = path_count; |
602 | path_count+= 2; | | 588 | path_count+= 2; |
603 | } else { | | 589 | } else { |
604 | while(j != dir_count) { | | 590 | while(j != dir_count) { |
605 | current->attr.rr_entry.SL.component[ | | 591 | current->attr.rr_entry.SL.component[ |
606 | path_count+2] = temp_cr[j]; | | 592 | path_count+2] = temp_cr[j]; |
607 | j++; | | 593 | j++; |
608 | path_count++; | | 594 | path_count++; |
609 | } | | 595 | } |
610 | } | | 596 | } |
611 | } else { | | 597 | } else { |
612 | if (dir_copied == 1) { | | 598 | if (dir_copied == 1) { |
613 | temp_cr[1] = dir_count; | | 599 | temp_cr[1] = dir_count; |
614 | memcpy(current->attr.rr_entry.SL.component + | | 600 | memcpy(current->attr.rr_entry.SL.component + |
615 | path_count, | | 601 | path_count, |
616 | temp_cr, dir_count + 2); | | 602 | temp_cr, dir_count + 2); |
617 | path_count += dir_count + 2; | | 603 | path_count += dir_count + 2; |
618 | } | | 604 | } |
619 | } | | 605 | } |
620 | | | 606 | |
621 | if (*sl_ptr == '\0') { | | 607 | if (*sl_ptr == '\0') { |
622 | done = 1; | | 608 | done = 1; |
623 | current->attr.rr_entry.SL.h.length[0] = path_count + 5; | | 609 | current->attr.rr_entry.SL.h.length[0] = path_count + 5; |
624 | TAILQ_INSERT_TAIL(&node->head, current, rr_ll); | | 610 | TAILQ_INSERT_TAIL(&node->head, current, rr_ll); |
625 | } else { | | 611 | } else { |
626 | sl_ptr++; | | 612 | sl_ptr++; |
627 | dir_count = 0; | | 613 | dir_count = 0; |
628 | dir_copied = 0; | | 614 | dir_copied = 0; |
629 | for(i = 0; i < 255; i++) { | | 615 | for(i = 0; i < 255; i++) { |
630 | temp_cr[i] = '\0'; | | 616 | temp_cr[i] = '\0'; |
631 | } | | 617 | } |
632 | } | | 618 | } |
633 | } | | 619 | } |
634 | } | | 620 | } |
635 | | | 621 | |
636 | int | | 622 | int |
637 | cd9660node_rrip_px(struct ISO_SUSP_ATTRIBUTES *v, fsnode *pxinfo) | | 623 | cd9660node_rrip_px(struct ISO_SUSP_ATTRIBUTES *v, fsnode *pxinfo) |
638 | { | | 624 | { |
639 | v->attr.rr_entry.PX.h.length[0] = 36; | | 625 | v->attr.rr_entry.PX.h.length[0] = 36; |
640 | v->attr.rr_entry.PX.h.version[0] = 1; | | 626 | v->attr.rr_entry.PX.h.version[0] = 1; |
641 | cd9660_bothendian_dword(pxinfo->inode->st.st_mode, | | 627 | cd9660_bothendian_dword(pxinfo->inode->st.st_mode, |
642 | v->attr.rr_entry.PX.mode); | | 628 | v->attr.rr_entry.PX.mode); |
643 | cd9660_bothendian_dword(pxinfo->inode->st.st_nlink, | | 629 | cd9660_bothendian_dword(pxinfo->inode->st.st_nlink, |
644 | v->attr.rr_entry.PX.links); | | 630 | v->attr.rr_entry.PX.links); |
645 | cd9660_bothendian_dword(pxinfo->inode->st.st_uid, | | 631 | cd9660_bothendian_dword(pxinfo->inode->st.st_uid, |
646 | v->attr.rr_entry.PX.uid); | | 632 | v->attr.rr_entry.PX.uid); |
647 | cd9660_bothendian_dword(pxinfo->inode->st.st_gid, | | 633 | cd9660_bothendian_dword(pxinfo->inode->st.st_gid, |
648 | v->attr.rr_entry.PX.gid); | | 634 | v->attr.rr_entry.PX.gid); |
649 | | | 635 | |
650 | /* Ignoring the serial number for now */ | | 636 | /* Ignoring the serial number for now */ |
651 | return 1; | | 637 | return 1; |
652 | } | | 638 | } |
653 | | | 639 | |
654 | int | | 640 | int |
655 | cd9660node_rrip_pn(struct ISO_SUSP_ATTRIBUTES *pn_field, fsnode *fnode) | | 641 | cd9660node_rrip_pn(struct ISO_SUSP_ATTRIBUTES *pn_field, fsnode *fnode) |
656 | { | | 642 | { |
657 | pn_field->attr.rr_entry.PN.h.length[0] = 20; | | 643 | pn_field->attr.rr_entry.PN.h.length[0] = 20; |
658 | pn_field->attr.rr_entry.PN.h.version[0] = 1; | | 644 | pn_field->attr.rr_entry.PN.h.version[0] = 1; |
659 | | | 645 | |
660 | if (sizeof (fnode->inode->st.st_rdev) > 4) | | 646 | if (sizeof (fnode->inode->st.st_rdev) > 4) |
661 | cd9660_bothendian_dword( | | 647 | cd9660_bothendian_dword( |
662 | (uint64_t)fnode->inode->st.st_rdev >> 32, | | 648 | (uint64_t)fnode->inode->st.st_rdev >> 32, |
663 | pn_field->attr.rr_entry.PN.high); | | 649 | pn_field->attr.rr_entry.PN.high); |
664 | else | | 650 | else |
665 | cd9660_bothendian_dword(0, pn_field->attr.rr_entry.PN.high); | | 651 | cd9660_bothendian_dword(0, pn_field->attr.rr_entry.PN.high); |
666 | | | 652 | |
667 | cd9660_bothendian_dword(fnode->inode->st.st_rdev & 0xffffffff, | | 653 | cd9660_bothendian_dword(fnode->inode->st.st_rdev & 0xffffffff, |
668 | pn_field->attr.rr_entry.PN.low); | | 654 | pn_field->attr.rr_entry.PN.low); |
669 | return 1; | | 655 | return 1; |
670 | } | | 656 | } |
671 | | | 657 | |
672 | #if 0 | | 658 | #if 0 |
673 | int | | 659 | int |
674 | cd9660node_rrip_nm(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *file_node) | | 660 | cd9660node_rrip_nm(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *file_node) |
675 | { | | 661 | { |
676 | int nm_length = strlen(file_node->isoDirRecord->name) + 5; | | 662 | int nm_length = strlen(file_node->isoDirRecord->name) + 5; |
677 | p->attr.rr_entry.NM.h.type[0] = 'N'; | | 663 | p->attr.rr_entry.NM.h.type[0] = 'N'; |
678 | p->attr.rr_entry.NM.h.type[1] = 'M'; | | 664 | p->attr.rr_entry.NM.h.type[1] = 'M'; |
679 | sprintf(p->attr.rr_entry.NM.altname, "%s", file_node->isoDirRecord->name); | | 665 | sprintf(p->attr.rr_entry.NM.altname, "%s", file_node->isoDirRecord->name); |
680 | p->attr.rr_entry.NM.h.length[0] = (unsigned char)nm_length; | | 666 | p->attr.rr_entry.NM.h.length[0] = (unsigned char)nm_length; |
681 | p->attr.rr_entry.NM.h.version[0] = (unsigned char)1; | | 667 | p->attr.rr_entry.NM.h.version[0] = (unsigned char)1; |
682 | p->attr.rr_entry.NM.flags[0] = (unsigned char) NM_PARENT; | | 668 | p->attr.rr_entry.NM.flags[0] = (unsigned char) NM_PARENT; |
683 | return 1; | | 669 | return 1; |
684 | } | | 670 | } |
685 | #endif | | 671 | #endif |
686 | | | 672 | |
687 | int | | 673 | int |
688 | cd9660node_rrip_tf(struct ISO_SUSP_ATTRIBUTES *p, fsnode *_node) | | 674 | cd9660node_rrip_tf(struct ISO_SUSP_ATTRIBUTES *p, fsnode *_node) |
689 | { | | 675 | { |
690 | p->attr.rr_entry.TF.flags[0] = TF_MODIFY | TF_ACCESS | TF_ATTRIBUTES; | | 676 | p->attr.rr_entry.TF.flags[0] = TF_MODIFY | TF_ACCESS | TF_ATTRIBUTES; |
691 | p->attr.rr_entry.TF.h.length[0] = 5; | | 677 | p->attr.rr_entry.TF.h.length[0] = 5; |
692 | p->attr.rr_entry.TF.h.version[0] = 1; | | 678 | p->attr.rr_entry.TF.h.version[0] = 1; |
693 | | | 679 | |
694 | /* | | 680 | /* |
695 | * Need to add creation time, backup time, | | 681 | * Need to add creation time, backup time, |
696 | * expiration time, and effective time. | | 682 | * expiration time, and effective time. |
697 | */ | | 683 | */ |
698 | | | 684 | |
699 | cd9660_time_915(p->attr.rr_entry.TF.timestamp, | | 685 | cd9660_time_915(p->attr.rr_entry.TF.timestamp, |
700 | _node->inode->st.st_mtime); | | 686 | _node->inode->st.st_mtime); |
701 | p->attr.rr_entry.TF.h.length[0] += 7; | | 687 | p->attr.rr_entry.TF.h.length[0] += 7; |
702 | | | 688 | |
703 | cd9660_time_915(p->attr.rr_entry.TF.timestamp + 7, | | 689 | cd9660_time_915(p->attr.rr_entry.TF.timestamp + 7, |
704 | _node->inode->st.st_atime); | | 690 | _node->inode->st.st_atime); |
705 | p->attr.rr_entry.TF.h.length[0] += 7; | | 691 | p->attr.rr_entry.TF.h.length[0] += 7; |
706 | | | 692 | |
707 | cd9660_time_915(p->attr.rr_entry.TF.timestamp + 14, | | 693 | cd9660_time_915(p->attr.rr_entry.TF.timestamp + 14, |
708 | _node->inode->st.st_ctime); | | 694 | _node->inode->st.st_ctime); |
709 | p->attr.rr_entry.TF.h.length[0] += 7; | | 695 | p->attr.rr_entry.TF.h.length[0] += 7; |
710 | return 1; | | 696 | return 1; |
711 | } | | 697 | } |
712 | | | 698 | |
713 | int | | 699 | int |
714 | cd9660_susp_sp(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *spinfo __unused) | | 700 | cd9660_susp_sp(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *spinfo __unused) |
715 | { | | 701 | { |
716 | p->attr.su_entry.SP.h.length[0] = 7; | | 702 | p->attr.su_entry.SP.h.length[0] = 7; |
717 | p->attr.su_entry.SP.h.version[0] = 1; | | 703 | p->attr.su_entry.SP.h.version[0] = 1; |
718 | p->attr.su_entry.SP.check[0] = 0xBE; | | 704 | p->attr.su_entry.SP.check[0] = 0xBE; |
719 | p->attr.su_entry.SP.check[1] = 0xEF; | | 705 | p->attr.su_entry.SP.check[1] = 0xEF; |
720 | p->attr.su_entry.SP.len_skp[0] = 0; | | 706 | p->attr.su_entry.SP.len_skp[0] = 0; |
721 | return 1; | | 707 | return 1; |
722 | } | | 708 | } |
723 | | | 709 | |
724 | int | | 710 | int |
725 | cd9660_susp_st(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *stinfo __unused) | | 711 | cd9660_susp_st(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *stinfo __unused) |
726 | { | | 712 | { |
727 | p->attr.su_entry.ST.h.type[0] = 'S'; | | 713 | p->attr.su_entry.ST.h.type[0] = 'S'; |
728 | p->attr.su_entry.ST.h.type[1] = 'T'; | | 714 | p->attr.su_entry.ST.h.type[1] = 'T'; |
729 | p->attr.su_entry.ST.h.length[0] = 4; | | 715 | p->attr.su_entry.ST.h.length[0] = 4; |
730 | p->attr.su_entry.ST.h.version[0] = 1; | | 716 | p->attr.su_entry.ST.h.version[0] = 1; |
731 | return 1; | | 717 | return 1; |
732 | } | | 718 | } |
733 | | | 719 | |
734 | int | | 720 | int |
735 | cd9660_susp_ce(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *spinfo __unused) | | 721 | cd9660_susp_ce(struct ISO_SUSP_ATTRIBUTES *p, cd9660node *spinfo __unused) |
736 | { | | 722 | { |
737 | p->attr.su_entry.CE.h.length[0] = 28; | | 723 | p->attr.su_entry.CE.h.length[0] = 28; |
738 | p->attr.su_entry.CE.h.version[0] = 1; | | 724 | p->attr.su_entry.CE.h.version[0] = 1; |
739 | /* Other attributes dont matter right now, will be updated later */ | | 725 | /* Other attributes dont matter right now, will be updated later */ |
740 | return 1; | | 726 | return 1; |
741 | } | | 727 | } |
742 | | | 728 | |
743 | int | | 729 | int |
744 | cd9660_susp_pd(struct ISO_SUSP_ATTRIBUTES *p __unused, int length __unused) | | 730 | cd9660_susp_pd(struct ISO_SUSP_ATTRIBUTES *p __unused, int length __unused) |
745 | { | | 731 | { |
746 | return 1; | | 732 | return 1; |
747 | } | | 733 | } |
748 | | | 734 | |
749 | void | | 735 | void |
750 | cd9660_rrip_add_NM(cd9660node *node, const char *name) | | 736 | cd9660_rrip_add_NM(cd9660node *node, const char *name) |
751 | { | | 737 | { |
752 | int working,len; | | 738 | int working,len; |
753 | const char *p; | | 739 | const char *p; |
754 | struct ISO_SUSP_ATTRIBUTES *r; | | 740 | struct ISO_SUSP_ATTRIBUTES *r; |
755 | | | 741 | |
756 | /* | | 742 | /* |
757 | * Each NM record has 254 byes to work with. This means that | | 743 | * Each NM record has 254 byes to work with. This means that |
758 | * the name data itself only has 249 bytes to work with. So, a | | 744 | * the name data itself only has 249 bytes to work with. So, a |
759 | * name with 251 characters would require two nm records. | | 745 | * name with 251 characters would require two nm records. |
760 | */ | | 746 | */ |
761 | p = name; | | 747 | p = name; |
762 | working = 1; | | 748 | working = 1; |
763 | while (working) { | | 749 | while (working) { |
764 | r = cd9660node_susp_create_node(SUSP_TYPE_RRIP, | | 750 | r = cd9660node_susp_create_node(SUSP_TYPE_RRIP, |
765 | SUSP_ENTRY_RRIP_NM, "NM", SUSP_LOC_ENTRY); | | 751 | SUSP_ENTRY_RRIP_NM, "NM", SUSP_LOC_ENTRY); |
766 | r->attr.rr_entry.NM.h.version[0] = 1; | | 752 | r->attr.rr_entry.NM.h.version[0] = 1; |
767 | r->attr.rr_entry.NM.flags[0] = RRIP_NM_FLAGS_NONE; | | 753 | r->attr.rr_entry.NM.flags[0] = RRIP_NM_FLAGS_NONE; |
768 | len = strlen(p); | | 754 | len = strlen(p); |
769 | | | 755 | |
770 | if (len > 249) { | | 756 | if (len > 249) { |
771 | len = 249; | | 757 | len = 249; |
772 | r->attr.rr_entry.NM.flags[0] = RRIP_NM_FLAGS_CONTINUE; | | 758 | r->attr.rr_entry.NM.flags[0] = RRIP_NM_FLAGS_CONTINUE; |
773 | } else { | | 759 | } else { |
774 | working = 0; | | 760 | working = 0; |
775 | } | | 761 | } |
776 | memcpy(r->attr.rr_entry.NM.altname, p, len); | | 762 | memcpy(r->attr.rr_entry.NM.altname, p, len); |
777 | r->attr.rr_entry.NM.h.length[0] = 5 + len; | | 763 | r->attr.rr_entry.NM.h.length[0] = 5 + len; |
778 | | | 764 | |
779 | TAILQ_INSERT_TAIL(&node->head, r, rr_ll); | | 765 | TAILQ_INSERT_TAIL(&node->head, r, rr_ll); |
780 | | | 766 | |
781 | p += len; | | 767 | p += len; |
782 | } | | 768 | } |
783 | } | | 769 | } |
784 | | | 770 | |
785 | void | | 771 | void |
786 | cd9660_rrip_NM(cd9660node *node) | | 772 | cd9660_rrip_NM(cd9660node *node) |
787 | { | | 773 | { |
788 | cd9660_rrip_add_NM(node, node->node->name); | | 774 | cd9660_rrip_add_NM(node, node->node->name); |
789 | } | | 775 | } |
790 | | | 776 | |
791 | struct ISO_SUSP_ATTRIBUTES* | | 777 | struct ISO_SUSP_ATTRIBUTES* |
792 | cd9660_susp_ER(cd9660node *node, | | 778 | cd9660_susp_ER(cd9660node *node, |
793 | u_char ext_version, const char* ext_id, const char* ext_des, | | 779 | u_char ext_version, const char* ext_id, const char* ext_des, |
794 | const char* ext_src) | | 780 | const char* ext_src) |
795 | { | | 781 | { |
796 | int l; | | 782 | int l; |
797 | struct ISO_SUSP_ATTRIBUTES *r; | | 783 | struct ISO_SUSP_ATTRIBUTES *r; |
798 | | | 784 | |
799 | r = cd9660node_susp_create_node(SUSP_TYPE_SUSP, | | 785 | r = cd9660node_susp_create_node(SUSP_TYPE_SUSP, |
800 | SUSP_ENTRY_SUSP_ER, "ER", SUSP_LOC_DOT); | | 786 | SUSP_ENTRY_SUSP_ER, "ER", SUSP_LOC_DOT); |
801 | | | 787 | |
802 | /* Fixed data is 8 bytes */ | | 788 | /* Fixed data is 8 bytes */ |
803 | r->attr.su_entry.ER.h.length[0] = 8; | | 789 | r->attr.su_entry.ER.h.length[0] = 8; |
804 | r->attr.su_entry.ER.h.version[0] = 1; | | 790 | r->attr.su_entry.ER.h.version[0] = 1; |
805 | | | 791 | |
806 | r->attr.su_entry.ER.len_id[0] = (u_char)strlen(ext_id); | | 792 | r->attr.su_entry.ER.len_id[0] = (u_char)strlen(ext_id); |
807 | r->attr.su_entry.ER.len_des[0] = (u_char)strlen(ext_des); | | 793 | r->attr.su_entry.ER.len_des[0] = (u_char)strlen(ext_des); |
808 | r->attr.su_entry.ER.len_src[0] = (u_char)strlen(ext_src); | | 794 | r->attr.su_entry.ER.len_src[0] = (u_char)strlen(ext_src); |
809 | | | 795 | |
810 | l = r->attr.su_entry.ER.len_id[0] + | | 796 | l = r->attr.su_entry.ER.len_id[0] + |
811 | r->attr.su_entry.ER.len_src[0] + | | 797 | r->attr.su_entry.ER.len_src[0] + |
812 | r->attr.su_entry.ER.len_des[0]; | | 798 | r->attr.su_entry.ER.len_des[0]; |
813 | | | 799 | |
814 | /* Everything must fit. */ | | 800 | /* Everything must fit. */ |
815 | assert(l + r->attr.su_entry.ER.h.length[0] <= 254); | | 801 | assert(l + r->attr.su_entry.ER.h.length[0] <= 254); |
816 | | | 802 | |
817 | r->attr.su_entry.ER.h.length[0] += (u_char)l; | | 803 | r->attr.su_entry.ER.h.length[0] += (u_char)l; |
818 | | | 804 | |
819 | | | 805 | |
820 | r->attr.su_entry.ER.ext_ver[0] = ext_version; | | 806 | r->attr.su_entry.ER.ext_ver[0] = ext_version; |
821 | memcpy(r->attr.su_entry.ER.ext_data, ext_id, | | 807 | memcpy(r->attr.su_entry.ER.ext_data, ext_id, |
822 | (int)r->attr.su_entry.ER.len_id[0]); | | 808 | (int)r->attr.su_entry.ER.len_id[0]); |
823 | l = (int) r->attr.su_entry.ER.len_id[0]; | | 809 | l = (int) r->attr.su_entry.ER.len_id[0]; |
824 | memcpy(r->attr.su_entry.ER.ext_data + l,ext_des, | | 810 | memcpy(r->attr.su_entry.ER.ext_data + l,ext_des, |
825 | (int)r->attr.su_entry.ER.len_des[0]); | | 811 | (int)r->attr.su_entry.ER.len_des[0]); |
826 | | | 812 | |
827 | l += (int)r->attr.su_entry.ER.len_des[0]; | | 813 | l += (int)r->attr.su_entry.ER.len_des[0]; |
828 | memcpy(r->attr.su_entry.ER.ext_data + l,ext_src, | | 814 | memcpy(r->attr.su_entry.ER.ext_data + l,ext_src, |
829 | (int)r->attr.su_entry.ER.len_src[0]); | | 815 | (int)r->attr.su_entry.ER.len_src[0]); |
830 | | | 816 | |
831 | TAILQ_INSERT_TAIL(&node->head, r, rr_ll); | | 817 | TAILQ_INSERT_TAIL(&node->head, r, rr_ll); |
832 | return r; | | 818 | return r; |
833 | } | | 819 | } |
834 | | | 820 | |
835 | struct ISO_SUSP_ATTRIBUTES* | | 821 | struct ISO_SUSP_ATTRIBUTES* |
836 | cd9660_susp_ES(struct ISO_SUSP_ATTRIBUTES *last __unused, cd9660node *node __unused) | | 822 | cd9660_susp_ES(struct ISO_SUSP_ATTRIBUTES *last __unused, cd9660node *node __unused) |
837 | { | | 823 | { |
838 | return NULL; | | 824 | return NULL; |
839 | } | | 825 | } |