Bug Summary

File:src/gnu/usr.sbin/mkhybrid/mkhybrid/../src/joliet.c
Warning:line 411, column 6
Value stored to 'npnt' is never read

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 joliet.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/gnu/usr.sbin/mkhybrid/mkhybrid/obj -resource-dir /usr/local/lib/clang/13.0.0 -D SYSTEM_ID_DEFAULT="OpenBSD" -D APPLE_HYB -D VANILLA_AUTOCONF -I /usr/src/gnu/usr.sbin/mkhybrid/mkhybrid/../src -I /usr/src/gnu/usr.sbin/mkhybrid/mkhybrid/../src/include -I /usr/src/gnu/usr.sbin/mkhybrid/mkhybrid/../src/libhfs_iso -I /usr/src/gnu/usr.sbin/mkhybrid/mkhybrid/../src/libfile -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/gnu/usr.sbin/mkhybrid/mkhybrid/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/gnu/usr.sbin/mkhybrid/mkhybrid/../src/joliet.c
1/*
2 * File joliet.c - handle Win95/WinNT long file/unicode extensions for iso9660.
3
4 Copyright 1997 Eric Youngdale.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20/* APPLE_HYB James Pearson j.pearson@ge.ucl.ac.uk 12/3/99 */
21
22/*
23 * Joliet extensions for ISO9660. These are spottily documented by
24 * Microsoft. In their infinite stupidity, they completely ignored
25 * the possibility of using an SUSP record with the long filename
26 * in it, and instead wrote out a duplicate directory tree with the
27 * long filenames in it.
28 *
29 * I am not sure why they did this. One reason is that they get the path
30 * tables with the long filenames in them.
31 *
32 * There are two basic principles to Joliet, and the non-Unicode variant
33 * known as Romeo. Long filenames seem to be the main one, and the second
34 * is that the character set and a few other things is substantially relaxed.
35 *
36 * The SVD is identical to the PVD, except:
37 *
38 * Id is 2, not 1 (indicates SVD).
39 * escape_sequences contains UCS-2 indicator (levels 1, 2 or 3).
40 * The root directory record points to a different extent (with different
41 * size).
42 * There are different path tables for the two sets of directory trees.
43 *
44 * The following fields are recorded in Unicode:
45 * system_id
46 * volume_id
47 * volume_set_id
48 * publisher_id
49 * preparer_id
50 * application_id
51 * copyright_file_id
52 * abstract_file_id
53 * bibliographic_file_id
54 *
55 * Unicode strings are always encoded in big-endian format.
56 *
57 * In a directory record, everything is the same as with iso9660, except
58 * that the name is recorded in unicode. The name length is specified in
59 * total bytes, not in number of unicode characters.
60 *
61 * The character set used for the names is different with UCS - the
62 * restrictions are that the following are not allowed:
63 *
64 * Characters (00)(00) through (00)(1f) (control chars)
65 * (00)(2a) '*'
66 * (00)(2f) '/'
67 * (00)(3a) ':'
68 * (00)(3b) ';'
69 * (00)(3f) '?'
70 * (00)(5c) '\'
71 */
72#include "config.h"
73#include "mkisofs.h"
74#include "iso9660.h"
75
76
77#include <stdlib.h>
78#include <time.h>
79
80static int jpath_table_index;
81static struct directory ** jpathlist;
82static int next_jpath_index = 1;
83static int sort_goof;
84
85static int generate_joliet_path_tables __PR((void))(void);
86static int DECL(joliet_sort_directory, (struct directory_entry ** sort_dir))joliet_sort_directory (struct directory_entry ** sort_dir);
87static void DECL(assign_joliet_directory_addresses, (struct directory * node))assign_joliet_directory_addresses (struct directory * node);
88static int jroot_gen __PR((void))(void);
89
90/*
91 * Function: convert_to_unicode
92 *
93 * Purpose: Perform a 1/2 assed unicode conversion on a text
94 * string.
95 *
96 * Notes:
97 */
98static void FDECL3(convert_to_unicode, unsigned char *, buffer, int, size, char *, source )convert_to_unicode(unsigned char * buffer, int size, char * source
)
99{
100 unsigned char * tmpbuf;
101 int i;
102 int j;
103
104 /*
105 * If we get a NULL pointer for the source, it means we have an inplace
106 * copy, and we need to make a temporary working copy first.
107 */
108 if( source == NULL((void *)0) )
109 {
110 tmpbuf = (u_char *) e_malloc(size);
111 memcpy( tmpbuf, buffer, size);
112 }
113 else
114 {
115 tmpbuf = (u_char *)source;
116 }
117
118 /*
119 * Now start copying characters. If the size was specified to be 0, then
120 * assume the input was 0 terminated.
121 */
122 j = 0;
123 for(i=0; i < size ; i += 2, j++)
124 {
125 buffer[i] = 0;
126 /*
127 * JS integrated from: Achim_Kaiser@t-online.de
128 *
129 * Let all valid unicode characters pass through (assuming ISO-8859-1).
130 * Others are set to '_' .
131 */
132 if( tmpbuf[j] != 0 &&
133 (tmpbuf[j] <= 0x1f || (tmpbuf[j] >= 0x7F && tmpbuf[j] <= 0xA0)) )
134 {
135 buffer[i+1] = '_';
136 }
137 else
138 {
139 switch(tmpbuf[j])
140 {
141 case '*':
142 case '/':
143 case ':':
144 case ';':
145 case '?':
146 case '\\':
147 /*
148 * Even Joliet has some standards as to what is allowed in a pathname.
149 * Pretty tame in comparison to what DOS restricts you to.
150 */
151 buffer[i+1] = '_';
152 break;
153 default:
154 buffer[i+1] = tmpbuf[j];
155 break;
156 }
157 }
158 }
159
160 if( source == NULL((void *)0) )
161 {
162 free(tmpbuf);
163 }
164}
165
166/*
167 * Function: joliet_strlen
168 *
169 * Purpose: Return length in bytes of string after conversion to unicode.
170 *
171 * Notes: This is provided mainly as a convenience so that when more intelligent
172 * Unicode conversion for either Multibyte or 8-bit codes is available that
173 * we can easily adapt.
174 */
175static int FDECL1(joliet_strlen, const char *, string)joliet_strlen(const char * string)
176{
177 int rtn;
178
179 rtn = strlen(string) << 1;
180
181 /*
182 * We do clamp the maximum length of a Joliet string to be the
183 * maximum path size. This helps to ensure that we don't completely
184 * bolix things up with very long paths. The Joliet specs say
185 * that the maximum length is 128 bytes, or 64 unicode characters.
186 */
187 if( rtn > 0x80)
188 {
189 rtn = 0x80;
190 }
191 return rtn;
192}
193
194/*
195 * Function: get_joliet_vol_desc
196 *
197 * Purpose: generate a Joliet compatible volume desc.
198 *
199 * Notes: Assume that we have the non-joliet vol desc
200 * already present in the buffer. Just modifiy the
201 * appropriate fields.
202 */
203static void FDECL1(get_joliet_vol_desc, struct iso_primary_descriptor *, jvol_desc)get_joliet_vol_desc(struct iso_primary_descriptor * jvol_desc
)
204{
205 jvol_desc->type[0] = ISO_VD_SUPPLEMENTARY2;
206
207 /*
208 * For now, always do Unicode level 3. I don't really know what 1 and 2
209 * are - perhaps a more limited Unicode set.
210 *
211 * FIXME(eric) - how does Romeo fit in here? As mkisofs just
212 * "expands" 8 bit character codes to 16 bits and does nothing
213 * special with the Unicode characters, therefore shouldn't mkisofs
214 * really be stating that it's using UCS-2 Level 1, not Level 3 for
215 * the Joliet directory tree.
216 */
217 strcpy(jvol_desc->escape_sequences, "%/@");
218
219 /*
220 * Until we have Unicode path tables, leave these unset.
221 */
222 set_733((char *) jvol_desc->path_table_size, jpath_table_size);
223 set_731(jvol_desc->type_l_path_table, jpath_table[0]);
224 set_731(jvol_desc->opt_type_l_path_table, jpath_table[1]);
225 set_732(jvol_desc->type_m_path_table, jpath_table[2]);
226 set_732(jvol_desc->opt_type_m_path_table, jpath_table[3]);
227
228 /*
229 * Set this one up.
230 */
231 memcpy(jvol_desc->root_directory_record, &jroot_record,
232 sizeof(jvol_desc->root_directory_record));
233
234 /*
235 * Finally, we have a bunch of strings to convert to Unicode.
236 * FIXME(eric) - I don't know how to do this in general, so we will
237 * just be really lazy and do a char -> short conversion. We probably
238 * will want to filter any characters >= 0x80.
239 */
240 convert_to_unicode((u_char *)jvol_desc->system_id, sizeof(jvol_desc->system_id), NULL((void *)0));
241 convert_to_unicode((u_char *)jvol_desc->volume_id, sizeof(jvol_desc->volume_id), NULL((void *)0));
242 convert_to_unicode((u_char *)jvol_desc->volume_set_id, sizeof(jvol_desc->volume_set_id), NULL((void *)0));
243 convert_to_unicode((u_char *)jvol_desc->publisher_id, sizeof(jvol_desc->publisher_id), NULL((void *)0));
244 convert_to_unicode((u_char *)jvol_desc->preparer_id, sizeof(jvol_desc->preparer_id), NULL((void *)0));
245 convert_to_unicode((u_char *)jvol_desc->application_id, sizeof(jvol_desc->application_id), NULL((void *)0));
246 convert_to_unicode((u_char *)jvol_desc->copyright_file_id, sizeof(jvol_desc->copyright_file_id), NULL((void *)0));
247 convert_to_unicode((u_char *)jvol_desc->abstract_file_id, sizeof(jvol_desc->abstract_file_id), NULL((void *)0));
248 convert_to_unicode((u_char *)jvol_desc->bibliographic_file_id, sizeof(jvol_desc->bibliographic_file_id), NULL((void *)0));
249
250
251}
252
253static void FDECL1(assign_joliet_directory_addresses, struct directory *, node)assign_joliet_directory_addresses(struct directory * node)
254{
255 int dir_size;
256 struct directory * dpnt;
257
258 dpnt = node;
259
260 while (dpnt)
261 {
262 if( (dpnt->dir_flags & INHIBIT_JOLIET_ENTRY0x08) == 0 )
263 {
264 /*
265 * If we already have an extent for this (i.e. it came from
266 * a multisession disc), then don't reassign a new extent.
267 */
268 dpnt->jpath_index = next_jpath_index++;
269 if( dpnt->jextent == 0 )
270 {
271 dpnt->jextent = last_extent;
272 dir_size = (dpnt->jsize + (SECTOR_SIZE(2048) - 1)) >> 11;
273 last_extent += dir_size;
274 }
275 }
276
277 /* skip if hidden - but not for the rr_moved dir */
278 if(dpnt->subdir && (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY0x08) || dpnt == reloc_dir))
279 {
280 assign_joliet_directory_addresses(dpnt->subdir);
281 }
282 dpnt = dpnt->next;
283 }
284}
285
286static
287void FDECL1(build_jpathlist, struct directory *, node)build_jpathlist(struct directory * node)
288{
289 struct directory * dpnt;
290
291 dpnt = node;
292
293 while (dpnt)
294
295 {
296 if( (dpnt->dir_flags & INHIBIT_JOLIET_ENTRY0x08) == 0 )
297 {
298 jpathlist[dpnt->jpath_index] = dpnt;
299 }
300 if(dpnt->subdir) build_jpathlist(dpnt->subdir);
301 dpnt = dpnt->next;
302 }
303} /* build_jpathlist(... */
304
305static int FDECL2(joliet_compare_paths, void const *, r, void const *, l)joliet_compare_paths(void const * r, void const * l)
306{
307 struct directory const *ll = *(struct directory * const *)l;
308 struct directory const *rr = *(struct directory * const *)r;
309 int rparent, lparent;
310
311 rparent = rr->parent->jpath_index;
312 lparent = ll->parent->jpath_index;
313 if( rr->parent == reloc_dir )
314 {
315 rparent = rr->self->parent_rec->filedir->jpath_index;
316 }
317
318 if( ll->parent == reloc_dir )
319 {
320 lparent = ll->self->parent_rec->filedir->jpath_index;
321 }
322
323 if (rparent < lparent)
324 {
325 return -1;
326 }
327
328 if (rparent > lparent)
329 {
330 return 1;
331 }
332#ifdef APPLE_HYB1
333 /* use Mac name for Joliet name */
334 if (USE_MAC_NAME(mac_name, rr->self)((mac_name) && ((rr->self)->hfs_ent != ((void *
)0)) && (rr->self)->hfs_type)
&& USE_MAC_NAME(mac_name, ll->self)((mac_name) && ((ll->self)->hfs_ent != ((void *
)0)) && (ll->self)->hfs_type)
)
335 return strcmp(rr->self->hfs_ent->name, ll->self->hfs_ent->name);
336 else
337#endif /* APPLE_HYB */
338 return strcmp(rr->self->name, ll->self->name);
339
340} /* compare_paths(... */
341
342static int generate_joliet_path_tables()
343{
344 struct directory_entry * de;
345 struct directory * dpnt;
346 int fix;
347 int j;
348 int namelen;
349 char * npnt;
350 char * npnt1;
351 int tablesize;
352
353 /*
354 * First allocate memory for the tables and initialize the memory
355 */
356 tablesize = jpath_blocks << 11;
357 jpath_table_m = (char *) e_malloc(tablesize);
358 jpath_table_l = (char *) e_malloc(tablesize);
359 memset(jpath_table_l, 0, tablesize);
360 memset(jpath_table_m, 0, tablesize);
361
362 if( next_jpath_index > 0xffff )
363 {
364 fprintf(stderr(&__sF[2]), "Unable to generate sane path tables - too many directories (%d)\n",
365 next_jpath_index);
366 exit(1);
367 }
368 /*
369 * Now start filling in the path tables. Start with root directory
370 */
371 jpath_table_index = 0;
372 jpathlist = (struct directory **) e_malloc(sizeof(struct directory *)
373 * next_jpath_index);
374 memset(jpathlist, 0, sizeof(struct directory *) * next_jpath_index);
375 build_jpathlist(root);
376
377 do
378 {
379 fix = 0;
380#ifdef __STDC__1
381 qsort(&jpathlist[1], next_jpath_index-1, sizeof(struct directory *),
382 (int (*)(const void *, const void *))joliet_compare_paths);
383#else
384 qsort(&jpathlist[1], next_jpath_index-1, sizeof(struct directory *),
385 joliet_compare_paths);
386#endif
387
388 for(j=1; j<next_jpath_index; j++)
389 {
390 if(jpathlist[j]->jpath_index != j)
391 {
392 jpathlist[j]->jpath_index = j;
393 fix++;
394 }
395 }
396 } while(fix);
397
398 for(j=1; j<next_jpath_index; j++)
399 {
400 dpnt = jpathlist[j];
401 if(!dpnt)
402 {
403 fprintf(stderr(&__sF[2]),"Entry %d not in path tables\n", j);
404 exit(1);
405 }
406 npnt = dpnt->de_name;
407
408 npnt1 = strrchr(npnt, PATH_SEPARATOR'/');
409 if(npnt1)
410 {
411 npnt = npnt1 + 1;
Value stored to 'npnt' is never read
412 }
413
414 de = dpnt->self;
415 if(!de)
416 {
417 fprintf(stderr(&__sF[2]),"Fatal goof - directory has amnesia\n");
418 exit(1);
419 }
420
421#ifdef APPLE_HYB1
422 if (USE_MAC_NAME(mac_name, de)((mac_name) && ((de)->hfs_ent != ((void *)0)) &&
(de)->hfs_type)
)
423 namelen = joliet_strlen(de->hfs_ent->name);
424 else
425#endif /* APPLE_HYB */
426 namelen = joliet_strlen(de->name);
427
428 if( dpnt == root )
429 {
430 jpath_table_l[jpath_table_index] = 1;
431 jpath_table_m[jpath_table_index] = 1;
432 }
433 else
434 {
435 jpath_table_l[jpath_table_index] = namelen;
436 jpath_table_m[jpath_table_index] = namelen;
437 }
438 jpath_table_index += 2;
439
440 set_731(jpath_table_l + jpath_table_index, dpnt->jextent);
441 set_732(jpath_table_m + jpath_table_index, dpnt->jextent);
442 jpath_table_index += 4;
443
444 if( dpnt->parent != reloc_dir )
445 {
446 set_721(jpath_table_l + jpath_table_index,
447 dpnt->parent->jpath_index);
448 set_722(jpath_table_m + jpath_table_index,
449 dpnt->parent->jpath_index);
450 }
451 else
452 {
453 set_721(jpath_table_l + jpath_table_index,
454 dpnt->self->parent_rec->filedir->jpath_index);
455 set_722(jpath_table_m + jpath_table_index,
456 dpnt->self->parent_rec->filedir->jpath_index);
457 }
458
459 jpath_table_index += 2;
460
461 /*
462 * The root directory is still represented in non-unicode fashion.
463 */
464 if( dpnt == root )
465 {
466 jpath_table_l[jpath_table_index] = 0;
467 jpath_table_m[jpath_table_index] = 0;
468 jpath_table_index ++;
469 }
470 else
471 {
472#ifdef APPLE_HYB1
473 if (USE_MAC_NAME(mac_name , de)((mac_name) && ((de)->hfs_ent != ((void *)0)) &&
(de)->hfs_type)
) {
474 convert_to_unicode((u_char *)jpath_table_l + jpath_table_index,
475 namelen, de->hfs_ent->name);
476 convert_to_unicode((u_char *)jpath_table_m + jpath_table_index,
477 namelen, de->hfs_ent->name);
478 }
479 else {
480#endif /* APPLE_HYB */
481 convert_to_unicode((u_char *)jpath_table_l + jpath_table_index,
482 namelen, de->name);
483 convert_to_unicode((u_char *)jpath_table_m + jpath_table_index,
484 namelen, de->name);
485#ifdef APPLE_HYB1
486 }
487#endif /* APPLE_HYB */
488
489 jpath_table_index += namelen;
490 }
491
492 if(jpath_table_index & 1)
493 {
494 jpath_table_index++; /* For odd lengths we pad */
495 }
496 }
497
498 free(jpathlist);
499 if(jpath_table_index != jpath_table_size)
500 {
501 fprintf(stderr(&__sF[2]),"Joliet path table lengths do not match %d %d\n",
502 jpath_table_index,
503 jpath_table_size);
504 }
505 return 0;
506} /* generate_path_tables(... */
507
508static void FDECL2(generate_one_joliet_directory, struct directory *, dpnt, FILE *, outfile)generate_one_joliet_directory(struct directory * dpnt, FILE *
outfile)
509{
510 unsigned int dir_index;
511 char * directory_buffer;
512 int new_reclen;
513 struct directory_entry * s_entry;
514 struct directory_entry * s_entry1;
515 struct iso_directory_record jrec;
516 unsigned int total_size;
517 int cvt_len;
518 struct directory * finddir;
519
520 total_size = (dpnt->jsize + (SECTOR_SIZE(2048) - 1)) & ~(SECTOR_SIZE(2048) - 1);
521 directory_buffer = (char *) e_malloc(total_size);
522 memset(directory_buffer, 0, total_size);
523 dir_index = 0;
524
525 s_entry = dpnt->jcontents;
526 while(s_entry)
527 {
528 if(s_entry->de_flags & INHIBIT_JOLIET_ENTRY0x08) {
529 s_entry = s_entry->jnext;
530 continue;
531 }
532
533 /*
534 * If this entry was a directory that was relocated, we have a bit
535 * of trouble here. We need to dig out the real thing and put it
536 * back here. In the Joliet tree, there is no relocated rock
537 * ridge, as there are no depth limits to a directory tree.
538 */
539 if( (s_entry->de_flags & RELOCATED_DIRECTORY0x20) != 0 )
540 {
541 for(s_entry1 = reloc_dir->contents; s_entry1; s_entry1 = s_entry1->next)
542 {
543 if( s_entry1->parent_rec == s_entry )
544 {
545 break;
546 }
547 }
548 if( s_entry1 == NULL((void *)0) )
549 {
550 /*
551 * We got trouble.
552 */
553 fprintf(stderr(&__sF[2]), "Unable to locate relocated directory\n");
554 exit(1);
555 }
556 }
557 else
558 {
559 s_entry1 = s_entry;
560 }
561
562 /*
563 * We do not allow directory entries to cross sector boundaries.
564 * Simply pad, and then start the next entry at the next sector
565 */
566 new_reclen = s_entry1->jreclen;
567 if( (dir_index & (SECTOR_SIZE(2048) - 1)) + new_reclen >= SECTOR_SIZE(2048) )
568 {
569 dir_index = (dir_index + (SECTOR_SIZE(2048) - 1)) &
570 ~(SECTOR_SIZE(2048) - 1);
571 }
572
573 memcpy(&jrec, &s_entry1->isorec, sizeof(struct iso_directory_record) -
574 sizeof(s_entry1->isorec.name));
575
576#ifdef APPLE_HYB1
577 /* Use the HFS name if it exists */
578 if (USE_MAC_NAME(mac_name, s_entry1)((mac_name) && ((s_entry1)->hfs_ent != ((void *)0)
) && (s_entry1)->hfs_type)
)
579 cvt_len = joliet_strlen(s_entry1->hfs_ent->name);
580 else
581#endif /* APPLE_HYB */
582 cvt_len = joliet_strlen(s_entry1->name);
583
584 /*
585 * Fix the record length - this was the non-Joliet version we
586 * were seeing.
587 */
588 jrec.name_len[0] = cvt_len;
589 jrec.length[0] = s_entry1->jreclen;
590
591 /*
592 * If this is a directory, fix the correct size and extent
593 * number.
594 */
595 if( (jrec.flags[0] & 2) != 0 )
596 {
597 if(strcmp(s_entry1->name,".") == 0)
598 {
599 jrec.name_len[0] = 1;
600 set_733((char *) jrec.extent, dpnt->jextent);
601 set_733((char *) jrec.size, ROUND_UP(dpnt->jsize)((dpnt->jsize + ((2048) - 1)) & ~((2048) - 1)));
602 }
603 else if(strcmp(s_entry1->name,"..") == 0)
604 {
605 jrec.name_len[0] = 1;
606 if( dpnt->parent == reloc_dir )
607 {
608 set_733((char *) jrec.extent, dpnt->self->parent_rec->filedir->jextent);
609 set_733((char *) jrec.size, ROUND_UP(dpnt->self->parent_rec->filedir->jsize)((dpnt->self->parent_rec->filedir->jsize + ((2048
) - 1)) & ~((2048) - 1))
);
610 }
611 else
612
613 {
614 set_733((char *) jrec.extent, dpnt->parent->jextent);
615 set_733((char *) jrec.size, ROUND_UP(dpnt->parent->jsize)((dpnt->parent->jsize + ((2048) - 1)) & ~((2048) - 1
))
);
616 }
617 }
618 else
619 {
620 if( (s_entry->de_flags & RELOCATED_DIRECTORY0x20) != 0 )
621 {
622 finddir = reloc_dir->subdir;
623 }
624 else
625 {
626 finddir = dpnt->subdir;
627 }
628 while(1==1)
629 {
630 if(finddir->self == s_entry1) break;
631 finddir = finddir->next;
632 if(!finddir)
633 {
634 fprintf(stderr(&__sF[2]),"Fatal goof - unable to find directory location\n"); exit(1);
635 }
636 }
637 set_733((char *) jrec.extent, finddir->jextent);
638 set_733((char *) jrec.size, ROUND_UP(finddir->jsize)((finddir->jsize + ((2048) - 1)) & ~((2048) - 1)));
639 }
640 }
641
642 memcpy(directory_buffer + dir_index, &jrec,
643 sizeof(struct iso_directory_record) -
644 sizeof(s_entry1->isorec.name));
645
646
647 dir_index += sizeof(struct iso_directory_record) -
648 sizeof (s_entry1->isorec.name);
649
650 /*
651 * Finally dump the Unicode version of the filename.
652 * Note - . and .. are the same as with non-Joliet discs.
653 */
654 if( (jrec.flags[0] & 2) != 0
655 && strcmp(s_entry1->name, ".") == 0 )
656 {
657 directory_buffer[dir_index++] = 0;
658 }
659 else if( (jrec.flags[0] & 2) != 0
660 && strcmp(s_entry1->name, "..") == 0 )
661 {
662 directory_buffer[dir_index++] = 1;
663 }
664 else
665 {
666#ifdef APPLE_HYB1
667 if (USE_MAC_NAME(mac_name, s_entry1)((mac_name) && ((s_entry1)->hfs_ent != ((void *)0)
) && (s_entry1)->hfs_type)
)
668 /* Use the HFS name if it exists */
669 convert_to_unicode((u_char *)directory_buffer + dir_index,
670 cvt_len,
671 s_entry1->hfs_ent->name);
672 else
673#endif /* APPLE_HYB */
674 convert_to_unicode((u_char *)directory_buffer + dir_index,
675 cvt_len,
676 s_entry1->name);
677 dir_index += cvt_len;
678 }
679
680 if(dir_index & 1)
681 {
682 directory_buffer[dir_index++] = 0;
683 }
684
685 s_entry = s_entry->jnext;
686 }
687
688 if(dpnt->jsize != dir_index)
689 {
690 fprintf(stderr(&__sF[2]),"Unexpected joliet directory length %d %d %s\n",dpnt->jsize,
691 dir_index, dpnt->de_name);
692 }
693
694 xfwrite(directory_buffer, 1, total_size, outfile);
695 last_extent_written += total_size >> 11;
696 free(directory_buffer);
697} /* generate_one_joliet_directory(... */
698
699static int FDECL1(joliet_sort_n_finish, struct directory *, this_dir)joliet_sort_n_finish(struct directory * this_dir)
700{
701 struct directory_entry * s_entry;
702 int status = 0;
703
704 /* don't want to skip this directory if it's the reloc_dir at the moment */
705 if(this_dir != reloc_dir && this_dir->dir_flags & INHIBIT_JOLIET_ENTRY0x08)
706 {
707 return 0;
708 }
709
710 for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next)
711 {
712 /* skip hidden entries */
713 if( (s_entry->de_flags & INHIBIT_JOLIET_ENTRY0x08) != 0 )
714 {
715 continue;
716 }
717
718 /*
719 * First update the path table sizes for directories.
720 *
721 * Finally, set the length of the directory entry if Joliet is used.
722 * The name is longer, but no Rock Ridge is ever used here, so
723 * depending upon the options the entry size might turn out to be about
724 * the same. The Unicode name is always a multiple of 2 bytes, so
725 * we always add 1 to make it an even number.
726 */
727 if(s_entry->isorec.flags[0] == 2)
728 {
729 if (strcmp(s_entry->name,".") && strcmp(s_entry->name,".."))
730 {
731#ifdef APPLE_HYB1
732 if (USE_MAC_NAME(mac_name, s_entry)((mac_name) && ((s_entry)->hfs_ent != ((void *)0))
&& (s_entry)->hfs_type)
)
733 /* Use the HFS name if it exists */
734 jpath_table_size += joliet_strlen(s_entry->hfs_ent->name) + sizeof(struct iso_path_table) - 1;
735 else
736#endif /* APPLE_HYB */
737 jpath_table_size += joliet_strlen(s_entry->name) + sizeof(struct iso_path_table) - 1;
738 if (jpath_table_size & 1)
739 {
740 jpath_table_size++;
741 }
742 }
743 else
744 {
745 if (this_dir == root && strlen(s_entry->name) == 1)
746 {
747 jpath_table_size += sizeof(struct iso_path_table);
748 if (jpath_table_size & 1) jpath_table_size++;
749 }
750 }
751 }
752
753 if (strcmp(s_entry->name,".") && strcmp(s_entry->name,".."))
754 {
755#ifdef APPLE_HYB1
756 if (USE_MAC_NAME(mac_name, s_entry)((mac_name) && ((s_entry)->hfs_ent != ((void *)0))
&& (s_entry)->hfs_type)
)
757 /* Use the HFS name if it exists */
758 s_entry->jreclen = sizeof(struct iso_directory_record)
759 - sizeof(s_entry->isorec.name)
760 + joliet_strlen(s_entry->hfs_ent->name)
761 + 1;
762 else
763#endif /* APPLE_HYB */
764 s_entry->jreclen = sizeof(struct iso_directory_record)
765 - sizeof(s_entry->isorec.name)
766 + joliet_strlen(s_entry->name)
767 + 1;
768 }
769 else
770 {
771 /*
772 * Special - for '.' and '..' we generate the same records we
773 * did for non-Joliet discs.
774 */
775 s_entry->jreclen = sizeof(struct iso_directory_record)
776 - sizeof(s_entry->isorec.name)
777 + 1;
778 }
779
780
781 }
782
783 if( (this_dir->dir_flags & INHIBIT_JOLIET_ENTRY0x08) != 0 )
784 {
785 return 0;
786 }
787
788 this_dir->jcontents = this_dir->contents;
789 status = joliet_sort_directory(&this_dir->jcontents);
790
791 /*
792 * Now go through the directory and figure out how large this one will be.
793 * Do not split a directory entry across a sector boundary
794 */
795 s_entry = this_dir->jcontents;
796/*
797 * XXX Is it ok to comment this out?
798 */
799/*XXX JS this_dir->ce_bytes = 0;*/
800 for(s_entry = this_dir->jcontents; s_entry; s_entry = s_entry->jnext)
801 {
802 int jreclen;
803
804 if( (s_entry->de_flags & INHIBIT_JOLIET_ENTRY0x08) != 0 )
805 {
806 continue;
807 }
808
809 jreclen = s_entry->jreclen;
810
811 if ((this_dir->jsize & (SECTOR_SIZE(2048) - 1)) + jreclen >= SECTOR_SIZE(2048))
812 {
813 this_dir->jsize = (this_dir->jsize + (SECTOR_SIZE(2048) - 1)) &
814 ~(SECTOR_SIZE(2048) - 1);
815 }
816 this_dir->jsize += jreclen;
817 }
818 return status;
819}
820
821/*
822 * Similar to the iso9660 case, except here we perform a full sort based upon the
823 * regular name of the file, not the 8.3 version.
824 */
825static int FDECL2(joliet_compare_dirs, const void *, rr, const void *, ll)joliet_compare_dirs(const void * rr, const void * ll)
826{
827 char * rpnt, *lpnt;
828 struct directory_entry ** r, **l;
829
830 r = (struct directory_entry **) rr;
831 l = (struct directory_entry **) ll;
832 rpnt = (*r)->name;
833 lpnt = (*l)->name;
834
835 /*
836 * If the entries are the same, this is an error.
837 */
838 if( strcmp(rpnt, lpnt) == 0 )
839 {
840 sort_goof++;
841 }
842
843 /*
844 * Put the '.' and '..' entries on the head of the sorted list.
845 * For normal ASCII, this always happens to be the case, but out of
846 * band characters cause this not to be the case sometimes.
847 */
848 if( strcmp(rpnt, ".") == 0 ) return -1;
849 if( strcmp(lpnt, ".") == 0 ) return 1;
850
851 if( strcmp(rpnt, "..") == 0 ) return -1;
852 if( strcmp(lpnt, "..") == 0 ) return 1;
853
854 while(*rpnt && *lpnt)
855 {
856 if(*rpnt == ';' && *lpnt != ';') return -1;
857 if(*rpnt != ';' && *lpnt == ';') return 1;
858
859 if(*rpnt == ';' && *lpnt == ';') return 0;
860
861 /*
862 * Extensions are not special here. Don't treat the dot as something that
863 * must be bumped to the start of the list.
864 */
865#if 0
866 if(*rpnt == '.' && *lpnt != '.') return -1;
867 if(*rpnt != '.' && *lpnt == '.') return 1;
868#endif
869
870 if(*rpnt < *lpnt) return -1;
871 if(*rpnt > *lpnt) return 1;
872 rpnt++; lpnt++;
873 }
874 if(*rpnt) return 1;
875 if(*lpnt) return -1;
876 return 0;
877}
878
879
880/*
881 * Function: sort_directory
882 *
883 * Purpose: Sort the directory in the appropriate ISO9660
884 * order.
885 *
886 * Notes: Returns 0 if OK, returns > 0 if an error occurred.
887 */
888static int FDECL1(joliet_sort_directory, struct directory_entry **, sort_dir)joliet_sort_directory(struct directory_entry ** sort_dir)
889{
890 int dcount = 0;
891 int i;
892 struct directory_entry * s_entry;
893 struct directory_entry ** sortlist;
894
895 s_entry = *sort_dir;
896 while(s_entry)
897 {
898 /* skip hidden entries */
899 if (!(s_entry->de_flags & INHIBIT_JOLIET_ENTRY0x08))
900 dcount++;
901 s_entry = s_entry->next;
902 }
903
904 /*
905 * OK, now we know how many there are. Build a vector for sorting.
906 */
907 sortlist = (struct directory_entry **)
908 e_malloc(sizeof(struct directory_entry *) * dcount);
909
910 dcount = 0;
911 s_entry = *sort_dir;
912 while(s_entry)
913 {
914 /* skip hidden entries */
915 if (!(s_entry->de_flags & INHIBIT_JOLIET_ENTRY0x08)) {
916 sortlist[dcount] = s_entry;
917 dcount++;
918 }
919 s_entry = s_entry->next;
920 }
921
922 sort_goof = 0;
923#ifdef __STDC__1
924 qsort(sortlist, dcount, sizeof(struct directory_entry *),
925 (int (*)(const void *, const void *))joliet_compare_dirs);
926#else
927 qsort(sortlist, dcount, sizeof(struct directory_entry *),
928 joliet_compare_dirs);
929#endif
930
931 /*
932 * Now reassemble the linked list in the proper sorted order
933 */
934 for(i=0; i<dcount-1; i++)
935 {
936 sortlist[i]->jnext = sortlist[i+1];
937 }
938
939 sortlist[dcount-1]->jnext = NULL((void *)0);
940 *sort_dir = sortlist[0];
941
942 free(sortlist);
943 return sort_goof;
944}
945
946int FDECL1(joliet_sort_tree, struct directory *, node)joliet_sort_tree(struct directory * node)
947{
948 struct directory * dpnt;
949 int ret = 0;
950
951 dpnt = node;
952
953 while (dpnt){
954 ret = joliet_sort_n_finish(dpnt);
955 if( ret )
956 {
957 break;
958 }
959 if(dpnt->subdir) ret = joliet_sort_tree(dpnt->subdir);
960 if( ret )
961 {
962 break;
963 }
964 dpnt = dpnt->next;
965 }
966 return ret;
967}
968
969static void FDECL2(generate_joliet_directories, struct directory *, node, FILE*, outfile)generate_joliet_directories(struct directory * node, FILE* outfile
)
{
970 struct directory * dpnt;
971
972 dpnt = node;
973
974 while (dpnt)
975 {
976 if( (dpnt->dir_flags & INHIBIT_JOLIET_ENTRY0x08) == 0 )
977 {
978 /*
979 * In theory we should never reuse a directory, so this doesn't
980 * make much sense.
981 */
982 if( dpnt->jextent > session_start )
983 {
984 generate_one_joliet_directory(dpnt, outfile);
985 }
986 }
987 /* skip if hidden - but not for the rr_moved dir */
988 if(dpnt->subdir && (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY0x08) || dpnt == reloc_dir))
989 generate_joliet_directories(dpnt->subdir, outfile);
990 dpnt = dpnt->next;
991 }
992}
993
994
995/*
996 * Function to write the EVD for the disc.
997 */
998static int FDECL1(jpathtab_write, FILE *, outfile)jpathtab_write(FILE * outfile)
999{
1000 /*
1001 * Next we write the path tables
1002 */
1003 xfwrite(jpath_table_l, 1, jpath_blocks << 11, outfile);
1004 xfwrite(jpath_table_m, 1, jpath_blocks << 11, outfile);
1005 last_extent_written += 2*jpath_blocks;
1006 free(jpath_table_l);
1007 free(jpath_table_m);
1008 jpath_table_l = NULL((void *)0);
1009 jpath_table_m = NULL((void *)0);
1010 return 0;
1011}
1012
1013static int FDECL1(jdirtree_size, int, starting_extent)jdirtree_size(int starting_extent)
1014{
1015 assign_joliet_directory_addresses(root);
1016 return 0;
1017}
1018
1019static int jroot_gen()
1020{
1021 jroot_record.length[0] = 1 + sizeof(struct iso_directory_record)
1022 - sizeof(jroot_record.name);
1023 jroot_record.ext_attr_length[0] = 0;
1024 set_733((char *) jroot_record.extent, root->jextent);
1025 set_733((char *) jroot_record.size, ROUND_UP(root->jsize)((root->jsize + ((2048) - 1)) & ~((2048) - 1)));
1026 iso9660_date(jroot_record.date, root_statbuf.st_mtimest_mtim.tv_sec);
1027 jroot_record.flags[0] = 2;
1028 jroot_record.file_unit_size[0] = 0;
1029 jroot_record.interleave[0] = 0;
1030 set_723(jroot_record.volume_sequence_number, volume_sequence_number);
1031 jroot_record.name_len[0] = 1;
1032 return 0;
1033}
1034
1035static int FDECL1(jdirtree_write, FILE *, outfile)jdirtree_write(FILE * outfile)
1036{
1037 generate_joliet_directories(root, outfile);
1038 return 0;
1039}
1040
1041/*
1042 * Function to write the EVD for the disc.
1043 */
1044static int FDECL1(jvd_write, FILE *, outfile)jvd_write(FILE * outfile)
1045{
1046 struct iso_primary_descriptor jvol_desc;
1047
1048 /*
1049 * Next we write out the boot volume descriptor for the disc
1050 */
1051 jvol_desc = vol_desc;
1052 get_joliet_vol_desc(&jvol_desc);
1053 xfwrite(&jvol_desc, 1, 2048, outfile);
1054 last_extent_written ++;
1055 return 0;
1056}
1057
1058/*
1059 * Functions to describe padding block at the start of the disc.
1060 */
1061static int FDECL1(jpathtab_size, int, starting_extent)jpathtab_size(int starting_extent)
1062{
1063 jpath_table[0] = starting_extent;
1064 jpath_table[1] = 0;
1065 jpath_table[2] = jpath_table[0] + jpath_blocks;
1066 jpath_table[3] = 0;
1067
1068 last_extent += 2*jpath_blocks;
1069 return 0;
1070}
1071
1072struct output_fragment joliet_desc = {NULL((void *)0), oneblock_size, jroot_gen,jvd_write};
1073struct output_fragment jpathtable_desc= {NULL((void *)0), jpathtab_size, generate_joliet_path_tables, jpathtab_write};
1074struct output_fragment jdirtree_desc = {NULL((void *)0), jdirtree_size, NULL((void *)0), jdirtree_write};