Bug Summary

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'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name iso9660_rrip.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/makefs/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.sbin/makefs -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/makefs/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.sbin/makefs/cd9660/iso9660_rrip.c
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
45static void cd9660_rrip_initialize_inode(cd9660node *);
46static int cd9660_susp_handle_continuation(iso9660_disk *, cd9660node *);
47static int cd9660_susp_handle_continuation_common(iso9660_disk *, cd9660node *,
48 int);
49
50int
51cd9660_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
95int
96cd9660_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 */
131int
132cd9660_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
165int
166cd9660_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
199static int
200cd9660_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 */
279static int
280cd9660_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
292int
293cd9660_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
321static void
322cd9660_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
367int
368cd9660_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
452struct ISO_SUSP_ATTRIBUTES*
453cd9660node_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
477int
478cd9660_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
485int
486cd9660_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
493int
494cd9660_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
501void
502cd9660_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
631int
632cd9660node_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
649int
650cd9660node_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
668int
669cd9660node_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
682int
683cd9660node_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
708int
709cd9660_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
719int
720cd9660_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
729int
730cd9660_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
738int
739cd9660_susp_pd(struct ISO_SUSP_ATTRIBUTES *p __unused__attribute__((__unused__)), int length __unused__attribute__((__unused__)))
740{
741 return 1;
742}
743
744void
745cd9660_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
780void
781cd9660_rrip_NM(cd9660node *node)
782{
783 cd9660_rrip_add_NM(node, node->node->name);
784}
785
786struct ISO_SUSP_ATTRIBUTES*
787cd9660_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
830struct ISO_SUSP_ATTRIBUTES*
831cd9660_susp_ES(struct ISO_SUSP_ATTRIBUTES *last __unused__attribute__((__unused__)), cd9660node *node __unused__attribute__((__unused__)))
832{
833 return NULL((void *)0);
834}