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