1 /*-
2  * Copyright (c) 2009-2012 Michihiro NAKAJIMA
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "archive_platform.h"
27 
28 #ifdef HAVE_SYS_TYPES_H
29 #include <sys/types.h>
30 #endif
31 #ifdef HAVE_SYS_UTSNAME_H
32 #include <sys/utsname.h>
33 #endif
34 #ifdef HAVE_ERRNO_H
35 #include <errno.h>
36 #endif
37 #ifdef HAVE_LIMITS_H
38 #include <limits.h>
39 #endif
40 #include <stdio.h>
41 #include <stdarg.h>
42 #ifdef HAVE_STDLIB_H
43 #include <stdlib.h>
44 #endif
45 #include <time.h>
46 #ifdef HAVE_UNISTD_H
47 #include <unistd.h>
48 #endif
49 #ifdef HAVE_ZLIB_H
50 #include <zlib.h>
51 #endif
52 
53 #include "archive.h"
54 #include "archive_endian.h"
55 #include "archive_entry.h"
56 #include "archive_entry_locale.h"
57 #include "archive_private.h"
58 #include "archive_rb.h"
59 #include "archive_write_private.h"
60 
61 #if defined(_WIN32) && !defined(__CYGWIN__)
62 #define getuid()			0
63 #define getgid()			0
64 #endif
65 
66 /*#define DEBUG 1*/
67 #ifdef DEBUG
68 /* To compare to the ISO image file made by mkisofs. */
69 #define COMPAT_MKISOFS		1
70 #endif
71 
72 #define LOGICAL_BLOCK_BITS			11
73 #define LOGICAL_BLOCK_SIZE			2048
74 #define PATH_TABLE_BLOCK_SIZE			4096
75 
76 #define SYSTEM_AREA_BLOCK			16
77 #define PRIMARY_VOLUME_DESCRIPTOR_BLOCK 	1
78 #define SUPPLEMENTARY_VOLUME_DESCRIPTOR_BLOCK 	1
79 #define BOOT_RECORD_DESCRIPTOR_BLOCK	 	1
80 #define VOLUME_DESCRIPTOR_SET_TERMINATOR_BLOCK	1
81 #define NON_ISO_FILE_SYSTEM_INFORMATION_BLOCK	1
82 #define RRIP_ER_BLOCK				1
83 #define PADDING_BLOCK				150
84 
85 #define FD_1_2M_SIZE		(1024 * 1200)
86 #define FD_1_44M_SIZE		(1024 * 1440)
87 #define FD_2_88M_SIZE		(1024 * 2880)
88 #define MULTI_EXTENT_SIZE	(ARCHIVE_LITERAL_LL(1) << 32)	/* 4Gi bytes. */
89 #define MAX_DEPTH		8
90 #define RR_CE_SIZE		28		/* SUSP "CE" extension size */
91 
92 #define FILE_FLAG_EXISTENCE	0x01
93 #define FILE_FLAG_DIRECTORY	0x02
94 #define FILE_FLAG_ASSOCIATED	0x04
95 #define FILE_FLAG_RECORD	0x08
96 #define FILE_FLAG_PROTECTION	0x10
97 #define FILE_FLAG_MULTI_EXTENT	0x80
98 
99 static const char rrip_identifier[] =
100 	"RRIP_1991A";
101 static const char rrip_descriptor[] =
102 	"THE ROCK RIDGE INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR "
103 	"POSIX FILE SYSTEM SEMANTICS";
104 static const char rrip_source[] =
105 	"PLEASE CONTACT DISC PUBLISHER FOR SPECIFICATION SOURCE.  "
106 	"SEE PUBLISHER IDENTIFIER IN PRIMARY VOLUME DESCRIPTOR FOR "
107 	"CONTACT INFORMATION.";
108 #define RRIP_ER_ID_SIZE		(sizeof(rrip_identifier)-1)
109 #define RRIP_ER_DSC_SIZE	(sizeof(rrip_descriptor)-1)
110 #define RRIP_ER_SRC_SIZE	(sizeof(rrip_source)-1)
111 #define RRIP_ER_SIZE		(8 + RRIP_ER_ID_SIZE + \
112 				RRIP_ER_DSC_SIZE + RRIP_ER_SRC_SIZE)
113 
114 static const unsigned char zisofs_magic[8] = {
115 	0x37, 0xE4, 0x53, 0x96, 0xC9, 0xDB, 0xD6, 0x07
116 };
117 
118 #define ZF_HEADER_SIZE	16	/* zisofs header size. */
119 #define ZF_LOG2_BS	15	/* log2 block size; 32K bytes. */
120 #define ZF_BLOCK_SIZE	(1UL << ZF_LOG2_BS)
121 
122 /*
123  * Manage extra records.
124  */
125 struct extr_rec {
126 	int		 location;
127 	int		 offset;
128 	unsigned char	 buf[LOGICAL_BLOCK_SIZE];
129 	struct extr_rec	*next;
130 };
131 
132 struct ctl_extr_rec {
133 	int		 use_extr;
134 	unsigned char	*bp;
135 	struct isoent	*isoent;
136 	unsigned char	*ce_ptr;
137 	int		 cur_len;
138 	int		 dr_len;
139 	int		 limit;
140 	int		 extr_off;
141 	int		 extr_loc;
142 };
143 #define DR_SAFETY	RR_CE_SIZE
144 #define DR_LIMIT	(254 - DR_SAFETY)
145 
146 /*
147  * The relation of struct isofile and isoent and archive_entry.
148  *
149  * Primary volume tree  --> struct isoent
150  *                                |
151  *                                v
152  *                          struct isofile --> archive_entry
153  *                                ^
154  *                                |
155  * Joliet volume tree   --> struct isoent
156  *
157  * struct isoent has specific information for volume.
158  */
159 
160 struct isofile {
161 	/* Used for managing struct isofile list. */
162 	struct isofile		*allnext;
163 	struct isofile		*datanext;
164 	/* Used for managing a hardlinked struct isofile list. */
165 	struct isofile		*hlnext;
166 	struct isofile		*hardlink_target;
167 
168 	struct archive_entry	*entry;
169 
170 	/*
171 	 * Used for making a directory tree.
172 	 */
173 	struct archive_string	 parentdir;
174 	struct archive_string	 basename;
175 	struct archive_string	 basename_utf16;
176 	struct archive_string	 symlink;
177 	int			 dircnt;	/* The number of elements of
178 						 * its parent directory */
179 
180 	/*
181 	 * Used for a Directory Record.
182 	 */
183 	struct content {
184 		int64_t		 offset_of_temp;
185 		int64_t		 size;
186 		int		 blocks;
187 		uint32_t 	 location;
188 		/*
189 		 * One extent equals one content.
190 		 * If this entry has multi extent, `next' variable points
191 		 * next content data.
192 		 */
193 		struct content	*next;		/* next content	*/
194 	} content, *cur_content;
195 	int			 write_content;
196 
197 	enum {
198 		NO = 0,
199 		BOOT_CATALOG,
200 		BOOT_IMAGE
201 	} boot;
202 
203 	/*
204 	 * Used for a zisofs.
205 	 */
206 	struct {
207 		unsigned char	 header_size;
208 		unsigned char	 log2_bs;
209 		uint32_t	 uncompressed_size;
210 	} zisofs;
211 };
212 
213 struct isoent {
214 	/* Keep `rbnode' at the first member of struct isoent. */
215 	struct archive_rb_node	 rbnode;
216 
217 	struct isofile		*file;
218 
219 	struct isoent		*parent;
220 	/* A list of children.(use chnext) */
221 	struct {
222 		struct isoent	*first;
223 		struct isoent	**last;
224 		int		 cnt;
225 	}			 children;
226 	struct archive_rb_tree	 rbtree;
227 
228 	/* A list of sub directories.(use drnext) */
229 	struct {
230 		struct isoent	*first;
231 		struct isoent	**last;
232 		int		 cnt;
233 	}			 subdirs;
234 	/* A sorted list of sub directories. */
235 	struct isoent		**children_sorted;
236 	/* Used for managing struct isoent list. */
237 	struct isoent		*chnext;
238 	struct isoent		*drnext;
239 	struct isoent		*ptnext;
240 
241 	/*
242 	 * Used for making a Directory Record.
243 	 */
244 	int			 dir_number;
245 	struct {
246 		int		 vd;
247 		int		 self;
248 		int		 parent;
249 		int		 normal;
250 	}			 dr_len;
251 	uint32_t 		 dir_location;
252 	int			 dir_block;
253 
254 	/*
255 	 * Identifier:
256 	 *   on primary, ISO9660 file/directory name.
257 	 *   on joliet, UCS2 file/directory name.
258 	 * ext_off   : offset of identifier extension.
259 	 * ext_len   : length of identifier extension.
260 	 * id_len    : byte size of identifier.
261 	 *   on primary, this is ext_off + ext_len + version length.
262 	 *   on joliet, this is ext_off + ext_len.
263 	 * mb_len    : length of multibyte-character of identifier.
264 	 *   on primary, mb_len and id_len are always the same.
265 	 *   on joliet, mb_len and id_len are different.
266 	 */
267 	char			*identifier;
268 	int			 ext_off;
269 	int			 ext_len;
270 	int			 id_len;
271 	int			 mb_len;
272 
273 	/*
274 	 * Used for making a Rockridge extension.
275 	 * This is a part of Directory Records.
276 	 */
277 	struct isoent		*rr_parent;
278 	struct isoent		*rr_child;
279 
280 	/* Extra Record.(which we call in this source file)
281 	 * A maximum size of the Directory Record is 254.
282 	 * so, if generated RRIP data of a file cannot into a Directory
283 	 * Record because of its size, that surplus data relocate this
284 	 * Extra Record.
285 	 */
286 	struct {
287 		struct extr_rec	*first;
288 		struct extr_rec	**last;
289 		struct extr_rec	*current;
290 	}			 extr_rec_list;
291 
292 	signed int		 virtual:1;
293 	/* If set to one, this file type is a directory.
294 	 * A convenience flag to be used as
295 	 * "archive_entry_filetype(isoent->file->entry) == AE_IFDIR".
296 	 */
297 	signed int		 dir:1;
298 };
299 
300 struct hardlink {
301 	struct archive_rb_node	 rbnode;
302 	int			 nlink;
303 	struct {
304 		struct isofile	*first;
305 		struct isofile	**last;
306 	}			 file_list;
307 };
308 
309 /*
310  * ISO writer options
311  */
312 struct iso_option {
313 	/*
314 	 * Usage  : abstract-file=<value>
315 	 * Type   : string, max 37 bytes
316 	 * Default: Not specified
317 	 * COMPAT : mkisofs -abstract <value>
318 	 *
319 	 * Specifies Abstract Filename.
320 	 * This file shall be described in the Root Directory
321 	 * and containing a abstract statement.
322 	 */
323 	unsigned int	 abstract_file:1;
324 #define OPT_ABSTRACT_FILE_DEFAULT	0	/* Not specified */
325 #define ABSTRACT_FILE_SIZE		37
326 
327 	/*
328 	 * Usage  : application-id=<value>
329 	 * Type   : string, max 128 bytes
330 	 * Default: Not specified
331 	 * COMPAT : mkisofs -A/-appid <value>.
332 	 *
333 	 * Specifies Application Identifier.
334 	 * If the first byte is set to '_'(5F), the remaining
335 	 * bytes of this option shall specify an identifier
336 	 * for a file containing the identification of the
337 	 * application.
338 	 * This file shall be described in the Root Directory.
339 	 */
340 	unsigned int	 application_id:1;
341 #define OPT_APPLICATION_ID_DEFAULT	0	/* Use default identifier */
342 #define APPLICATION_IDENTIFIER_SIZE	128
343 
344 	/*
345 	 * Usage : !allow-vernum
346 	 * Type  : boolean
347 	 * Default: Enabled
348 	 *	  : Violates the ISO9660 standard if disable.
349 	 * COMPAT: mkisofs -N
350 	 *
351 	 * Allow filenames to use version numbers.
352 	 */
353 	unsigned int	 allow_vernum:1;
354 #define OPT_ALLOW_VERNUM_DEFAULT	1	/* Enabled */
355 
356 	/*
357 	 * Usage  : biblio-file=<value>
358 	 * Type   : string, max 37 bytes
359 	 * Default: Not specified
360 	 * COMPAT : mkisofs -biblio <value>
361 	 *
362 	 * Specifies Bibliographic Filename.
363 	 * This file shall be described in the Root Directory
364 	 * and containing bibliographic records.
365 	 */
366 	unsigned int	 biblio_file:1;
367 #define OPT_BIBLIO_FILE_DEFAULT		0	/* Not specified */
368 #define BIBLIO_FILE_SIZE		37
369 
370 	/*
371 	 * Usage  : boot=<value>
372 	 * Type   : string
373 	 * Default: Not specified
374 	 * COMPAT : mkisofs -b/-eltorito-boot <value>
375 	 *
376 	 * Specifies "El Torito" boot image file to make
377 	 * a bootable CD.
378 	 */
379 	unsigned int	 boot:1;
380 #define OPT_BOOT_DEFAULT		0	/* Not specified */
381 
382 	/*
383 	 * Usage  : boot-catalog=<value>
384 	 * Type   : string
385 	 * Default: "boot.catalog"
386 	 * COMPAT : mkisofs -c/-eltorito-catalog <value>
387 	 *
388 	 * Specifies a fullpath of El Torito boot catalog.
389 	 */
390 	unsigned int	 boot_catalog:1;
391 #define OPT_BOOT_CATALOG_DEFAULT	0	/* Not specified */
392 
393 	/*
394 	 * Usage  : boot-info-table
395 	 * Type   : boolean
396 	 * Default: Disabled
397 	 * COMPAT : mkisofs -boot-info-table
398 	 *
399 	 * Modify the boot image file specified by `boot'
400 	 * option; ISO writer stores boot file information
401 	 * into the boot file in ISO image at offset 8
402 	 * through offset 64.
403 	 */
404 	unsigned int	 boot_info_table:1;
405 #define OPT_BOOT_INFO_TABLE_DEFAULT	0	/* Disabled */
406 
407 	/*
408 	 * Usage  : boot-load-seg=<value>
409 	 * Type   : hexadecimal
410 	 * Default: Not specified
411 	 * COMPAT : mkisofs -boot-load-seg <value>
412 	 *
413 	 * Specifies a load segment for boot image.
414 	 * This is used with no-emulation mode.
415 	 */
416 	unsigned int	 boot_load_seg:1;
417 #define OPT_BOOT_LOAD_SEG_DEFAULT	0	/* Not specified */
418 
419 	/*
420 	 * Usage  : boot-load-size=<value>
421 	 * Type   : decimal
422 	 * Default: Not specified
423 	 * COMPAT : mkisofs -boot-load-size <value>
424 	 *
425 	 * Specifies a sector count for boot image.
426 	 * This is used with no-emulation mode.
427 	 */
428 	unsigned int	 boot_load_size:1;
429 #define OPT_BOOT_LOAD_SIZE_DEFAULT	0	/* Not specified */
430 
431 	/*
432 	 * Usage  : boot-type=<boot-media-type>
433 	 *        : 'no-emulation' : 'no emulation' image
434 	 *        :           'fd' : floppy disk image
435 	 *        :    'hard-disk' : hard disk image
436 	 * Type   : string
437 	 * Default: Auto detect
438 	 *        : We check a size of boot image;
439 	 *        : If the size is just 1.22M/1.44M/2.88M,
440 	 *        : we assume boot_type is 'fd';
441 	 *        : otherwise boot_type is 'no-emulation'.
442 	 * COMPAT :
443 	 *    boot=no-emulation
444 	 *	mkisofs -no-emul-boot
445 	 *    boot=fd
446 	 *	This is a default on the mkisofs.
447 	 *    boot=hard-disk
448 	 *	mkisofs -hard-disk-boot
449 	 *
450 	 * Specifies a type of "El Torito" boot image.
451 	 */
452 	unsigned int	 boot_type:2;
453 #define OPT_BOOT_TYPE_AUTO		0	/* auto detect		  */
454 #define OPT_BOOT_TYPE_NO_EMU		1	/* ``no emulation'' image */
455 #define OPT_BOOT_TYPE_FD		2	/* floppy disk image	  */
456 #define OPT_BOOT_TYPE_HARD_DISK		3	/* hard disk image	  */
457 #define OPT_BOOT_TYPE_DEFAULT		OPT_BOOT_TYPE_AUTO
458 
459 	/*
460 	 * Usage  : compression-level=<value>
461 	 * Type   : decimal
462 	 * Default: Not specified
463 	 * COMPAT : NONE
464 	 *
465 	 * Specifies compression level for option zisofs=direct.
466 	 */
467 	unsigned int	 compression_level:1;
468 #define OPT_COMPRESSION_LEVEL_DEFAULT	0	/* Not specified */
469 
470 	/*
471 	 * Usage  : copyright-file=<value>
472 	 * Type   : string, max 37 bytes
473 	 * Default: Not specified
474 	 * COMPAT : mkisofs -copyright <value>
475 	 *
476 	 * Specifies Copyright Filename.
477 	 * This file shall be described in the Root Directory
478 	 * and containing a copyright statement.
479 	 */
480 	unsigned int	 copyright_file:1;
481 #define OPT_COPYRIGHT_FILE_DEFAULT	0	/* Not specified */
482 #define COPYRIGHT_FILE_SIZE		37
483 
484 	/*
485 	 * Usage  : gid=<value>
486 	 * Type   : decimal
487 	 * Default: Not specified
488 	 * COMPAT : mkisofs -gid <value>
489 	 *
490 	 * Specifies a group id to rewrite the group id of all files.
491 	 */
492 	unsigned int	 gid:1;
493 #define OPT_GID_DEFAULT			0	/* Not specified */
494 
495 	/*
496 	 * Usage  : iso-level=[1234]
497 	 * Type   : decimal
498 	 * Default: 1
499 	 * COMPAT : mkisofs -iso-level <value>
500 	 *
501 	 * Specifies ISO9600 Level.
502 	 * Level 1: [DEFAULT]
503 	 *   - limits each file size less than 4Gi bytes;
504 	 *   - a File Name shall not contain more than eight
505 	 *     d-characters or eight d1-characters;
506 	 *   - a File Name Extension shall not contain more than
507 	 *     three d-characters or three d1-characters;
508 	 *   - a Directory Identifier shall not contain more
509 	 *     than eight d-characters or eight d1-characters.
510 	 * Level 2:
511 	 *   - limits each file size less than 4Giga bytes;
512 	 *   - a File Name shall not contain more than thirty
513 	 *     d-characters or thirty d1-characters;
514 	 *   - a File Name Extension shall not contain more than
515 	 *     thirty d-characters or thirty d1-characters;
516 	 *   - a Directory Identifier shall not contain more
517 	 *     than thirty-one d-characters or thirty-one
518 	 *     d1-characters.
519 	 * Level 3:
520 	 *   - no limit of file size; use multi extent.
521 	 * Level 4:
522 	 *   - this level 4 simulates mkisofs option
523 	 *     '-iso-level 4';
524 	 *   - crate a enhanced volume as mkisofs doing;
525 	 *   - allow a File Name to have leading dot;
526 	 *   - allow a File Name to have all ASCII letters;
527 	 *   - allow a File Name to have multiple dots;
528 	 *   - allow more then 8 depths of directory trees;
529 	 *   - disable a version number to a File Name;
530 	 *   - disable a forced period to the tail of a File Name;
531 	 *   - the maximum length of files and directories is raised to 193.
532 	 *     if rockridge option is disabled, raised to 207.
533 	 */
534 	unsigned int	 iso_level:3;
535 #define OPT_ISO_LEVEL_DEFAULT		1	/* ISO Level 1 */
536 
537 	/*
538 	 * Usage  : joliet[=long]
539 	 *        : !joliet
540 	 *        :   Do not generate Joliet Volume and Records.
541 	 *        : joliet [DEFAULT]
542 	 *        :   Generates Joliet Volume and Directory Records.
543 	 *        :   [COMPAT: mkisofs -J/-joliet]
544 	 *        : joliet=long
545 	 *        :   The joliet filenames are up to 103 Unicode
546 	 *        :   characters.
547 	 *        :   This option breaks the Joliet specification.
548 	 *        :   [COMPAT: mkisofs -J -joliet-long]
549 	 * Type   : boolean/string
550 	 * Default: Enabled
551 	 * COMPAT : mkisofs -J / -joliet-long
552 	 *
553 	 * Generates Joliet Volume and Directory Records.
554 	 */
555 	unsigned int	 joliet:2;
556 #define OPT_JOLIET_DISABLE		0	/* Not generate Joliet Records. */
557 #define OPT_JOLIET_ENABLE		1	/* Generate Joliet Records.  */
558 #define OPT_JOLIET_LONGNAME		2	/* Use long joliet filenames.*/
559 #define OPT_JOLIET_DEFAULT		OPT_JOLIET_ENABLE
560 
561 	/*
562 	 * Usage  : !limit-depth
563 	 * Type   : boolean
564 	 * Default: Enabled
565 	 *	  : Violates the ISO9660 standard if disable.
566 	 * COMPAT : mkisofs -D/-disable-deep-relocation
567 	 *
568 	 * The number of levels in hierarchy cannot exceed eight.
569 	 */
570 	unsigned int	 limit_depth:1;
571 #define OPT_LIMIT_DEPTH_DEFAULT		1	/* Enabled */
572 
573 	/*
574 	 * Usage  : !limit-dirs
575 	 * Type   : boolean
576 	 * Default: Enabled
577 	 *	  : Violates the ISO9660 standard if disable.
578 	 * COMPAT : mkisofs -no-limit-pathtables
579 	 *
580 	 * Limits the number of directories less than 65536 due
581 	 * to the size of the Parent Directory Number of Path
582 	 * Table.
583 	 */
584 	unsigned int	 limit_dirs:1;
585 #define OPT_LIMIT_DIRS_DEFAULT		1	/* Enabled */
586 
587 	/*
588 	 * Usage  : !pad
589 	 * Type   : boolean
590 	 * Default: Enabled
591 	 * COMPAT : -pad/-no-pad
592 	 *
593 	 * Pads the end of the ISO image by null of 300Ki bytes.
594 	 */
595 	unsigned int	 pad:1;
596 #define OPT_PAD_DEFAULT			1	/* Enabled */
597 
598 	/*
599 	 * Usage  : publisher=<value>
600 	 * Type   : string, max 128 bytes
601 	 * Default: Not specified
602 	 * COMPAT : mkisofs -publisher <value>
603 	 *
604 	 * Specifies Publisher Identifier.
605 	 * If the first byte is set to '_'(5F), the remaining
606 	 * bytes of this option shall specify an identifier
607 	 * for a file containing the identification of the user.
608 	 * This file shall be described in the Root Directory.
609 	 */
610 	unsigned int	 publisher:1;
611 #define OPT_PUBLISHER_DEFAULT		0	/* Not specified */
612 #define PUBLISHER_IDENTIFIER_SIZE	128
613 
614 	/*
615 	 * Usage  : rockridge
616 	 *        : !rockridge
617 	 *        :    disable to generate SUSP and RR records.
618 	 *        : rockridge
619 	 *        :    the same as 'rockridge=useful'.
620 	 *        : rockridge=strict
621 	 *        :    generate SUSP and RR records.
622 	 *        :    [COMPAT: mkisofs -R]
623 	 *        : rockridge=useful [DEFAULT]
624 	 *        :    generate SUSP and RR records.
625 	 *        :    [COMPAT: mkisofs -r]
626 	 *        :    NOTE  Our rockridge=useful option does not set a zero
627 	 *        :          to uid and gid, you should use application
628 	 *        :          option such as --gid,--gname,--uid and --uname
629 	 *        :          bsdtar options instead.
630 	 * Type   : boolean/string
631 	 * Default: Enabled as rockridge=useful
632 	 * COMPAT : mkisofs -r / -R
633 	 *
634 	 * Generates SUSP and RR records.
635 	 */
636 	unsigned int	 rr:2;
637 #define OPT_RR_DISABLED			0
638 #define OPT_RR_STRICT			1
639 #define OPT_RR_USEFUL			2
640 #define OPT_RR_DEFAULT			OPT_RR_USEFUL
641 
642 	/*
643 	 * Usage  : volume-id=<value>
644 	 * Type   : string, max 32 bytes
645 	 * Default: Not specified
646 	 * COMPAT : mkisofs -V <value>
647 	 *
648 	 * Specifies Volume Identifier.
649 	 */
650 	unsigned int	 volume_id:1;
651 #define OPT_VOLUME_ID_DEFAULT		0	/* Use default identifier */
652 #define VOLUME_IDENTIFIER_SIZE		32
653 
654 	/*
655 	 * Usage  : !zisofs [DEFAULT]
656 	 *        :    Disable to generate RRIP 'ZF' extension.
657 	 *        : zisofs
658 	 *        :    Make files zisofs file and generate RRIP 'ZF'
659  	 *        :    extension. So you do not need mkzftree utility
660 	 *        :    for making zisofs.
661 	 *        :    When the file size is less than one Logical Block
662 	 *        :    size, that file will not zisofs'ed since it does
663 	 *        :    reduce an ISO-image size.
664 	 *        :
665 	 *        :    When you specify option 'boot=<boot-image>', that
666 	 *        :    'boot-image' file won't be converted to zisofs file.
667 	 * Type   : boolean
668 	 * Default: Disabled
669 	 *
670 	 * Generates RRIP 'ZF' System Use Entry.
671 	 */
672 	unsigned int	 zisofs:1;
673 #define OPT_ZISOFS_DISABLED		0
674 #define OPT_ZISOFS_DIRECT		1
675 #define OPT_ZISOFS_DEFAULT		OPT_ZISOFS_DISABLED
676 
677 };
678 
679 struct iso9660 {
680 	/* The creation time of ISO image. */
681 	time_t			 birth_time;
682 	/* A file stream of a temporary file, which file contents
683 	 * save to until ISO image can be created. */
684 	int			 temp_fd;
685 
686 	struct isofile		*cur_file;
687 	struct isoent		*cur_dirent;
688 	struct archive_string	 cur_dirstr;
689 	uint64_t		 bytes_remaining;
690 	int			 need_multi_extent;
691 
692 	/* Temporary string buffer for Joliet extension. */
693 	struct archive_string	 utf16be;
694 	struct archive_string	 mbs;
695 
696 	struct archive_string_conv *sconv_to_utf16be;
697 	struct archive_string_conv *sconv_from_utf16be;
698 
699 	/* A list of all of struct isofile entries. */
700 	struct {
701 		struct isofile	*first;
702 		struct isofile	**last;
703 	}			 all_file_list;
704 
705 	/* A list of struct isofile entries which have its
706 	 * contents and are not a directory, a hardlinked file
707 	 * and a symlink file. */
708 	struct {
709 		struct isofile	*first;
710 		struct isofile	**last;
711 	}			 data_file_list;
712 
713 	/* Used for managing to find hardlinking files. */
714 	struct archive_rb_tree	 hardlink_rbtree;
715 
716 	/* Used for making the Path Table Record. */
717 	struct vdd {
718 		/* the root of entry tree. */
719 		struct isoent	*rootent;
720 		enum vdd_type {
721 			VDD_PRIMARY,
722 			VDD_JOLIET,
723 			VDD_ENHANCED
724 		} vdd_type;
725 
726 		struct path_table {
727 			struct isoent		*first;
728 			struct isoent		**last;
729 			struct isoent		**sorted;
730 			int			 cnt;
731 		} *pathtbl;
732 		int				 max_depth;
733 
734 		int		 path_table_block;
735 		int		 path_table_size;
736 		int		 location_type_L_path_table;
737 		int		 location_type_M_path_table;
738 		int		 total_dir_block;
739 	} primary, joliet;
740 
741 	/* Used for making a Volume Descriptor. */
742 	int			 volume_space_size;
743 	int			 volume_sequence_number;
744 	int			 total_file_block;
745 	struct archive_string	 volume_identifier;
746 	struct archive_string	 publisher_identifier;
747 	struct archive_string	 data_preparer_identifier;
748 	struct archive_string	 application_identifier;
749 	struct archive_string	 copyright_file_identifier;
750 	struct archive_string	 abstract_file_identifier;
751 	struct archive_string	 bibliographic_file_identifier;
752 
753 	/* Used for making rockridge extensions. */
754 	int			 location_rrip_er;
755 
756 	/* Used for making zisofs. */
757 	struct {
758 		signed int	 detect_magic:1;
759 		signed int	 making:1;
760 		signed int	 allzero:1;
761 		unsigned char	 magic_buffer[64];
762 		int		 magic_cnt;
763 
764 #ifdef HAVE_ZLIB_H
765 		/*
766 		 * Copy a compressed file to iso9660.zisofs.temp_fd
767 		 * and also copy a uncompressed file(original file) to
768 		 * iso9660.temp_fd . If the number of logical block
769 		 * of the compressed file is less than the number of
770 		 * logical block of the uncompressed file, use it and
771 		 * remove the copy of the uncompressed file.
772 		 * but if not, we use uncompressed file and remove
773 		 * the copy of the compressed file.
774 		 */
775 		uint32_t	*block_pointers;
776 		size_t		 block_pointers_allocated;
777 		int		 block_pointers_cnt;
778 		int		 block_pointers_idx;
779 		int64_t		 total_size;
780 		int64_t		 block_offset;
781 
782 		z_stream	 stream;
783 		int		 stream_valid;
784 		int64_t		 remaining;
785 		int		 compression_level;
786 #endif
787 	} zisofs;
788 
789 	struct isoent		*directories_too_deep;
790 	int			 dircnt_max;
791 
792 	/* Write buffer. */
793 #define wb_buffmax()	(LOGICAL_BLOCK_SIZE * 32)
794 #define wb_remaining(a)	(((struct iso9660 *)(a)->format_data)->wbuff_remaining)
795 #define wb_offset(a)	(((struct iso9660 *)(a)->format_data)->wbuff_offset \
796 		+ wb_buffmax() - wb_remaining(a))
797 	unsigned char		 wbuff[LOGICAL_BLOCK_SIZE * 32];
798 	size_t			 wbuff_remaining;
799 	enum {
800 		WB_TO_STREAM,
801 		WB_TO_TEMP
802 	} 			 wbuff_type;
803 	int64_t			 wbuff_offset;
804 	int64_t			 wbuff_written;
805 	int64_t			 wbuff_tail;
806 
807 	/* 'El Torito' boot data. */
808 	struct {
809 		/* boot catalog file */
810 		struct archive_string	 catalog_filename;
811 		struct isoent		*catalog;
812 		/* boot image file */
813 		struct archive_string	 boot_filename;
814 		struct isoent		*boot;
815 
816 		unsigned char		 platform_id;
817 #define BOOT_PLATFORM_X86	0
818 #define BOOT_PLATFORM_PPC	1
819 #define BOOT_PLATFORM_MAC	2
820 		struct archive_string	 id;
821 		unsigned char		 media_type;
822 #define BOOT_MEDIA_NO_EMULATION		0
823 #define BOOT_MEDIA_1_2M_DISKETTE	1
824 #define BOOT_MEDIA_1_44M_DISKETTE	2
825 #define BOOT_MEDIA_2_88M_DISKETTE	3
826 #define BOOT_MEDIA_HARD_DISK		4
827 		unsigned char		 system_type;
828 		uint16_t		 boot_load_seg;
829 		uint16_t		 boot_load_size;
830 #define BOOT_LOAD_SIZE		4
831 	} el_torito;
832 
833 	struct iso_option	 opt;
834 };
835 
836 /*
837  * Types of Volume Descriptor
838  */
839 enum VD_type {
840 	VDT_BOOT_RECORD=0,	/* Boot Record Volume Descriptor 	*/
841 	VDT_PRIMARY=1,		/* Primary Volume Descriptor		*/
842 	VDT_SUPPLEMENTARY=2,	/* Supplementary Volume Descriptor	*/
843 	VDT_TERMINATOR=255	/* Volume Descriptor Set Terminator	*/
844 };
845 
846 /*
847  * Types of Directory Record
848  */
849 enum dir_rec_type {
850 	DIR_REC_VD,		/* Stored in Volume Descriptor.	*/
851 	DIR_REC_SELF,		/* Stored as Current Directory.	*/
852 	DIR_REC_PARENT,		/* Stored as Parent Directory.	*/
853 	DIR_REC_NORMAL 		/* Stored as Child.		*/
854 };
855 
856 /*
857  * Kinds of Volume Descriptor Character
858  */
859 enum vdc {
860 	VDC_STD,
861 	VDC_LOWERCASE,
862 	VDC_UCS2,
863 	VDC_UCS2_DIRECT
864 };
865 
866 /*
867  * IDentifier Resolver.
868  * Used for resolving duplicated filenames.
869  */
870 struct idr {
871 	struct idrent {
872 		struct archive_rb_node	rbnode;
873 		/* Used in wait_list. */
874 		struct idrent		*wnext;
875 		struct idrent		*avail;
876 
877 		struct isoent		*isoent;
878 		int			 weight;
879 		int			 noff;
880 		int			 rename_num;
881 	} *idrent_pool;
882 
883 	struct archive_rb_tree		 rbtree;
884 
885 	struct {
886 		struct idrent		*first;
887 		struct idrent		**last;
888 	} wait_list;
889 
890 	int				 pool_size;
891 	int				 pool_idx;
892 	int				 num_size;
893 	int				 null_size;
894 
895 	char				 char_map[0x80];
896 };
897 
898 enum char_type {
899 	A_CHAR,
900 	D_CHAR
901 };
902 
903 
904 static int	iso9660_options(struct archive_write *,
905 		    const char *, const char *);
906 static int	iso9660_write_header(struct archive_write *,
907 		    struct archive_entry *);
908 static ssize_t	iso9660_write_data(struct archive_write *,
909 		    const void *, size_t);
910 static int	iso9660_finish_entry(struct archive_write *);
911 static int	iso9660_close(struct archive_write *);
912 static int	iso9660_free(struct archive_write *);
913 
914 static void	get_system_identitier(char *, size_t);
915 static void	set_str(unsigned char *, const char *, size_t, char,
916 		    const char *);
917 static inline int joliet_allowed_char(unsigned char, unsigned char);
918 static int	set_str_utf16be(struct archive_write *, unsigned char *,
919 			const char *, size_t, uint16_t, enum vdc);
920 static int	set_str_a_characters_bp(struct archive_write *,
921 			unsigned char *, int, int, const char *, enum vdc);
922 static int	set_str_d_characters_bp(struct archive_write *,
923 			unsigned char *, int, int, const char *, enum  vdc);
924 static void	set_VD_bp(unsigned char *, enum VD_type, unsigned char);
925 static inline void set_unused_field_bp(unsigned char *, int, int);
926 
927 static unsigned char *extra_open_record(unsigned char *, int,
928 		    struct isoent *, struct ctl_extr_rec *);
929 static void	extra_close_record(struct ctl_extr_rec *, int);
930 static unsigned char * extra_next_record(struct ctl_extr_rec *, int);
931 static unsigned char *extra_get_record(struct isoent *, int *, int *, int *);
932 static void	extra_tell_used_size(struct ctl_extr_rec *, int);
933 static int	extra_setup_location(struct isoent *, int);
934 static int	set_directory_record_rr(unsigned char *, int,
935 		    struct isoent *, struct iso9660 *, enum dir_rec_type);
936 static int	set_directory_record(unsigned char *, size_t,
937 		    struct isoent *, struct iso9660 *, enum dir_rec_type,
938 		    enum vdd_type);
939 static inline int get_dir_rec_size(struct iso9660 *, struct isoent *,
940 		    enum dir_rec_type, enum vdd_type);
941 static inline unsigned char *wb_buffptr(struct archive_write *);
942 static int	wb_write_out(struct archive_write *);
943 static int	wb_consume(struct archive_write *, size_t);
944 #ifdef HAVE_ZLIB_H
945 static int	wb_set_offset(struct archive_write *, int64_t);
946 #endif
947 static int	write_null(struct archive_write *, size_t);
948 static int	write_VD_terminator(struct archive_write *);
949 static int	set_file_identifier(unsigned char *, int, int, enum vdc,
950 		    struct archive_write *, struct vdd *,
951 		    struct archive_string *, const char *, int,
952 		    enum char_type);
953 static int	write_VD(struct archive_write *, struct vdd *);
954 static int	write_VD_boot_record(struct archive_write *);
955 static int	write_information_block(struct archive_write *);
956 static int	write_path_table(struct archive_write *, int,
957 		    struct vdd *);
958 static int	write_directory_descriptors(struct archive_write *,
959 		    struct vdd *);
960 static int	write_file_descriptors(struct archive_write *);
961 static int	write_rr_ER(struct archive_write *);
962 static void	calculate_path_table_size(struct vdd *);
963 
964 static void	isofile_init_entry_list(struct iso9660 *);
965 static void	isofile_add_entry(struct iso9660 *, struct isofile *);
966 static void	isofile_free_all_entries(struct iso9660 *);
967 static void	isofile_init_entry_data_file_list(struct iso9660 *);
968 static void	isofile_add_data_file(struct iso9660 *, struct isofile *);
969 static struct isofile * isofile_new(struct archive_write *,
970 		    struct archive_entry *);
971 static void	isofile_free(struct isofile *);
972 static int	isofile_gen_utility_names(struct archive_write *,
973 		    struct isofile *);
974 static int	isofile_register_hardlink(struct archive_write *,
975 		    struct isofile *);
976 static void	isofile_connect_hardlink_files(struct iso9660 *);
977 static void	isofile_init_hardlinks(struct iso9660 *);
978 static void	isofile_free_hardlinks(struct iso9660 *);
979 
980 static struct isoent *isoent_new(struct isofile *);
981 static int	isoent_clone_tree(struct archive_write *,
982 		    struct isoent **, struct isoent *);
983 static void	_isoent_free(struct isoent *isoent);
984 static void	isoent_free_all(struct isoent *);
985 static struct isoent * isoent_create_virtual_dir(struct archive_write *,
986 		    struct iso9660 *, const char *);
987 static int	isoent_cmp_node(const struct archive_rb_node *,
988 		    const struct archive_rb_node *);
989 static int	isoent_cmp_key(const struct archive_rb_node *,
990 		    const void *);
991 static int	isoent_add_child_head(struct isoent *, struct isoent *);
992 static int	isoent_add_child_tail(struct isoent *, struct isoent *);
993 static void	isoent_remove_child(struct isoent *, struct isoent *);
994 static void	isoent_setup_directory_location(struct iso9660 *,
995 		    int, struct vdd *);
996 static void	isoent_setup_file_location(struct iso9660 *, int);
997 static int	get_path_component(char *, size_t, const char *);
998 static int	isoent_tree(struct archive_write *, struct isoent **);
999 static struct isoent *isoent_find_child(struct isoent *, const char *);
1000 static struct isoent *isoent_find_entry(struct isoent *, const char *);
1001 static void	idr_relaxed_filenames(char *);
1002 static void	idr_init(struct iso9660 *, struct vdd *, struct idr *);
1003 static void	idr_cleanup(struct idr *);
1004 static int	idr_ensure_poolsize(struct archive_write *, struct idr *,
1005 		    int);
1006 static int	idr_start(struct archive_write *, struct idr *,
1007 		    int, int, int, int, const struct archive_rb_tree_ops *);
1008 static void	idr_register(struct idr *, struct isoent *, int,
1009 		    int);
1010 static void	idr_extend_identifier(struct idrent *, int, int);
1011 static void	idr_resolve(struct idr *, void (*)(unsigned char *, int));
1012 static void	idr_set_num(unsigned char *, int);
1013 static void	idr_set_num_beutf16(unsigned char *, int);
1014 static int	isoent_gen_iso9660_identifier(struct archive_write *,
1015 		    struct isoent *, struct idr *);
1016 static int	isoent_gen_joliet_identifier(struct archive_write *,
1017 		    struct isoent *, struct idr *);
1018 static int	isoent_cmp_iso9660_identifier(const struct isoent *,
1019 		    const struct isoent *);
1020 static int	isoent_cmp_node_iso9660(const struct archive_rb_node *,
1021 		    const struct archive_rb_node *);
1022 static int	isoent_cmp_key_iso9660(const struct archive_rb_node *,
1023 		    const void *);
1024 static int	isoent_cmp_joliet_identifier(const struct isoent *,
1025 		    const struct isoent *);
1026 static int	isoent_cmp_node_joliet(const struct archive_rb_node *,
1027 		    const struct archive_rb_node *);
1028 static int	isoent_cmp_key_joliet(const struct archive_rb_node *,
1029 		    const void *);
1030 static inline void path_table_add_entry(struct path_table *, struct isoent *);
1031 static inline struct isoent * path_table_last_entry(struct path_table *);
1032 static int	isoent_make_path_table(struct archive_write *);
1033 static int	isoent_find_out_boot_file(struct archive_write *,
1034 		    struct isoent *);
1035 static int	isoent_create_boot_catalog(struct archive_write *,
1036 		    struct isoent *);
1037 static size_t	fd_boot_image_size(int);
1038 static int	make_boot_catalog(struct archive_write *);
1039 static int	setup_boot_information(struct archive_write *);
1040 
1041 static int	zisofs_init(struct archive_write *, struct isofile *);
1042 static void	zisofs_detect_magic(struct archive_write *,
1043 		    const void *, size_t);
1044 static int	zisofs_write_to_temp(struct archive_write *,
1045 		    const void *, size_t);
1046 static int	zisofs_finish_entry(struct archive_write *);
1047 static int	zisofs_rewind_boot_file(struct archive_write *);
1048 static int	zisofs_free(struct archive_write *);
1049 
1050 int
1051 archive_write_set_format_iso9660(struct archive *_a)
1052 {
1053 	struct archive_write *a = (struct archive_write *)_a;
1054 	struct iso9660 *iso9660;
1055 
1056 	archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
1057 	    ARCHIVE_STATE_NEW, "archive_write_set_format_iso9660");
1058 
1059 	/* If another format was already registered, unregister it. */
1060 	if (a->format_free != NULL)
1061 		(a->format_free)(a);
1062 
1063 	iso9660 = calloc(1, sizeof(*iso9660));
1064 	if (iso9660 == NULL) {
1065 		archive_set_error(&a->archive, ENOMEM,
1066 		    "Can't allocate iso9660 data");
1067 		return (ARCHIVE_FATAL);
1068 	}
1069 	iso9660->birth_time = 0;
1070 	iso9660->temp_fd = -1;
1071 	iso9660->cur_file = NULL;
1072 	iso9660->primary.max_depth = 0;
1073 	iso9660->primary.vdd_type = VDD_PRIMARY;
1074 	iso9660->primary.pathtbl = NULL;
1075 	iso9660->joliet.rootent = NULL;
1076 	iso9660->joliet.max_depth = 0;
1077 	iso9660->joliet.vdd_type = VDD_JOLIET;
1078 	iso9660->joliet.pathtbl = NULL;
1079 	isofile_init_entry_list(iso9660);
1080 	isofile_init_entry_data_file_list(iso9660);
1081 	isofile_init_hardlinks(iso9660);
1082 	iso9660->directories_too_deep = NULL;
1083 	iso9660->dircnt_max = 1;
1084 	iso9660->wbuff_remaining = wb_buffmax();
1085 	iso9660->wbuff_type = WB_TO_TEMP;
1086 	iso9660->wbuff_offset = 0;
1087 	iso9660->wbuff_written = 0;
1088 	iso9660->wbuff_tail = 0;
1089 	archive_string_init(&(iso9660->utf16be));
1090 	archive_string_init(&(iso9660->mbs));
1091 
1092 	/*
1093 	 * Init Identifiers used for PVD and SVD.
1094 	 */
1095 	archive_string_init(&(iso9660->volume_identifier));
1096 	archive_strcpy(&(iso9660->volume_identifier), "CDROM");
1097 	archive_string_init(&(iso9660->publisher_identifier));
1098 	archive_string_init(&(iso9660->data_preparer_identifier));
1099 	archive_string_init(&(iso9660->application_identifier));
1100 	archive_strcpy(&(iso9660->application_identifier),
1101 	    archive_version_string());
1102 	archive_string_init(&(iso9660->copyright_file_identifier));
1103 	archive_string_init(&(iso9660->abstract_file_identifier));
1104 	archive_string_init(&(iso9660->bibliographic_file_identifier));
1105 
1106 	/*
1107 	 * Init El Torito bootable CD variables.
1108 	 */
1109 	archive_string_init(&(iso9660->el_torito.catalog_filename));
1110 	iso9660->el_torito.catalog = NULL;
1111 	/* Set default file name of boot catalog  */
1112 	archive_strcpy(&(iso9660->el_torito.catalog_filename),
1113 	    "boot.catalog");
1114 	archive_string_init(&(iso9660->el_torito.boot_filename));
1115 	iso9660->el_torito.boot = NULL;
1116 	iso9660->el_torito.platform_id = BOOT_PLATFORM_X86;
1117 	archive_string_init(&(iso9660->el_torito.id));
1118 	iso9660->el_torito.boot_load_seg = 0;
1119 	iso9660->el_torito.boot_load_size = BOOT_LOAD_SIZE;
1120 
1121 	/*
1122 	 * Init zisofs variables.
1123 	 */
1124 #ifdef HAVE_ZLIB_H
1125 	iso9660->zisofs.block_pointers = NULL;
1126 	iso9660->zisofs.block_pointers_allocated = 0;
1127 	iso9660->zisofs.stream_valid = 0;
1128 	iso9660->zisofs.compression_level = 9;
1129 	memset(&(iso9660->zisofs.stream), 0,
1130 	    sizeof(iso9660->zisofs.stream));
1131 #endif
1132 
1133 	/*
1134 	 * Set default value of iso9660 options.
1135 	 */
1136 	iso9660->opt.abstract_file = OPT_ABSTRACT_FILE_DEFAULT;
1137 	iso9660->opt.application_id = OPT_APPLICATION_ID_DEFAULT;
1138 	iso9660->opt.allow_vernum = OPT_ALLOW_VERNUM_DEFAULT;
1139 	iso9660->opt.biblio_file = OPT_BIBLIO_FILE_DEFAULT;
1140 	iso9660->opt.boot = OPT_BOOT_DEFAULT;
1141 	iso9660->opt.boot_catalog = OPT_BOOT_CATALOG_DEFAULT;
1142 	iso9660->opt.boot_info_table = OPT_BOOT_INFO_TABLE_DEFAULT;
1143 	iso9660->opt.boot_load_seg = OPT_BOOT_LOAD_SEG_DEFAULT;
1144 	iso9660->opt.boot_load_size = OPT_BOOT_LOAD_SIZE_DEFAULT;
1145 	iso9660->opt.boot_type = OPT_BOOT_TYPE_DEFAULT;
1146 	iso9660->opt.compression_level = OPT_COMPRESSION_LEVEL_DEFAULT;
1147 	iso9660->opt.copyright_file = OPT_COPYRIGHT_FILE_DEFAULT;
1148 	iso9660->opt.iso_level = OPT_ISO_LEVEL_DEFAULT;
1149 	iso9660->opt.joliet = OPT_JOLIET_DEFAULT;
1150 	iso9660->opt.limit_depth = OPT_LIMIT_DEPTH_DEFAULT;
1151 	iso9660->opt.limit_dirs = OPT_LIMIT_DIRS_DEFAULT;
1152 	iso9660->opt.pad = OPT_PAD_DEFAULT;
1153 	iso9660->opt.publisher = OPT_PUBLISHER_DEFAULT;
1154 	iso9660->opt.rr = OPT_RR_DEFAULT;
1155 	iso9660->opt.volume_id = OPT_VOLUME_ID_DEFAULT;
1156 	iso9660->opt.zisofs = OPT_ZISOFS_DEFAULT;
1157 
1158 	/* Create the root directory. */
1159 	iso9660->primary.rootent =
1160 	    isoent_create_virtual_dir(a, iso9660, "");
1161 	if (iso9660->primary.rootent == NULL) {
1162 		free(iso9660);
1163 		archive_set_error(&a->archive, ENOMEM,
1164 		    "Can't allocate memory");
1165 		return (ARCHIVE_FATAL);
1166 	}
1167 	iso9660->primary.rootent->parent = iso9660->primary.rootent;
1168 	iso9660->cur_dirent = iso9660->primary.rootent;
1169 	archive_string_init(&(iso9660->cur_dirstr));
1170 	archive_string_ensure(&(iso9660->cur_dirstr), 1);
1171 	iso9660->cur_dirstr.s[0] = 0;
1172 	iso9660->sconv_to_utf16be = NULL;
1173 	iso9660->sconv_from_utf16be = NULL;
1174 
1175 	a->format_data = iso9660;
1176 	a->format_name = "iso9660";
1177 	a->format_options = iso9660_options;
1178 	a->format_write_header = iso9660_write_header;
1179 	a->format_write_data = iso9660_write_data;
1180 	a->format_finish_entry = iso9660_finish_entry;
1181 	a->format_close = iso9660_close;
1182 	a->format_free = iso9660_free;
1183 	a->archive.archive_format = ARCHIVE_FORMAT_ISO9660;
1184 	a->archive.archive_format_name = "ISO9660";
1185 
1186 	return (ARCHIVE_OK);
1187 }
1188 
1189 static int
1190 get_str_opt(struct archive_write *a, struct archive_string *s,
1191     size_t maxsize, const char *key, const char *value)
1192 {
1193 
1194 	if (strlen(value) > maxsize) {
1195 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1196 		    "Value is longer than %zu characters "
1197 		    "for option ``%s''", maxsize, key);
1198 		return (ARCHIVE_FATAL);
1199 	}
1200 	archive_strcpy(s, value);
1201 	return (ARCHIVE_OK);
1202 }
1203 
1204 static int
1205 get_num_opt(struct archive_write *a, int *num, int high, int low,
1206     const char *key, const char *value)
1207 {
1208 	const char *p = value;
1209 	int data = 0;
1210 	int neg = 0;
1211 
1212 	if (p == NULL) {
1213 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1214 		    "Invalid value(empty) for option ``%s''", key);
1215 		return (ARCHIVE_FATAL);
1216 	}
1217 	if (*p == '-') {
1218 		neg = 1;
1219 		p++;
1220 	}
1221 	while (*p) {
1222 		if (*p >= '0' && *p <= '9')
1223 			data = data * 10 + *p - '0';
1224 		else {
1225 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1226 			    "Invalid value for option ``%s''", key);
1227 			return (ARCHIVE_FATAL);
1228 		}
1229 		if (data > high) {
1230 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1231 			    "Invalid value(over %d) for "
1232 			    "option ``%s''", high, key);
1233 			return (ARCHIVE_FATAL);
1234 		}
1235 		if (data < low) {
1236 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1237 			    "Invalid value(under %d) for "
1238 			    "option ``%s''", low, key);
1239 			return (ARCHIVE_FATAL);
1240 		}
1241 		p++;
1242 	}
1243 	if (neg)
1244 		data *= -1;
1245 	*num = data;
1246 
1247 	return (ARCHIVE_OK);
1248 }
1249 
1250 static int
1251 iso9660_options(struct archive_write *a, const char *key, const char *value)
1252 {
1253 	struct iso9660 *iso9660 = a->format_data;
1254 	const char *p;
1255 	int r;
1256 
1257 	switch (key[0]) {
1258 	case 'a':
1259 		if (strcmp(key, "abstract-file") == 0) {
1260 			r = get_str_opt(a,
1261 			    &(iso9660->abstract_file_identifier),
1262 			    ABSTRACT_FILE_SIZE, key, value);
1263 			iso9660->opt.abstract_file = r == ARCHIVE_OK;
1264 			return (r);
1265 		}
1266 		if (strcmp(key, "application-id") == 0) {
1267 			r = get_str_opt(a,
1268 			    &(iso9660->application_identifier),
1269 			    APPLICATION_IDENTIFIER_SIZE, key, value);
1270 			iso9660->opt.application_id = r == ARCHIVE_OK;
1271 			return (r);
1272 		}
1273 		if (strcmp(key, "allow-vernum") == 0) {
1274 			iso9660->opt.allow_vernum = value != NULL;
1275 			return (ARCHIVE_OK);
1276 		}
1277 		break;
1278 	case 'b':
1279 		if (strcmp(key, "biblio-file") == 0) {
1280 			r = get_str_opt(a,
1281 			    &(iso9660->bibliographic_file_identifier),
1282 			    BIBLIO_FILE_SIZE, key, value);
1283 			iso9660->opt.biblio_file = r == ARCHIVE_OK;
1284 			return (r);
1285 		}
1286 		if (strcmp(key, "boot") == 0) {
1287 			if (value == NULL)
1288 				iso9660->opt.boot = 0;
1289 			else {
1290 				iso9660->opt.boot = 1;
1291 				archive_strcpy(
1292 				    &(iso9660->el_torito.boot_filename),
1293 				    value);
1294 			}
1295 			return (ARCHIVE_OK);
1296 		}
1297 		if (strcmp(key, "boot-catalog") == 0) {
1298 			r = get_str_opt(a,
1299 			    &(iso9660->el_torito.catalog_filename),
1300 			    1024, key, value);
1301 			iso9660->opt.boot_catalog = r == ARCHIVE_OK;
1302 			return (r);
1303 		}
1304 		if (strcmp(key, "boot-info-table") == 0) {
1305 			iso9660->opt.boot_info_table = value != NULL;
1306 			return (ARCHIVE_OK);
1307 		}
1308 		if (strcmp(key, "boot-load-seg") == 0) {
1309 			uint32_t seg;
1310 
1311 			iso9660->opt.boot_load_seg = 0;
1312 			if (value == NULL)
1313 				goto invalid_value;
1314 			seg = 0;
1315 			p = value;
1316 			if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X'))
1317 				p += 2;
1318 			while (*p) {
1319 				if (seg)
1320 					seg <<= 4;
1321 				if (*p >= 'A' && *p <= 'F')
1322 					seg += *p - 'A' + 0x0a;
1323 				else if (*p >= 'a' && *p <= 'f')
1324 					seg += *p - 'a' + 0x0a;
1325 				else if (*p >= '0' && *p <= '9')
1326 					seg += *p - '0';
1327 				else
1328 					goto invalid_value;
1329 				if (seg > 0xffff) {
1330 					archive_set_error(&a->archive,
1331 					    ARCHIVE_ERRNO_MISC,
1332 					    "Invalid value(over 0xffff) for "
1333 					    "option ``%s''", key);
1334 					return (ARCHIVE_FATAL);
1335 				}
1336 				p++;
1337 			}
1338 			iso9660->el_torito.boot_load_seg = (uint16_t)seg;
1339 			iso9660->opt.boot_load_seg = 1;
1340 			return (ARCHIVE_OK);
1341 		}
1342 		if (strcmp(key, "boot-load-size") == 0) {
1343 			int num = 0;
1344 			r = get_num_opt(a, &num, 0xffff, 1, key, value);
1345 			iso9660->opt.boot_load_size = r == ARCHIVE_OK;
1346 			if (r != ARCHIVE_OK)
1347 				return (ARCHIVE_FATAL);
1348 			iso9660->el_torito.boot_load_size = (uint16_t)num;
1349 			return (ARCHIVE_OK);
1350 		}
1351 		if (strcmp(key, "boot-type") == 0) {
1352 			if (value == NULL)
1353 				goto invalid_value;
1354 			if (strcmp(value, "no-emulation") == 0)
1355 				iso9660->opt.boot_type = OPT_BOOT_TYPE_NO_EMU;
1356 			else if (strcmp(value, "fd") == 0)
1357 				iso9660->opt.boot_type = OPT_BOOT_TYPE_FD;
1358 			else if (strcmp(value, "hard-disk") == 0)
1359 				iso9660->opt.boot_type = OPT_BOOT_TYPE_HARD_DISK;
1360 			else
1361 				goto invalid_value;
1362 			return (ARCHIVE_OK);
1363 		}
1364 		break;
1365 	case 'c':
1366 		if (strcmp(key, "compression-level") == 0) {
1367 #ifdef HAVE_ZLIB_H
1368 			if (value == NULL ||
1369 			    !(value[0] >= '0' && value[0] <= '9') ||
1370 			    value[1] != '\0')
1371 				goto invalid_value;
1372                 	iso9660->zisofs.compression_level = value[0] - '0';
1373 			iso9660->opt.compression_level = 1;
1374                 	return (ARCHIVE_OK);
1375 #else
1376 			archive_set_error(&a->archive,
1377 			    ARCHIVE_ERRNO_MISC,
1378 			    "Option ``%s'' "
1379 			    "is not supported on this platform.", key);
1380 			return (ARCHIVE_FATAL);
1381 #endif
1382 		}
1383 		if (strcmp(key, "copyright-file") == 0) {
1384 			r = get_str_opt(a,
1385 			    &(iso9660->copyright_file_identifier),
1386 			    COPYRIGHT_FILE_SIZE, key, value);
1387 			iso9660->opt.copyright_file = r == ARCHIVE_OK;
1388 			return (r);
1389 		}
1390 #ifdef DEBUG
1391 		/* Specifies Volume creation date and time;
1392 		 * year(4),month(2),day(2),hour(2),minute(2),second(2).
1393 		 * e.g. "20090929033757"
1394 		 */
1395 		if (strcmp(key, "creation") == 0) {
1396 			struct tm tm;
1397 			char buf[5];
1398 
1399 			p = value;
1400 			if (p == NULL || strlen(p) < 14)
1401 				goto invalid_value;
1402 			memset(&tm, 0, sizeof(tm));
1403 			memcpy(buf, p, 4); buf[4] = '\0'; p += 4;
1404 			tm.tm_year = strtol(buf, NULL, 10) - 1900;
1405 			memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
1406 			tm.tm_mon = strtol(buf, NULL, 10) - 1;
1407 			memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
1408 			tm.tm_mday = strtol(buf, NULL, 10);
1409 			memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
1410 			tm.tm_hour = strtol(buf, NULL, 10);
1411 			memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
1412 			tm.tm_min = strtol(buf, NULL, 10);
1413 			memcpy(buf, p, 2); buf[2] = '\0';
1414 			tm.tm_sec = strtol(buf, NULL, 10);
1415 			iso9660->birth_time = mktime(&tm);
1416 			return (ARCHIVE_OK);
1417 		}
1418 #endif
1419 		break;
1420 	case 'i':
1421 		if (strcmp(key, "iso-level") == 0) {
1422 			if (value != NULL && value[1] == '\0' &&
1423 			    (value[0] >= '1' && value[0] <= '4')) {
1424 				iso9660->opt.iso_level = value[0]-'0';
1425 				return (ARCHIVE_OK);
1426 			}
1427 			goto invalid_value;
1428 		}
1429 		break;
1430 	case 'j':
1431 		if (strcmp(key, "joliet") == 0) {
1432 			if (value == NULL)
1433 				iso9660->opt.joliet = OPT_JOLIET_DISABLE;
1434 			else if (strcmp(value, "1") == 0)
1435 				iso9660->opt.joliet = OPT_JOLIET_ENABLE;
1436 			else if (strcmp(value, "long") == 0)
1437 				iso9660->opt.joliet = OPT_JOLIET_LONGNAME;
1438 			else
1439 				goto invalid_value;
1440 			return (ARCHIVE_OK);
1441 		}
1442 		break;
1443 	case 'l':
1444 		if (strcmp(key, "limit-depth") == 0) {
1445 			iso9660->opt.limit_depth = value != NULL;
1446 			return (ARCHIVE_OK);
1447 		}
1448 		if (strcmp(key, "limit-dirs") == 0) {
1449 			iso9660->opt.limit_dirs = value != NULL;
1450 			return (ARCHIVE_OK);
1451 		}
1452 		break;
1453 	case 'p':
1454 		if (strcmp(key, "pad") == 0) {
1455 			iso9660->opt.pad = value != NULL;
1456 			return (ARCHIVE_OK);
1457 		}
1458 		if (strcmp(key, "publisher") == 0) {
1459 			r = get_str_opt(a,
1460 			    &(iso9660->publisher_identifier),
1461 			    PUBLISHER_IDENTIFIER_SIZE, key, value);
1462 			iso9660->opt.publisher = r == ARCHIVE_OK;
1463 			return (r);
1464 		}
1465 		break;
1466 	case 'r':
1467 		if (strcmp(key, "rockridge") == 0 ||
1468 		    strcmp(key, "Rockridge") == 0) {
1469 			if (value == NULL)
1470 				iso9660->opt.rr = OPT_RR_DISABLED;
1471 			else if (strcmp(value, "1") == 0)
1472 				iso9660->opt.rr = OPT_RR_USEFUL;
1473 			else if (strcmp(value, "strict") == 0)
1474 				iso9660->opt.rr = OPT_RR_STRICT;
1475 			else if (strcmp(value, "useful") == 0)
1476 				iso9660->opt.rr = OPT_RR_USEFUL;
1477 			else
1478 				goto invalid_value;
1479 			return (ARCHIVE_OK);
1480 		}
1481 		break;
1482 	case 'v':
1483 		if (strcmp(key, "volume-id") == 0) {
1484 			r = get_str_opt(a, &(iso9660->volume_identifier),
1485 			    VOLUME_IDENTIFIER_SIZE, key, value);
1486 			iso9660->opt.volume_id = r == ARCHIVE_OK;
1487 			return (r);
1488 		}
1489 		break;
1490 	case 'z':
1491 		if (strcmp(key, "zisofs") == 0) {
1492 			if (value == NULL)
1493 				iso9660->opt.zisofs = OPT_ZISOFS_DISABLED;
1494 			else {
1495 #ifdef HAVE_ZLIB_H
1496 				iso9660->opt.zisofs = OPT_ZISOFS_DIRECT;
1497 #else
1498 				archive_set_error(&a->archive,
1499 				    ARCHIVE_ERRNO_MISC,
1500 				    "``zisofs'' "
1501 				    "is not supported on this platform.");
1502 				return (ARCHIVE_FATAL);
1503 #endif
1504 			}
1505 			return (ARCHIVE_OK);
1506 		}
1507 		break;
1508 	}
1509 
1510 	/* Note: The "warn" return is just to inform the options
1511 	 * supervisor that we didn't handle it.  It will generate
1512 	 * a suitable error if no one used this option. */
1513 	return (ARCHIVE_WARN);
1514 
1515 invalid_value:
1516 	archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1517 	    "Invalid value for option ``%s''", key);
1518 	return (ARCHIVE_FAILED);
1519 }
1520 
1521 static int
1522 iso9660_write_header(struct archive_write *a, struct archive_entry *entry)
1523 {
1524 	struct iso9660 *iso9660;
1525 	struct isofile *file;
1526 	struct isoent *isoent;
1527 	int r, ret = ARCHIVE_OK;
1528 
1529 	iso9660 = a->format_data;
1530 
1531 	iso9660->cur_file = NULL;
1532 	iso9660->bytes_remaining = 0;
1533 	iso9660->need_multi_extent = 0;
1534 	if (archive_entry_filetype(entry) == AE_IFLNK
1535 	    && iso9660->opt.rr == OPT_RR_DISABLED) {
1536 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1537 		    "Ignore symlink file.");
1538 		iso9660->cur_file = NULL;
1539 		return (ARCHIVE_WARN);
1540 	}
1541 	if (archive_entry_filetype(entry) == AE_IFREG &&
1542 	    archive_entry_size(entry) >= MULTI_EXTENT_SIZE) {
1543 		if (iso9660->opt.iso_level < 3) {
1544 			archive_set_error(&a->archive,
1545 			    ARCHIVE_ERRNO_MISC,
1546 			    "Ignore over %lld bytes file. "
1547 			    "This file too large.",
1548 			    MULTI_EXTENT_SIZE);
1549 				iso9660->cur_file = NULL;
1550 			return (ARCHIVE_WARN);
1551 		}
1552 		iso9660->need_multi_extent = 1;
1553 	}
1554 
1555 	file = isofile_new(a, entry);
1556 	if (file == NULL) {
1557 		archive_set_error(&a->archive, ENOMEM,
1558 		    "Can't allocate data");
1559 		return (ARCHIVE_FATAL);
1560 	}
1561 	r = isofile_gen_utility_names(a, file);
1562 	if (r < ARCHIVE_WARN) {
1563 		isofile_free(file);
1564 		return (r);
1565 	}
1566 	else if (r < ret)
1567 		ret = r;
1568 
1569 	/*
1570 	 * Ignore a path which looks like the top of directory name
1571 	 * since we have already made the root directory of an ISO image.
1572 	 */
1573 	if (archive_strlen(&(file->parentdir)) == 0 &&
1574 	    archive_strlen(&(file->basename)) == 0) {
1575 		isofile_free(file);
1576 		return (r);
1577 	}
1578 
1579 	isofile_add_entry(iso9660, file);
1580 	isoent = isoent_new(file);
1581 	if (isoent == NULL) {
1582 		archive_set_error(&a->archive, ENOMEM,
1583 		    "Can't allocate data");
1584 		return (ARCHIVE_FATAL);
1585 	}
1586 	if (isoent->file->dircnt > iso9660->dircnt_max)
1587 		iso9660->dircnt_max = isoent->file->dircnt;
1588 
1589 	/* Add the current file into tree */
1590 	r = isoent_tree(a, &isoent);
1591 	if (r != ARCHIVE_OK)
1592 		return (r);
1593 
1594 	/* If there is the same file in tree and
1595 	 * the current file is older than the file in tree.
1596 	 * So we don't need the current file data anymore. */
1597 	if (isoent->file != file)
1598 		return (ARCHIVE_OK);
1599 
1600 	/* Non regular files contents are unneeded to be saved to
1601 	 * temporary files. */
1602 	if (archive_entry_filetype(file->entry) != AE_IFREG)
1603 		return (ret);
1604 
1605 	/*
1606 	 * Set the current file to cur_file to read its contents.
1607 	 */
1608 	iso9660->cur_file = file;
1609 
1610 	if (archive_entry_nlink(file->entry) > 1) {
1611 		r = isofile_register_hardlink(a, file);
1612 		if (r != ARCHIVE_OK)
1613 			return (ARCHIVE_FATAL);
1614 	}
1615 
1616 	/*
1617 	 * Prepare to save the contents of the file.
1618 	 */
1619 	if (iso9660->temp_fd < 0) {
1620 		iso9660->temp_fd = __archive_mktemp(NULL);
1621 		if (iso9660->temp_fd < 0) {
1622 			archive_set_error(&a->archive, errno,
1623 			    "Couldn't create temporary file");
1624 			return (ARCHIVE_FATAL);
1625 		}
1626 	}
1627 
1628 	/* Save an offset of current file in temporary file. */
1629 	file->content.offset_of_temp = wb_offset(a);
1630 	file->cur_content = &(file->content);
1631 	r = zisofs_init(a, file);
1632 	if (r < ret)
1633 		ret = r;
1634 	iso9660->bytes_remaining =  archive_entry_size(file->entry);
1635 
1636 	return (ret);
1637 }
1638 
1639 static int
1640 write_to_temp(struct archive_write *a, const void *buff, size_t s)
1641 {
1642 	struct iso9660 *iso9660 = a->format_data;
1643 	ssize_t written;
1644 	const unsigned char *b;
1645 
1646 	b = (const unsigned char *)buff;
1647 	while (s) {
1648 		written = write(iso9660->temp_fd, b, s);
1649 		if (written < 0) {
1650 			archive_set_error(&a->archive, errno,
1651 			    "Can't write to temporary file");
1652 			return (ARCHIVE_FATAL);
1653 		}
1654 		s -= written;
1655 		b += written;
1656 	}
1657 	return (ARCHIVE_OK);
1658 }
1659 
1660 static int
1661 wb_write_to_temp(struct archive_write *a, const void *buff, size_t s)
1662 {
1663 	const char *xp = buff;
1664 	size_t xs = s;
1665 
1666 	/*
1667 	 * If a written data size is big enough to use system-call
1668 	 * and there is no waiting data, this calls write_to_temp() in
1669 	 * order to reduce a extra memory copy.
1670 	 */
1671 	if (wb_remaining(a) == wb_buffmax() && s > (1024 * 16)) {
1672 		struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
1673 		xs = s % LOGICAL_BLOCK_SIZE;
1674 		iso9660->wbuff_offset += s - xs;
1675 		if (write_to_temp(a, buff, s - xs) != ARCHIVE_OK)
1676 			return (ARCHIVE_FATAL);
1677 		if (xs == 0)
1678 			return (ARCHIVE_OK);
1679 		xp += s - xs;
1680 	}
1681 
1682 	while (xs) {
1683 		size_t size = xs;
1684 		if (size > wb_remaining(a))
1685 			size = wb_remaining(a);
1686 		memcpy(wb_buffptr(a), xp, size);
1687 		if (wb_consume(a, size) != ARCHIVE_OK)
1688 			return (ARCHIVE_FATAL);
1689 		xs -= size;
1690 		xp += size;
1691 	}
1692 	return (ARCHIVE_OK);
1693 }
1694 
1695 static int
1696 wb_write_padding_to_temp(struct archive_write *a, int64_t csize)
1697 {
1698 	size_t ns;
1699 	int ret;
1700 
1701 	ns = (size_t)(csize % LOGICAL_BLOCK_SIZE);
1702 	if (ns != 0)
1703 		ret = write_null(a, LOGICAL_BLOCK_SIZE - ns);
1704 	else
1705 		ret = ARCHIVE_OK;
1706 	return (ret);
1707 }
1708 
1709 static ssize_t
1710 write_iso9660_data(struct archive_write *a, const void *buff, size_t s)
1711 {
1712 	struct iso9660 *iso9660 = a->format_data;
1713 	size_t ws;
1714 
1715 	if (iso9660->temp_fd < 0) {
1716 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1717 		    "Couldn't create temporary file");
1718 		return (ARCHIVE_FATAL);
1719 	}
1720 
1721 	ws = s;
1722 	if (iso9660->need_multi_extent &&
1723 	    (iso9660->cur_file->cur_content->size + ws) >=
1724 	      (MULTI_EXTENT_SIZE - LOGICAL_BLOCK_SIZE)) {
1725 		struct content *con;
1726 		size_t ts;
1727 
1728 		ts = (size_t)(MULTI_EXTENT_SIZE - LOGICAL_BLOCK_SIZE -
1729 		    iso9660->cur_file->cur_content->size);
1730 
1731 		if (iso9660->zisofs.detect_magic)
1732 			zisofs_detect_magic(a, buff, ts);
1733 
1734 		if (iso9660->zisofs.making) {
1735 			if (zisofs_write_to_temp(a, buff, ts) != ARCHIVE_OK)
1736 				return (ARCHIVE_FATAL);
1737 		} else {
1738 			if (wb_write_to_temp(a, buff, ts) != ARCHIVE_OK)
1739 				return (ARCHIVE_FATAL);
1740 			iso9660->cur_file->cur_content->size += ts;
1741 		}
1742 
1743 		/* Write padding. */
1744 		if (wb_write_padding_to_temp(a,
1745 		    iso9660->cur_file->cur_content->size) != ARCHIVE_OK)
1746 			return (ARCHIVE_FATAL);
1747 
1748 		/* Compute the logical block number. */
1749 		iso9660->cur_file->cur_content->blocks = (int)
1750 		    ((iso9660->cur_file->cur_content->size
1751 		     + LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS);
1752 
1753 		/*
1754 		 * Make next extent.
1755 		 */
1756 		ws -= ts;
1757 		buff = (const void *)(((const unsigned char *)buff) + ts);
1758 		/* Make a content for next extent. */
1759 		con = calloc(1, sizeof(*con));
1760 		if (con == NULL) {
1761 			archive_set_error(&a->archive, ENOMEM,
1762 			    "Can't allocate content data");
1763 			return (ARCHIVE_FATAL);
1764 		}
1765 		con->offset_of_temp = wb_offset(a);
1766 		iso9660->cur_file->cur_content->next = con;
1767 		iso9660->cur_file->cur_content = con;
1768 #ifdef HAVE_ZLIB_H
1769 		iso9660->zisofs.block_offset = 0;
1770 #endif
1771 	}
1772 
1773 	if (iso9660->zisofs.detect_magic)
1774 		zisofs_detect_magic(a, buff, ws);
1775 
1776 	if (iso9660->zisofs.making) {
1777 		if (zisofs_write_to_temp(a, buff, ws) != ARCHIVE_OK)
1778 			return (ARCHIVE_FATAL);
1779 	} else {
1780 		if (wb_write_to_temp(a, buff, ws) != ARCHIVE_OK)
1781 			return (ARCHIVE_FATAL);
1782 		iso9660->cur_file->cur_content->size += ws;
1783 	}
1784 
1785 	return (s);
1786 }
1787 
1788 static ssize_t
1789 iso9660_write_data(struct archive_write *a, const void *buff, size_t s)
1790 {
1791 	struct iso9660 *iso9660 = a->format_data;
1792 	ssize_t r;
1793 
1794 	if (iso9660->cur_file == NULL)
1795 		return (0);
1796 	if (archive_entry_filetype(iso9660->cur_file->entry) != AE_IFREG)
1797 		return (0);
1798 	if (s > iso9660->bytes_remaining)
1799 		s = (size_t)iso9660->bytes_remaining;
1800 	if (s == 0)
1801 		return (0);
1802 
1803 	r = write_iso9660_data(a, buff, s);
1804 	if (r > 0)
1805 		iso9660->bytes_remaining -= r;
1806 	return (r);
1807 }
1808 
1809 static int
1810 iso9660_finish_entry(struct archive_write *a)
1811 {
1812 	struct iso9660 *iso9660 = a->format_data;
1813 
1814 	if (iso9660->cur_file == NULL)
1815 		return (ARCHIVE_OK);
1816 	if (archive_entry_filetype(iso9660->cur_file->entry) != AE_IFREG)
1817 		return (ARCHIVE_OK);
1818 	if (iso9660->cur_file->content.size == 0)
1819 		return (ARCHIVE_OK);
1820 
1821 	/* If there are unwritten data, write null data instead. */
1822 	while (iso9660->bytes_remaining > 0) {
1823 		size_t s;
1824 
1825 		s = (iso9660->bytes_remaining > a->null_length)?
1826 		    a->null_length: (size_t)iso9660->bytes_remaining;
1827 		if (write_iso9660_data(a, a->nulls, s) < 0)
1828 			return (ARCHIVE_FATAL);
1829 		iso9660->bytes_remaining -= s;
1830 	}
1831 
1832 	if (iso9660->zisofs.making && zisofs_finish_entry(a) != ARCHIVE_OK)
1833 		return (ARCHIVE_FATAL);
1834 
1835 	/* Write padding. */
1836 	if (wb_write_padding_to_temp(a, iso9660->cur_file->cur_content->size)
1837 	    != ARCHIVE_OK)
1838 		return (ARCHIVE_FATAL);
1839 
1840 	/* Compute the logical block number. */
1841 	iso9660->cur_file->cur_content->blocks = (int)
1842 	    ((iso9660->cur_file->cur_content->size
1843 	     + LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS);
1844 
1845 	/* Add the current file to data file list. */
1846 	isofile_add_data_file(iso9660, iso9660->cur_file);
1847 
1848 	return (ARCHIVE_OK);
1849 }
1850 
1851 static int
1852 iso9660_close(struct archive_write *a)
1853 {
1854 	struct iso9660 *iso9660;
1855 	int ret, blocks;
1856 
1857 	iso9660 = a->format_data;
1858 
1859 	/*
1860 	 * Write remaining data out to the temporary file.
1861 	 */
1862 	if (wb_remaining(a) > 0) {
1863 		ret = wb_write_out(a);
1864 		if (ret < 0)
1865 			return (ret);
1866 	}
1867 
1868 	/*
1869 	 * Preparations...
1870 	 */
1871 #ifdef DEBUG
1872 	if (iso9660->birth_time == 0)
1873 #endif
1874 		time(&(iso9660->birth_time));
1875 
1876 	/*
1877 	 * Prepare a bootable ISO image.
1878 	 */
1879 	if (iso9660->opt.boot) {
1880 		/* Find out the boot file entry. */
1881 		ret = isoent_find_out_boot_file(a, iso9660->primary.rootent);
1882 		if (ret < 0)
1883 			return (ret);
1884 		/* Reconvert the boot file from zisofs'ed form to
1885 		 * plain form. */
1886 		ret = zisofs_rewind_boot_file(a);
1887 		if (ret < 0)
1888 			return (ret);
1889 		/* Write remaining data out to the temporary file. */
1890 		if (wb_remaining(a) > 0) {
1891 			ret = wb_write_out(a);
1892 			if (ret < 0)
1893 				return (ret);
1894 		}
1895 		/* Create the boot catalog. */
1896 		ret = isoent_create_boot_catalog(a, iso9660->primary.rootent);
1897 		if (ret < 0)
1898 			return (ret);
1899 	}
1900 
1901 	/*
1902 	 * Prepare joliet extensions.
1903 	 */
1904 	if (iso9660->opt.joliet) {
1905 		/* Make a new tree for joliet. */
1906 		ret = isoent_clone_tree(a, &(iso9660->joliet.rootent),
1907 		    iso9660->primary.rootent);
1908 		if (ret < 0)
1909 			return (ret);
1910 		/* Make sure we have UTF-16BE converters.
1911 		 * if there is no file entry, converters are still
1912 		 * uninitialized. */
1913 		if (iso9660->sconv_to_utf16be == NULL) {
1914 			iso9660->sconv_to_utf16be =
1915 			    archive_string_conversion_to_charset(
1916 				&(a->archive), "UTF-16BE", 1);
1917 			if (iso9660->sconv_to_utf16be == NULL)
1918 				/* Couldn't allocate memory */
1919 				return (ARCHIVE_FATAL);
1920 			iso9660->sconv_from_utf16be =
1921 			    archive_string_conversion_from_charset(
1922 				&(a->archive), "UTF-16BE", 1);
1923 			if (iso9660->sconv_from_utf16be == NULL)
1924 				/* Couldn't allocate memory */
1925 				return (ARCHIVE_FATAL);
1926 		}
1927 	}
1928 
1929 	/*
1930 	 * Make Path Tables.
1931 	 */
1932 	ret = isoent_make_path_table(a);
1933 	if (ret < 0)
1934 		return (ret);
1935 
1936 	/*
1937 	 * Calculate a total volume size and setup all locations of
1938 	 * contents of an iso9660 image.
1939 	 */
1940 	blocks = SYSTEM_AREA_BLOCK
1941 		+ PRIMARY_VOLUME_DESCRIPTOR_BLOCK
1942 		+ VOLUME_DESCRIPTOR_SET_TERMINATOR_BLOCK
1943 		+ NON_ISO_FILE_SYSTEM_INFORMATION_BLOCK;
1944 	if (iso9660->opt.boot)
1945 		blocks += BOOT_RECORD_DESCRIPTOR_BLOCK;
1946 	if (iso9660->opt.joliet)
1947 		blocks += SUPPLEMENTARY_VOLUME_DESCRIPTOR_BLOCK;
1948 	if (iso9660->opt.iso_level == 4)
1949 		blocks += SUPPLEMENTARY_VOLUME_DESCRIPTOR_BLOCK;
1950 
1951 	/* Setup the locations of Path Table. */
1952 	iso9660->primary.location_type_L_path_table = blocks;
1953 	blocks += iso9660->primary.path_table_block;
1954 	iso9660->primary.location_type_M_path_table = blocks;
1955 	blocks += iso9660->primary.path_table_block;
1956 	if (iso9660->opt.joliet) {
1957 		iso9660->joliet.location_type_L_path_table = blocks;
1958 		blocks += iso9660->joliet.path_table_block;
1959 		iso9660->joliet.location_type_M_path_table = blocks;
1960 		blocks += iso9660->joliet.path_table_block;
1961 	}
1962 
1963 	/* Setup the locations of directories. */
1964 	isoent_setup_directory_location(iso9660, blocks,
1965 	    &(iso9660->primary));
1966 	blocks += iso9660->primary.total_dir_block;
1967 	if (iso9660->opt.joliet) {
1968 		isoent_setup_directory_location(iso9660, blocks,
1969 		    &(iso9660->joliet));
1970 		blocks += iso9660->joliet.total_dir_block;
1971 	}
1972 
1973 	if (iso9660->opt.rr) {
1974 		iso9660->location_rrip_er = blocks;
1975 		blocks += RRIP_ER_BLOCK;
1976 	}
1977 
1978 	/* Setup the locations of all file contents. */
1979  	isoent_setup_file_location(iso9660, blocks);
1980 	blocks += iso9660->total_file_block;
1981 	if (iso9660->opt.boot && iso9660->opt.boot_info_table) {
1982 		ret = setup_boot_information(a);
1983 		if (ret < 0)
1984 			return (ret);
1985 	}
1986 
1987 	/* Now we have a total volume size. */
1988 	iso9660->volume_space_size = blocks;
1989 	if (iso9660->opt.pad)
1990 		iso9660->volume_space_size += PADDING_BLOCK;
1991 	iso9660->volume_sequence_number = 1;
1992 
1993 
1994 	/*
1995 	 * Write an ISO 9660 image.
1996 	 */
1997 
1998 	/* Switch to start using wbuff as file buffer. */
1999 	iso9660->wbuff_remaining = wb_buffmax();
2000 	iso9660->wbuff_type = WB_TO_STREAM;
2001 	iso9660->wbuff_offset = 0;
2002 	iso9660->wbuff_written = 0;
2003 	iso9660->wbuff_tail = 0;
2004 
2005 	/* Write The System Area */
2006 	ret = write_null(a, SYSTEM_AREA_BLOCK * LOGICAL_BLOCK_SIZE);
2007 	if (ret != ARCHIVE_OK)
2008 		return (ARCHIVE_FATAL);
2009 
2010 	/* Write Primary Volume Descriptor */
2011 	ret = write_VD(a, &(iso9660->primary));
2012 	if (ret != ARCHIVE_OK)
2013 		return (ARCHIVE_FATAL);
2014 
2015 	if (iso9660->opt.boot) {
2016 		/* Write Boot Record Volume Descriptor */
2017 		ret = write_VD_boot_record(a);
2018 		if (ret != ARCHIVE_OK)
2019 			return (ARCHIVE_FATAL);
2020 	}
2021 
2022 	if (iso9660->opt.iso_level == 4) {
2023 		/* Write Enhanced Volume Descriptor */
2024 		iso9660->primary.vdd_type = VDD_ENHANCED;
2025 		ret = write_VD(a, &(iso9660->primary));
2026 		iso9660->primary.vdd_type = VDD_PRIMARY;
2027 		if (ret != ARCHIVE_OK)
2028 			return (ARCHIVE_FATAL);
2029 	}
2030 
2031 	if (iso9660->opt.joliet) {
2032 		ret = write_VD(a, &(iso9660->joliet));
2033 		if (ret != ARCHIVE_OK)
2034 			return (ARCHIVE_FATAL);
2035 	}
2036 
2037 	/* Write Volume Descriptor Set Terminator */
2038 	ret = write_VD_terminator(a);
2039 	if (ret != ARCHIVE_OK)
2040 		return (ARCHIVE_FATAL);
2041 
2042 	/* Write Non-ISO File System Information */
2043 	ret = write_information_block(a);
2044 	if (ret != ARCHIVE_OK)
2045 		return (ARCHIVE_FATAL);
2046 
2047 	/* Write Type L Path Table */
2048 	ret = write_path_table(a, 0, &(iso9660->primary));
2049 	if (ret != ARCHIVE_OK)
2050 		return (ARCHIVE_FATAL);
2051 
2052 	/* Write Type M Path Table */
2053 	ret = write_path_table(a, 1, &(iso9660->primary));
2054 	if (ret != ARCHIVE_OK)
2055 		return (ARCHIVE_FATAL);
2056 
2057 	if (iso9660->opt.joliet) {
2058 		/* Write Type L Path Table */
2059 		ret = write_path_table(a, 0, &(iso9660->joliet));
2060 		if (ret != ARCHIVE_OK)
2061 			return (ARCHIVE_FATAL);
2062 
2063 		/* Write Type M Path Table */
2064 		ret = write_path_table(a, 1, &(iso9660->joliet));
2065 		if (ret != ARCHIVE_OK)
2066 			return (ARCHIVE_FATAL);
2067 	}
2068 
2069 	/* Write Directory Descriptors */
2070 	ret = write_directory_descriptors(a, &(iso9660->primary));
2071 	if (ret != ARCHIVE_OK)
2072 		return (ARCHIVE_FATAL);
2073 
2074 	if (iso9660->opt.joliet) {
2075 		ret = write_directory_descriptors(a, &(iso9660->joliet));
2076 		if (ret != ARCHIVE_OK)
2077 			return (ARCHIVE_FATAL);
2078 	}
2079 
2080 	if (iso9660->opt.rr) {
2081 		/* Write Rockridge ER(Extensions Reference) */
2082 		ret = write_rr_ER(a);
2083 		if (ret != ARCHIVE_OK)
2084 			return (ARCHIVE_FATAL);
2085 	}
2086 
2087 	/* Write File Descriptors */
2088 	ret = write_file_descriptors(a);
2089 	if (ret != ARCHIVE_OK)
2090 		return (ARCHIVE_FATAL);
2091 
2092 	/* Write Padding  */
2093 	if (iso9660->opt.pad) {
2094 		ret = write_null(a, PADDING_BLOCK * LOGICAL_BLOCK_SIZE);
2095 		if (ret != ARCHIVE_OK)
2096 			return (ARCHIVE_FATAL);
2097 	}
2098 
2099 	if (iso9660->directories_too_deep != NULL) {
2100 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
2101 		    "%s: Directories too deep.",
2102 		    archive_entry_pathname(
2103 			iso9660->directories_too_deep->file->entry));
2104 		return (ARCHIVE_WARN);
2105 	}
2106 
2107 	/* Write remaining data out. */
2108 	ret = wb_write_out(a);
2109 
2110 	return (ret);
2111 }
2112 
2113 static int
2114 iso9660_free(struct archive_write *a)
2115 {
2116 	struct iso9660 *iso9660;
2117 	int i, ret;
2118 
2119 	iso9660 = a->format_data;
2120 
2121 	/* Close the temporary file. */
2122 	if (iso9660->temp_fd >= 0)
2123 		close(iso9660->temp_fd);
2124 
2125 	/* Free some stuff for zisofs operations. */
2126 	ret = zisofs_free(a);
2127 
2128 	/* Remove directory entries in tree which includes file entries. */
2129 	isoent_free_all(iso9660->primary.rootent);
2130 	for (i = 0; i < iso9660->primary.max_depth; i++)
2131 		free(iso9660->primary.pathtbl[i].sorted);
2132 	free(iso9660->primary.pathtbl);
2133 
2134 	if (iso9660->opt.joliet) {
2135 		isoent_free_all(iso9660->joliet.rootent);
2136 		for (i = 0; i < iso9660->joliet.max_depth; i++)
2137 			free(iso9660->joliet.pathtbl[i].sorted);
2138 		free(iso9660->joliet.pathtbl);
2139 	}
2140 
2141 	/* Remove isofile entries. */
2142 	isofile_free_all_entries(iso9660);
2143 	isofile_free_hardlinks(iso9660);
2144 
2145 	archive_string_free(&(iso9660->cur_dirstr));
2146 	archive_string_free(&(iso9660->volume_identifier));
2147 	archive_string_free(&(iso9660->publisher_identifier));
2148 	archive_string_free(&(iso9660->data_preparer_identifier));
2149 	archive_string_free(&(iso9660->application_identifier));
2150 	archive_string_free(&(iso9660->copyright_file_identifier));
2151 	archive_string_free(&(iso9660->abstract_file_identifier));
2152 	archive_string_free(&(iso9660->bibliographic_file_identifier));
2153 	archive_string_free(&(iso9660->el_torito.catalog_filename));
2154 	archive_string_free(&(iso9660->el_torito.boot_filename));
2155 	archive_string_free(&(iso9660->el_torito.id));
2156 	archive_string_free(&(iso9660->utf16be));
2157 	archive_string_free(&(iso9660->mbs));
2158 
2159 	free(iso9660);
2160 	a->format_data = NULL;
2161 
2162 	return (ret);
2163 }
2164 
2165 /*
2166  * Get the System Identifier
2167  */
2168 static void
2169 get_system_identitier(char *system_id, size_t size)
2170 {
2171 #if defined(HAVE_SYS_UTSNAME_H)
2172 	struct utsname u;
2173 
2174 	uname(&u);
2175 	strncpy(system_id, u.sysname, size-1);
2176 	system_id[size-1] = '\0';
2177 #elif defined(_WIN32) && !defined(__CYGWIN__)
2178 	strncpy(system_id, "Windows", size-1);
2179 	system_id[size-1] = '\0';
2180 #else
2181 #error no way to get the system identifier on your platform.
2182 #endif
2183 }
2184 
2185 static void
2186 set_str(unsigned char *p, const char *s, size_t l, char f, const char *map)
2187 {
2188 	unsigned char c;
2189 
2190 	if (s == NULL)
2191 		s = "";
2192 	while ((c = *s++) != 0 && l > 0) {
2193 		if (c >= 0x80 || map[c] == 0)
2194 		 {
2195 			/* illegal character */
2196 			if (c >= 'a' && c <= 'z') {
2197 				/* convert c from a-z to A-Z */
2198 				c -= 0x20;
2199 			} else
2200 				c = 0x5f;
2201 		}
2202 		*p++ = c;
2203 		l--;
2204 	}
2205 	/* If l isn't zero, fill p buffer by the character
2206 	 * which indicated by f. */
2207 	if (l > 0)
2208 		memset(p , f, l);
2209 }
2210 
2211 static inline int
2212 joliet_allowed_char(unsigned char high, unsigned char low)
2213 {
2214 	int utf16 = (high << 8) | low;
2215 
2216 	if (utf16 <= 0x001F)
2217 		return (0);
2218 
2219 	switch (utf16) {
2220 	case 0x002A: /* '*' */
2221 	case 0x002F: /* '/' */
2222 	case 0x003A: /* ':' */
2223 	case 0x003B: /* ';' */
2224 	case 0x003F: /* '?' */
2225 	case 0x005C: /* '\' */
2226 		return (0);/* Not allowed. */
2227 	}
2228 	return (1);
2229 }
2230 
2231 static int
2232 set_str_utf16be(struct archive_write *a, unsigned char *p, const char *s,
2233     size_t l, uint16_t uf, enum vdc vdc)
2234 {
2235 	size_t size, i;
2236 	int onepad;
2237 
2238 	if (s == NULL)
2239 		s = "";
2240 	if (l & 0x01) {
2241 		onepad = 1;
2242 		l &= ~1;
2243 	} else
2244 		onepad = 0;
2245 	if (vdc == VDC_UCS2) {
2246 		struct iso9660 *iso9660 = a->format_data;
2247 		if (archive_strncpy_l(&iso9660->utf16be, s, strlen(s),
2248 		    iso9660->sconv_to_utf16be) != 0 && errno == ENOMEM) {
2249 			archive_set_error(&a->archive, ENOMEM,
2250 			    "Can't allocate memory for UTF-16BE");
2251 			return (ARCHIVE_FATAL);
2252 		}
2253 		size = iso9660->utf16be.length;
2254 		if (size > l)
2255 			size = l;
2256 		memcpy(p, iso9660->utf16be.s, size);
2257 	} else {
2258 		const uint16_t *u16 = (const uint16_t *)s;
2259 
2260 		size = 0;
2261 		while (*u16++)
2262 			size += 2;
2263 		if (size > l)
2264 			size = l;
2265 		memcpy(p, s, size);
2266 	}
2267 	for (i = 0; i < size; i += 2, p += 2) {
2268 		if (!joliet_allowed_char(p[0], p[1]))
2269 			archive_be16enc(p, 0x005F);/* '_' */
2270 	}
2271 	l -= size;
2272 	while (l > 0) {
2273 		archive_be16enc(p, uf);
2274 		p += 2;
2275 		l -= 2;
2276 	}
2277 	if (onepad)
2278 		*p = 0;
2279 	return (ARCHIVE_OK);
2280 }
2281 
2282 static const char a_characters_map[0x80] = {
2283 /*  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F          */
2284     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
2285     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
2286     1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20-2F */
2287     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30-3F */
2288     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
2289     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
2290     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 60-6F */
2291     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 70-7F */
2292 };
2293 
2294 static const char a1_characters_map[0x80] = {
2295 /*  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F          */
2296     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
2297     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
2298     1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20-2F */
2299     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30-3F */
2300     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
2301     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
2302     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60-6F */
2303     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,/* 70-7F */
2304 };
2305 
2306 static const char d_characters_map[0x80] = {
2307 /*  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F          */
2308     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
2309     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
2310     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 20-2F */
2311     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,/* 30-3F */
2312     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
2313     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
2314     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 60-6F */
2315     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 70-7F */
2316 };
2317 
2318 static const char d1_characters_map[0x80] = {
2319 /*  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F          */
2320     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
2321     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
2322     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 20-2F */
2323     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,/* 30-3F */
2324     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
2325     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
2326     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60-6F */
2327     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,/* 70-7F */
2328 };
2329 
2330 static int
2331 set_str_a_characters_bp(struct archive_write *a, unsigned char *bp,
2332     int from, int to, const char *s, enum vdc vdc)
2333 {
2334 	int r;
2335 
2336 	switch (vdc) {
2337 	case VDC_STD:
2338 		set_str(bp+from, s, to - from + 1, 0x20,
2339 		    a_characters_map);
2340 		r = ARCHIVE_OK;
2341 		break;
2342 	case VDC_LOWERCASE:
2343 		set_str(bp+from, s, to - from + 1, 0x20,
2344 		    a1_characters_map);
2345 		r = ARCHIVE_OK;
2346 		break;
2347 	case VDC_UCS2:
2348 	case VDC_UCS2_DIRECT:
2349 		r = set_str_utf16be(a, bp+from, s, to - from + 1,
2350 		    0x0020, vdc);
2351 		break;
2352 	default:
2353 		r = ARCHIVE_FATAL;
2354 	}
2355 	return (r);
2356 }
2357 
2358 static int
2359 set_str_d_characters_bp(struct archive_write *a, unsigned char *bp,
2360     int from, int to, const char *s, enum  vdc vdc)
2361 {
2362 	int r;
2363 
2364 	switch (vdc) {
2365 	case VDC_STD:
2366 		set_str(bp+from, s, to - from + 1, 0x20,
2367 		    d_characters_map);
2368 		r = ARCHIVE_OK;
2369 		break;
2370 	case VDC_LOWERCASE:
2371 		set_str(bp+from, s, to - from + 1, 0x20,
2372 		    d1_characters_map);
2373 		r = ARCHIVE_OK;
2374 		break;
2375 	case VDC_UCS2:
2376 	case VDC_UCS2_DIRECT:
2377 		r = set_str_utf16be(a, bp+from, s, to - from + 1,
2378 		    0x0020, vdc);
2379 		break;
2380 	default:
2381 		r = ARCHIVE_FATAL;
2382 	}
2383 	return (r);
2384 }
2385 
2386 static void
2387 set_VD_bp(unsigned char *bp, enum VD_type type, unsigned char ver)
2388 {
2389 
2390 	/* Volume Descriptor Type */
2391 	bp[1] = (unsigned char)type;
2392 	/* Standard Identifier */
2393 	memcpy(bp + 2, "CD001", 5);
2394 	/* Volume Descriptor Version */
2395 	bp[7] = ver;
2396 }
2397 
2398 static inline void
2399 set_unused_field_bp(unsigned char *bp, int from, int to)
2400 {
2401 	memset(bp + from, 0, to - from + 1);
2402 }
2403 
2404 /*
2405  * 8-bit unsigned numerical values.
2406  * ISO9660 Standard 7.1.1
2407  */
2408 static inline void
2409 set_num_711(unsigned char *p, unsigned char value)
2410 {
2411 	*p = value;
2412 }
2413 
2414 /*
2415  * 8-bit signed numerical values.
2416  * ISO9660 Standard 7.1.2
2417  */
2418 static inline void
2419 set_num_712(unsigned char *p, char value)
2420 {
2421 	*((char *)p) = value;
2422 }
2423 
2424 /*
2425  * Least significant byte first.
2426  * ISO9660 Standard 7.2.1
2427  */
2428 static inline void
2429 set_num_721(unsigned char *p, uint16_t value)
2430 {
2431 	archive_le16enc(p, value);
2432 }
2433 
2434 /*
2435  * Most significant byte first.
2436  * ISO9660 Standard 7.2.2
2437  */
2438 static inline void
2439 set_num_722(unsigned char *p, uint16_t value)
2440 {
2441 	archive_be16enc(p, value);
2442 }
2443 
2444 /*
2445  * Both-byte orders.
2446  * ISO9660 Standard 7.2.3
2447  */
2448 static void
2449 set_num_723(unsigned char *p, uint16_t value)
2450 {
2451 	archive_le16enc(p, value);
2452 	archive_be16enc(p+2, value);
2453 }
2454 
2455 /*
2456  * Least significant byte first.
2457  * ISO9660 Standard 7.3.1
2458  */
2459 static inline void
2460 set_num_731(unsigned char *p, uint32_t value)
2461 {
2462 	archive_le32enc(p, value);
2463 }
2464 
2465 /*
2466  * Most significant byte first.
2467  * ISO9660 Standard 7.3.2
2468  */
2469 static inline void
2470 set_num_732(unsigned char *p, uint32_t value)
2471 {
2472 	archive_be32enc(p, value);
2473 }
2474 
2475 /*
2476  * Both-byte orders.
2477  * ISO9660 Standard 7.3.3
2478  */
2479 static inline void
2480 set_num_733(unsigned char *p, uint32_t value)
2481 {
2482 	archive_le32enc(p, value);
2483 	archive_be32enc(p+4, value);
2484 }
2485 
2486 static void
2487 set_digit(unsigned char *p, size_t s, int value)
2488 {
2489 
2490 	while (s--) {
2491 		p[s] = '0' + (value % 10);
2492 		value /= 10;
2493 	}
2494 }
2495 
2496 #if defined(HAVE_STRUCT_TM_TM_GMTOFF)
2497 #define get_gmoffset(tm)	((tm)->tm_gmtoff)
2498 #elif defined(HAVE_STRUCT_TM___TM_GMTOFF)
2499 #define get_gmoffset(tm)	((tm)->__tm_gmtoff)
2500 #else
2501 static long
2502 get_gmoffset(struct tm *tm)
2503 {
2504 	long offset;
2505 
2506 #if defined(HAVE__GET_TIMEZONE)
2507 	_get_timezone(&offset);
2508 #elif defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
2509 	offset = _timezone;
2510 #else
2511 	offset = timezone;
2512 #endif
2513 	offset *= -1;
2514 	if (tm->tm_isdst)
2515 		offset += 3600;
2516 	return (offset);
2517 }
2518 #endif
2519 
2520 static void
2521 get_tmfromtime(struct tm *tm, time_t *t)
2522 {
2523 #if HAVE_LOCALTIME_R
2524 	tzset();
2525 	localtime_r(t, tm);
2526 #elif HAVE__LOCALTIME64_S
2527 	__time64_t tmp_t = (__time64_t) *t; //time_t may be shorter than 64 bits
2528 	_localtime64_s(tm, &tmp_t);
2529 #else
2530 	memcpy(tm, localtime(t), sizeof(*tm));
2531 #endif
2532 }
2533 
2534 /*
2535  * Date and Time Format.
2536  * ISO9660 Standard 8.4.26.1
2537  */
2538 static void
2539 set_date_time(unsigned char *p, time_t t)
2540 {
2541 	struct tm tm;
2542 
2543 	get_tmfromtime(&tm, &t);
2544 	set_digit(p, 4, tm.tm_year + 1900);
2545 	set_digit(p+4, 2, tm.tm_mon + 1);
2546 	set_digit(p+6, 2, tm.tm_mday);
2547 	set_digit(p+8, 2, tm.tm_hour);
2548 	set_digit(p+10, 2, tm.tm_min);
2549 	set_digit(p+12, 2, tm.tm_sec);
2550 	set_digit(p+14, 2, 0);
2551 	set_num_712(p+16, (char)(get_gmoffset(&tm)/(60*15)));
2552 }
2553 
2554 static void
2555 set_date_time_null(unsigned char *p)
2556 {
2557 	memset(p, (int)'0', 16);
2558 	p[16] = 0;
2559 }
2560 
2561 static void
2562 set_time_915(unsigned char *p, time_t t)
2563 {
2564 	struct tm tm;
2565 
2566 	get_tmfromtime(&tm, &t);
2567 	set_num_711(p+0, tm.tm_year);
2568 	set_num_711(p+1, tm.tm_mon+1);
2569 	set_num_711(p+2, tm.tm_mday);
2570 	set_num_711(p+3, tm.tm_hour);
2571 	set_num_711(p+4, tm.tm_min);
2572 	set_num_711(p+5, tm.tm_sec);
2573 	set_num_712(p+6, (char)(get_gmoffset(&tm)/(60*15)));
2574 }
2575 
2576 
2577 /*
2578  * Write SUSP "CE" System Use Entry.
2579  */
2580 static int
2581 set_SUSP_CE(unsigned char *p, int location, int offset, int size)
2582 {
2583 	unsigned char *bp = p -1;
2584 	/*  Extend the System Use Area
2585 	 *   "CE" Format:
2586 	 *               len  ver
2587 	 *    +----+----+----+----+-----------+-----------+
2588 	 *    | 'C'| 'E'| 1C | 01 | LOCATION1 | LOCATION2 |
2589 	 *    +----+----+----+----+-----------+-----------+
2590 	 *    0    1    2    3    4          12          20
2591 	 *    +-----------+
2592 	 *    | LOCATION3 |
2593 	 *    +-----------+
2594 	 *   20          28
2595 	 *   LOCATION1 : Location of Continuation of System Use Area.
2596 	 *   LOCATION2 : Offset to Start of Continuation.
2597 	 *   LOCATION3 : Length of the Continuation.
2598 	 */
2599 
2600 	bp[1] = 'C';
2601 	bp[2] = 'E';
2602 	bp[3] = RR_CE_SIZE;	/* length	*/
2603 	bp[4] = 1;		/* version	*/
2604 	set_num_733(bp+5, location);
2605 	set_num_733(bp+13, offset);
2606 	set_num_733(bp+21, size);
2607 	return (RR_CE_SIZE);
2608 }
2609 
2610 /*
2611  * The functions, which names are beginning with extra_, are used to
2612  * control extra records.
2613  * The maximum size of a Directory Record is 254. When a filename is
2614  * very long, all of RRIP data of a file won't stored to the Directory
2615  * Record and so remaining RRIP data store to an extra record instead.
2616  */
2617 static unsigned char *
2618 extra_open_record(unsigned char *bp, int dr_len, struct isoent *isoent,
2619     struct ctl_extr_rec *ctl)
2620 {
2621 	ctl->bp = bp;
2622 	if (bp != NULL)
2623 		bp += dr_len;
2624 	ctl->use_extr = 0;
2625 	ctl->isoent = isoent;
2626 	ctl->ce_ptr = NULL;
2627 	ctl->cur_len = ctl->dr_len = dr_len;
2628 	ctl->limit = DR_LIMIT;
2629 
2630 	return (bp);
2631 }
2632 
2633 static void
2634 extra_close_record(struct ctl_extr_rec *ctl, int ce_size)
2635 {
2636 	int padding = 0;
2637 
2638 	if (ce_size > 0)
2639 		extra_tell_used_size(ctl, ce_size);
2640 	/* Padding. */
2641 	if (ctl->cur_len & 0x01) {
2642 		ctl->cur_len++;
2643 		if (ctl->bp != NULL)
2644 			ctl->bp[ctl->cur_len] = 0;
2645 		padding = 1;
2646 	}
2647 	if (ctl->use_extr) {
2648 		if (ctl->ce_ptr != NULL)
2649 			set_SUSP_CE(ctl->ce_ptr, ctl->extr_loc,
2650 			    ctl->extr_off, ctl->cur_len - padding);
2651 	} else
2652 		ctl->dr_len = ctl->cur_len;
2653 }
2654 
2655 #define extra_space(ctl)	((ctl)->limit - (ctl)->cur_len)
2656 
2657 static unsigned char *
2658 extra_next_record(struct ctl_extr_rec *ctl, int length)
2659 {
2660 	int cur_len = ctl->cur_len;/* save cur_len */
2661 
2662 	/* Close the current extra record or Directory Record. */
2663 	extra_close_record(ctl, RR_CE_SIZE);
2664 
2665 	/* Get a next extra record. */
2666 	ctl->use_extr = 1;
2667 	if (ctl->bp != NULL) {
2668 		/* Storing data into an extra record. */
2669 		unsigned char *p;
2670 
2671 		/* Save the pointer where a CE extension will be
2672 		 * stored to. */
2673 		ctl->ce_ptr = &ctl->bp[cur_len+1];
2674 		p = extra_get_record(ctl->isoent,
2675 		    &ctl->limit, &ctl->extr_off, &ctl->extr_loc);
2676 		ctl->bp = p - 1;/* the base of bp offset is 1. */
2677 	} else
2678 		/* Calculating the size of an extra record. */
2679 		(void)extra_get_record(ctl->isoent,
2680 		    &ctl->limit, NULL, NULL);
2681 	ctl->cur_len = 0;
2682 	/* Check if an extra record is almost full.
2683 	 * If so, get a next one. */
2684 	if (extra_space(ctl) < length)
2685 		(void)extra_next_record(ctl, length);
2686 
2687 	return (ctl->bp);
2688 }
2689 
2690 static inline struct extr_rec *
2691 extra_last_record(struct isoent *isoent)
2692 {
2693 	if (isoent->extr_rec_list.first == NULL)
2694 		return (NULL);
2695 	return ((struct extr_rec *)(void *)
2696 		((char *)(isoent->extr_rec_list.last)
2697 		    - offsetof(struct extr_rec, next)));
2698 }
2699 
2700 static unsigned char *
2701 extra_get_record(struct isoent *isoent, int *space, int *off, int *loc)
2702 {
2703 	struct extr_rec *rec;
2704 
2705 	isoent = isoent->parent;
2706 	if (off != NULL) {
2707 		/* Storing data into an extra record. */
2708 		rec = isoent->extr_rec_list.current;
2709 		if (DR_SAFETY > LOGICAL_BLOCK_SIZE - rec->offset)
2710 			rec = rec->next;
2711 	} else {
2712 		/* Calculating the size of an extra record. */
2713 		rec = extra_last_record(isoent);
2714 		if (rec == NULL ||
2715 		    DR_SAFETY > LOGICAL_BLOCK_SIZE - rec->offset) {
2716 			rec = malloc(sizeof(*rec));
2717 			if (rec == NULL)
2718 				return (NULL);
2719 			rec->location = 0;
2720 			rec->offset = 0;
2721 			/* Insert `rec` into the tail of isoent->extr_rec_list */
2722 			rec->next = NULL;
2723 			/*
2724 			 * Note: testing isoent->extr_rec_list.last == NULL
2725 			 * here is really unneeded since it has been already
2726 			 * initialized at isoent_new function but Clang Static
2727 			 * Analyzer claims that it is dereference of null
2728 			 * pointer.
2729 			 */
2730 			if (isoent->extr_rec_list.last == NULL)
2731 				isoent->extr_rec_list.last =
2732 					&(isoent->extr_rec_list.first);
2733 			*isoent->extr_rec_list.last = rec;
2734 			isoent->extr_rec_list.last = &(rec->next);
2735 		}
2736 	}
2737 	*space = LOGICAL_BLOCK_SIZE - rec->offset - DR_SAFETY;
2738 	if (*space & 0x01)
2739 		*space -= 1;/* Keep padding space. */
2740 	if (off != NULL)
2741 		*off = rec->offset;
2742 	if (loc != NULL)
2743 		*loc = rec->location;
2744 	isoent->extr_rec_list.current = rec;
2745 
2746 	return (&rec->buf[rec->offset]);
2747 }
2748 
2749 static void
2750 extra_tell_used_size(struct ctl_extr_rec *ctl, int size)
2751 {
2752 	struct isoent *isoent;
2753 	struct extr_rec *rec;
2754 
2755 	if (ctl->use_extr) {
2756 		isoent = ctl->isoent->parent;
2757 		rec = isoent->extr_rec_list.current;
2758 		if (rec != NULL)
2759 			rec->offset += size;
2760 	}
2761 	ctl->cur_len += size;
2762 }
2763 
2764 static int
2765 extra_setup_location(struct isoent *isoent, int location)
2766 {
2767 	struct extr_rec *rec;
2768 	int cnt;
2769 
2770 	cnt = 0;
2771 	rec = isoent->extr_rec_list.first;
2772 	isoent->extr_rec_list.current = rec;
2773 	while (rec) {
2774 		cnt++;
2775 		rec->location = location++;
2776 		rec->offset = 0;
2777 		rec = rec->next;
2778 	}
2779 	return (cnt);
2780 }
2781 
2782 /*
2783  * Create the RRIP entries.
2784  */
2785 static int
2786 set_directory_record_rr(unsigned char *bp, int dr_len,
2787     struct isoent *isoent, struct iso9660 *iso9660, enum dir_rec_type t)
2788 {
2789 	/* Flags(BP 5) of the Rockridge "RR" System Use Field */
2790 	unsigned char rr_flag;
2791 #define RR_USE_PX	0x01
2792 #define RR_USE_PN	0x02
2793 #define RR_USE_SL	0x04
2794 #define RR_USE_NM	0x08
2795 #define RR_USE_CL	0x10
2796 #define RR_USE_PL	0x20
2797 #define RR_USE_RE	0x40
2798 #define RR_USE_TF	0x80
2799 	int length;
2800 	struct ctl_extr_rec ctl;
2801 	struct isoent *rr_parent, *pxent;
2802 	struct isofile *file;
2803 
2804 	bp = extra_open_record(bp, dr_len, isoent, &ctl);
2805 
2806 	if (t == DIR_REC_PARENT) {
2807 		rr_parent = isoent->rr_parent;
2808 		pxent = isoent->parent;
2809 		if (rr_parent != NULL)
2810 			isoent = rr_parent;
2811 		else
2812 			isoent = isoent->parent;
2813 	} else {
2814 		rr_parent = NULL;
2815 		pxent = isoent;
2816 	}
2817 	file = isoent->file;
2818 
2819 	if (t != DIR_REC_NORMAL) {
2820 		rr_flag = RR_USE_PX | RR_USE_TF;
2821 		if (rr_parent != NULL)
2822 			rr_flag |= RR_USE_PL;
2823 	} else {
2824 		rr_flag = RR_USE_PX | RR_USE_NM | RR_USE_TF;
2825 		if (archive_entry_filetype(file->entry) == AE_IFLNK)
2826 			rr_flag |= RR_USE_SL;
2827 		if (isoent->rr_parent != NULL)
2828 			rr_flag |= RR_USE_RE;
2829 		if (isoent->rr_child != NULL)
2830 			rr_flag |= RR_USE_CL;
2831 		if (archive_entry_filetype(file->entry) == AE_IFCHR ||
2832 		    archive_entry_filetype(file->entry) == AE_IFBLK)
2833 			rr_flag |= RR_USE_PN;
2834 #ifdef COMPAT_MKISOFS
2835 		/*
2836 		 * mkisofs 2.01.01a63 records "RE" extension to
2837 		 * the entry of "rr_moved" directory.
2838 		 * I don't understand this behavior.
2839 		 */
2840 		if (isoent->virtual &&
2841 		    isoent->parent == iso9660->primary.rootent &&
2842 		    strcmp(isoent->file->basename.s, "rr_moved") == 0)
2843 			rr_flag |= RR_USE_RE;
2844 #endif
2845 	}
2846 
2847 	/* Write "SP" System Use Entry. */
2848 	if (t == DIR_REC_SELF && isoent == isoent->parent) {
2849 		length = 7;
2850 		if (bp != NULL) {
2851 			bp[1] = 'S';
2852 			bp[2] = 'P';
2853 			bp[3] = length;
2854 			bp[4] = 1;	/* version	*/
2855 			bp[5] = 0xBE;  /* Check Byte	*/
2856 			bp[6] = 0xEF;  /* Check Byte	*/
2857 			bp[7] = 0;
2858 			bp += length;
2859 		}
2860 		extra_tell_used_size(&ctl, length);
2861 	}
2862 
2863 	/* Write "RR" System Use Entry. */
2864 	length = 5;
2865 	if (extra_space(&ctl) < length)
2866 		bp = extra_next_record(&ctl, length);
2867 	if (bp != NULL) {
2868 		bp[1] = 'R';
2869 		bp[2] = 'R';
2870 		bp[3] = length;
2871 		bp[4] = 1;	/* version */
2872 		bp[5] = rr_flag;
2873 		bp += length;
2874 	}
2875 	extra_tell_used_size(&ctl, length);
2876 
2877 	/* Write "NM" System Use Entry. */
2878 	if (rr_flag & RR_USE_NM) {
2879 		/*
2880 		 *   "NM" Format:
2881 		 *     e.g. a basename is 'foo'
2882 		 *               len  ver  flg
2883 		 *    +----+----+----+----+----+----+----+----+
2884 		 *    | 'N'| 'M'| 08 | 01 | 00 | 'f'| 'o'| 'o'|
2885 		 *    +----+----+----+----+----+----+----+----+
2886 		 *    <----------------- len ----------------->
2887 		 */
2888 		size_t nmlen = file->basename.length;
2889 		const char *nm = file->basename.s;
2890 		size_t nmmax;
2891 
2892 		if (extra_space(&ctl) < 6)
2893 			bp = extra_next_record(&ctl, 6);
2894 		if (bp != NULL) {
2895 			bp[1] = 'N';
2896 			bp[2] = 'M';
2897 			bp[4] = 1;	    /* version	*/
2898 		}
2899 		nmmax = extra_space(&ctl);
2900 		if (nmmax > 0xff)
2901 			nmmax = 0xff;
2902 		while (nmlen + 5 > nmmax) {
2903 			length = (int)nmmax;
2904 			if (bp != NULL) {
2905 				bp[3] = length;
2906 				bp[5] = 0x01;/* Alternate Name continues
2907 					       * in next "NM" field */
2908 				memcpy(bp+6, nm, length - 5);
2909 				bp += length;
2910 			}
2911 			nmlen -= length - 5;
2912 			nm += length - 5;
2913 			extra_tell_used_size(&ctl, length);
2914 			if (extra_space(&ctl) < 6) {
2915 				bp = extra_next_record(&ctl, 6);
2916 				nmmax = extra_space(&ctl);
2917 				if (nmmax > 0xff)
2918 					nmmax = 0xff;
2919 			}
2920 			if (bp != NULL) {
2921 				bp[1] = 'N';
2922 				bp[2] = 'M';
2923 				bp[4] = 1;    /* version */
2924 			}
2925 		}
2926 		length = 5 + (int)nmlen;
2927 		if (bp != NULL) {
2928 			bp[3] = length;
2929 			bp[5] = 0;
2930 			memcpy(bp+6, nm, nmlen);
2931 			bp += length;
2932 		}
2933 		extra_tell_used_size(&ctl, length);
2934 	}
2935 
2936 	/* Write "PX" System Use Entry. */
2937 	if (rr_flag & RR_USE_PX) {
2938 		/*
2939 		 *   "PX" Format:
2940 		 *               len  ver
2941 		 *    +----+----+----+----+-----------+-----------+
2942 		 *    | 'P'| 'X'| 2C | 01 | FILE MODE |   LINKS   |
2943 		 *    +----+----+----+----+-----------+-----------+
2944 		 *    0    1    2    3    4          12          20
2945 		 *    +-----------+-----------+------------------+
2946 		 *    |  USER ID  | GROUP ID  |FILE SERIAL NUMBER|
2947 		 *    +-----------+-----------+------------------+
2948 		 *   20          28          36                 44
2949 		 */
2950 		length = 44;
2951 		if (extra_space(&ctl) < length)
2952 			bp = extra_next_record(&ctl, length);
2953 		if (bp != NULL) {
2954 			mode_t mode;
2955 			int64_t uid;
2956 			int64_t gid;
2957 
2958 			mode = archive_entry_mode(file->entry);
2959 			uid = archive_entry_uid(file->entry);
2960 			gid = archive_entry_gid(file->entry);
2961 			if (iso9660->opt.rr == OPT_RR_USEFUL) {
2962 				/*
2963 				 * This action is similar to mkisofs -r option
2964 				 * but our rockridge=useful option does not
2965 				 * set a zero to uid and gid.
2966 				 */
2967 				/* set all read bit ON */
2968 				mode |= 0444;
2969 #if !defined(_WIN32) && !defined(__CYGWIN__)
2970 				if (mode & 0111)
2971 #endif
2972 					/* set all exec bit ON */
2973 					mode |= 0111;
2974 				/* clear all write bits. */
2975 				mode &= ~0222;
2976 				/* clear setuid,setgid,sticky bits. */
2977 				mode &= ~07000;
2978 			}
2979 
2980 			bp[1] = 'P';
2981 			bp[2] = 'X';
2982 			bp[3] = length;
2983 			bp[4] = 1;	/* version	*/
2984 			/* file mode */
2985 			set_num_733(bp+5, mode);
2986 			/* file links (stat.st_nlink) */
2987 			set_num_733(bp+13,
2988 			    archive_entry_nlink(file->entry));
2989 			set_num_733(bp+21, (uint32_t)uid);
2990 			set_num_733(bp+29, (uint32_t)gid);
2991 			/* File Serial Number */
2992 			if (pxent->dir)
2993 				set_num_733(bp+37, pxent->dir_location);
2994 			else if (file->hardlink_target != NULL)
2995 				set_num_733(bp+37,
2996 				    file->hardlink_target->cur_content->location);
2997 			else
2998 				set_num_733(bp+37,
2999 				    file->cur_content->location);
3000 			bp += length;
3001 		}
3002 		extra_tell_used_size(&ctl, length);
3003 	}
3004 
3005 	/* Write "SL" System Use Entry. */
3006 	if (rr_flag & RR_USE_SL) {
3007 		/*
3008 		 *   "SL" Format:
3009 		 *     e.g. a symbolic name is 'foo/bar'
3010 		 *               len  ver  flg
3011 		 *    +----+----+----+----+----+------------+
3012 		 *    | 'S'| 'L'| 0F | 01 | 00 | components |
3013 		 *    +----+----+----+----+----+-----+------+
3014 		 *    0    1    2    3    4    5  ...|...  15
3015 		 *    <----------------- len --------+------>
3016 		 *    components :                   |
3017 		 *     cflg clen                     |
3018 		 *    +----+----+----+----+----+     |
3019 		 *    | 00 | 03 | 'f'| 'o'| 'o'| <---+
3020 		 *    +----+----+----+----+----+     |
3021 		 *    5    6    7    8    9   10     |
3022 		 *     cflg clen                     |
3023 		 *    +----+----+----+----+----+     |
3024 		 *    | 00 | 03 | 'b'| 'a'| 'r'| <---+
3025 		 *    +----+----+----+----+----+
3026 		 *   10   11   12   13   14   15
3027 		 *
3028 		 *    - cflg : flag of component
3029 		 *    - clen : length of component
3030 		 */
3031 		const char *sl;
3032 		char sl_last;
3033 
3034 		if (extra_space(&ctl) < 7)
3035 			bp = extra_next_record(&ctl, 7);
3036 		sl = file->symlink.s;
3037 		sl_last = '\0';
3038 		if (bp != NULL) {
3039 			bp[1] = 'S';
3040 			bp[2] = 'L';
3041 			bp[4] = 1;	/* version	*/
3042 		}
3043 		for (;;) {
3044 			unsigned char *nc, *cf,  *cl, cldmy = 0;
3045 			int sllen, slmax;
3046 
3047 			slmax = extra_space(&ctl);
3048 			if (slmax > 0xff)
3049 				slmax = 0xff;
3050 			if (bp != NULL)
3051 				nc = &bp[6];
3052 			else
3053 				nc = NULL;
3054 			cf = cl = NULL;
3055 			sllen = 0;
3056 			while (*sl && sllen + 11 < slmax) {
3057 				if (sl_last == '\0' && sl[0] == '/') {
3058 					/*
3059 					 *     flg  len
3060 					 *    +----+----+
3061 					 *    | 08 | 00 | ROOT component.
3062 					 *    +----+----+ ("/")
3063 					 *
3064 				 	 * Root component has to appear
3065 				 	 * at the first component only.
3066 					 */
3067 					if (nc != NULL) {
3068 						cf = nc++;
3069 						*cf = 0x08; /* ROOT */
3070 						*nc++ = 0;
3071 					}
3072 					sllen += 2;
3073 					sl++;
3074 					sl_last = '/';
3075 					cl = NULL;
3076 					continue;
3077 				}
3078 				if (((sl_last == '\0' || sl_last == '/') &&
3079 				      sl[0] == '.' && sl[1] == '.' &&
3080 				     (sl[2] == '/' || sl[2] == '\0')) ||
3081 				    (sl[0] == '/' &&
3082 				      sl[1] == '.' && sl[2] == '.' &&
3083 				     (sl[3] == '/' || sl[3] == '\0'))) {
3084 					/*
3085 					 *     flg  len
3086 					 *    +----+----+
3087 					 *    | 04 | 00 | PARENT component.
3088 					 *    +----+----+ ("..")
3089 					 */
3090 					if (nc != NULL) {
3091 						cf = nc++;
3092 						*cf = 0x04; /* PARENT */
3093 						*nc++ = 0;
3094 					}
3095 					sllen += 2;
3096 					if (sl[0] == '/')
3097 						sl += 3;/* skip "/.." */
3098 					else
3099 						sl += 2;/* skip ".." */
3100 					sl_last = '.';
3101 					cl = NULL;
3102 					continue;
3103 				}
3104 				if (((sl_last == '\0' || sl_last == '/') &&
3105 				      sl[0] == '.' &&
3106 				     (sl[1] == '/' || sl[1] == '\0')) ||
3107 				    (sl[0] == '/' && sl[1] == '.' &&
3108 				     (sl[2] == '/' || sl[2] == '\0'))) {
3109 					/*
3110 					 *     flg  len
3111 					 *    +----+----+
3112 					 *    | 02 | 00 | CURRENT component.
3113 					 *    +----+----+ (".")
3114 					 */
3115 					if (nc != NULL) {
3116 						cf = nc++;
3117 						*cf = 0x02; /* CURRENT */
3118 						*nc++ = 0;
3119 					}
3120 					sllen += 2;
3121 					if (sl[0] == '/')
3122 						sl += 2;/* skip "/." */
3123 					else
3124 						sl ++;  /* skip "." */
3125 					sl_last = '.';
3126 					cl = NULL;
3127 					continue;
3128 				}
3129 				if (sl[0] == '/' || cl == NULL) {
3130 					if (nc != NULL) {
3131 						cf = nc++;
3132 						*cf = 0;
3133 						cl = nc++;
3134 						*cl = 0;
3135 					} else
3136 						cl = &cldmy;
3137 					sllen += 2;
3138 					if (sl[0] == '/') {
3139 						sl_last = *sl++;
3140 						continue;
3141 					}
3142 				}
3143 				sl_last = *sl++;
3144 				if (nc != NULL) {
3145 					*nc++ = sl_last;
3146 					(*cl) ++;
3147 				}
3148 				sllen++;
3149 			}
3150 			if (*sl) {
3151 				length = 5 + sllen;
3152 				if (bp != NULL) {
3153 					/*
3154 					 * Mark flg as CONTINUE component.
3155 					 */
3156 					*cf |= 0x01;
3157 					/*
3158 					 *               len  ver  flg
3159 					 *    +----+----+----+----+----+-
3160 					 *    | 'S'| 'L'| XX | 01 | 01 |
3161 					 *    +----+----+----+----+----+-
3162 					 *                           ^
3163 					 *           continues in next "SL"
3164 					 */
3165 					bp[3] = length;
3166 					bp[5] = 0x01;/* This Symbolic Link
3167 						      * continues in next
3168 						      * "SL" field */
3169 					bp += length;
3170 				}
3171 				extra_tell_used_size(&ctl, length);
3172 				if (extra_space(&ctl) < 11)
3173 					bp = extra_next_record(&ctl, 11);
3174 				if (bp != NULL) {
3175 					/* Next 'SL' */
3176 					bp[1] = 'S';
3177 					bp[2] = 'L';
3178 					bp[4] = 1;    /* version */
3179 				}
3180 			} else {
3181 				length = 5 + sllen;
3182 				if (bp != NULL) {
3183 					bp[3] = length;
3184 					bp[5] = 0;
3185 					bp += length;
3186 				}
3187 				extra_tell_used_size(&ctl, length);
3188 				break;
3189 			}
3190 		}
3191 	}
3192 
3193 	/* Write "TF" System Use Entry. */
3194 	if (rr_flag & RR_USE_TF) {
3195 		/*
3196 		 *   "TF" Format:
3197 		 *               len  ver
3198 		 *    +----+----+----+----+-----+-------------+
3199 		 *    | 'T'| 'F'| XX | 01 |FLAGS| TIME STAMPS |
3200 		 *    +----+----+----+----+-----+-------------+
3201 		 *    0    1    2    3    4     5            XX
3202 		 *    TIME STAMPS : ISO 9660 Standard 9.1.5.
3203 		 *                  If TF_LONG_FORM FLAGS is set,
3204 		 *                  use ISO9660 Standard 8.4.26.1.
3205 		 */
3206 #define TF_CREATION	0x01	/* Creation time recorded		*/
3207 #define TF_MODIFY	0x02	/* Modification time recorded		*/
3208 #define TF_ACCESS	0x04	/* Last Access time recorded		*/
3209 #define TF_ATTRIBUTES	0x08	/* Last Attribute Change time recorded  */
3210 #define TF_BACKUP	0x10	/* Last Backup time recorded		*/
3211 #define TF_EXPIRATION	0x20	/* Expiration time recorded		*/
3212 #define TF_EFFECTIVE	0x40	/* Effective time recorded		*/
3213 #define TF_LONG_FORM	0x80	/* ISO 9660 17-byte time format used	*/
3214 		unsigned char tf_flags;
3215 
3216 		length = 5;
3217 		tf_flags = 0;
3218 #ifndef COMPAT_MKISOFS
3219 		if (archive_entry_birthtime_is_set(file->entry) &&
3220 		    archive_entry_birthtime(file->entry) <=
3221 		    archive_entry_mtime(file->entry)) {
3222 			length += 7;
3223 			tf_flags |= TF_CREATION;
3224 		}
3225 #endif
3226 		if (archive_entry_mtime_is_set(file->entry)) {
3227 			length += 7;
3228 			tf_flags |= TF_MODIFY;
3229 		}
3230 		if (archive_entry_atime_is_set(file->entry)) {
3231 			length += 7;
3232 			tf_flags |= TF_ACCESS;
3233 		}
3234 		if (archive_entry_ctime_is_set(file->entry)) {
3235 			length += 7;
3236 			tf_flags |= TF_ATTRIBUTES;
3237 		}
3238 		if (extra_space(&ctl) < length)
3239 			bp = extra_next_record(&ctl, length);
3240 		if (bp != NULL) {
3241 			bp[1] = 'T';
3242 			bp[2] = 'F';
3243 			bp[3] = length;
3244 			bp[4] = 1;	/* version	*/
3245 			bp[5] = tf_flags;
3246 			bp += 5;
3247 			/* Creation time */
3248 			if (tf_flags & TF_CREATION) {
3249 				set_time_915(bp+1,
3250 				    archive_entry_birthtime(file->entry));
3251 				bp += 7;
3252 			}
3253 			/* Modification time */
3254 			if (tf_flags & TF_MODIFY) {
3255 				set_time_915(bp+1,
3256 				    archive_entry_mtime(file->entry));
3257 				bp += 7;
3258 			}
3259 			/* Last Access time */
3260 			if (tf_flags & TF_ACCESS) {
3261 				set_time_915(bp+1,
3262 				    archive_entry_atime(file->entry));
3263 				bp += 7;
3264 			}
3265 			/* Last Attribute Change time */
3266 			if (tf_flags & TF_ATTRIBUTES) {
3267 				set_time_915(bp+1,
3268 				    archive_entry_ctime(file->entry));
3269 				bp += 7;
3270 			}
3271 		}
3272 		extra_tell_used_size(&ctl, length);
3273 	}
3274 
3275 	/* Write "RE" System Use Entry. */
3276 	if (rr_flag & RR_USE_RE) {
3277 		/*
3278 		 *   "RE" Format:
3279 		 *               len  ver
3280 		 *    +----+----+----+----+
3281 		 *    | 'R'| 'E'| 04 | 01 |
3282 		 *    +----+----+----+----+
3283 		 *    0    1    2    3    4
3284 		 */
3285 		length = 4;
3286 		if (extra_space(&ctl) < length)
3287 			bp = extra_next_record(&ctl, length);
3288 		if (bp != NULL) {
3289 			bp[1] = 'R';
3290 			bp[2] = 'E';
3291 			bp[3] = length;
3292 			bp[4] = 1;	/* version	*/
3293 			bp += length;
3294 		}
3295 		extra_tell_used_size(&ctl, length);
3296 	}
3297 
3298 	/* Write "PL" System Use Entry. */
3299 	if (rr_flag & RR_USE_PL) {
3300 		/*
3301 		 *   "PL" Format:
3302 		 *               len  ver
3303 		 *    +----+----+----+----+------------+
3304 		 *    | 'P'| 'L'| 0C | 01 | *LOCATION  |
3305 		 *    +----+----+----+----+------------+
3306 		 *    0    1    2    3    4           12
3307 		 *    *LOCATION: location of parent directory
3308 		 */
3309 		length = 12;
3310 		if (extra_space(&ctl) < length)
3311 			bp = extra_next_record(&ctl, length);
3312 		if (bp != NULL) {
3313 			bp[1] = 'P';
3314 			bp[2] = 'L';
3315 			bp[3] = length;
3316 			bp[4] = 1;	/* version	*/
3317 			set_num_733(bp + 5,
3318 			    rr_parent->dir_location);
3319 			bp += length;
3320 		}
3321 		extra_tell_used_size(&ctl, length);
3322 	}
3323 
3324 	/* Write "CL" System Use Entry. */
3325 	if (rr_flag & RR_USE_CL) {
3326 		/*
3327 		 *   "CL" Format:
3328 		 *               len  ver
3329 		 *    +----+----+----+----+------------+
3330 		 *    | 'C'| 'L'| 0C | 01 | *LOCATION  |
3331 		 *    +----+----+----+----+------------+
3332 		 *    0    1    2    3    4           12
3333 		 *    *LOCATION: location of child directory
3334 		 */
3335 		length = 12;
3336 		if (extra_space(&ctl) < length)
3337 			bp = extra_next_record(&ctl, length);
3338 		if (bp != NULL) {
3339 			bp[1] = 'C';
3340 			bp[2] = 'L';
3341 			bp[3] = length;
3342 			bp[4] = 1;	/* version	*/
3343 			set_num_733(bp + 5,
3344 			    isoent->rr_child->dir_location);
3345 			bp += length;
3346 		}
3347 		extra_tell_used_size(&ctl, length);
3348 	}
3349 
3350 	/* Write "PN" System Use Entry. */
3351 	if (rr_flag & RR_USE_PN) {
3352 		/*
3353 		 *   "PN" Format:
3354 		 *               len  ver
3355 		 *    +----+----+----+----+------------+------------+
3356 		 *    | 'P'| 'N'| 14 | 01 | dev_t high | dev_t low  |
3357 		 *    +----+----+----+----+------------+------------+
3358 		 *    0    1    2    3    4           12           20
3359 		 */
3360 		length = 20;
3361 		if (extra_space(&ctl) < length)
3362 			bp = extra_next_record(&ctl, length);
3363 		if (bp != NULL) {
3364 			uint64_t dev;
3365 
3366 			bp[1] = 'P';
3367 			bp[2] = 'N';
3368 			bp[3] = length;
3369 			bp[4] = 1;	/* version	*/
3370 			dev = (uint64_t)archive_entry_rdev(file->entry);
3371 			set_num_733(bp + 5, (uint32_t)(dev >> 32));
3372 			set_num_733(bp + 13, (uint32_t)(dev & 0xFFFFFFFF));
3373 			bp += length;
3374 		}
3375 		extra_tell_used_size(&ctl, length);
3376 	}
3377 
3378 	/* Write "ZF" System Use Entry. */
3379 	if (file->zisofs.header_size) {
3380 		/*
3381 		 *   "ZF" Format:
3382 		 *               len  ver
3383 		 *    +----+----+----+----+----+----+-------------+
3384 		 *    | 'Z'| 'F'| 10 | 01 | 'p'| 'z'| Header Size |
3385 		 *    +----+----+----+----+----+----+-------------+
3386 		 *    0    1    2    3    4    5    6             7
3387 		 *    +--------------------+-------------------+
3388 		 *    | Log2 of block Size | Uncompressed Size |
3389 		 *    +--------------------+-------------------+
3390 		 *    7                    8                   16
3391 		 */
3392 		length = 16;
3393 		if (extra_space(&ctl) < length)
3394 			bp = extra_next_record(&ctl, length);
3395 		if (bp != NULL) {
3396 			bp[1] = 'Z';
3397 			bp[2] = 'F';
3398 			bp[3] = length;
3399 			bp[4] = 1;	/* version	*/
3400 			bp[5] = 'p';
3401 			bp[6] = 'z';
3402 			bp[7] = file->zisofs.header_size;
3403 			bp[8] = file->zisofs.log2_bs;
3404 			set_num_733(bp + 9, file->zisofs.uncompressed_size);
3405 			bp += length;
3406 		}
3407 		extra_tell_used_size(&ctl, length);
3408 	}
3409 
3410 	/* Write "CE" System Use Entry. */
3411 	if (t == DIR_REC_SELF && isoent == isoent->parent) {
3412 		length = RR_CE_SIZE;
3413 		if (bp != NULL)
3414 			set_SUSP_CE(bp+1, iso9660->location_rrip_er,
3415 			    0, RRIP_ER_SIZE);
3416 		extra_tell_used_size(&ctl, length);
3417 	}
3418 
3419 	extra_close_record(&ctl, 0);
3420 
3421 	return (ctl.dr_len);
3422 }
3423 
3424 /*
3425  * Write data of a Directory Record or calculate writing bytes itself.
3426  * If parameter `p' is NULL, calculates the size of writing data, which
3427  * a Directory Record needs to write, then it saved and return
3428  * the calculated size.
3429  * Parameter `n' is a remaining size of buffer. when parameter `p' is
3430  * not NULL, check whether that `n' is not less than the saved size.
3431  * if that `n' is small, return zero.
3432  *
3433  * This format of the Directory Record is according to
3434  * ISO9660 Standard 9.1
3435  */
3436 static int
3437 set_directory_record(unsigned char *p, size_t n, struct isoent *isoent,
3438     struct iso9660 *iso9660, enum dir_rec_type t,
3439     enum vdd_type vdd_type)
3440 {
3441 	unsigned char *bp;
3442 	size_t dr_len;
3443 	size_t fi_len;
3444 
3445 	if (p != NULL) {
3446 		/*
3447 		 * Check whether a write buffer size is less than the
3448 		 * saved size which is needed to write this Directory
3449 		 * Record.
3450 		 */
3451 		switch (t) {
3452 		case DIR_REC_VD:
3453 			dr_len = isoent->dr_len.vd; break;
3454 		case DIR_REC_SELF:
3455 			dr_len = isoent->dr_len.self; break;
3456 		case DIR_REC_PARENT:
3457 			dr_len = isoent->dr_len.parent; break;
3458 		case DIR_REC_NORMAL:
3459 		default:
3460 			dr_len = isoent->dr_len.normal; break;
3461 		}
3462 		if (dr_len > n)
3463 			return (0);/* Needs more buffer size. */
3464 	}
3465 
3466 	if (t == DIR_REC_NORMAL && isoent->identifier != NULL)
3467 		fi_len = isoent->id_len;
3468 	else
3469 		fi_len = 1;
3470 
3471 	if (p != NULL) {
3472 		struct isoent *xisoent;
3473 		struct isofile *file;
3474 		unsigned char flag;
3475 
3476 		if (t == DIR_REC_PARENT)
3477 			xisoent = isoent->parent;
3478 		else
3479 			xisoent = isoent;
3480 		file = isoent->file;
3481 		if (file->hardlink_target != NULL)
3482 			file = file->hardlink_target;
3483 		/* Make a file flag. */
3484 		if (xisoent->dir)
3485 			flag = FILE_FLAG_DIRECTORY;
3486 		else {
3487 			if (file->cur_content->next != NULL)
3488 				flag = FILE_FLAG_MULTI_EXTENT;
3489 			else
3490 				flag = 0;
3491 		}
3492 
3493 		bp = p -1;
3494 		/* Extended Attribute Record Length */
3495 		set_num_711(bp+2, 0);
3496 		/* Location of Extent */
3497 		if (xisoent->dir)
3498 			set_num_733(bp+3, xisoent->dir_location);
3499 		else
3500 			set_num_733(bp+3, file->cur_content->location);
3501 		/* Data Length */
3502 		if (xisoent->dir)
3503 			set_num_733(bp+11,
3504 			    xisoent->dir_block * LOGICAL_BLOCK_SIZE);
3505 		else
3506 			set_num_733(bp+11, (uint32_t)file->cur_content->size);
3507 		/* Recording Date and Time */
3508 		/* NOTE:
3509 		 *  If a file type is symbolic link, you are seeing this
3510 		 *  field value is different from a value mkisofs makes.
3511 		 *  libarchive uses lstat to get this one, but it
3512 		 *  seems mkisofs uses stat to get.
3513 		 */
3514 		set_time_915(bp+19,
3515 		    archive_entry_mtime(xisoent->file->entry));
3516 		/* File Flags */
3517 		bp[26] = flag;
3518 		/* File Unit Size */
3519 		set_num_711(bp+27, 0);
3520 		/* Interleave Gap Size */
3521 		set_num_711(bp+28, 0);
3522 		/* Volume Sequence Number */
3523 		set_num_723(bp+29, iso9660->volume_sequence_number);
3524 		/* Length of File Identifier */
3525 		set_num_711(bp+33, (unsigned char)fi_len);
3526 		/* File Identifier */
3527 		switch (t) {
3528 		case DIR_REC_VD:
3529 		case DIR_REC_SELF:
3530 			set_num_711(bp+34, 0);
3531 			break;
3532 		case DIR_REC_PARENT:
3533 			set_num_711(bp+34, 1);
3534 			break;
3535 		case DIR_REC_NORMAL:
3536 			if (isoent->identifier != NULL)
3537 				memcpy(bp+34, isoent->identifier, fi_len);
3538 			else
3539 				set_num_711(bp+34, 0);
3540 			break;
3541 		}
3542 	} else
3543 		bp = NULL;
3544 	dr_len = 33 + fi_len;
3545 	/* Padding Field */
3546 	if (dr_len & 0x01) {
3547 		dr_len ++;
3548 		if (p != NULL)
3549 			bp[dr_len] = 0;
3550 	}
3551 
3552 	/* Volume Descriptor does not record extension. */
3553 	if (t == DIR_REC_VD) {
3554 		if (p != NULL)
3555 			/* Length of Directory Record */
3556 			set_num_711(p, (unsigned char)dr_len);
3557 		else
3558 			isoent->dr_len.vd = (int)dr_len;
3559 		return ((int)dr_len);
3560 	}
3561 
3562 	/* Rockridge */
3563 	if (iso9660->opt.rr && vdd_type != VDD_JOLIET)
3564 		dr_len = set_directory_record_rr(bp, (int)dr_len,
3565 		    isoent, iso9660, t);
3566 
3567 	if (p != NULL)
3568 		/* Length of Directory Record */
3569 		set_num_711(p, (unsigned char)dr_len);
3570 	else {
3571 		/*
3572 		 * Save the size which is needed to write this
3573 		 * Directory Record.
3574 		 */
3575 		switch (t) {
3576 		case DIR_REC_VD:
3577 			/* This case does not come, but compiler
3578 			 * complains that DIR_REC_VD not handled
3579 			 *  in switch ....  */
3580 			break;
3581 		case DIR_REC_SELF:
3582 			isoent->dr_len.self = (int)dr_len; break;
3583 		case DIR_REC_PARENT:
3584 			isoent->dr_len.parent = (int)dr_len; break;
3585 		case DIR_REC_NORMAL:
3586 			isoent->dr_len.normal = (int)dr_len; break;
3587 		}
3588 	}
3589 
3590 	return ((int)dr_len);
3591 }
3592 
3593 /*
3594  * Calculate the size of a directory record.
3595  */
3596 static inline int
3597 get_dir_rec_size(struct iso9660 *iso9660, struct isoent *isoent,
3598     enum dir_rec_type t, enum vdd_type vdd_type)
3599 {
3600 
3601 	return (set_directory_record(NULL, SIZE_MAX,
3602 	    isoent, iso9660, t, vdd_type));
3603 }
3604 
3605 /*
3606  * Manage to write ISO-image data with wbuff to reduce calling
3607  * __archive_write_output() for performance.
3608  */
3609 
3610 
3611 static inline unsigned char *
3612 wb_buffptr(struct archive_write *a)
3613 {
3614 	struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
3615 
3616 	return (&(iso9660->wbuff[sizeof(iso9660->wbuff)
3617 		- iso9660->wbuff_remaining]));
3618 }
3619 
3620 static int
3621 wb_write_out(struct archive_write *a)
3622 {
3623 	struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
3624 	size_t wsize, nw;
3625 	int r;
3626 
3627 	wsize = sizeof(iso9660->wbuff) - iso9660->wbuff_remaining;
3628 	nw = wsize % LOGICAL_BLOCK_SIZE;
3629 	if (iso9660->wbuff_type == WB_TO_STREAM)
3630 		r = __archive_write_output(a, iso9660->wbuff, wsize - nw);
3631 	else
3632 		r = write_to_temp(a, iso9660->wbuff, wsize - nw);
3633 	/* Increase the offset. */
3634 	iso9660->wbuff_offset += wsize - nw;
3635 	if (iso9660->wbuff_offset > iso9660->wbuff_written)
3636 		iso9660->wbuff_written = iso9660->wbuff_offset;
3637 	iso9660->wbuff_remaining = sizeof(iso9660->wbuff);
3638 	if (nw) {
3639 		iso9660->wbuff_remaining -= nw;
3640 		memmove(iso9660->wbuff, iso9660->wbuff + wsize - nw, nw);
3641 	}
3642 	return (r);
3643 }
3644 
3645 static int
3646 wb_consume(struct archive_write *a, size_t size)
3647 {
3648 	struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
3649 
3650 	if (size > iso9660->wbuff_remaining ||
3651 	    iso9660->wbuff_remaining == 0) {
3652 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
3653 		    "Internal Programming error: iso9660:wb_consume()"
3654 		    " size=%jd, wbuff_remaining=%jd",
3655 		    (intmax_t)size, (intmax_t)iso9660->wbuff_remaining);
3656 		return (ARCHIVE_FATAL);
3657 	}
3658 	iso9660->wbuff_remaining -= size;
3659 	if (iso9660->wbuff_remaining < LOGICAL_BLOCK_SIZE)
3660 		return (wb_write_out(a));
3661 	return (ARCHIVE_OK);
3662 }
3663 
3664 #ifdef HAVE_ZLIB_H
3665 
3666 static int
3667 wb_set_offset(struct archive_write *a, int64_t off)
3668 {
3669 	struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
3670 	int64_t used, ext_bytes;
3671 
3672 	if (iso9660->wbuff_type != WB_TO_TEMP) {
3673 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
3674 		    "Internal Programming error: iso9660:wb_set_offset()");
3675 		return (ARCHIVE_FATAL);
3676 	}
3677 
3678 	used = sizeof(iso9660->wbuff) - iso9660->wbuff_remaining;
3679 	if (iso9660->wbuff_offset + used > iso9660->wbuff_tail)
3680 		iso9660->wbuff_tail = iso9660->wbuff_offset + used;
3681 	if (iso9660->wbuff_offset < iso9660->wbuff_written) {
3682 		if (used > 0 &&
3683 		    write_to_temp(a, iso9660->wbuff, (size_t)used) != ARCHIVE_OK)
3684 			return (ARCHIVE_FATAL);
3685 		iso9660->wbuff_offset = iso9660->wbuff_written;
3686 		lseek(iso9660->temp_fd, iso9660->wbuff_offset, SEEK_SET);
3687 		iso9660->wbuff_remaining = sizeof(iso9660->wbuff);
3688 		used = 0;
3689 	}
3690 	if (off < iso9660->wbuff_offset) {
3691 		/*
3692 		 * Write out waiting data.
3693 		 */
3694 		if (used > 0) {
3695 			if (wb_write_out(a) != ARCHIVE_OK)
3696 				return (ARCHIVE_FATAL);
3697 		}
3698 		lseek(iso9660->temp_fd, off, SEEK_SET);
3699 		iso9660->wbuff_offset = off;
3700 		iso9660->wbuff_remaining = sizeof(iso9660->wbuff);
3701 	} else if (off <= iso9660->wbuff_tail) {
3702 		iso9660->wbuff_remaining = (size_t)
3703 		    (sizeof(iso9660->wbuff) - (off - iso9660->wbuff_offset));
3704 	} else {
3705 		ext_bytes = off - iso9660->wbuff_tail;
3706 		iso9660->wbuff_remaining = (size_t)(sizeof(iso9660->wbuff)
3707 		   - (iso9660->wbuff_tail - iso9660->wbuff_offset));
3708 		while (ext_bytes >= (int64_t)iso9660->wbuff_remaining) {
3709 			if (write_null(a, (size_t)iso9660->wbuff_remaining)
3710 			    != ARCHIVE_OK)
3711 				return (ARCHIVE_FATAL);
3712 			ext_bytes -= iso9660->wbuff_remaining;
3713 		}
3714 		if (ext_bytes > 0) {
3715 			if (write_null(a, (size_t)ext_bytes) != ARCHIVE_OK)
3716 				return (ARCHIVE_FATAL);
3717 		}
3718 	}
3719 	return (ARCHIVE_OK);
3720 }
3721 
3722 #endif /* HAVE_ZLIB_H */
3723 
3724 static int
3725 write_null(struct archive_write *a, size_t size)
3726 {
3727 	size_t remaining;
3728 	unsigned char *p, *old;
3729 	int r;
3730 
3731 	remaining = wb_remaining(a);
3732 	p = wb_buffptr(a);
3733 	if (size <= remaining) {
3734 		memset(p, 0, size);
3735 		return (wb_consume(a, size));
3736 	}
3737 	memset(p, 0, remaining);
3738 	r = wb_consume(a, remaining);
3739 	if (r != ARCHIVE_OK)
3740 		return (r);
3741 	size -= remaining;
3742 	old = p;
3743 	p = wb_buffptr(a);
3744 	memset(p, 0, old - p);
3745 	remaining = wb_remaining(a);
3746 	while (size) {
3747 		size_t wsize = size;
3748 
3749 		if (wsize > remaining)
3750 			wsize = remaining;
3751 		r = wb_consume(a, wsize);
3752 		if (r != ARCHIVE_OK)
3753 			return (r);
3754 		size -= wsize;
3755 	}
3756 	return (ARCHIVE_OK);
3757 }
3758 
3759 /*
3760  * Write Volume Descriptor Set Terminator
3761  */
3762 static int
3763 write_VD_terminator(struct archive_write *a)
3764 {
3765 	unsigned char *bp;
3766 
3767 	bp = wb_buffptr(a) -1;
3768 	set_VD_bp(bp, VDT_TERMINATOR, 1);
3769 	set_unused_field_bp(bp, 8, LOGICAL_BLOCK_SIZE);
3770 
3771 	return (wb_consume(a, LOGICAL_BLOCK_SIZE));
3772 }
3773 
3774 static int
3775 set_file_identifier(unsigned char *bp, int from, int to, enum vdc vdc,
3776     struct archive_write *a, struct vdd *vdd, struct archive_string *id,
3777     const char *label, int leading_under, enum char_type char_type)
3778 {
3779 	char identifier[256];
3780 	struct isoent *isoent;
3781 	const char *ids;
3782 	size_t len;
3783 	int r;
3784 
3785 	if (id->length > 0 && leading_under && id->s[0] != '_') {
3786 		if (char_type == A_CHAR)
3787 			r = set_str_a_characters_bp(a, bp, from, to, id->s, vdc);
3788 		else
3789 			r = set_str_d_characters_bp(a, bp, from, to, id->s, vdc);
3790 	} else if (id->length > 0) {
3791 		ids = id->s;
3792 		if (leading_under)
3793 			ids++;
3794 		isoent = isoent_find_entry(vdd->rootent, ids);
3795 		if (isoent == NULL) {
3796 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
3797 			    "Not Found %s `%s'.",
3798 			    label, ids);
3799 			return (ARCHIVE_FATAL);
3800 		}
3801 		len = isoent->ext_off + isoent->ext_len;
3802 		if (vdd->vdd_type == VDD_JOLIET) {
3803 			if (len > sizeof(identifier)-2)
3804 				len = sizeof(identifier)-2;
3805 		} else {
3806 			if (len > sizeof(identifier)-1)
3807 				len = sizeof(identifier)-1;
3808 		}
3809 		memcpy(identifier, isoent->identifier, len);
3810 		identifier[len] = '\0';
3811 		if (vdd->vdd_type == VDD_JOLIET) {
3812 			identifier[len+1] = 0;
3813 			vdc = VDC_UCS2_DIRECT;
3814 		}
3815 		if (char_type == A_CHAR)
3816 			r = set_str_a_characters_bp(a, bp, from, to,
3817 			    identifier, vdc);
3818 		else
3819 			r = set_str_d_characters_bp(a, bp, from, to,
3820 			    identifier, vdc);
3821 	} else {
3822 		if (char_type == A_CHAR)
3823 			r = set_str_a_characters_bp(a, bp, from, to, NULL, vdc);
3824 		else
3825 			r = set_str_d_characters_bp(a, bp, from, to, NULL, vdc);
3826 	}
3827 	return (r);
3828 }
3829 
3830 /*
3831  * Write Primary/Supplementary Volume Descriptor
3832  */
3833 static int
3834 write_VD(struct archive_write *a, struct vdd *vdd)
3835 {
3836 	struct iso9660 *iso9660;
3837 	unsigned char *bp;
3838 	uint16_t volume_set_size = 1;
3839 	char identifier[256];
3840 	enum VD_type vdt;
3841 	enum vdc vdc;
3842 	unsigned char vd_ver, fst_ver;
3843 	int r;
3844 
3845 	iso9660 = a->format_data;
3846 	switch (vdd->vdd_type) {
3847 	case VDD_JOLIET:
3848 		vdt = VDT_SUPPLEMENTARY;
3849 		vd_ver = fst_ver = 1;
3850 		vdc = VDC_UCS2;
3851 		break;
3852 	case VDD_ENHANCED:
3853 		vdt = VDT_SUPPLEMENTARY;
3854 		vd_ver = fst_ver = 2;
3855 		vdc = VDC_LOWERCASE;
3856 		break;
3857 	case VDD_PRIMARY:
3858 	default:
3859 		vdt = VDT_PRIMARY;
3860 		vd_ver = fst_ver = 1;
3861 #ifdef COMPAT_MKISOFS
3862 		vdc = VDC_LOWERCASE;
3863 #else
3864 		vdc = VDC_STD;
3865 #endif
3866 		break;
3867 	}
3868 
3869 	bp = wb_buffptr(a) -1;
3870 	/* Volume Descriptor Type */
3871 	set_VD_bp(bp, vdt, vd_ver);
3872 	/* Unused Field */
3873 	set_unused_field_bp(bp, 8, 8);
3874 	/* System Identifier */
3875 	get_system_identitier(identifier, sizeof(identifier));
3876 	r = set_str_a_characters_bp(a, bp, 9, 40, identifier, vdc);
3877 	if (r != ARCHIVE_OK)
3878 		return (r);
3879 	/* Volume Identifier */
3880 	r = set_str_d_characters_bp(a, bp, 41, 72,
3881 	    iso9660->volume_identifier.s, vdc);
3882 	if (r != ARCHIVE_OK)
3883 		return (r);
3884 	/* Unused Field */
3885 	set_unused_field_bp(bp, 73, 80);
3886 	/* Volume Space Size */
3887 	set_num_733(bp+81, iso9660->volume_space_size);
3888 	if (vdd->vdd_type == VDD_JOLIET) {
3889 		/* Escape Sequences */
3890 		bp[89] = 0x25;/* UCS-2 Level 3 */
3891 		bp[90] = 0x2F;
3892 		bp[91] = 0x45;
3893 		memset(bp + 92, 0, 120 - 92 + 1);
3894 	} else {
3895 		/* Unused Field */
3896 		set_unused_field_bp(bp, 89, 120);
3897 	}
3898 	/* Volume Set Size */
3899 	set_num_723(bp+121, volume_set_size);
3900 	/* Volume Sequence Number */
3901 	set_num_723(bp+125, iso9660->volume_sequence_number);
3902 	/* Logical Block Size */
3903 	set_num_723(bp+129, LOGICAL_BLOCK_SIZE);
3904 	/* Path Table Size */
3905 	set_num_733(bp+133, vdd->path_table_size);
3906 	/* Location of Occurrence of Type L Path Table */
3907 	set_num_731(bp+141, vdd->location_type_L_path_table);
3908 	/* Location of Optional Occurrence of Type L Path Table */
3909 	set_num_731(bp+145, 0);
3910 	/* Location of Occurrence of Type M Path Table */
3911 	set_num_732(bp+149, vdd->location_type_M_path_table);
3912 	/* Location of Optional Occurrence of Type M Path Table */
3913 	set_num_732(bp+153, 0);
3914 	/* Directory Record for Root Directory(BP 157 to 190) */
3915 	set_directory_record(bp+157, 190-157+1, vdd->rootent,
3916 	    iso9660, DIR_REC_VD, vdd->vdd_type);
3917 	/* Volume Set Identifier */
3918 	r = set_str_d_characters_bp(a, bp, 191, 318, "", vdc);
3919 	if (r != ARCHIVE_OK)
3920 		return (r);
3921 	/* Publisher Identifier */
3922 	r = set_file_identifier(bp, 319, 446, vdc, a, vdd,
3923 	    &(iso9660->publisher_identifier),
3924 	    "Publisher File", 1, A_CHAR);
3925 	if (r != ARCHIVE_OK)
3926 		return (r);
3927 	/* Data Preparer Identifier */
3928 	r = set_file_identifier(bp, 447, 574, vdc, a, vdd,
3929 	    &(iso9660->data_preparer_identifier),
3930 	    "Data Preparer File", 1, A_CHAR);
3931 	if (r != ARCHIVE_OK)
3932 		return (r);
3933 	/* Application Identifier */
3934 	r = set_file_identifier(bp, 575, 702, vdc, a, vdd,
3935 	    &(iso9660->application_identifier),
3936 	    "Application File", 1, A_CHAR);
3937 	if (r != ARCHIVE_OK)
3938 		return (r);
3939 	/* Copyright File Identifier */
3940 	r = set_file_identifier(bp, 703, 739, vdc, a, vdd,
3941 	    &(iso9660->copyright_file_identifier),
3942 	    "Copyright File", 0, D_CHAR);
3943 	if (r != ARCHIVE_OK)
3944 		return (r);
3945 	/* Abstract File Identifier */
3946 	r = set_file_identifier(bp, 740, 776, vdc, a, vdd,
3947 	    &(iso9660->abstract_file_identifier),
3948 	    "Abstract File", 0, D_CHAR);
3949 	if (r != ARCHIVE_OK)
3950 		return (r);
3951 	/* Bibliographic File Identifier */
3952 	r = set_file_identifier(bp, 777, 813, vdc, a, vdd,
3953 	    &(iso9660->bibliographic_file_identifier),
3954 	    "Bibliongraphic File", 0, D_CHAR);
3955 	if (r != ARCHIVE_OK)
3956 		return (r);
3957 	/* Volume Creation Date and Time */
3958 	set_date_time(bp+814, iso9660->birth_time);
3959 	/* Volume Modification Date and Time */
3960 	set_date_time(bp+831, iso9660->birth_time);
3961 	/* Volume Expiration Date and Time(obsolete) */
3962 	set_date_time_null(bp+848);
3963 	/* Volume Effective Date and Time */
3964 	set_date_time(bp+865, iso9660->birth_time);
3965 	/* File Structure Version */
3966 	bp[882] = fst_ver;
3967 	/* Reserved */
3968 	bp[883] = 0;
3969 	/* Application Use */
3970 	memset(bp + 884, 0x20, 1395 - 884 + 1);
3971 	/* Reserved */
3972 	set_unused_field_bp(bp, 1396, LOGICAL_BLOCK_SIZE);
3973 
3974 	return (wb_consume(a, LOGICAL_BLOCK_SIZE));
3975 }
3976 
3977 /*
3978  * Write Boot Record Volume Descriptor
3979  */
3980 static int
3981 write_VD_boot_record(struct archive_write *a)
3982 {
3983 	struct iso9660 *iso9660;
3984 	unsigned char *bp;
3985 
3986 	iso9660 = a->format_data;
3987 	bp = wb_buffptr(a) -1;
3988 	/* Volume Descriptor Type */
3989 	set_VD_bp(bp, VDT_BOOT_RECORD, 1);
3990 	/* Boot System Identifier */
3991 	memcpy(bp+8, "EL TORITO SPECIFICATION", 23);
3992 	set_unused_field_bp(bp, 8+23, 39);
3993 	/* Unused */
3994 	set_unused_field_bp(bp, 40, 71);
3995 	/* Absolute pointer to first sector of Boot Catalog */
3996 	set_num_731(bp+72,
3997 	    iso9660->el_torito.catalog->file->content.location);
3998 	/* Unused */
3999 	set_unused_field_bp(bp, 76, LOGICAL_BLOCK_SIZE);
4000 
4001 	return (wb_consume(a, LOGICAL_BLOCK_SIZE));
4002 }
4003 
4004 enum keytype {
4005 	KEY_FLG,
4006 	KEY_STR,
4007 	KEY_INT,
4008 	KEY_HEX
4009 };
4010 static void
4011 set_option_info(struct archive_string *info, int *opt, const char *key,
4012     enum keytype type,  ...)
4013 {
4014 	va_list ap;
4015 	char prefix;
4016 	const char *s;
4017 	int d;
4018 
4019 	prefix = (*opt==0)? ' ':',';
4020 	va_start(ap, type);
4021 	switch (type) {
4022 	case KEY_FLG:
4023 		d = va_arg(ap, int);
4024 		archive_string_sprintf(info, "%c%s%s",
4025 		    prefix, (d == 0)?"!":"", key);
4026 		break;
4027 	case KEY_STR:
4028 		s = va_arg(ap, const char *);
4029 		archive_string_sprintf(info, "%c%s=%s",
4030 		    prefix, key, s);
4031 		break;
4032 	case KEY_INT:
4033 		d = va_arg(ap, int);
4034 		archive_string_sprintf(info, "%c%s=%d",
4035 		    prefix, key, d);
4036 		break;
4037 	case KEY_HEX:
4038 		d = va_arg(ap, int);
4039 		archive_string_sprintf(info, "%c%s=%x",
4040 		    prefix, key, d);
4041 		break;
4042 	}
4043 	va_end(ap);
4044 
4045 	*opt = 1;
4046 }
4047 
4048 /*
4049  * Make Non-ISO File System Information
4050  */
4051 static int
4052 write_information_block(struct archive_write *a)
4053 {
4054 	struct iso9660 *iso9660;
4055 	char buf[128];
4056 	const char *v;
4057 	int opt, r;
4058 	struct archive_string info;
4059 	size_t info_size = LOGICAL_BLOCK_SIZE *
4060 			       NON_ISO_FILE_SYSTEM_INFORMATION_BLOCK;
4061 
4062 	iso9660 = (struct iso9660 *)a->format_data;
4063 	if (info_size > wb_remaining(a)) {
4064 		r = wb_write_out(a);
4065 		if (r != ARCHIVE_OK)
4066 			return (r);
4067 	}
4068 	archive_string_init(&info);
4069 	if (archive_string_ensure(&info, info_size) == NULL) {
4070 		archive_set_error(&a->archive, ENOMEM,
4071 		    "Can't allocate memory");
4072 		return (ARCHIVE_FATAL);
4073 	}
4074 	memset(info.s, 0, info_size);
4075 	opt = 0;
4076 #if defined(HAVE__CTIME64_S)
4077 	{
4078 		__time64_t iso9660_birth_time_tmp = (__time64_t) iso9660->birth_time; //time_t may be shorter than 64 bits
4079 		_ctime64_s(buf, sizeof(buf), &(iso9660_birth_time_tmp));
4080 	}
4081 #elif defined(HAVE_CTIME_R)
4082 	ctime_r(&(iso9660->birth_time), buf);
4083 #else
4084 	strncpy(buf, ctime(&(iso9660->birth_time)), sizeof(buf)-1);
4085 	buf[sizeof(buf)-1] = '\0';
4086 #endif
4087 	archive_string_sprintf(&info,
4088 	    "INFO %s%s", buf, archive_version_string());
4089 	if (iso9660->opt.abstract_file != OPT_ABSTRACT_FILE_DEFAULT)
4090 		set_option_info(&info, &opt, "abstract-file",
4091 		    KEY_STR, iso9660->abstract_file_identifier.s);
4092 	if (iso9660->opt.application_id != OPT_APPLICATION_ID_DEFAULT)
4093 		set_option_info(&info, &opt, "application-id",
4094 		    KEY_STR, iso9660->application_identifier.s);
4095 	if (iso9660->opt.allow_vernum != OPT_ALLOW_VERNUM_DEFAULT)
4096 		set_option_info(&info, &opt, "allow-vernum",
4097 		    KEY_FLG, iso9660->opt.allow_vernum);
4098 	if (iso9660->opt.biblio_file != OPT_BIBLIO_FILE_DEFAULT)
4099 		set_option_info(&info, &opt, "biblio-file",
4100 		    KEY_STR, iso9660->bibliographic_file_identifier.s);
4101 	if (iso9660->opt.boot != OPT_BOOT_DEFAULT)
4102 		set_option_info(&info, &opt, "boot",
4103 		    KEY_STR, iso9660->el_torito.boot_filename.s);
4104 	if (iso9660->opt.boot_catalog != OPT_BOOT_CATALOG_DEFAULT)
4105 		set_option_info(&info, &opt, "boot-catalog",
4106 		    KEY_STR, iso9660->el_torito.catalog_filename.s);
4107 	if (iso9660->opt.boot_info_table != OPT_BOOT_INFO_TABLE_DEFAULT)
4108 		set_option_info(&info, &opt, "boot-info-table",
4109 		    KEY_FLG, iso9660->opt.boot_info_table);
4110 	if (iso9660->opt.boot_load_seg != OPT_BOOT_LOAD_SEG_DEFAULT)
4111 		set_option_info(&info, &opt, "boot-load-seg",
4112 		    KEY_HEX, iso9660->el_torito.boot_load_seg);
4113 	if (iso9660->opt.boot_load_size != OPT_BOOT_LOAD_SIZE_DEFAULT)
4114 		set_option_info(&info, &opt, "boot-load-size",
4115 		    KEY_INT, iso9660->el_torito.boot_load_size);
4116 	if (iso9660->opt.boot_type != OPT_BOOT_TYPE_DEFAULT) {
4117 		v = "no-emulation";
4118 		if (iso9660->opt.boot_type == OPT_BOOT_TYPE_FD)
4119 			v = "fd";
4120 		if (iso9660->opt.boot_type == OPT_BOOT_TYPE_HARD_DISK)
4121 			v = "hard-disk";
4122 		set_option_info(&info, &opt, "boot-type",
4123 		    KEY_STR, v);
4124 	}
4125 #ifdef HAVE_ZLIB_H
4126 	if (iso9660->opt.compression_level != OPT_COMPRESSION_LEVEL_DEFAULT)
4127 		set_option_info(&info, &opt, "compression-level",
4128 		    KEY_INT, iso9660->zisofs.compression_level);
4129 #endif
4130 	if (iso9660->opt.copyright_file != OPT_COPYRIGHT_FILE_DEFAULT)
4131 		set_option_info(&info, &opt, "copyright-file",
4132 		    KEY_STR, iso9660->copyright_file_identifier.s);
4133 	if (iso9660->opt.iso_level != OPT_ISO_LEVEL_DEFAULT)
4134 		set_option_info(&info, &opt, "iso-level",
4135 		    KEY_INT, iso9660->opt.iso_level);
4136 	if (iso9660->opt.joliet != OPT_JOLIET_DEFAULT) {
4137 		if (iso9660->opt.joliet == OPT_JOLIET_LONGNAME)
4138 			set_option_info(&info, &opt, "joliet",
4139 			    KEY_STR, "long");
4140 		else
4141 			set_option_info(&info, &opt, "joliet",
4142 			    KEY_FLG, iso9660->opt.joliet);
4143 	}
4144 	if (iso9660->opt.limit_depth != OPT_LIMIT_DEPTH_DEFAULT)
4145 		set_option_info(&info, &opt, "limit-depth",
4146 		    KEY_FLG, iso9660->opt.limit_depth);
4147 	if (iso9660->opt.limit_dirs != OPT_LIMIT_DIRS_DEFAULT)
4148 		set_option_info(&info, &opt, "limit-dirs",
4149 		    KEY_FLG, iso9660->opt.limit_dirs);
4150 	if (iso9660->opt.pad != OPT_PAD_DEFAULT)
4151 		set_option_info(&info, &opt, "pad",
4152 		    KEY_FLG, iso9660->opt.pad);
4153 	if (iso9660->opt.publisher != OPT_PUBLISHER_DEFAULT)
4154 		set_option_info(&info, &opt, "publisher",
4155 		    KEY_STR, iso9660->publisher_identifier.s);
4156 	if (iso9660->opt.rr != OPT_RR_DEFAULT) {
4157 		if (iso9660->opt.rr == OPT_RR_DISABLED)
4158 			set_option_info(&info, &opt, "rockridge",
4159 			    KEY_FLG, iso9660->opt.rr);
4160 		else if (iso9660->opt.rr == OPT_RR_STRICT)
4161 			set_option_info(&info, &opt, "rockridge",
4162 			    KEY_STR, "strict");
4163 		else if (iso9660->opt.rr == OPT_RR_USEFUL)
4164 			set_option_info(&info, &opt, "rockridge",
4165 			    KEY_STR, "useful");
4166 	}
4167 	if (iso9660->opt.volume_id != OPT_VOLUME_ID_DEFAULT)
4168 		set_option_info(&info, &opt, "volume-id",
4169 		    KEY_STR, iso9660->volume_identifier.s);
4170 	if (iso9660->opt.zisofs != OPT_ZISOFS_DEFAULT)
4171 		set_option_info(&info, &opt, "zisofs",
4172 		    KEY_FLG, iso9660->opt.zisofs);
4173 
4174 	memcpy(wb_buffptr(a), info.s, info_size);
4175 	archive_string_free(&info);
4176 	return (wb_consume(a, info_size));
4177 }
4178 
4179 static int
4180 write_rr_ER(struct archive_write *a)
4181 {
4182 	unsigned char *p;
4183 
4184 	p = wb_buffptr(a);
4185 
4186 	memset(p, 0, LOGICAL_BLOCK_SIZE);
4187 	p[0] = 'E';
4188 	p[1] = 'R';
4189 	p[3] = 0x01;
4190 	p[2] = RRIP_ER_SIZE;
4191 	p[4] = RRIP_ER_ID_SIZE;
4192 	p[5] = RRIP_ER_DSC_SIZE;
4193 	p[6] = RRIP_ER_SRC_SIZE;
4194 	p[7] = 0x01;
4195 	memcpy(&p[8], rrip_identifier, p[4]);
4196 	memcpy(&p[8+p[4]], rrip_descriptor, p[5]);
4197 	memcpy(&p[8+p[4]+p[5]], rrip_source, p[6]);
4198 
4199 	return (wb_consume(a, LOGICAL_BLOCK_SIZE));
4200 }
4201 
4202 static void
4203 calculate_path_table_size(struct vdd *vdd)
4204 {
4205 	int depth, size;
4206 	struct path_table *pt;
4207 
4208 	pt = vdd->pathtbl;
4209 	size = 0;
4210 	for (depth = 0; depth < vdd->max_depth; depth++) {
4211 		struct isoent **ptbl;
4212 		int i, cnt;
4213 
4214 		if ((cnt = pt[depth].cnt) == 0)
4215 			break;
4216 
4217 		ptbl = pt[depth].sorted;
4218 		for (i = 0; i < cnt; i++) {
4219 			int len;
4220 
4221 			if (ptbl[i]->identifier == NULL)
4222 				len = 1; /* root directory */
4223 			else
4224 				len = ptbl[i]->id_len;
4225 			if (len & 0x01)
4226 				len++; /* Padding Field */
4227 			size += 8 + len;
4228 		}
4229 	}
4230 	vdd->path_table_size = size;
4231 	vdd->path_table_block =
4232 	    ((size + PATH_TABLE_BLOCK_SIZE -1) /
4233 	    PATH_TABLE_BLOCK_SIZE) *
4234 	    (PATH_TABLE_BLOCK_SIZE / LOGICAL_BLOCK_SIZE);
4235 }
4236 
4237 static int
4238 _write_path_table(struct archive_write *a, int type_m, int depth,
4239     struct vdd *vdd)
4240 {
4241 	unsigned char *bp, *wb;
4242 	struct isoent **ptbl;
4243 	size_t wbremaining;
4244 	int i, r, wsize;
4245 
4246 	if (vdd->pathtbl[depth].cnt == 0)
4247 		return (0);
4248 
4249 	wsize = 0;
4250 	wb = wb_buffptr(a);
4251 	wbremaining = wb_remaining(a);
4252 	bp = wb - 1;
4253 	ptbl = vdd->pathtbl[depth].sorted;
4254 	for (i = 0; i < vdd->pathtbl[depth].cnt; i++) {
4255 		struct isoent *np;
4256 		size_t len;
4257 
4258 		np = ptbl[i];
4259 		if (np->identifier == NULL)
4260 			len = 1; /* root directory */
4261 		else
4262 			len = np->id_len;
4263 		if (wbremaining - ((bp+1) - wb) < (len + 1 + 8)) {
4264 			r = wb_consume(a, (bp+1) - wb);
4265 			if (r < 0)
4266 				return (r);
4267 			wb = wb_buffptr(a);
4268 			wbremaining = wb_remaining(a);
4269 			bp = wb -1;
4270 		}
4271 		/* Length of Directory Identifier */
4272 		set_num_711(bp+1, (unsigned char)len);
4273 		/* Extended Attribute Record Length */
4274 		set_num_711(bp+2, 0);
4275 		/* Location of Extent */
4276 		if (type_m)
4277 			set_num_732(bp+3, np->dir_location);
4278 		else
4279 			set_num_731(bp+3, np->dir_location);
4280 		/* Parent Directory Number */
4281 		if (type_m)
4282 			set_num_722(bp+7, np->parent->dir_number);
4283 		else
4284 			set_num_721(bp+7, np->parent->dir_number);
4285 		/* Directory Identifier */
4286 		if (np->identifier == NULL)
4287 			bp[9] = 0;
4288 		else
4289 			memcpy(&bp[9], np->identifier, len);
4290 		if (len & 0x01) {
4291 			/* Padding Field */
4292 			bp[9+len] = 0;
4293 			len++;
4294 		}
4295 		wsize += 8 + (int)len;
4296 		bp += 8 + len;
4297 	}
4298 	if ((bp + 1) > wb) {
4299 		r = wb_consume(a, (bp+1)-wb);
4300 		if (r < 0)
4301 			return (r);
4302 	}
4303 	return (wsize);
4304 }
4305 
4306 static int
4307 write_path_table(struct archive_write *a, int type_m, struct vdd *vdd)
4308 {
4309 	int depth, r;
4310 	size_t path_table_size;
4311 
4312 	r = ARCHIVE_OK;
4313 	path_table_size = 0;
4314 	for (depth = 0; depth < vdd->max_depth; depth++) {
4315 		r = _write_path_table(a, type_m, depth, vdd);
4316 		if (r < 0)
4317 			return (r);
4318 		path_table_size += r;
4319 	}
4320 
4321 	/* Write padding data. */
4322 	path_table_size = path_table_size % PATH_TABLE_BLOCK_SIZE;
4323 	if (path_table_size > 0)
4324 		r = write_null(a, PATH_TABLE_BLOCK_SIZE - path_table_size);
4325 	return (r);
4326 }
4327 
4328 static int
4329 calculate_directory_descriptors(struct iso9660 *iso9660, struct vdd *vdd,
4330     struct isoent *isoent, int depth)
4331 {
4332 	struct isoent **enttbl;
4333 	int bs, block, i;
4334 
4335 	block = 1;
4336 	bs = get_dir_rec_size(iso9660, isoent, DIR_REC_SELF, vdd->vdd_type);
4337 	bs += get_dir_rec_size(iso9660, isoent, DIR_REC_PARENT, vdd->vdd_type);
4338 
4339 	if (isoent->children.cnt <= 0 || (vdd->vdd_type != VDD_JOLIET &&
4340 	    !iso9660->opt.rr && depth + 1 >= vdd->max_depth))
4341 		return (block);
4342 
4343 	enttbl = isoent->children_sorted;
4344 	for (i = 0; i < isoent->children.cnt; i++) {
4345 		struct isoent *np = enttbl[i];
4346 		struct isofile *file;
4347 
4348 		file = np->file;
4349 		if (file->hardlink_target != NULL)
4350 			file = file->hardlink_target;
4351 		file->cur_content = &(file->content);
4352 		do {
4353 			int dr_l;
4354 
4355 			dr_l = get_dir_rec_size(iso9660, np, DIR_REC_NORMAL,
4356 			    vdd->vdd_type);
4357 			if ((bs + dr_l) > LOGICAL_BLOCK_SIZE) {
4358 				block ++;
4359 				bs = dr_l;
4360 			} else
4361 				bs += dr_l;
4362 			file->cur_content = file->cur_content->next;
4363 		} while (file->cur_content != NULL);
4364 	}
4365 	return (block);
4366 }
4367 
4368 static int
4369 _write_directory_descriptors(struct archive_write *a, struct vdd *vdd,
4370     struct isoent *isoent, int depth)
4371 {
4372 	struct iso9660 *iso9660 = a->format_data;
4373 	struct isoent **enttbl;
4374 	unsigned char *p, *wb;
4375 	int i, r;
4376 	int dr_l;
4377 
4378 	p = wb = wb_buffptr(a);
4379 #define WD_REMAINING	(LOGICAL_BLOCK_SIZE - (p - wb))
4380 	p += set_directory_record(p, WD_REMAINING, isoent,
4381 	    iso9660, DIR_REC_SELF, vdd->vdd_type);
4382 	p += set_directory_record(p, WD_REMAINING, isoent,
4383 	    iso9660, DIR_REC_PARENT, vdd->vdd_type);
4384 
4385 	if (isoent->children.cnt <= 0 || (vdd->vdd_type != VDD_JOLIET &&
4386 	    !iso9660->opt.rr && depth + 1 >= vdd->max_depth)) {
4387 		memset(p, 0, WD_REMAINING);
4388 		return (wb_consume(a, LOGICAL_BLOCK_SIZE));
4389 	}
4390 
4391 	enttbl = isoent->children_sorted;
4392 	for (i = 0; i < isoent->children.cnt; i++) {
4393 		struct isoent *np = enttbl[i];
4394 		struct isofile *file = np->file;
4395 
4396 		if (file->hardlink_target != NULL)
4397 			file = file->hardlink_target;
4398 		file->cur_content = &(file->content);
4399 		do {
4400 			dr_l = set_directory_record(p, WD_REMAINING,
4401 			    np, iso9660, DIR_REC_NORMAL,
4402 			    vdd->vdd_type);
4403 			if (dr_l == 0) {
4404 				memset(p, 0, WD_REMAINING);
4405 				r = wb_consume(a, LOGICAL_BLOCK_SIZE);
4406 				if (r < 0)
4407 					return (r);
4408 				p = wb = wb_buffptr(a);
4409 				dr_l = set_directory_record(p,
4410 				    WD_REMAINING, np, iso9660,
4411 				    DIR_REC_NORMAL, vdd->vdd_type);
4412 			}
4413 			p += dr_l;
4414 			file->cur_content = file->cur_content->next;
4415 		} while (file->cur_content != NULL);
4416 	}
4417 	memset(p, 0, WD_REMAINING);
4418 	return (wb_consume(a, LOGICAL_BLOCK_SIZE));
4419 }
4420 
4421 static int
4422 write_directory_descriptors(struct archive_write *a, struct vdd *vdd)
4423 {
4424 	struct isoent *np;
4425 	int depth, r;
4426 
4427 	depth = 0;
4428 	np = vdd->rootent;
4429 	do {
4430 		struct extr_rec *extr;
4431 
4432 		r = _write_directory_descriptors(a, vdd, np, depth);
4433 		if (r < 0)
4434 			return (r);
4435 		if (vdd->vdd_type != VDD_JOLIET) {
4436 			/*
4437 			 * This extract record is used by SUSP,RRIP.
4438 			 * Not for joliet.
4439 			 */
4440 			for (extr = np->extr_rec_list.first;
4441 			    extr != NULL;
4442 			    extr = extr->next) {
4443 				unsigned char *wb;
4444 
4445 				wb = wb_buffptr(a);
4446 				memcpy(wb, extr->buf, extr->offset);
4447 				memset(wb + extr->offset, 0,
4448 				    LOGICAL_BLOCK_SIZE - extr->offset);
4449 				r = wb_consume(a, LOGICAL_BLOCK_SIZE);
4450 				if (r < 0)
4451 					return (r);
4452 			}
4453 		}
4454 
4455 		if (np->subdirs.first != NULL && depth + 1 < vdd->max_depth) {
4456 			/* Enter to sub directories. */
4457 			np = np->subdirs.first;
4458 			depth++;
4459 			continue;
4460 		}
4461 		while (np != np->parent) {
4462 			if (np->drnext == NULL) {
4463 				/* Return to the parent directory. */
4464 				np = np->parent;
4465 				depth--;
4466 			} else {
4467 				np = np->drnext;
4468 				break;
4469 			}
4470 		}
4471 	} while (np != np->parent);
4472 
4473 	return (ARCHIVE_OK);
4474 }
4475 
4476 /*
4477  * Read file contents from the temporary file, and write it.
4478  */
4479 static int
4480 write_file_contents(struct archive_write *a, int64_t offset, int64_t size)
4481 {
4482 	struct iso9660 *iso9660 = a->format_data;
4483 	int r;
4484 
4485 	lseek(iso9660->temp_fd, offset, SEEK_SET);
4486 
4487 	while (size) {
4488 		size_t rsize;
4489 		ssize_t rs;
4490 		unsigned char *wb;
4491 
4492 		wb = wb_buffptr(a);
4493 		rsize = wb_remaining(a);
4494 		if (rsize > (size_t)size)
4495 			rsize = (size_t)size;
4496 		rs = read(iso9660->temp_fd, wb, rsize);
4497 		if (rs <= 0) {
4498 			archive_set_error(&a->archive, errno,
4499 			    "Can't read temporary file(%jd)", (intmax_t)rs);
4500 			return (ARCHIVE_FATAL);
4501 		}
4502 		size -= rs;
4503 		r = wb_consume(a, rs);
4504 		if (r < 0)
4505 			return (r);
4506 	}
4507 	return (ARCHIVE_OK);
4508 }
4509 
4510 static int
4511 write_file_descriptors(struct archive_write *a)
4512 {
4513 	struct iso9660 *iso9660 = a->format_data;
4514 	struct isofile *file;
4515 	int64_t blocks, offset;
4516 	int r;
4517 
4518 	blocks = 0;
4519 	offset = 0;
4520 
4521 	/* Make the boot catalog contents, and write it. */
4522 	if (iso9660->el_torito.catalog != NULL) {
4523 		r = make_boot_catalog(a);
4524 		if (r < 0)
4525 			return (r);
4526 	}
4527 
4528 	/* Write the boot file contents. */
4529 	if (iso9660->el_torito.boot != NULL) {
4530 		file = iso9660->el_torito.boot->file;
4531 		blocks = file->content.blocks;
4532 		offset = file->content.offset_of_temp;
4533 		if (offset != 0) {
4534 			r = write_file_contents(a, offset,
4535 			    blocks << LOGICAL_BLOCK_BITS);
4536 			if (r < 0)
4537 				return (r);
4538 			blocks = 0;
4539 			offset = 0;
4540 		}
4541 	}
4542 
4543 	/* Write out all file contents. */
4544 	for (file = iso9660->data_file_list.first;
4545 	    file != NULL; file = file->datanext) {
4546 
4547 		if (!file->write_content)
4548 			continue;
4549 
4550 		if ((offset + (blocks << LOGICAL_BLOCK_BITS)) <
4551 		     file->content.offset_of_temp) {
4552 			if (blocks > 0) {
4553 				r = write_file_contents(a, offset,
4554 				    blocks << LOGICAL_BLOCK_BITS);
4555 				if (r < 0)
4556 					return (r);
4557 			}
4558 			blocks = 0;
4559 			offset = file->content.offset_of_temp;
4560 		}
4561 
4562 		file->cur_content = &(file->content);
4563 		do {
4564 			blocks += file->cur_content->blocks;
4565 			/* Next fragment */
4566 			file->cur_content = file->cur_content->next;
4567 		} while (file->cur_content != NULL);
4568 	}
4569 
4570 	/* Flush out remaining blocks. */
4571 	if (blocks > 0) {
4572 		r = write_file_contents(a, offset,
4573 		    blocks << LOGICAL_BLOCK_BITS);
4574 		if (r < 0)
4575 			return (r);
4576 	}
4577 
4578 	return (ARCHIVE_OK);
4579 }
4580 
4581 static void
4582 isofile_init_entry_list(struct iso9660 *iso9660)
4583 {
4584 	iso9660->all_file_list.first = NULL;
4585 	iso9660->all_file_list.last = &(iso9660->all_file_list.first);
4586 }
4587 
4588 static void
4589 isofile_add_entry(struct iso9660 *iso9660, struct isofile *file)
4590 {
4591 	file->allnext = NULL;
4592 	*iso9660->all_file_list.last = file;
4593 	iso9660->all_file_list.last = &(file->allnext);
4594 }
4595 
4596 static void
4597 isofile_free_all_entries(struct iso9660 *iso9660)
4598 {
4599 	struct isofile *file, *file_next;
4600 
4601 	file = iso9660->all_file_list.first;
4602 	while (file != NULL) {
4603 		file_next = file->allnext;
4604 		isofile_free(file);
4605 		file = file_next;
4606 	}
4607 }
4608 
4609 static void
4610 isofile_init_entry_data_file_list(struct iso9660 *iso9660)
4611 {
4612 	iso9660->data_file_list.first = NULL;
4613 	iso9660->data_file_list.last = &(iso9660->data_file_list.first);
4614 }
4615 
4616 static void
4617 isofile_add_data_file(struct iso9660 *iso9660, struct isofile *file)
4618 {
4619 	file->datanext = NULL;
4620 	*iso9660->data_file_list.last = file;
4621 	iso9660->data_file_list.last = &(file->datanext);
4622 }
4623 
4624 
4625 static struct isofile *
4626 isofile_new(struct archive_write *a, struct archive_entry *entry)
4627 {
4628 	struct isofile *file;
4629 
4630 	file = calloc(1, sizeof(*file));
4631 	if (file == NULL)
4632 		return (NULL);
4633 
4634 	if (entry != NULL)
4635 		file->entry = archive_entry_clone(entry);
4636 	else
4637 		file->entry = archive_entry_new2(&a->archive);
4638 	if (file->entry == NULL) {
4639 		free(file);
4640 		return (NULL);
4641 	}
4642 	archive_string_init(&(file->parentdir));
4643 	archive_string_init(&(file->basename));
4644 	archive_string_init(&(file->basename_utf16));
4645 	archive_string_init(&(file->symlink));
4646 	file->cur_content = &(file->content);
4647 
4648 	return (file);
4649 }
4650 
4651 static void
4652 isofile_free(struct isofile *file)
4653 {
4654 	struct content *con, *tmp;
4655 
4656 	con = file->content.next;
4657 	while (con != NULL) {
4658 		tmp = con;
4659 		con = con->next;
4660 		free(tmp);
4661 	}
4662 	archive_entry_free(file->entry);
4663 	archive_string_free(&(file->parentdir));
4664 	archive_string_free(&(file->basename));
4665 	archive_string_free(&(file->basename_utf16));
4666 	archive_string_free(&(file->symlink));
4667 	free(file);
4668 }
4669 
4670 #if defined(_WIN32) || defined(__CYGWIN__)
4671 static int
4672 cleanup_backslash_1(char *p)
4673 {
4674 	int mb, dos;
4675 
4676 	mb = dos = 0;
4677 	while (*p) {
4678 		if (*(unsigned char *)p > 127)
4679 			mb = 1;
4680 		if (*p == '\\') {
4681 			/* If we have not met any multi-byte characters,
4682 			 * we can replace '\' with '/'. */
4683 			if (!mb)
4684 				*p = '/';
4685 			dos = 1;
4686 		}
4687 		p++;
4688 	}
4689 	if (!mb || !dos)
4690 		return (0);
4691 	return (-1);
4692 }
4693 
4694 static void
4695 cleanup_backslash_2(wchar_t *p)
4696 {
4697 
4698 	/* Convert a path-separator from '\' to  '/' */
4699 	while (*p != L'\0') {
4700 		if (*p == L'\\')
4701 			*p = L'/';
4702 		p++;
4703 	}
4704 }
4705 #endif
4706 
4707 /*
4708  * Generate a parent directory name and a base name from a pathname.
4709  */
4710 static int
4711 isofile_gen_utility_names(struct archive_write *a, struct isofile *file)
4712 {
4713 	struct iso9660 *iso9660;
4714 	const char *pathname;
4715 	char *p, *dirname, *slash;
4716 	size_t len;
4717 	int ret = ARCHIVE_OK;
4718 
4719 	iso9660 = a->format_data;
4720 
4721 	archive_string_empty(&(file->parentdir));
4722 	archive_string_empty(&(file->basename));
4723 	archive_string_empty(&(file->basename_utf16));
4724 	archive_string_empty(&(file->symlink));
4725 
4726 	pathname =  archive_entry_pathname(file->entry);
4727 	if (pathname == NULL || pathname[0] == '\0') {/* virtual root */
4728 		file->dircnt = 0;
4729 		return (ret);
4730 	}
4731 
4732 	/*
4733 	 * Make a UTF-16BE basename if Joliet extension enabled.
4734 	 */
4735 	if (iso9660->opt.joliet) {
4736 		const char *u16, *ulast;
4737 		size_t u16len, ulen_last;
4738 
4739 		if (iso9660->sconv_to_utf16be == NULL) {
4740 			iso9660->sconv_to_utf16be =
4741 			    archive_string_conversion_to_charset(
4742 				&(a->archive), "UTF-16BE", 1);
4743 			if (iso9660->sconv_to_utf16be == NULL)
4744 				/* Couldn't allocate memory */
4745 				return (ARCHIVE_FATAL);
4746 			iso9660->sconv_from_utf16be =
4747 			    archive_string_conversion_from_charset(
4748 				&(a->archive), "UTF-16BE", 1);
4749 			if (iso9660->sconv_from_utf16be == NULL)
4750 				/* Couldn't allocate memory */
4751 				return (ARCHIVE_FATAL);
4752 		}
4753 
4754 		/*
4755 		 * Convert a filename to UTF-16BE.
4756 		 */
4757 		if (0 > archive_entry_pathname_l(file->entry, &u16, &u16len,
4758 		    iso9660->sconv_to_utf16be)) {
4759 			if (errno == ENOMEM) {
4760 				archive_set_error(&a->archive, ENOMEM,
4761 				    "Can't allocate memory for UTF-16BE");
4762 				return (ARCHIVE_FATAL);
4763 			}
4764 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
4765 			    "A filename cannot be converted to UTF-16BE;"
4766 			    "You should disable making Joliet extension");
4767 			ret = ARCHIVE_WARN;
4768 		}
4769 
4770 		/*
4771 		 * Make sure a path separator is not in the last;
4772 		 * Remove trailing '/'.
4773 		 */
4774 		while (u16len >= 2) {
4775 #if defined(_WIN32) || defined(__CYGWIN__)
4776 			if (u16[u16len-2] == 0 &&
4777 			    (u16[u16len-1] == '/' || u16[u16len-1] == '\\'))
4778 #else
4779 			if (u16[u16len-2] == 0 && u16[u16len-1] == '/')
4780 #endif
4781 			{
4782 				u16len -= 2;
4783 			} else
4784 				break;
4785 		}
4786 
4787 		/*
4788 		 * Find a basename in UTF-16BE.
4789 		 */
4790 		ulast = u16;
4791 		u16len >>= 1;
4792 		ulen_last = u16len;
4793 		while (u16len > 0) {
4794 #if defined(_WIN32) || defined(__CYGWIN__)
4795 			if (u16[0] == 0 && (u16[1] == '/' || u16[1] == '\\'))
4796 #else
4797 			if (u16[0] == 0 && u16[1] == '/')
4798 #endif
4799 			{
4800 				ulast = u16 + 2;
4801 				ulen_last = u16len -1;
4802 			}
4803 			u16 += 2;
4804 			u16len --;
4805 		}
4806 		ulen_last <<= 1;
4807 		if (archive_string_ensure(&(file->basename_utf16),
4808 		    ulen_last) == NULL) {
4809 			archive_set_error(&a->archive, ENOMEM,
4810 			    "Can't allocate memory for UTF-16BE");
4811 			return (ARCHIVE_FATAL);
4812 		}
4813 
4814 		/*
4815 		 * Set UTF-16BE basename.
4816 		 */
4817 		memcpy(file->basename_utf16.s, ulast, ulen_last);
4818 		file->basename_utf16.length = ulen_last;
4819 	}
4820 
4821 	archive_strcpy(&(file->parentdir), pathname);
4822 #if defined(_WIN32) || defined(__CYGWIN__)
4823 	/*
4824 	 * Convert a path-separator from '\' to  '/'
4825 	 */
4826 	if (cleanup_backslash_1(file->parentdir.s) != 0) {
4827 		const wchar_t *wp = archive_entry_pathname_w(file->entry);
4828 		struct archive_wstring ws;
4829 
4830 		if (wp != NULL) {
4831 			int r;
4832 			archive_string_init(&ws);
4833 			archive_wstrcpy(&ws, wp);
4834 			cleanup_backslash_2(ws.s);
4835 			archive_string_empty(&(file->parentdir));
4836 			r = archive_string_append_from_wcs(&(file->parentdir),
4837 			    ws.s, ws.length);
4838 			archive_wstring_free(&ws);
4839 			if (r < 0 && errno == ENOMEM) {
4840 				archive_set_error(&a->archive, ENOMEM,
4841 				    "Can't allocate memory");
4842 				return (ARCHIVE_FATAL);
4843 			}
4844 		}
4845 	}
4846 #endif
4847 
4848 	len = file->parentdir.length;
4849 	p = dirname = file->parentdir.s;
4850 
4851 	/*
4852 	 * Remove leading '/', '../' and './' elements
4853 	 */
4854 	while (*p) {
4855 		if (p[0] == '/') {
4856 			p++;
4857 			len--;
4858 		} else if (p[0] != '.')
4859 			break;
4860 		else if (p[1] == '.' && p[2] == '/') {
4861 			p += 3;
4862 			len -= 3;
4863 		} else if (p[1] == '/' || (p[1] == '.' && p[2] == '\0')) {
4864 			p += 2;
4865 			len -= 2;
4866 		} else if (p[1] == '\0') {
4867 			p++;
4868 			len--;
4869 		} else
4870 			break;
4871 	}
4872 	if (p != dirname) {
4873 		memmove(dirname, p, len+1);
4874 		p = dirname;
4875 	}
4876 	/*
4877 	 * Remove "/","/." and "/.." elements from tail.
4878 	 */
4879 	while (len > 0) {
4880 		size_t ll = len;
4881 
4882 		if (len > 0 && p[len-1] == '/') {
4883 			p[len-1] = '\0';
4884 			len--;
4885 		}
4886 		if (len > 1 && p[len-2] == '/' && p[len-1] == '.') {
4887 			p[len-2] = '\0';
4888 			len -= 2;
4889 		}
4890 		if (len > 2 && p[len-3] == '/' && p[len-2] == '.' &&
4891 		    p[len-1] == '.') {
4892 			p[len-3] = '\0';
4893 			len -= 3;
4894 		}
4895 		if (ll == len)
4896 			break;
4897 	}
4898 	while (*p) {
4899 		if (p[0] == '/') {
4900 			if (p[1] == '/')
4901 				/* Convert '//' --> '/' */
4902 				memmove(p, p+1, strlen(p+1) + 1);
4903 			else if (p[1] == '.' && p[2] == '/')
4904 				/* Convert '/./' --> '/' */
4905 				memmove(p, p+2, strlen(p+2) + 1);
4906 			else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
4907 				/* Convert 'dir/dir1/../dir2/'
4908 				 *     --> 'dir/dir2/'
4909 				 */
4910 				char *rp = p -1;
4911 				while (rp >= dirname) {
4912 					if (*rp == '/')
4913 						break;
4914 					--rp;
4915 				}
4916 				if (rp > dirname) {
4917 					strcpy(rp, p+3);
4918 					p = rp;
4919 				} else {
4920 					strcpy(dirname, p+4);
4921 					p = dirname;
4922 				}
4923 			} else
4924 				p++;
4925 		} else
4926 			p++;
4927 	}
4928 	p = dirname;
4929 	len = strlen(p);
4930 
4931 	if (archive_entry_filetype(file->entry) == AE_IFLNK) {
4932 		/* Convert symlink name too. */
4933 		pathname = archive_entry_symlink(file->entry);
4934 		archive_strcpy(&(file->symlink),  pathname);
4935 #if defined(_WIN32) || defined(__CYGWIN__)
4936 		/*
4937 		 * Convert a path-separator from '\' to  '/'
4938 		 */
4939 		if (archive_strlen(&(file->symlink)) > 0 &&
4940 		    cleanup_backslash_1(file->symlink.s) != 0) {
4941 			const wchar_t *wp =
4942 			    archive_entry_symlink_w(file->entry);
4943 			struct archive_wstring ws;
4944 
4945 			if (wp != NULL) {
4946 				int r;
4947 				archive_string_init(&ws);
4948 				archive_wstrcpy(&ws, wp);
4949 				cleanup_backslash_2(ws.s);
4950 				archive_string_empty(&(file->symlink));
4951 				r = archive_string_append_from_wcs(
4952 				    &(file->symlink),
4953 				    ws.s, ws.length);
4954 				archive_wstring_free(&ws);
4955 				if (r < 0 && errno == ENOMEM) {
4956 					archive_set_error(&a->archive, ENOMEM,
4957 					    "Can't allocate memory");
4958 					return (ARCHIVE_FATAL);
4959 				}
4960 			}
4961 		}
4962 #endif
4963 	}
4964 	/*
4965 	 * - Count up directory elements.
4966 	 * - Find out the position which points the last position of
4967 	 *   path separator('/').
4968 	 */
4969 	slash = NULL;
4970 	file->dircnt = 0;
4971 	for (; *p != '\0'; p++)
4972 		if (*p == '/') {
4973 			slash = p;
4974 			file->dircnt++;
4975 		}
4976 	if (slash == NULL) {
4977 		/* The pathname doesn't have a parent directory. */
4978 		file->parentdir.length = len;
4979 		archive_string_copy(&(file->basename), &(file->parentdir));
4980 		archive_string_empty(&(file->parentdir));
4981 		*file->parentdir.s = '\0';
4982 		return (ret);
4983 	}
4984 
4985 	/* Make a basename from dirname and slash */
4986 	*slash  = '\0';
4987 	file->parentdir.length = slash - dirname;
4988 	archive_strcpy(&(file->basename),  slash + 1);
4989 	if (archive_entry_filetype(file->entry) == AE_IFDIR)
4990 		file->dircnt ++;
4991 	return (ret);
4992 }
4993 
4994 /*
4995  * Register a entry to get a hardlink target.
4996  */
4997 static int
4998 isofile_register_hardlink(struct archive_write *a, struct isofile *file)
4999 {
5000 	struct iso9660 *iso9660 = a->format_data;
5001 	struct hardlink *hl;
5002 	const char *pathname;
5003 
5004 	archive_entry_set_nlink(file->entry, 1);
5005 	pathname = archive_entry_hardlink(file->entry);
5006 	if (pathname == NULL) {
5007 		/* This `file` is a hardlink target. */
5008 		hl = malloc(sizeof(*hl));
5009 		if (hl == NULL) {
5010 			archive_set_error(&a->archive, ENOMEM,
5011 			    "Can't allocate memory");
5012 			return (ARCHIVE_FATAL);
5013 		}
5014 		hl->nlink = 1;
5015 		/* A hardlink target must be the first position. */
5016 		file->hlnext = NULL;
5017 		hl->file_list.first = file;
5018 		hl->file_list.last = &(file->hlnext);
5019 		__archive_rb_tree_insert_node(&(iso9660->hardlink_rbtree),
5020 		    (struct archive_rb_node *)hl);
5021 	} else {
5022 		hl = (struct hardlink *)__archive_rb_tree_find_node(
5023 		    &(iso9660->hardlink_rbtree), pathname);
5024 		if (hl != NULL) {
5025 			/* Insert `file` entry into the tail. */
5026 			file->hlnext = NULL;
5027 			*hl->file_list.last = file;
5028 			hl->file_list.last = &(file->hlnext);
5029 			hl->nlink++;
5030 		}
5031 		archive_entry_unset_size(file->entry);
5032 	}
5033 
5034 	return (ARCHIVE_OK);
5035 }
5036 
5037 /*
5038  * Hardlinked files have to have the same location of extent.
5039  * We have to find out hardlink target entries for the entries
5040  * which have a hardlink target name.
5041  */
5042 static void
5043 isofile_connect_hardlink_files(struct iso9660 *iso9660)
5044 {
5045 	struct archive_rb_node *n;
5046 	struct hardlink *hl;
5047 	struct isofile *target, *nf;
5048 
5049 	ARCHIVE_RB_TREE_FOREACH(n, &(iso9660->hardlink_rbtree)) {
5050 		hl = (struct hardlink *)n;
5051 
5052 		/* The first entry must be a hardlink target. */
5053 		target = hl->file_list.first;
5054 		archive_entry_set_nlink(target->entry, hl->nlink);
5055 		/* Set a hardlink target to reference entries. */
5056 		for (nf = target->hlnext;
5057 		    nf != NULL; nf = nf->hlnext) {
5058 			nf->hardlink_target = target;
5059 			archive_entry_set_nlink(nf->entry, hl->nlink);
5060 		}
5061 	}
5062 }
5063 
5064 static int
5065 isofile_hd_cmp_node(const struct archive_rb_node *n1,
5066     const struct archive_rb_node *n2)
5067 {
5068 	const struct hardlink *h1 = (const struct hardlink *)n1;
5069 	const struct hardlink *h2 = (const struct hardlink *)n2;
5070 
5071 	return (strcmp(archive_entry_pathname(h1->file_list.first->entry),
5072 		       archive_entry_pathname(h2->file_list.first->entry)));
5073 }
5074 
5075 static int
5076 isofile_hd_cmp_key(const struct archive_rb_node *n, const void *key)
5077 {
5078 	const struct hardlink *h = (const struct hardlink *)n;
5079 
5080 	return (strcmp(archive_entry_pathname(h->file_list.first->entry),
5081 		       (const char *)key));
5082 }
5083 
5084 static void
5085 isofile_init_hardlinks(struct iso9660 *iso9660)
5086 {
5087 	static const struct archive_rb_tree_ops rb_ops = {
5088 		isofile_hd_cmp_node, isofile_hd_cmp_key,
5089 	};
5090 
5091 	__archive_rb_tree_init(&(iso9660->hardlink_rbtree), &rb_ops);
5092 }
5093 
5094 static void
5095 isofile_free_hardlinks(struct iso9660 *iso9660)
5096 {
5097 	struct archive_rb_node *n, *tmp;
5098 
5099 	ARCHIVE_RB_TREE_FOREACH_SAFE(n, &(iso9660->hardlink_rbtree), tmp) {
5100 		__archive_rb_tree_remove_node(&(iso9660->hardlink_rbtree), n);
5101 		free(n);
5102 	}
5103 }
5104 
5105 static struct isoent *
5106 isoent_new(struct isofile *file)
5107 {
5108 	struct isoent *isoent;
5109 	static const struct archive_rb_tree_ops rb_ops = {
5110 		isoent_cmp_node, isoent_cmp_key,
5111 	};
5112 
5113 	isoent = calloc(1, sizeof(*isoent));
5114 	if (isoent == NULL)
5115 		return (NULL);
5116 	isoent->file = file;
5117 	isoent->children.first = NULL;
5118 	isoent->children.last = &(isoent->children.first);
5119 	__archive_rb_tree_init(&(isoent->rbtree), &rb_ops);
5120 	isoent->subdirs.first = NULL;
5121 	isoent->subdirs.last = &(isoent->subdirs.first);
5122 	isoent->extr_rec_list.first = NULL;
5123 	isoent->extr_rec_list.last = &(isoent->extr_rec_list.first);
5124 	isoent->extr_rec_list.current = NULL;
5125 	if (archive_entry_filetype(file->entry) == AE_IFDIR)
5126 		isoent->dir = 1;
5127 
5128 	return (isoent);
5129 }
5130 
5131 static inline struct isoent *
5132 isoent_clone(struct isoent *src)
5133 {
5134 	return (isoent_new(src->file));
5135 }
5136 
5137 static void
5138 _isoent_free(struct isoent *isoent)
5139 {
5140 	struct extr_rec *er, *er_next;
5141 
5142 	free(isoent->children_sorted);
5143 	free(isoent->identifier);
5144 	er = isoent->extr_rec_list.first;
5145 	while (er != NULL) {
5146 		er_next = er->next;
5147 		free(er);
5148 		er = er_next;
5149 	}
5150 	free(isoent);
5151 }
5152 
5153 static void
5154 isoent_free_all(struct isoent *isoent)
5155 {
5156 	struct isoent *np, *np_temp;
5157 
5158 	if (isoent == NULL)
5159 		return;
5160 	np = isoent;
5161 	for (;;) {
5162 		if (np->dir) {
5163 			if (np->children.first != NULL) {
5164 				/* Enter to sub directories. */
5165 				np = np->children.first;
5166 				continue;
5167 			}
5168 		}
5169 		for (;;) {
5170 			np_temp = np;
5171 			if (np->chnext == NULL) {
5172 				/* Return to the parent directory. */
5173 				np = np->parent;
5174 				_isoent_free(np_temp);
5175 				if (np == np_temp)
5176 					return;
5177 			} else {
5178 				np = np->chnext;
5179 				_isoent_free(np_temp);
5180 				break;
5181 			}
5182 		}
5183 	}
5184 }
5185 
5186 static struct isoent *
5187 isoent_create_virtual_dir(struct archive_write *a, struct iso9660 *iso9660, const char *pathname)
5188 {
5189 	struct isofile *file;
5190 	struct isoent *isoent;
5191 
5192 	file = isofile_new(a, NULL);
5193 	if (file == NULL)
5194 		return (NULL);
5195 	archive_entry_set_pathname(file->entry, pathname);
5196 	archive_entry_unset_mtime(file->entry);
5197 	archive_entry_unset_atime(file->entry);
5198 	archive_entry_unset_ctime(file->entry);
5199 	archive_entry_set_uid(file->entry, getuid());
5200 	archive_entry_set_gid(file->entry, getgid());
5201 	archive_entry_set_mode(file->entry, 0555 | AE_IFDIR);
5202 	archive_entry_set_nlink(file->entry, 2);
5203 	if (isofile_gen_utility_names(a, file) < ARCHIVE_WARN) {
5204 		isofile_free(file);
5205 		return (NULL);
5206 	}
5207 	isofile_add_entry(iso9660, file);
5208 
5209 	isoent = isoent_new(file);
5210 	if (isoent == NULL)
5211 		return (NULL);
5212 	isoent->dir = 1;
5213 	isoent->virtual = 1;
5214 
5215 	return (isoent);
5216 }
5217 
5218 static int
5219 isoent_cmp_node(const struct archive_rb_node *n1,
5220     const struct archive_rb_node *n2)
5221 {
5222 	const struct isoent *e1 = (const struct isoent *)n1;
5223 	const struct isoent *e2 = (const struct isoent *)n2;
5224 
5225 	return (strcmp(e1->file->basename.s, e2->file->basename.s));
5226 }
5227 
5228 static int
5229 isoent_cmp_key(const struct archive_rb_node *n, const void *key)
5230 {
5231 	const struct isoent *e = (const struct isoent *)n;
5232 
5233 	return (strcmp(e->file->basename.s, (const char *)key));
5234 }
5235 
5236 static int
5237 isoent_add_child_head(struct isoent *parent, struct isoent *child)
5238 {
5239 
5240 	if (!__archive_rb_tree_insert_node(
5241 	    &(parent->rbtree), (struct archive_rb_node *)child))
5242 		return (0);
5243 	if ((child->chnext = parent->children.first) == NULL)
5244 		parent->children.last = &(child->chnext);
5245 	parent->children.first = child;
5246 	parent->children.cnt++;
5247 	child->parent = parent;
5248 
5249 	/* Add a child to a sub-directory chain */
5250 	if (child->dir) {
5251 		if ((child->drnext = parent->subdirs.first) == NULL)
5252 			parent->subdirs.last = &(child->drnext);
5253 		parent->subdirs.first = child;
5254 		parent->subdirs.cnt++;
5255 		child->parent = parent;
5256 	} else
5257 		child->drnext = NULL;
5258 	return (1);
5259 }
5260 
5261 static int
5262 isoent_add_child_tail(struct isoent *parent, struct isoent *child)
5263 {
5264 
5265 	if (!__archive_rb_tree_insert_node(
5266 	    &(parent->rbtree), (struct archive_rb_node *)child))
5267 		return (0);
5268 	child->chnext = NULL;
5269 	*parent->children.last = child;
5270 	parent->children.last = &(child->chnext);
5271 	parent->children.cnt++;
5272 	child->parent = parent;
5273 
5274 	/* Add a child to a sub-directory chain */
5275 	child->drnext = NULL;
5276 	if (child->dir) {
5277 		*parent->subdirs.last = child;
5278 		parent->subdirs.last = &(child->drnext);
5279 		parent->subdirs.cnt++;
5280 		child->parent = parent;
5281 	}
5282 	return (1);
5283 }
5284 
5285 static void
5286 isoent_remove_child(struct isoent *parent, struct isoent *child)
5287 {
5288 	struct isoent *ent;
5289 
5290 	/* Remove a child entry from children chain. */
5291 	ent = parent->children.first;
5292 	while (ent->chnext != child)
5293 		ent = ent->chnext;
5294 	if ((ent->chnext = ent->chnext->chnext) == NULL)
5295 		parent->children.last = &(ent->chnext);
5296 	parent->children.cnt--;
5297 
5298 	if (child->dir) {
5299 		/* Remove a child entry from sub-directory chain. */
5300 		ent = parent->subdirs.first;
5301 		while (ent->drnext != child)
5302 			ent = ent->drnext;
5303 		if ((ent->drnext = ent->drnext->drnext) == NULL)
5304 			parent->subdirs.last = &(ent->drnext);
5305 		parent->subdirs.cnt--;
5306 	}
5307 
5308 	__archive_rb_tree_remove_node(&(parent->rbtree),
5309 	    (struct archive_rb_node *)child);
5310 }
5311 
5312 static int
5313 isoent_clone_tree(struct archive_write *a, struct isoent **nroot,
5314     struct isoent *root)
5315 {
5316 	struct isoent *np, *xroot, *newent;
5317 
5318 	np = root;
5319 	xroot = NULL;
5320 	do {
5321 		newent = isoent_clone(np);
5322 		if (newent == NULL) {
5323 			archive_set_error(&a->archive, ENOMEM,
5324 			    "Can't allocate memory");
5325 			return (ARCHIVE_FATAL);
5326 		}
5327 		if (xroot == NULL) {
5328 			*nroot = xroot = newent;
5329 			newent->parent = xroot;
5330 		} else
5331 			isoent_add_child_tail(xroot, newent);
5332 		if (np->dir && np->children.first != NULL) {
5333 			/* Enter to sub directories. */
5334 			np = np->children.first;
5335 			xroot = newent;
5336 			continue;
5337 		}
5338 		while (np != np->parent) {
5339 			if (np->chnext == NULL) {
5340 				/* Return to the parent directory. */
5341 				np = np->parent;
5342 				xroot = xroot->parent;
5343 			} else {
5344 				np = np->chnext;
5345 				break;
5346 			}
5347 		}
5348 	} while (np != np->parent);
5349 
5350 	return (ARCHIVE_OK);
5351 }
5352 
5353 /*
5354  * Setup directory locations.
5355  */
5356 static void
5357 isoent_setup_directory_location(struct iso9660 *iso9660, int location,
5358     struct vdd *vdd)
5359 {
5360 	struct isoent *np;
5361 	int depth;
5362 
5363 	vdd->total_dir_block = 0;
5364 	depth = 0;
5365 	np = vdd->rootent;
5366 	do {
5367 		int block;
5368 
5369 		np->dir_block = calculate_directory_descriptors(
5370 		    iso9660, vdd, np, depth);
5371 		vdd->total_dir_block += np->dir_block;
5372 		np->dir_location = location;
5373 		location += np->dir_block;
5374 		block = extra_setup_location(np, location);
5375 		vdd->total_dir_block += block;
5376 		location += block;
5377 
5378 		if (np->subdirs.first != NULL && depth + 1 < vdd->max_depth) {
5379 			/* Enter to sub directories. */
5380 			np = np->subdirs.first;
5381 			depth++;
5382 			continue;
5383 		}
5384 		while (np != np->parent) {
5385 			if (np->drnext == NULL) {
5386 				/* Return to the parent directory. */
5387 				np = np->parent;
5388 				depth--;
5389 			} else {
5390 				np = np->drnext;
5391 				break;
5392 			}
5393 		}
5394 	} while (np != np->parent);
5395 }
5396 
5397 static void
5398 _isoent_file_location(struct iso9660 *iso9660, struct isoent *isoent,
5399     int *symlocation)
5400 {
5401 	struct isoent **children;
5402 	int n;
5403 
5404 	if (isoent->children.cnt == 0)
5405 		return;
5406 
5407 	children = isoent->children_sorted;
5408 	for (n = 0; n < isoent->children.cnt; n++) {
5409 		struct isoent *np;
5410 		struct isofile *file;
5411 
5412 		np = children[n];
5413 		if (np->dir)
5414 			continue;
5415 		if (np == iso9660->el_torito.boot)
5416 			continue;
5417 		file = np->file;
5418 		if (file->boot || file->hardlink_target != NULL)
5419 			continue;
5420 		if (archive_entry_filetype(file->entry) == AE_IFLNK ||
5421 		    file->content.size == 0) {
5422 			/*
5423 			 * Do not point a valid location.
5424 			 * Make sure entry is not hardlink file.
5425 			 */
5426 			file->content.location = (*symlocation)--;
5427 			continue;
5428 		}
5429 
5430 		file->write_content = 1;
5431 	}
5432 }
5433 
5434 /*
5435  * Setup file locations.
5436  */
5437 static void
5438 isoent_setup_file_location(struct iso9660 *iso9660, int location)
5439 {
5440 	struct isoent *isoent;
5441 	struct isoent *np;
5442 	struct isofile *file;
5443 	size_t size;
5444 	int block;
5445 	int depth;
5446 	int joliet;
5447 	int symlocation;
5448 	int total_block;
5449 
5450 	iso9660->total_file_block = 0;
5451 	if ((isoent = iso9660->el_torito.catalog) != NULL) {
5452 		isoent->file->content.location = location;
5453 		block = (int)((archive_entry_size(isoent->file->entry) +
5454 		    LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS);
5455 		location += block;
5456 		iso9660->total_file_block += block;
5457 	}
5458 	if ((isoent = iso9660->el_torito.boot) != NULL) {
5459 		isoent->file->content.location = location;
5460 		size = fd_boot_image_size(iso9660->el_torito.media_type);
5461 		if (size == 0)
5462 			size = (size_t)archive_entry_size(isoent->file->entry);
5463 		block = ((int)size + LOGICAL_BLOCK_SIZE -1)
5464 		    >> LOGICAL_BLOCK_BITS;
5465 		location += block;
5466 		iso9660->total_file_block += block;
5467 		isoent->file->content.blocks = block;
5468 	}
5469 
5470 	depth = 0;
5471 	symlocation = -16;
5472 	if (!iso9660->opt.rr && iso9660->opt.joliet) {
5473 		joliet = 1;
5474 		np = iso9660->joliet.rootent;
5475 	} else {
5476 		joliet = 0;
5477 		np = iso9660->primary.rootent;
5478 	}
5479 	do {
5480 		_isoent_file_location(iso9660, np, &symlocation);
5481 
5482 		if (np->subdirs.first != NULL &&
5483 		    (joliet ||
5484 		    ((iso9660->opt.rr == OPT_RR_DISABLED &&
5485 		      depth + 2 < iso9660->primary.max_depth) ||
5486 		     (iso9660->opt.rr &&
5487 		      depth + 1 < iso9660->primary.max_depth)))) {
5488 			/* Enter to sub directories. */
5489 			np = np->subdirs.first;
5490 			depth++;
5491 			continue;
5492 		}
5493 		while (np != np->parent) {
5494 			if (np->drnext == NULL) {
5495 				/* Return to the parent directory. */
5496 				np = np->parent;
5497 				depth--;
5498 			} else {
5499 				np = np->drnext;
5500 				break;
5501 			}
5502 		}
5503 	} while (np != np->parent);
5504 
5505 	total_block = 0;
5506 	for (file = iso9660->data_file_list.first;
5507 	    file != NULL; file = file->datanext) {
5508 
5509 		if (!file->write_content)
5510 			continue;
5511 
5512 		file->cur_content = &(file->content);
5513 		do {
5514 			file->cur_content->location = location;
5515 			location += file->cur_content->blocks;
5516 			total_block += file->cur_content->blocks;
5517 			/* Next fragment */
5518 			file->cur_content = file->cur_content->next;
5519 		} while (file->cur_content != NULL);
5520 	}
5521 	iso9660->total_file_block += total_block;
5522 }
5523 
5524 static int
5525 get_path_component(char *name, size_t n, const char *fn)
5526 {
5527 	char *p;
5528 	size_t l;
5529 
5530 	p = strchr(fn, '/');
5531 	if (p == NULL) {
5532 		if ((l = strlen(fn)) == 0)
5533 			return (0);
5534 	} else
5535 		l = p - fn;
5536 	if (l > n -1)
5537 		return (-1);
5538 	memcpy(name, fn, l);
5539 	name[l] = '\0';
5540 
5541 	return ((int)l);
5542 }
5543 
5544 /*
5545  * Add a new entry into the tree.
5546  */
5547 static int
5548 isoent_tree(struct archive_write *a, struct isoent **isoentpp)
5549 {
5550 #if defined(_WIN32) && !defined(__CYGWIN__)
5551 	char name[_MAX_FNAME];/* Included null terminator size. */
5552 #elif defined(NAME_MAX) && NAME_MAX >= 255
5553 	char name[NAME_MAX+1];
5554 #else
5555 	char name[256];
5556 #endif
5557 	struct iso9660 *iso9660 = a->format_data;
5558 	struct isoent *dent, *isoent, *np;
5559 	struct isofile *f1, *f2;
5560 	const char *fn, *p;
5561 	int l;
5562 
5563 	isoent = *isoentpp;
5564 	dent = iso9660->primary.rootent;
5565 	if (isoent->file->parentdir.length > 0)
5566 		fn = p = isoent->file->parentdir.s;
5567 	else
5568 		fn = p = "";
5569 
5570 	/*
5571 	 * If the path of the parent directory of `isoent' entry is
5572 	 * the same as the path of `cur_dirent', add isoent to
5573 	 * `cur_dirent'.
5574 	 */
5575 	if (archive_strlen(&(iso9660->cur_dirstr))
5576 	      == archive_strlen(&(isoent->file->parentdir)) &&
5577 	    strcmp(iso9660->cur_dirstr.s, fn) == 0) {
5578 		if (!isoent_add_child_tail(iso9660->cur_dirent, isoent)) {
5579 			np = (struct isoent *)__archive_rb_tree_find_node(
5580 			    &(iso9660->cur_dirent->rbtree),
5581 			    isoent->file->basename.s);
5582 			goto same_entry;
5583 		}
5584 		return (ARCHIVE_OK);
5585 	}
5586 
5587 	for (;;) {
5588 		l = get_path_component(name, sizeof(name), fn);
5589 		if (l == 0) {
5590 			np = NULL;
5591 			break;
5592 		}
5593 		if (l < 0) {
5594 			archive_set_error(&a->archive,
5595 			    ARCHIVE_ERRNO_MISC,
5596 			    "A name buffer is too small");
5597 			_isoent_free(isoent);
5598 			return (ARCHIVE_FATAL);
5599 		}
5600 
5601 		np = isoent_find_child(dent, name);
5602 		if (np == NULL || fn[0] == '\0')
5603 			break;
5604 
5605 		/* Find next subdirectory. */
5606 		if (!np->dir) {
5607 			/* NOT Directory! */
5608 			archive_set_error(&a->archive,
5609 			    ARCHIVE_ERRNO_MISC,
5610 			    "`%s' is not directory, we cannot insert `%s' ",
5611 			    archive_entry_pathname(np->file->entry),
5612 			    archive_entry_pathname(isoent->file->entry));
5613 			_isoent_free(isoent);
5614 			*isoentpp = NULL;
5615 			return (ARCHIVE_FAILED);
5616 		}
5617 		fn += l;
5618 		if (fn[0] == '/')
5619 			fn++;
5620 		dent = np;
5621 	}
5622 	if (np == NULL) {
5623 		/*
5624 		 * Create virtual parent directories.
5625 		 */
5626 		while (fn[0] != '\0') {
5627 			struct isoent *vp;
5628 			struct archive_string as;
5629 
5630 			archive_string_init(&as);
5631 			archive_strncat(&as, p, fn - p + l);
5632 			if (as.s[as.length-1] == '/') {
5633 				as.s[as.length-1] = '\0';
5634 				as.length--;
5635 			}
5636 			vp = isoent_create_virtual_dir(a, iso9660, as.s);
5637 			if (vp == NULL) {
5638 				archive_string_free(&as);
5639 				archive_set_error(&a->archive, ENOMEM,
5640 				    "Can't allocate memory");
5641 				_isoent_free(isoent);
5642 				*isoentpp = NULL;
5643 				return (ARCHIVE_FATAL);
5644 			}
5645 			archive_string_free(&as);
5646 
5647 			if (vp->file->dircnt > iso9660->dircnt_max)
5648 				iso9660->dircnt_max = vp->file->dircnt;
5649 			isoent_add_child_tail(dent, vp);
5650 			np = vp;
5651 
5652 			fn += l;
5653 			if (fn[0] == '/')
5654 				fn++;
5655 			l = get_path_component(name, sizeof(name), fn);
5656 			if (l < 0) {
5657 				archive_string_free(&as);
5658 				archive_set_error(&a->archive,
5659 				    ARCHIVE_ERRNO_MISC,
5660 				    "A name buffer is too small");
5661 				_isoent_free(isoent);
5662 				*isoentpp = NULL;
5663 				return (ARCHIVE_FATAL);
5664 			}
5665 			dent = np;
5666 		}
5667 
5668 		/* Found out the parent directory where isoent can be
5669 		 * inserted. */
5670 		iso9660->cur_dirent = dent;
5671 		archive_string_empty(&(iso9660->cur_dirstr));
5672 		archive_string_ensure(&(iso9660->cur_dirstr),
5673 		    archive_strlen(&(dent->file->parentdir)) +
5674 		    archive_strlen(&(dent->file->basename)) + 2);
5675 		if (archive_strlen(&(dent->file->parentdir)) +
5676 		    archive_strlen(&(dent->file->basename)) == 0)
5677 			iso9660->cur_dirstr.s[0] = 0;
5678 		else {
5679 			if (archive_strlen(&(dent->file->parentdir)) > 0) {
5680 				archive_string_copy(&(iso9660->cur_dirstr),
5681 				    &(dent->file->parentdir));
5682 				archive_strappend_char(&(iso9660->cur_dirstr), '/');
5683 			}
5684 			archive_string_concat(&(iso9660->cur_dirstr),
5685 			    &(dent->file->basename));
5686 		}
5687 
5688 		if (!isoent_add_child_tail(dent, isoent)) {
5689 			np = (struct isoent *)__archive_rb_tree_find_node(
5690 			    &(dent->rbtree), isoent->file->basename.s);
5691 			goto same_entry;
5692 		}
5693 		return (ARCHIVE_OK);
5694 	}
5695 
5696 same_entry:
5697 	/*
5698 	 * We have already has the entry the filename of which is
5699 	 * the same.
5700 	 */
5701 	f1 = np->file;
5702 	f2 = isoent->file;
5703 
5704 	/* If the file type of entries is different,
5705 	 * we cannot handle it. */
5706 	if (archive_entry_filetype(f1->entry) !=
5707 	    archive_entry_filetype(f2->entry)) {
5708 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
5709 		    "Found duplicate entries `%s' and its file type is "
5710 		    "different",
5711 		    archive_entry_pathname(f1->entry));
5712 		_isoent_free(isoent);
5713 		*isoentpp = NULL;
5714 		return (ARCHIVE_FAILED);
5715 	}
5716 
5717 	/* Swap file entries. */
5718 	np->file = f2;
5719 	isoent->file = f1;
5720 	np->virtual = 0;
5721 
5722 	_isoent_free(isoent);
5723 	*isoentpp = np;
5724 	return (ARCHIVE_OK);
5725 }
5726 
5727 /*
5728  * Find a entry from `isoent'
5729  */
5730 static struct isoent *
5731 isoent_find_child(struct isoent *isoent, const char *child_name)
5732 {
5733 	struct isoent *np;
5734 
5735 	np = (struct isoent *)__archive_rb_tree_find_node(
5736 	    &(isoent->rbtree), child_name);
5737 	return (np);
5738 }
5739 
5740 /*
5741  * Find a entry full-path of which is specified by `fn' parameter,
5742  * in the tree.
5743  */
5744 static struct isoent *
5745 isoent_find_entry(struct isoent *rootent, const char *fn)
5746 {
5747 #if defined(_WIN32) && !defined(__CYGWIN__)
5748 	char name[_MAX_FNAME];/* Included null terminator size. */
5749 #elif defined(NAME_MAX) && NAME_MAX >= 255
5750 	char name[NAME_MAX+1];
5751 #else
5752 	char name[256];
5753 #endif
5754 	struct isoent *isoent, *np;
5755 	int l;
5756 
5757 	isoent = rootent;
5758 	np = NULL;
5759 	for (;;) {
5760 		l = get_path_component(name, sizeof(name), fn);
5761 		if (l == 0)
5762 			break;
5763 		fn += l;
5764 		if (fn[0] == '/')
5765 			fn++;
5766 
5767 		np = isoent_find_child(isoent, name);
5768 		if (np == NULL)
5769 			break;
5770 		if (fn[0] == '\0')
5771 			break;/* We found out the entry */
5772 
5773 		/* Try sub directory. */
5774 		isoent = np;
5775 		np = NULL;
5776 		if (!isoent->dir)
5777 			break;/* Not directory */
5778 	}
5779 
5780 	return (np);
5781 }
5782 
5783 /*
5784  * Following idr_* functions are used for resolving duplicated filenames
5785  * and unreceivable filenames to generate ISO9660/Joliet Identifiers.
5786  */
5787 
5788 static void
5789 idr_relaxed_filenames(char *map)
5790 {
5791 	int i;
5792 
5793 	for (i = 0x21; i <= 0x2F; i++)
5794 		map[i] = 1;
5795 	for (i = 0x3A; i <= 0x41; i++)
5796 		map[i] = 1;
5797 	for (i = 0x5B; i <= 0x5E; i++)
5798 		map[i] = 1;
5799 	map[0x60] = 1;
5800 	for (i = 0x7B; i <= 0x7E; i++)
5801 		map[i] = 1;
5802 }
5803 
5804 static void
5805 idr_init(struct iso9660 *iso9660, struct vdd *vdd, struct idr *idr)
5806 {
5807 
5808 	idr->idrent_pool = NULL;
5809 	idr->pool_size = 0;
5810 	if (vdd->vdd_type != VDD_JOLIET) {
5811 		if (iso9660->opt.iso_level <= 3) {
5812 			memcpy(idr->char_map, d_characters_map,
5813 			    sizeof(idr->char_map));
5814 		} else {
5815 			memcpy(idr->char_map, d1_characters_map,
5816 			    sizeof(idr->char_map));
5817 			idr_relaxed_filenames(idr->char_map);
5818 		}
5819 	}
5820 }
5821 
5822 static void
5823 idr_cleanup(struct idr *idr)
5824 {
5825 	free(idr->idrent_pool);
5826 }
5827 
5828 static int
5829 idr_ensure_poolsize(struct archive_write *a, struct idr *idr,
5830     int cnt)
5831 {
5832 
5833 	if (idr->pool_size < cnt) {
5834 		void *p;
5835 		const int bk = (1 << 7) - 1;
5836 		int psize;
5837 
5838 		psize = (cnt + bk) & ~bk;
5839 		p = realloc(idr->idrent_pool, sizeof(struct idrent) * psize);
5840 		if (p == NULL) {
5841 			archive_set_error(&a->archive, ENOMEM,
5842 			    "Can't allocate memory");
5843 			return (ARCHIVE_FATAL);
5844 		}
5845 		idr->idrent_pool = (struct idrent *)p;
5846 		idr->pool_size = psize;
5847 	}
5848 	return (ARCHIVE_OK);
5849 }
5850 
5851 static int
5852 idr_start(struct archive_write *a, struct idr *idr, int cnt, int ffmax,
5853     int num_size, int null_size, const struct archive_rb_tree_ops *rbt_ops)
5854 {
5855 	int r;
5856 
5857 	(void)ffmax; /* UNUSED */
5858 
5859 	r = idr_ensure_poolsize(a, idr, cnt);
5860 	if (r != ARCHIVE_OK)
5861 		return (r);
5862 	__archive_rb_tree_init(&(idr->rbtree), rbt_ops);
5863 	idr->wait_list.first = NULL;
5864 	idr->wait_list.last = &(idr->wait_list.first);
5865 	idr->pool_idx = 0;
5866 	idr->num_size = num_size;
5867 	idr->null_size = null_size;
5868 	return (ARCHIVE_OK);
5869 }
5870 
5871 static void
5872 idr_register(struct idr *idr, struct isoent *isoent, int weight, int noff)
5873 {
5874 	struct idrent *idrent, *n;
5875 
5876 	idrent = &(idr->idrent_pool[idr->pool_idx++]);
5877 	idrent->wnext = idrent->avail = NULL;
5878 	idrent->isoent = isoent;
5879 	idrent->weight = weight;
5880 	idrent->noff = noff;
5881 	idrent->rename_num = 0;
5882 
5883 	if (!__archive_rb_tree_insert_node(&(idr->rbtree), &(idrent->rbnode))) {
5884 		n = (struct idrent *)__archive_rb_tree_find_node(
5885 		    &(idr->rbtree), idrent->isoent);
5886 		if (n != NULL) {
5887 			/* this `idrent' needs to rename. */
5888 			idrent->avail = n;
5889 			*idr->wait_list.last = idrent;
5890 			idr->wait_list.last = &(idrent->wnext);
5891 		}
5892 	}
5893 }
5894 
5895 static void
5896 idr_extend_identifier(struct idrent *wnp, int numsize, int nullsize)
5897 {
5898 	unsigned char *p;
5899 	int wnp_ext_off;
5900 
5901 	wnp_ext_off = wnp->isoent->ext_off;
5902 	if (wnp->noff + numsize != wnp_ext_off) {
5903 		p = (unsigned char *)wnp->isoent->identifier;
5904 		/* Extend the filename; foo.c --> foo___.c */
5905 		memmove(p + wnp->noff + numsize, p + wnp_ext_off,
5906 		    wnp->isoent->ext_len + nullsize);
5907 		wnp->isoent->ext_off = wnp_ext_off = wnp->noff + numsize;
5908 		wnp->isoent->id_len = wnp_ext_off + wnp->isoent->ext_len;
5909 	}
5910 }
5911 
5912 static void
5913 idr_resolve(struct idr *idr, void (*fsetnum)(unsigned char *p, int num))
5914 {
5915 	struct idrent *n;
5916 	unsigned char *p;
5917 
5918 	for (n = idr->wait_list.first; n != NULL; n = n->wnext) {
5919 		idr_extend_identifier(n, idr->num_size, idr->null_size);
5920 		p = (unsigned char *)n->isoent->identifier + n->noff;
5921 		do {
5922 			fsetnum(p, n->avail->rename_num++);
5923 		} while (!__archive_rb_tree_insert_node(
5924 		    &(idr->rbtree), &(n->rbnode)));
5925 	}
5926 }
5927 
5928 static void
5929 idr_set_num(unsigned char *p, int num)
5930 {
5931 	static const char xdig[] = {
5932 		'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
5933 		'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
5934 		'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
5935 		'U', 'V', 'W', 'X', 'Y', 'Z'
5936 	};
5937 
5938 	num %= sizeof(xdig) * sizeof(xdig) * sizeof(xdig);
5939 	p[0] = xdig[(num / (sizeof(xdig) * sizeof(xdig)))];
5940 	num %= sizeof(xdig) * sizeof(xdig);
5941 	p[1] = xdig[ (num / sizeof(xdig))];
5942 	num %= sizeof(xdig);
5943 	p[2] = xdig[num];
5944 }
5945 
5946 static void
5947 idr_set_num_beutf16(unsigned char *p, int num)
5948 {
5949 	static const uint16_t xdig[] = {
5950 		0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
5951 		0x0036, 0x0037, 0x0038, 0x0039,
5952 		0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046,
5953 		0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C,
5954 		0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052,
5955 		0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
5956 		0x0059, 0x005A
5957 	};
5958 #define XDIG_CNT	(sizeof(xdig)/sizeof(xdig[0]))
5959 
5960 	num %= XDIG_CNT * XDIG_CNT * XDIG_CNT;
5961 	archive_be16enc(p, xdig[(num / (XDIG_CNT * XDIG_CNT))]);
5962 	num %= XDIG_CNT * XDIG_CNT;
5963 	archive_be16enc(p+2, xdig[ (num / XDIG_CNT)]);
5964 	num %= XDIG_CNT;
5965 	archive_be16enc(p+4, xdig[num]);
5966 }
5967 
5968 /*
5969  * Generate ISO9660 Identifier.
5970  */
5971 static int
5972 isoent_gen_iso9660_identifier(struct archive_write *a, struct isoent *isoent,
5973     struct idr *idr)
5974 {
5975 	struct iso9660 *iso9660;
5976 	struct isoent *np;
5977 	char *p;
5978 	int l, r;
5979 	const char *char_map;
5980 	char allow_ldots, allow_multidot, allow_period, allow_vernum;
5981 	int fnmax, ffmax, dnmax;
5982 	static const struct archive_rb_tree_ops rb_ops = {
5983 		isoent_cmp_node_iso9660, isoent_cmp_key_iso9660
5984 	};
5985 
5986 	if (isoent->children.cnt == 0)
5987 		return (0);
5988 
5989 	iso9660 = a->format_data;
5990 	char_map = idr->char_map;
5991 	if (iso9660->opt.iso_level <= 3) {
5992 		allow_ldots = 0;
5993 		allow_multidot = 0;
5994 		allow_period = 1;
5995 		allow_vernum = iso9660->opt.allow_vernum;
5996 		if (iso9660->opt.iso_level == 1) {
5997 			fnmax = 8;
5998 			ffmax = 12;/* fnmax + '.' + 3 */
5999 			dnmax = 8;
6000 		} else {
6001 			fnmax = 30;
6002 			ffmax = 31;
6003 			dnmax = 31;
6004 		}
6005 	} else {
6006 		allow_ldots = allow_multidot = 1;
6007 		allow_period = allow_vernum = 0;
6008 		if (iso9660->opt.rr)
6009 			/*
6010 			 * MDR : The maximum size of Directory Record(254).
6011 			 * DRL : A Directory Record Length(33).
6012 			 * CE  : A size of SUSP CE System Use Entry(28).
6013 			 * MDR - DRL - CE = 254 - 33 - 28 = 193.
6014 			 */
6015 			fnmax = ffmax = dnmax = 193;
6016 		else
6017 			/*
6018 			 * XA  : CD-ROM XA System Use Extension
6019 			 *       Information(14).
6020 			 * MDR - DRL - XA = 254 - 33 -14 = 207.
6021 			 */
6022 			fnmax = ffmax = dnmax = 207;
6023 	}
6024 
6025 	r = idr_start(a, idr, isoent->children.cnt, ffmax, 3, 1, &rb_ops);
6026 	if (r < 0)
6027 		return (r);
6028 
6029 	for (np = isoent->children.first; np != NULL; np = np->chnext) {
6030 		char *dot, *xdot;
6031 		int ext_off, noff, weight;
6032 
6033 		l = (int)np->file->basename.length;
6034 		p = malloc(l+31+2+1);
6035 		if (p == NULL) {
6036 			archive_set_error(&a->archive, ENOMEM,
6037 			    "Can't allocate memory");
6038 			return (ARCHIVE_FATAL);
6039 		}
6040 		memcpy(p, np->file->basename.s, l);
6041 		p[l] = '\0';
6042 		np->identifier = p;
6043 
6044 		dot = xdot = NULL;
6045 		if (!allow_ldots) {
6046 			/*
6047 			 * If there is a '.' character at the first byte,
6048 			 * it has to be replaced by '_' character.
6049 			 */
6050 			if (*p == '.')
6051 				*p++ = '_';
6052 		}
6053 		for (;*p; p++) {
6054 			if (*p & 0x80) {
6055 				*p = '_';
6056 				continue;
6057 			}
6058 			if (char_map[(unsigned char)*p]) {
6059 				/* if iso-level is '4', a character '.' is
6060 				 * allowed by char_map. */
6061 				if (*p == '.') {
6062 					xdot = dot;
6063 					dot = p;
6064 				}
6065 				continue;
6066 			}
6067 			if (*p >= 'a' && *p <= 'z') {
6068 				*p -= 'a' - 'A';
6069 				continue;
6070 			}
6071 			if (*p == '.') {
6072 				xdot = dot;
6073 				dot = p;
6074 				if (allow_multidot)
6075 					continue;
6076 			}
6077 			*p = '_';
6078 		}
6079 		p = np->identifier;
6080 		weight = -1;
6081 		if (dot == NULL) {
6082 			int nammax;
6083 
6084 			if (np->dir)
6085 				nammax = dnmax;
6086 			else
6087 				nammax = fnmax;
6088 
6089 			if (l > nammax) {
6090 				p[nammax] = '\0';
6091 				weight = nammax;
6092 				ext_off = nammax;
6093 			} else
6094 				ext_off = l;
6095 		} else {
6096 			*dot = '.';
6097 			ext_off = (int)(dot - p);
6098 
6099 			if (iso9660->opt.iso_level == 1) {
6100 				if (dot - p <= 8) {
6101 					if (strlen(dot) > 4) {
6102 						/* A length of a file extension
6103 						 * must be less than 4 */
6104 						dot[4] = '\0';
6105 						weight = 0;
6106 					}
6107 				} else {
6108 					p[8] = dot[0];
6109 					p[9] = dot[1];
6110 					p[10] = dot[2];
6111 					p[11] = dot[3];
6112 					p[12] = '\0';
6113 					weight = 8;
6114 					ext_off = 8;
6115 				}
6116 			} else if (np->dir) {
6117 				if (l > dnmax) {
6118 					p[dnmax] = '\0';
6119 					weight = dnmax;
6120 					if (ext_off > dnmax)
6121 						ext_off = dnmax;
6122 				}
6123 			} else if (l > ffmax) {
6124 				int extlen = (int)strlen(dot);
6125 				int xdoff;
6126 
6127 				if (xdot != NULL)
6128 					xdoff = (int)(xdot - p);
6129 				else
6130 					xdoff = 0;
6131 
6132 				if (extlen > 1 && xdoff < fnmax-1) {
6133 					int off;
6134 
6135 					if (extlen > ffmax)
6136 						extlen = ffmax;
6137 					off = ffmax - extlen;
6138 					if (off == 0) {
6139 						/* A dot('.')  character
6140 						 * doesn't place to the first
6141 						 * byte of identifier. */
6142 						off ++;
6143 						extlen --;
6144 					}
6145 					memmove(p+off, dot, extlen);
6146 					p[ffmax] = '\0';
6147 					ext_off = off;
6148 					weight = off;
6149 #ifdef COMPAT_MKISOFS
6150 				} else if (xdoff >= fnmax-1) {
6151 					/* Simulate a bug(?) of mkisofs. */
6152 					p[fnmax-1] = '\0';
6153 					ext_off = fnmax-1;
6154 					weight = fnmax-1;
6155 #endif
6156 				} else {
6157 					p[fnmax] = '\0';
6158 					ext_off = fnmax;
6159 					weight = fnmax;
6160 				}
6161 			}
6162 		}
6163 		/* Save an offset of a file name extension to sort files. */
6164 		np->ext_off = ext_off;
6165 		np->ext_len = (int)strlen(&p[ext_off]);
6166 		np->id_len = l = ext_off + np->ext_len;
6167 
6168 		/* Make an offset of the number which is used to be set
6169 		 * hexadecimal number to avoid duplicate identifier. */
6170 		if (iso9660->opt.iso_level == 1) {
6171 			if (ext_off >= 5)
6172 				noff = 5;
6173 			else
6174 				noff = ext_off;
6175 		} else {
6176 			if (l == ffmax)
6177 				noff = ext_off - 3;
6178 			else if (l == ffmax-1)
6179 				noff = ext_off - 2;
6180 			else if (l == ffmax-2)
6181 				noff = ext_off - 1;
6182 			else
6183 				noff = ext_off;
6184 		}
6185 		/* Register entry to the identifier resolver. */
6186 		idr_register(idr, np, weight, noff);
6187 	}
6188 
6189 	/* Resolve duplicate identifier. */
6190 	idr_resolve(idr, idr_set_num);
6191 
6192 	/* Add a period and a version number to identifiers. */
6193 	for (np = isoent->children.first; np != NULL; np = np->chnext) {
6194 		if (!np->dir && np->rr_child == NULL) {
6195 			p = np->identifier + np->ext_off + np->ext_len;
6196 			if (np->ext_len == 0 && allow_period) {
6197 				*p++ = '.';
6198 				np->ext_len = 1;
6199 			}
6200 			if (np->ext_len == 1 && !allow_period) {
6201 				*--p = '\0';
6202 				np->ext_len = 0;
6203 			}
6204 			np->id_len = np->ext_off + np->ext_len;
6205 			if (allow_vernum) {
6206 				*p++ = ';';
6207 				*p++ = '1';
6208 				np->id_len += 2;
6209 			}
6210 			*p = '\0';
6211 		} else
6212 			np->id_len = np->ext_off + np->ext_len;
6213 		np->mb_len = np->id_len;
6214 	}
6215 	return (ARCHIVE_OK);
6216 }
6217 
6218 /*
6219  * Generate Joliet Identifier.
6220  */
6221 static int
6222 isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
6223     struct idr *idr)
6224 {
6225 	struct iso9660 *iso9660;
6226 	struct isoent *np;
6227 	unsigned char *p;
6228 	size_t l;
6229 	int r;
6230 	size_t ffmax, parent_len;
6231 	static const struct archive_rb_tree_ops rb_ops = {
6232 		isoent_cmp_node_joliet, isoent_cmp_key_joliet
6233 	};
6234 
6235 	if (isoent->children.cnt == 0)
6236 		return (0);
6237 
6238 	iso9660 = a->format_data;
6239 	if (iso9660->opt.joliet == OPT_JOLIET_LONGNAME)
6240 		ffmax = 206;
6241 	else
6242 		ffmax = 128;
6243 
6244 	r = idr_start(a, idr, isoent->children.cnt, (int)ffmax, 6, 2, &rb_ops);
6245 	if (r < 0)
6246 		return (r);
6247 
6248 	parent_len = 1;
6249 	for (np = isoent; np->parent != np; np = np->parent)
6250 		parent_len += np->mb_len + 1;
6251 
6252 	for (np = isoent->children.first; np != NULL; np = np->chnext) {
6253 		unsigned char *dot;
6254 		int ext_off, noff, weight;
6255 		size_t lt;
6256 
6257 		if ((l = np->file->basename_utf16.length) > ffmax)
6258 			l = ffmax;
6259 
6260 		p = malloc((l+1)*2);
6261 		if (p == NULL) {
6262 			archive_set_error(&a->archive, ENOMEM,
6263 			    "Can't allocate memory");
6264 			return (ARCHIVE_FATAL);
6265 		}
6266 		memcpy(p, np->file->basename_utf16.s, l);
6267 		p[l] = 0;
6268 		p[l+1] = 0;
6269 
6270 		np->identifier = (char *)p;
6271 		lt = l;
6272 		dot = p + l;
6273 		weight = 0;
6274 		while (lt > 0) {
6275 			if (!joliet_allowed_char(p[0], p[1]))
6276 				archive_be16enc(p, 0x005F); /* '_' */
6277 			else if (p[0] == 0 && p[1] == 0x2E) /* '.' */
6278 				dot = p;
6279 			p += 2;
6280 			lt -= 2;
6281 		}
6282 		ext_off = (int)(dot - (unsigned char *)np->identifier);
6283 		np->ext_off = ext_off;
6284 		np->ext_len = (int)l - ext_off;
6285 		np->id_len = (int)l;
6286 
6287 		/*
6288 		 * Get a length of MBS of a full-pathname.
6289 		 */
6290 		if (np->file->basename_utf16.length > ffmax) {
6291 			if (archive_strncpy_l(&iso9660->mbs,
6292 			    (const char *)np->identifier, l,
6293 				iso9660->sconv_from_utf16be) != 0 &&
6294 			    errno == ENOMEM) {
6295 				archive_set_error(&a->archive, errno,
6296 				    "No memory");
6297 				return (ARCHIVE_FATAL);
6298 			}
6299 			np->mb_len = (int)iso9660->mbs.length;
6300 			if (np->mb_len != (int)np->file->basename.length)
6301 				weight = np->mb_len;
6302 		} else
6303 			np->mb_len = (int)np->file->basename.length;
6304 
6305 		/* If a length of full-pathname is longer than 240 bytes,
6306 		 * it violates Joliet extensions regulation. */
6307 		if (parent_len > 240
6308 		    || np->mb_len > 240
6309 		    || parent_len + np->mb_len > 240) {
6310 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
6311 			    "The regulation of Joliet extensions;"
6312 			    " A length of a full-pathname of `%s' is "
6313 			    "longer than 240 bytes, (p=%d, b=%d)",
6314 			    archive_entry_pathname(np->file->entry),
6315 			    (int)parent_len, (int)np->mb_len);
6316 			return (ARCHIVE_FATAL);
6317 		}
6318 
6319 		/* Make an offset of the number which is used to be set
6320 		 * hexadecimal number to avoid duplicate identifier. */
6321 		if (l == ffmax)
6322 			noff = ext_off - 6;
6323 		else if (l == ffmax-2)
6324 			noff = ext_off - 4;
6325 		else if (l == ffmax-4)
6326 			noff = ext_off - 2;
6327 		else
6328 			noff = ext_off;
6329 		/* Register entry to the identifier resolver. */
6330 		idr_register(idr, np, weight, noff);
6331 	}
6332 
6333 	/* Resolve duplicate identifier with Joliet Volume. */
6334 	idr_resolve(idr, idr_set_num_beutf16);
6335 
6336 	return (ARCHIVE_OK);
6337 }
6338 
6339 /*
6340  * This comparing rule is according to ISO9660 Standard 9.3
6341  */
6342 static int
6343 isoent_cmp_iso9660_identifier(const struct isoent *p1, const struct isoent *p2)
6344 {
6345 	const char *s1, *s2;
6346 	int cmp;
6347 	int l;
6348 
6349 	s1 = p1->identifier;
6350 	s2 = p2->identifier;
6351 
6352 	/* Compare File Name */
6353 	l = p1->ext_off;
6354 	if (l > p2->ext_off)
6355 		l = p2->ext_off;
6356 	cmp = memcmp(s1, s2, l);
6357 	if (cmp != 0)
6358 		return (cmp);
6359 	if (p1->ext_off < p2->ext_off) {
6360 		s2 += l;
6361 		l = p2->ext_off - p1->ext_off;
6362 		while (l--)
6363 			if (0x20 != *s2++)
6364 				return (0x20
6365 				    - *(const unsigned char *)(s2 - 1));
6366 	} else if (p1->ext_off > p2->ext_off) {
6367 		s1 += l;
6368 		l = p1->ext_off - p2->ext_off;
6369 		while (l--)
6370 			if (0x20 != *s1++)
6371 				return (*(const unsigned char *)(s1 - 1)
6372 				    - 0x20);
6373 	}
6374 	/* Compare File Name Extension */
6375 	if (p1->ext_len == 0 && p2->ext_len == 0)
6376 		return (0);
6377 	if (p1->ext_len == 1 && p2->ext_len == 1)
6378 		return (0);
6379 	if (p1->ext_len <= 1)
6380 		return (-1);
6381 	if (p2->ext_len <= 1)
6382 		return (1);
6383 	l = p1->ext_len;
6384 	if (l > p2->ext_len)
6385 		l = p2->ext_len;
6386 	s1 = p1->identifier + p1->ext_off;
6387 	s2 = p2->identifier + p2->ext_off;
6388 	if (l > 1) {
6389 		cmp = memcmp(s1, s2, l);
6390 		if (cmp != 0)
6391 			return (cmp);
6392 	}
6393 	if (p1->ext_len < p2->ext_len) {
6394 		s2 += l;
6395 		l = p2->ext_len - p1->ext_len;
6396 		while (l--)
6397 			if (0x20 != *s2++)
6398 				return (0x20
6399 				    - *(const unsigned char *)(s2 - 1));
6400 	} else if (p1->ext_len > p2->ext_len) {
6401 		s1 += l;
6402 		l = p1->ext_len - p2->ext_len;
6403 		while (l--)
6404 			if (0x20 != *s1++)
6405 				return (*(const unsigned char *)(s1 - 1)
6406 				    - 0x20);
6407 	}
6408 	/* Compare File Version Number */
6409 	/* No operation. The File Version Number is always one. */
6410 
6411 	return (cmp);
6412 }
6413 
6414 static int
6415 isoent_cmp_node_iso9660(const struct archive_rb_node *n1,
6416     const struct archive_rb_node *n2)
6417 {
6418 	const struct idrent *e1 = (const struct idrent *)n1;
6419 	const struct idrent *e2 = (const struct idrent *)n2;
6420 
6421 	return (isoent_cmp_iso9660_identifier(e2->isoent, e1->isoent));
6422 }
6423 
6424 static int
6425 isoent_cmp_key_iso9660(const struct archive_rb_node *node, const void *key)
6426 {
6427 	const struct isoent *isoent = (const struct isoent *)key;
6428 	const struct idrent *idrent = (const struct idrent *)node;
6429 
6430 	return (isoent_cmp_iso9660_identifier(isoent, idrent->isoent));
6431 }
6432 
6433 static int
6434 isoent_cmp_joliet_identifier(const struct isoent *p1, const struct isoent *p2)
6435 {
6436 	const unsigned char *s1, *s2;
6437 	int cmp;
6438 	int l;
6439 
6440 	s1 = (const unsigned char *)p1->identifier;
6441 	s2 = (const unsigned char *)p2->identifier;
6442 
6443 	/* Compare File Name */
6444 	l = p1->ext_off;
6445 	if (l > p2->ext_off)
6446 		l = p2->ext_off;
6447 	cmp = memcmp(s1, s2, l);
6448 	if (cmp != 0)
6449 		return (cmp);
6450 	if (p1->ext_off < p2->ext_off) {
6451 		s2 += l;
6452 		l = p2->ext_off - p1->ext_off;
6453 		while (l--)
6454 			if (0 != *s2++)
6455 				return (- *(const unsigned char *)(s2 - 1));
6456 	} else if (p1->ext_off > p2->ext_off) {
6457 		s1 += l;
6458 		l = p1->ext_off - p2->ext_off;
6459 		while (l--)
6460 			if (0 != *s1++)
6461 				return (*(const unsigned char *)(s1 - 1));
6462 	}
6463 	/* Compare File Name Extension */
6464 	if (p1->ext_len == 0 && p2->ext_len == 0)
6465 		return (0);
6466 	if (p1->ext_len == 2 && p2->ext_len == 2)
6467 		return (0);
6468 	if (p1->ext_len <= 2)
6469 		return (-1);
6470 	if (p2->ext_len <= 2)
6471 		return (1);
6472 	l = p1->ext_len;
6473 	if (l > p2->ext_len)
6474 		l = p2->ext_len;
6475 	s1 = (unsigned char *)(p1->identifier + p1->ext_off);
6476 	s2 = (unsigned char *)(p2->identifier + p2->ext_off);
6477 	if (l > 1) {
6478 		cmp = memcmp(s1, s2, l);
6479 		if (cmp != 0)
6480 			return (cmp);
6481 	}
6482 	if (p1->ext_len < p2->ext_len) {
6483 		s2 += l;
6484 		l = p2->ext_len - p1->ext_len;
6485 		while (l--)
6486 			if (0 != *s2++)
6487 				return (- *(const unsigned char *)(s2 - 1));
6488 	} else if (p1->ext_len > p2->ext_len) {
6489 		s1 += l;
6490 		l = p1->ext_len - p2->ext_len;
6491 		while (l--)
6492 			if (0 != *s1++)
6493 				return (*(const unsigned char *)(s1 - 1));
6494 	}
6495 	/* Compare File Version Number */
6496 	/* No operation. The File Version Number is always one. */
6497 
6498 	return (cmp);
6499 }
6500 
6501 static int
6502 isoent_cmp_node_joliet(const struct archive_rb_node *n1,
6503     const struct archive_rb_node *n2)
6504 {
6505 	const struct idrent *e1 = (const struct idrent *)n1;
6506 	const struct idrent *e2 = (const struct idrent *)n2;
6507 
6508 	return (isoent_cmp_joliet_identifier(e2->isoent, e1->isoent));
6509 }
6510 
6511 static int
6512 isoent_cmp_key_joliet(const struct archive_rb_node *node, const void *key)
6513 {
6514 	const struct isoent *isoent = (const struct isoent *)key;
6515 	const struct idrent *idrent = (const struct idrent *)node;
6516 
6517 	return (isoent_cmp_joliet_identifier(isoent, idrent->isoent));
6518 }
6519 
6520 static int
6521 isoent_make_sorted_files(struct archive_write *a, struct isoent *isoent,
6522     struct idr *idr)
6523 {
6524 	struct archive_rb_node *rn;
6525 	struct isoent **children;
6526 
6527 	children = malloc(isoent->children.cnt * sizeof(struct isoent *));
6528 	if (children == NULL) {
6529 		archive_set_error(&a->archive, ENOMEM,
6530 		    "Can't allocate memory");
6531 		return (ARCHIVE_FATAL);
6532 	}
6533 	isoent->children_sorted = children;
6534 
6535 	ARCHIVE_RB_TREE_FOREACH(rn, &(idr->rbtree)) {
6536 		struct idrent *idrent = (struct idrent *)rn;
6537 		*children ++ = idrent->isoent;
6538 	}
6539 	return (ARCHIVE_OK);
6540 }
6541 
6542 /*
6543  * - Generate ISO9660 and Joliet identifiers from basenames.
6544  * - Sort files by each directory.
6545  */
6546 static int
6547 isoent_traverse_tree(struct archive_write *a, struct vdd* vdd)
6548 {
6549 	struct iso9660 *iso9660 = a->format_data;
6550 	struct isoent *np;
6551 	struct idr idr;
6552 	int depth;
6553 	int r;
6554 	int (*genid)(struct archive_write *, struct isoent *, struct idr *);
6555 
6556 	idr_init(iso9660, vdd, &idr);
6557 	np = vdd->rootent;
6558 	depth = 0;
6559 	if (vdd->vdd_type == VDD_JOLIET)
6560 		genid = isoent_gen_joliet_identifier;
6561 	else
6562 		genid = isoent_gen_iso9660_identifier;
6563 	do {
6564 		if (np->virtual &&
6565 		    !archive_entry_mtime_is_set(np->file->entry)) {
6566 			/* Set properly times to virtual directory */
6567 			archive_entry_set_mtime(np->file->entry,
6568 			    iso9660->birth_time, 0);
6569 			archive_entry_set_atime(np->file->entry,
6570 			    iso9660->birth_time, 0);
6571 			archive_entry_set_ctime(np->file->entry,
6572 			    iso9660->birth_time, 0);
6573 		}
6574 		if (np->children.first != NULL) {
6575 			if (vdd->vdd_type != VDD_JOLIET &&
6576 			    !iso9660->opt.rr && depth + 1 >= vdd->max_depth) {
6577 				if (np->children.cnt > 0)
6578 					iso9660->directories_too_deep = np;
6579 			} else {
6580 				/* Generate Identifier */
6581 				r = genid(a, np, &idr);
6582 				if (r < 0)
6583 					goto exit_traverse_tree;
6584 				r = isoent_make_sorted_files(a, np, &idr);
6585 				if (r < 0)
6586 					goto exit_traverse_tree;
6587 
6588 				if (np->subdirs.first != NULL &&
6589 				    depth + 1 < vdd->max_depth) {
6590 					/* Enter to sub directories. */
6591 					np = np->subdirs.first;
6592 					depth++;
6593 					continue;
6594 				}
6595 			}
6596 		}
6597 		while (np != np->parent) {
6598 			if (np->drnext == NULL) {
6599 				/* Return to the parent directory. */
6600 				np = np->parent;
6601 				depth--;
6602 			} else {
6603 				np = np->drnext;
6604 				break;
6605 			}
6606 		}
6607 	} while (np != np->parent);
6608 
6609 	r = ARCHIVE_OK;
6610 exit_traverse_tree:
6611 	idr_cleanup(&idr);
6612 
6613 	return (r);
6614 }
6615 
6616 /*
6617  * Collect directory entries into path_table by a directory depth.
6618  */
6619 static int
6620 isoent_collect_dirs(struct vdd *vdd, struct isoent *rootent, int depth)
6621 {
6622 	struct isoent *np;
6623 
6624 	if (rootent == NULL)
6625 		rootent = vdd->rootent;
6626 	np = rootent;
6627 	do {
6628 		/* Register current directory to pathtable. */
6629 		path_table_add_entry(&(vdd->pathtbl[depth]), np);
6630 
6631 		if (np->subdirs.first != NULL && depth + 1 < vdd->max_depth) {
6632 			/* Enter to sub directories. */
6633 			np = np->subdirs.first;
6634 			depth++;
6635 			continue;
6636 		}
6637 		while (np != rootent) {
6638 			if (np->drnext == NULL) {
6639 				/* Return to the parent directory. */
6640 				np = np->parent;
6641 				depth--;
6642 			} else {
6643 				np = np->drnext;
6644 				break;
6645 			}
6646 		}
6647 	} while (np != rootent);
6648 
6649 	return (ARCHIVE_OK);
6650 }
6651 
6652 /*
6653  * The entry whose number of levels in a directory hierarchy is
6654  * large than eight relocate to rr_move directory.
6655  */
6656 static int
6657 isoent_rr_move_dir(struct archive_write *a, struct isoent **rr_moved,
6658     struct isoent *curent, struct isoent **newent)
6659 {
6660 	struct iso9660 *iso9660 = a->format_data;
6661 	struct isoent *rrmoved, *mvent, *np;
6662 
6663 	if ((rrmoved = *rr_moved) == NULL) {
6664 		struct isoent *rootent = iso9660->primary.rootent;
6665 		/* There isn't rr_move entry.
6666 		 * Create rr_move entry and insert it into the root entry.
6667 		 */
6668 		rrmoved = isoent_create_virtual_dir(a, iso9660, "rr_moved");
6669 		if (rrmoved == NULL) {
6670 			archive_set_error(&a->archive, ENOMEM,
6671 			    "Can't allocate memory");
6672 			return (ARCHIVE_FATAL);
6673 		}
6674 		/* Add "rr_moved" entry to the root entry. */
6675 		isoent_add_child_head(rootent, rrmoved);
6676 		archive_entry_set_nlink(rootent->file->entry,
6677 		    archive_entry_nlink(rootent->file->entry) + 1);
6678 		/* Register "rr_moved" entry to second level pathtable. */
6679 		path_table_add_entry(&(iso9660->primary.pathtbl[1]), rrmoved);
6680 		/* Save rr_moved. */
6681 		*rr_moved = rrmoved;
6682 	}
6683 	/*
6684 	 * Make a clone of curent which is going to be relocated
6685 	 * to rr_moved.
6686 	 */
6687 	mvent = isoent_clone(curent);
6688 	if (mvent == NULL) {
6689 		archive_set_error(&a->archive, ENOMEM,
6690 		    "Can't allocate memory");
6691 		return (ARCHIVE_FATAL);
6692 	}
6693 	/* linking..  and use for creating "CL", "PL" and "RE" */
6694 	mvent->rr_parent = curent->parent;
6695 	curent->rr_child = mvent;
6696 	/*
6697 	 * Move subdirectories from the curent to mvent
6698 	 */
6699 	if (curent->children.first != NULL) {
6700 		*mvent->children.last = curent->children.first;
6701 		mvent->children.last = curent->children.last;
6702 	}
6703 	for (np = mvent->children.first; np != NULL; np = np->chnext)
6704 		np->parent = mvent;
6705 	mvent->children.cnt = curent->children.cnt;
6706 	curent->children.cnt = 0;
6707 	curent->children.first = NULL;
6708 	curent->children.last = &curent->children.first;
6709 
6710 	if (curent->subdirs.first != NULL) {
6711 		*mvent->subdirs.last = curent->subdirs.first;
6712 		mvent->subdirs.last = curent->subdirs.last;
6713 	}
6714 	mvent->subdirs.cnt = curent->subdirs.cnt;
6715 	curent->subdirs.cnt = 0;
6716 	curent->subdirs.first = NULL;
6717 	curent->subdirs.last = &curent->subdirs.first;
6718 
6719 	/*
6720 	 * The mvent becomes a child of the rr_moved entry.
6721 	 */
6722 	isoent_add_child_tail(rrmoved, mvent);
6723 	archive_entry_set_nlink(rrmoved->file->entry,
6724 	    archive_entry_nlink(rrmoved->file->entry) + 1);
6725 	/*
6726 	 * This entry which relocated to the rr_moved directory
6727 	 * has to set the flag as a file.
6728 	 * See also RRIP 4.1.5.1 Description of the "CL" System Use Entry.
6729 	 */
6730 	curent->dir = 0;
6731 
6732 	*newent = mvent;
6733 
6734 	return (ARCHIVE_OK);
6735 }
6736 
6737 static int
6738 isoent_rr_move(struct archive_write *a)
6739 {
6740 	struct iso9660 *iso9660 = a->format_data;
6741 	struct path_table *pt;
6742 	struct isoent *rootent, *rr_moved;
6743 	struct isoent *np, *last;
6744 	int r;
6745 
6746 	pt = &(iso9660->primary.pathtbl[MAX_DEPTH-1]);
6747 	/* There aren't level 8 directories reaching a deeper level. */
6748 	if (pt->cnt == 0)
6749 		return (ARCHIVE_OK);
6750 
6751 	rootent = iso9660->primary.rootent;
6752 	/* If "rr_moved" directory is already existing,
6753 	 * we have to use it. */
6754 	rr_moved = isoent_find_child(rootent, "rr_moved");
6755 	if (rr_moved != NULL &&
6756 	    rr_moved != rootent->children.first) {
6757 		/*
6758 		 * It's necessary that rr_move is the first entry
6759 		 * of the root.
6760 		 */
6761 		/* Remove "rr_moved" entry from children chain. */
6762 		isoent_remove_child(rootent, rr_moved);
6763 
6764 		/* Add "rr_moved" entry into the head of children chain. */
6765 		isoent_add_child_head(rootent, rr_moved);
6766 	}
6767 
6768 	/*
6769 	 * Check level 8 path_table.
6770 	 * If find out sub directory entries, that entries move to rr_move.
6771 	 */
6772 	np = pt->first;
6773 	while (np != NULL) {
6774 		last = path_table_last_entry(pt);
6775 		for (; np != NULL; np = np->ptnext) {
6776 			struct isoent *mvent;
6777 			struct isoent *newent;
6778 
6779 			if (!np->dir)
6780 				continue;
6781 			for (mvent = np->subdirs.first;
6782 			    mvent != NULL; mvent = mvent->drnext) {
6783 				r = isoent_rr_move_dir(a, &rr_moved,
6784 				    mvent, &newent);
6785 				if (r < 0)
6786 					return (r);
6787 				isoent_collect_dirs(&(iso9660->primary),
6788 				    newent, 2);
6789 			}
6790 		}
6791 		/* If new entries are added to level 8 path_talbe,
6792 		 * its sub directory entries move to rr_move too.
6793 		 */
6794 		np = last->ptnext;
6795 	}
6796 
6797 	return (ARCHIVE_OK);
6798 }
6799 
6800 /*
6801  * This comparing rule is according to ISO9660 Standard 6.9.1
6802  */
6803 static int
6804 _compare_path_table(const void *v1, const void *v2)
6805 {
6806 	const struct isoent *p1, *p2;
6807 	const char *s1, *s2;
6808 	int cmp, l;
6809 
6810 	p1 = *((const struct isoent **)(uintptr_t)v1);
6811 	p2 = *((const struct isoent **)(uintptr_t)v2);
6812 
6813 	/* Compare parent directory number */
6814 	cmp = p1->parent->dir_number - p2->parent->dir_number;
6815 	if (cmp != 0)
6816 		return (cmp);
6817 
6818 	/* Compare identifier */
6819 	s1 = p1->identifier;
6820 	s2 = p2->identifier;
6821 	l = p1->ext_off;
6822 	if (l > p2->ext_off)
6823 		l = p2->ext_off;
6824 	cmp = strncmp(s1, s2, l);
6825 	if (cmp != 0)
6826 		return (cmp);
6827 	if (p1->ext_off < p2->ext_off) {
6828 		s2 += l;
6829 		l = p2->ext_off - p1->ext_off;
6830 		while (l--)
6831 			if (0x20 != *s2++)
6832 				return (0x20
6833 				    - *(const unsigned char *)(s2 - 1));
6834 	} else if (p1->ext_off > p2->ext_off) {
6835 		s1 += l;
6836 		l = p1->ext_off - p2->ext_off;
6837 		while (l--)
6838 			if (0x20 != *s1++)
6839 				return (*(const unsigned char *)(s1 - 1)
6840 				    - 0x20);
6841 	}
6842 	return (0);
6843 }
6844 
6845 static int
6846 _compare_path_table_joliet(const void *v1, const void *v2)
6847 {
6848 	const struct isoent *p1, *p2;
6849 	const unsigned char *s1, *s2;
6850 	int cmp, l;
6851 
6852 	p1 = *((const struct isoent **)(uintptr_t)v1);
6853 	p2 = *((const struct isoent **)(uintptr_t)v2);
6854 
6855 	/* Compare parent directory number */
6856 	cmp = p1->parent->dir_number - p2->parent->dir_number;
6857 	if (cmp != 0)
6858 		return (cmp);
6859 
6860 	/* Compare identifier */
6861 	s1 = (const unsigned char *)p1->identifier;
6862 	s2 = (const unsigned char *)p2->identifier;
6863 	l = p1->ext_off;
6864 	if (l > p2->ext_off)
6865 		l = p2->ext_off;
6866 	cmp = memcmp(s1, s2, l);
6867 	if (cmp != 0)
6868 		return (cmp);
6869 	if (p1->ext_off < p2->ext_off) {
6870 		s2 += l;
6871 		l = p2->ext_off - p1->ext_off;
6872 		while (l--)
6873 			if (0 != *s2++)
6874 				return (- *(const unsigned char *)(s2 - 1));
6875 	} else if (p1->ext_off > p2->ext_off) {
6876 		s1 += l;
6877 		l = p1->ext_off - p2->ext_off;
6878 		while (l--)
6879 			if (0 != *s1++)
6880 				return (*(const unsigned char *)(s1 - 1));
6881 	}
6882 	return (0);
6883 }
6884 
6885 static inline void
6886 path_table_add_entry(struct path_table *pathtbl, struct isoent *ent)
6887 {
6888 	ent->ptnext = NULL;
6889 	*pathtbl->last = ent;
6890 	pathtbl->last = &(ent->ptnext);
6891 	pathtbl->cnt ++;
6892 }
6893 
6894 static inline struct isoent *
6895 path_table_last_entry(struct path_table *pathtbl)
6896 {
6897 	if (pathtbl->first == NULL)
6898 		return (NULL);
6899 	return (((struct isoent *)(void *)
6900 		((char *)(pathtbl->last) - offsetof(struct isoent, ptnext))));
6901 }
6902 
6903 /*
6904  * Sort directory entries in path_table
6905  * and assign directory number to each entries.
6906  */
6907 static int
6908 isoent_make_path_table_2(struct archive_write *a, struct vdd *vdd,
6909     int depth, int *dir_number)
6910 {
6911 	struct isoent *np;
6912 	struct isoent **enttbl;
6913 	struct path_table *pt;
6914 	int i;
6915 
6916 	pt = &vdd->pathtbl[depth];
6917 	if (pt->cnt == 0) {
6918 		pt->sorted = NULL;
6919 		return (ARCHIVE_OK);
6920 	}
6921 	enttbl = malloc(pt->cnt * sizeof(struct isoent *));
6922 	if (enttbl == NULL) {
6923 		archive_set_error(&a->archive, ENOMEM,
6924 		    "Can't allocate memory");
6925 		return (ARCHIVE_FATAL);
6926 	}
6927 	pt->sorted = enttbl;
6928 	for (np = pt->first; np != NULL; np = np->ptnext)
6929 		*enttbl ++ = np;
6930 	enttbl = pt->sorted;
6931 
6932 	switch (vdd->vdd_type) {
6933 	case VDD_PRIMARY:
6934 	case VDD_ENHANCED:
6935 #ifdef __COMPAR_FN_T
6936 		qsort(enttbl, pt->cnt, sizeof(struct isoent *),
6937 		    (__compar_fn_t)_compare_path_table);
6938 #else
6939 		qsort(enttbl, pt->cnt, sizeof(struct isoent *),
6940 		    _compare_path_table);
6941 #endif
6942 		break;
6943 	case VDD_JOLIET:
6944 #ifdef __COMPAR_FN_T
6945 		qsort(enttbl, pt->cnt, sizeof(struct isoent *),
6946 		    (__compar_fn_t)_compare_path_table_joliet);
6947 #else
6948 		qsort(enttbl, pt->cnt, sizeof(struct isoent *),
6949 		    _compare_path_table_joliet);
6950 #endif
6951 		break;
6952 	}
6953 	for (i = 0; i < pt->cnt; i++)
6954 		enttbl[i]->dir_number = (*dir_number)++;
6955 
6956 	return (ARCHIVE_OK);
6957 }
6958 
6959 static int
6960 isoent_alloc_path_table(struct archive_write *a, struct vdd *vdd,
6961     int max_depth)
6962 {
6963 	int i;
6964 
6965 	vdd->max_depth = max_depth;
6966 	vdd->pathtbl = malloc(sizeof(*vdd->pathtbl) * vdd->max_depth);
6967 	if (vdd->pathtbl == NULL) {
6968 		archive_set_error(&a->archive, ENOMEM,
6969 		    "Can't allocate memory");
6970 		return (ARCHIVE_FATAL);
6971 	}
6972 	for (i = 0; i < vdd->max_depth; i++) {
6973 		vdd->pathtbl[i].first = NULL;
6974 		vdd->pathtbl[i].last = &(vdd->pathtbl[i].first);
6975 		vdd->pathtbl[i].sorted = NULL;
6976 		vdd->pathtbl[i].cnt = 0;
6977 	}
6978 	return (ARCHIVE_OK);
6979 }
6980 
6981 /*
6982  * Make Path Tables
6983  */
6984 static int
6985 isoent_make_path_table(struct archive_write *a)
6986 {
6987 	struct iso9660 *iso9660 = a->format_data;
6988 	int depth, r;
6989 	int dir_number;
6990 
6991 	/*
6992 	 * Init Path Table.
6993 	 */
6994 	if (iso9660->dircnt_max >= MAX_DEPTH &&
6995 	    (!iso9660->opt.limit_depth || iso9660->opt.iso_level == 4))
6996 		r = isoent_alloc_path_table(a, &(iso9660->primary),
6997 		    iso9660->dircnt_max + 1);
6998 	else
6999 		/* The number of levels in the hierarchy cannot exceed
7000 		 * eight. */
7001 		r = isoent_alloc_path_table(a, &(iso9660->primary),
7002 		    MAX_DEPTH);
7003 	if (r < 0)
7004 		return (r);
7005 	if (iso9660->opt.joliet) {
7006 		r = isoent_alloc_path_table(a, &(iso9660->joliet),
7007 		    iso9660->dircnt_max + 1);
7008 		if (r < 0)
7009 			return (r);
7010 	}
7011 
7012 	/* Step 0.
7013 	 * - Collect directories for primary and joliet.
7014 	 */
7015 	isoent_collect_dirs(&(iso9660->primary), NULL, 0);
7016 	if (iso9660->opt.joliet)
7017 		isoent_collect_dirs(&(iso9660->joliet), NULL, 0);
7018 	/*
7019 	 * Rockridge; move deeper depth directories to rr_moved.
7020 	 */
7021 	if (iso9660->opt.rr) {
7022 		r = isoent_rr_move(a);
7023 		if (r < 0)
7024 			return (r);
7025 	}
7026 
7027  	/* Update nlink. */
7028 	isofile_connect_hardlink_files(iso9660);
7029 
7030 	/* Step 1.
7031 	 * - Renew a value of the depth of that directories.
7032 	 * - Resolve hardlinks.
7033  	 * - Convert pathnames to ISO9660 name or UCS2(joliet).
7034 	 * - Sort files by each directory.
7035 	 */
7036 	r = isoent_traverse_tree(a, &(iso9660->primary));
7037 	if (r < 0)
7038 		return (r);
7039 	if (iso9660->opt.joliet) {
7040 		r = isoent_traverse_tree(a, &(iso9660->joliet));
7041 		if (r < 0)
7042 			return (r);
7043 	}
7044 
7045 	/* Step 2.
7046 	 * - Sort directories.
7047 	 * - Assign all directory number.
7048 	 */
7049 	dir_number = 1;
7050 	for (depth = 0; depth < iso9660->primary.max_depth; depth++) {
7051 		r = isoent_make_path_table_2(a, &(iso9660->primary),
7052 		    depth, &dir_number);
7053 		if (r < 0)
7054 			return (r);
7055 	}
7056 	if (iso9660->opt.joliet) {
7057 		dir_number = 1;
7058 		for (depth = 0; depth < iso9660->joliet.max_depth; depth++) {
7059 			r = isoent_make_path_table_2(a, &(iso9660->joliet),
7060 			    depth, &dir_number);
7061 			if (r < 0)
7062 				return (r);
7063 		}
7064 	}
7065 	if (iso9660->opt.limit_dirs && dir_number > 0xffff) {
7066 		/*
7067 		 * Maximum number of directories is 65535(0xffff)
7068 		 * doe to size(16bit) of Parent Directory Number of
7069 		 * the Path Table.
7070 		 * See also ISO9660 Standard 9.4.
7071 		 */
7072 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
7073 		    "Too many directories(%d) over 65535.", dir_number);
7074 		return (ARCHIVE_FATAL);
7075 	}
7076 
7077 	/* Get the size of the Path Table. */
7078 	calculate_path_table_size(&(iso9660->primary));
7079 	if (iso9660->opt.joliet)
7080 		calculate_path_table_size(&(iso9660->joliet));
7081 
7082 	return (ARCHIVE_OK);
7083 }
7084 
7085 static int
7086 isoent_find_out_boot_file(struct archive_write *a, struct isoent *rootent)
7087 {
7088 	struct iso9660 *iso9660 = a->format_data;
7089 
7090 	/* Find a isoent of the boot file. */
7091 	iso9660->el_torito.boot = isoent_find_entry(rootent,
7092 	    iso9660->el_torito.boot_filename.s);
7093 	if (iso9660->el_torito.boot == NULL) {
7094 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
7095 		    "Can't find the boot image file ``%s''",
7096 		    iso9660->el_torito.boot_filename.s);
7097 		return (ARCHIVE_FATAL);
7098 	}
7099 	iso9660->el_torito.boot->file->boot = BOOT_IMAGE;
7100 	return (ARCHIVE_OK);
7101 }
7102 
7103 static int
7104 isoent_create_boot_catalog(struct archive_write *a, struct isoent *rootent)
7105 {
7106 	struct iso9660 *iso9660 = a->format_data;
7107 	struct isofile *file;
7108 	struct isoent *isoent;
7109 	struct archive_entry *entry;
7110 
7111 	(void)rootent; /* UNUSED */
7112 	/*
7113 	 * Create the entry which is the "boot.catalog" file.
7114 	 */
7115 	file = isofile_new(a, NULL);
7116 	if (file == NULL) {
7117 		archive_set_error(&a->archive, ENOMEM,
7118 		    "Can't allocate memory");
7119 		return (ARCHIVE_FATAL);
7120 	}
7121 	archive_entry_set_pathname(file->entry,
7122 	    iso9660->el_torito.catalog_filename.s);
7123 	archive_entry_set_size(file->entry, LOGICAL_BLOCK_SIZE);
7124 	archive_entry_set_mtime(file->entry, iso9660->birth_time, 0);
7125 	archive_entry_set_atime(file->entry, iso9660->birth_time, 0);
7126 	archive_entry_set_ctime(file->entry, iso9660->birth_time, 0);
7127 	archive_entry_set_uid(file->entry, getuid());
7128 	archive_entry_set_gid(file->entry, getgid());
7129 	archive_entry_set_mode(file->entry, AE_IFREG | 0444);
7130 	archive_entry_set_nlink(file->entry, 1);
7131 
7132 	if (isofile_gen_utility_names(a, file) < ARCHIVE_WARN) {
7133 		isofile_free(file);
7134 		return (ARCHIVE_FATAL);
7135 	}
7136 	file->boot = BOOT_CATALOG;
7137 	file->content.size = LOGICAL_BLOCK_SIZE;
7138 	isofile_add_entry(iso9660, file);
7139 
7140 	isoent = isoent_new(file);
7141 	if (isoent == NULL) {
7142 		archive_set_error(&a->archive, ENOMEM,
7143 		    "Can't allocate memory");
7144 		return (ARCHIVE_FATAL);
7145 	}
7146 	isoent->virtual = 1;
7147 
7148 	/* Add the "boot.catalog" entry into tree */
7149 	if (isoent_tree(a, &isoent) != ARCHIVE_OK)
7150 		return (ARCHIVE_FATAL);
7151 
7152 	iso9660->el_torito.catalog = isoent;
7153 	/*
7154 	 * Get a boot media type.
7155 	 */
7156 	switch (iso9660->opt.boot_type) {
7157 	default:
7158 	case OPT_BOOT_TYPE_AUTO:
7159 		/* Try detecting a media type of the boot image. */
7160 		entry = iso9660->el_torito.boot->file->entry;
7161 		if (archive_entry_size(entry) == FD_1_2M_SIZE)
7162 			iso9660->el_torito.media_type =
7163 			    BOOT_MEDIA_1_2M_DISKETTE;
7164 		else if (archive_entry_size(entry) == FD_1_44M_SIZE)
7165 			iso9660->el_torito.media_type =
7166 			    BOOT_MEDIA_1_44M_DISKETTE;
7167 		else if (archive_entry_size(entry) == FD_2_88M_SIZE)
7168 			iso9660->el_torito.media_type =
7169 			    BOOT_MEDIA_2_88M_DISKETTE;
7170 		else
7171 			/* We cannot decide whether the boot image is
7172 			 * hard-disk. */
7173 			iso9660->el_torito.media_type =
7174 			    BOOT_MEDIA_NO_EMULATION;
7175 		break;
7176 	case OPT_BOOT_TYPE_NO_EMU:
7177 		iso9660->el_torito.media_type = BOOT_MEDIA_NO_EMULATION;
7178 		break;
7179 	case OPT_BOOT_TYPE_HARD_DISK:
7180 		iso9660->el_torito.media_type = BOOT_MEDIA_HARD_DISK;
7181 		break;
7182 	case OPT_BOOT_TYPE_FD:
7183 		entry = iso9660->el_torito.boot->file->entry;
7184 		if (archive_entry_size(entry) <= FD_1_2M_SIZE)
7185 			iso9660->el_torito.media_type =
7186 			    BOOT_MEDIA_1_2M_DISKETTE;
7187 		else if (archive_entry_size(entry) <= FD_1_44M_SIZE)
7188 			iso9660->el_torito.media_type =
7189 			    BOOT_MEDIA_1_44M_DISKETTE;
7190 		else if (archive_entry_size(entry) <= FD_2_88M_SIZE)
7191 			iso9660->el_torito.media_type =
7192 			    BOOT_MEDIA_2_88M_DISKETTE;
7193 		else {
7194 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
7195 			    "Boot image file(``%s'') size is too big "
7196 			    "for fd type.",
7197 			    iso9660->el_torito.boot_filename.s);
7198 			return (ARCHIVE_FATAL);
7199 		}
7200 		break;
7201 	}
7202 
7203 	/*
7204 	 * Get a system type.
7205 	 * TODO: `El Torito' specification says "A copy of byte 5 from the
7206 	 *       Partition Table found in the boot image".
7207 	 */
7208 	iso9660->el_torito.system_type = 0;
7209 
7210 	/*
7211 	 * Get an ID.
7212 	 */
7213 	if (iso9660->opt.publisher)
7214 		archive_string_copy(&(iso9660->el_torito.id),
7215 		    &(iso9660->publisher_identifier));
7216 
7217 
7218 	return (ARCHIVE_OK);
7219 }
7220 
7221 /*
7222  * If a media type is floppy, return its image size.
7223  * otherwise return 0.
7224  */
7225 static size_t
7226 fd_boot_image_size(int media_type)
7227 {
7228 	switch (media_type) {
7229 	case BOOT_MEDIA_1_2M_DISKETTE:
7230 		return (FD_1_2M_SIZE);
7231 	case BOOT_MEDIA_1_44M_DISKETTE:
7232 		return (FD_1_44M_SIZE);
7233 	case BOOT_MEDIA_2_88M_DISKETTE:
7234 		return (FD_2_88M_SIZE);
7235 	default:
7236 		return (0);
7237 	}
7238 }
7239 
7240 /*
7241  * Make a boot catalog image data.
7242  */
7243 static int
7244 make_boot_catalog(struct archive_write *a)
7245 {
7246 	struct iso9660 *iso9660 = a->format_data;
7247 	unsigned char *block;
7248 	unsigned char *p;
7249 	uint16_t sum, *wp;
7250 
7251 	block = wb_buffptr(a);
7252 	memset(block, 0, LOGICAL_BLOCK_SIZE);
7253 	p = block;
7254 	/*
7255 	 * Validation Entry
7256 	 */
7257 	/* Header ID */
7258 	p[0] = 1;
7259 	/* Platform ID */
7260 	p[1] = iso9660->el_torito.platform_id;
7261 	/* Reserved */
7262 	p[2] = p[3] = 0;
7263 	/* ID */
7264 	if (archive_strlen(&(iso9660->el_torito.id)) > 0)
7265 		strncpy((char *)p+4, iso9660->el_torito.id.s, 23);
7266 	p[27] = 0;
7267 	/* Checksum */
7268 	p[28] = p[29] = 0;
7269 	/* Key */
7270 	p[30] = 0x55;
7271 	p[31] = 0xAA;
7272 
7273 	sum = 0;
7274 	wp = (uint16_t *)block;
7275 	while (wp < (uint16_t *)&block[32])
7276 		sum += archive_le16dec(wp++);
7277 	set_num_721(&block[28], (~sum) + 1);
7278 
7279 	/*
7280 	 * Initial/Default Entry
7281 	 */
7282 	p = &block[32];
7283 	/* Boot Indicator */
7284 	p[0] = 0x88;
7285 	/* Boot media type */
7286 	p[1] = iso9660->el_torito.media_type;
7287 	/* Load Segment */
7288 	if (iso9660->el_torito.media_type == BOOT_MEDIA_NO_EMULATION)
7289 		set_num_721(&p[2], iso9660->el_torito.boot_load_seg);
7290 	else
7291 		set_num_721(&p[2], 0);
7292 	/* System Type */
7293 	p[4] = iso9660->el_torito.system_type;
7294 	/* Unused */
7295 	p[5] = 0;
7296 	/* Sector Count */
7297 	if (iso9660->el_torito.media_type == BOOT_MEDIA_NO_EMULATION)
7298 		set_num_721(&p[6], iso9660->el_torito.boot_load_size);
7299 	else
7300 		set_num_721(&p[6], 1);
7301 	/* Load RBA */
7302 	set_num_731(&p[8],
7303 	    iso9660->el_torito.boot->file->content.location);
7304 	/* Unused */
7305 	memset(&p[12], 0, 20);
7306 
7307 	return (wb_consume(a, LOGICAL_BLOCK_SIZE));
7308 }
7309 
7310 static int
7311 setup_boot_information(struct archive_write *a)
7312 {
7313 	struct iso9660 *iso9660 = a->format_data;
7314 	struct isoent *np;
7315 	int64_t size;
7316 	uint32_t sum;
7317 	unsigned char buff[4096];
7318 
7319 	np = iso9660->el_torito.boot;
7320 	lseek(iso9660->temp_fd,
7321 	    np->file->content.offset_of_temp + 64, SEEK_SET);
7322 	size = archive_entry_size(np->file->entry) - 64;
7323 	if (size <= 0) {
7324 		archive_set_error(&a->archive, errno,
7325 		    "Boot file(%jd) is too small", (intmax_t)size + 64);
7326 		return (ARCHIVE_FATAL);
7327 	}
7328 	sum = 0;
7329 	while (size > 0) {
7330 		size_t rsize;
7331 		ssize_t i, rs;
7332 
7333 		if (size > (int64_t)sizeof(buff))
7334 			rsize = sizeof(buff);
7335 		else
7336 			rsize = (size_t)size;
7337 
7338 		rs = read(iso9660->temp_fd, buff, rsize);
7339 		if (rs <= 0) {
7340 			archive_set_error(&a->archive, errno,
7341 			    "Can't read temporary file(%jd)",
7342 			    (intmax_t)rs);
7343 			return (ARCHIVE_FATAL);
7344 		}
7345 		for (i = 0; i < rs; i += 4)
7346 			sum += archive_le32dec(buff + i);
7347 		size -= rs;
7348 	}
7349 	/* Set the location of Primary Volume Descriptor. */
7350 	set_num_731(buff, SYSTEM_AREA_BLOCK);
7351 	/* Set the location of the boot file. */
7352 	set_num_731(buff+4, np->file->content.location);
7353 	/* Set the size of the boot file. */
7354 	size = fd_boot_image_size(iso9660->el_torito.media_type);
7355 	if (size == 0)
7356 		size = archive_entry_size(np->file->entry);
7357 	set_num_731(buff+8, (uint32_t)size);
7358 	/* Set the sum of the boot file. */
7359 	set_num_731(buff+12, sum);
7360 	/* Clear reserved bytes. */
7361 	memset(buff+16, 0, 40);
7362 
7363 	/* Overwrite the boot file. */
7364 	lseek(iso9660->temp_fd,
7365 	    np->file->content.offset_of_temp + 8, SEEK_SET);
7366 	return (write_to_temp(a, buff, 56));
7367 }
7368 
7369 #ifdef HAVE_ZLIB_H
7370 
7371 static int
7372 zisofs_init_zstream(struct archive_write *a)
7373 {
7374 	struct iso9660 *iso9660 = a->format_data;
7375 	int r;
7376 
7377 	iso9660->zisofs.stream.next_in = NULL;
7378 	iso9660->zisofs.stream.avail_in = 0;
7379 	iso9660->zisofs.stream.total_in = 0;
7380 	iso9660->zisofs.stream.total_out = 0;
7381 	if (iso9660->zisofs.stream_valid)
7382 		r = deflateReset(&(iso9660->zisofs.stream));
7383 	else {
7384 		r = deflateInit(&(iso9660->zisofs.stream),
7385 		    iso9660->zisofs.compression_level);
7386 		iso9660->zisofs.stream_valid = 1;
7387 	}
7388 	switch (r) {
7389 	case Z_OK:
7390 		break;
7391 	default:
7392 	case Z_STREAM_ERROR:
7393 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
7394 		    "Internal error initializing "
7395 		    "compression library: invalid setup parameter");
7396 		return (ARCHIVE_FATAL);
7397 	case Z_MEM_ERROR:
7398 		archive_set_error(&a->archive, ENOMEM,
7399 		    "Internal error initializing "
7400 		    "compression library");
7401 		return (ARCHIVE_FATAL);
7402 	case Z_VERSION_ERROR:
7403 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
7404 		    "Internal error initializing "
7405 		    "compression library: invalid library version");
7406 		return (ARCHIVE_FATAL);
7407 	}
7408 	return (ARCHIVE_OK);
7409 }
7410 
7411 #endif /* HAVE_ZLIB_H */
7412 
7413 static int
7414 zisofs_init(struct archive_write *a,  struct isofile *file)
7415 {
7416 	struct iso9660 *iso9660 = a->format_data;
7417 #ifdef HAVE_ZLIB_H
7418 	uint64_t tsize;
7419 	size_t _ceil, bpsize;
7420 	int r;
7421 #endif
7422 
7423 	iso9660->zisofs.detect_magic = 0;
7424 	iso9660->zisofs.making = 0;
7425 
7426 	if (!iso9660->opt.rr || !iso9660->opt.zisofs)
7427 		return (ARCHIVE_OK);
7428 
7429 	if (archive_entry_size(file->entry) >= 24 &&
7430 	    archive_entry_size(file->entry) < MULTI_EXTENT_SIZE) {
7431 		/* Acceptable file size for zisofs. */
7432 		iso9660->zisofs.detect_magic = 1;
7433 		iso9660->zisofs.magic_cnt = 0;
7434 	}
7435 	if (!iso9660->zisofs.detect_magic)
7436 		return (ARCHIVE_OK);
7437 
7438 #ifdef HAVE_ZLIB_H
7439 	/* The number of Logical Blocks which uncompressed data
7440 	 * will use in iso-image file is the same as the number of
7441 	 * Logical Blocks which zisofs(compressed) data will use
7442 	 * in ISO-image file. It won't reduce iso-image file size. */
7443 	if (archive_entry_size(file->entry) <= LOGICAL_BLOCK_SIZE)
7444 		return (ARCHIVE_OK);
7445 
7446 	/* Initialize compression library */
7447 	r = zisofs_init_zstream(a);
7448 	if (r != ARCHIVE_OK)
7449 		return (ARCHIVE_FATAL);
7450 
7451 	/* Mark file->zisofs to create RRIP 'ZF' Use Entry. */
7452 	file->zisofs.header_size = ZF_HEADER_SIZE >> 2;
7453 	file->zisofs.log2_bs = ZF_LOG2_BS;
7454 	file->zisofs.uncompressed_size =
7455 		(uint32_t)archive_entry_size(file->entry);
7456 
7457 	/* Calculate a size of Block Pointers of zisofs. */
7458 	_ceil = (file->zisofs.uncompressed_size + ZF_BLOCK_SIZE -1)
7459 		>> file->zisofs.log2_bs;
7460 	iso9660->zisofs.block_pointers_cnt = (int)_ceil + 1;
7461 	iso9660->zisofs.block_pointers_idx = 0;
7462 
7463 	/* Ensure a buffer size used for Block Pointers */
7464 	bpsize = iso9660->zisofs.block_pointers_cnt *
7465 	    sizeof(iso9660->zisofs.block_pointers[0]);
7466 	if (iso9660->zisofs.block_pointers_allocated < bpsize) {
7467 		free(iso9660->zisofs.block_pointers);
7468 		iso9660->zisofs.block_pointers = malloc(bpsize);
7469 		if (iso9660->zisofs.block_pointers == NULL) {
7470 			archive_set_error(&a->archive, ENOMEM,
7471 			    "Can't allocate data");
7472 			return (ARCHIVE_FATAL);
7473 		}
7474 		iso9660->zisofs.block_pointers_allocated = bpsize;
7475 	}
7476 
7477 	/*
7478 	 * Skip zisofs header and Block Pointers, which we will write
7479 	 * after all compressed data of a file written to the temporary
7480 	 * file.
7481 	 */
7482 	tsize = ZF_HEADER_SIZE + bpsize;
7483 	if (write_null(a, (size_t)tsize) != ARCHIVE_OK)
7484 		return (ARCHIVE_FATAL);
7485 
7486 	/*
7487 	 * Initialize some variables to make zisofs.
7488 	 */
7489 	archive_le32enc(&(iso9660->zisofs.block_pointers[0]),
7490 		(uint32_t)tsize);
7491 	iso9660->zisofs.remaining = file->zisofs.uncompressed_size;
7492 	iso9660->zisofs.making = 1;
7493 	iso9660->zisofs.allzero = 1;
7494 	iso9660->zisofs.block_offset = tsize;
7495 	iso9660->zisofs.total_size = tsize;
7496 	iso9660->cur_file->cur_content->size = tsize;
7497 #endif
7498 
7499 	return (ARCHIVE_OK);
7500 }
7501 
7502 static void
7503 zisofs_detect_magic(struct archive_write *a, const void *buff, size_t s)
7504 {
7505 	struct iso9660 *iso9660 = a->format_data;
7506 	struct isofile *file = iso9660->cur_file;
7507 	const unsigned char *p, *endp;
7508 	const unsigned char *magic_buff;
7509 	uint32_t uncompressed_size;
7510 	unsigned char header_size;
7511 	unsigned char log2_bs;
7512 	size_t _ceil, doff;
7513 	uint32_t bst, bed;
7514 	int magic_max;
7515 	int64_t entry_size;
7516 
7517 	entry_size = archive_entry_size(file->entry);
7518 	if ((int64_t)sizeof(iso9660->zisofs.magic_buffer) > entry_size)
7519 		magic_max = (int)entry_size;
7520 	else
7521 		magic_max = sizeof(iso9660->zisofs.magic_buffer);
7522 
7523 	if (iso9660->zisofs.magic_cnt == 0 && s >= (size_t)magic_max)
7524 		/* It's unnecessary we copy buffer. */
7525 		magic_buff = buff;
7526 	else {
7527 		if (iso9660->zisofs.magic_cnt < magic_max) {
7528 			size_t l;
7529 
7530 			l = sizeof(iso9660->zisofs.magic_buffer)
7531 			    - iso9660->zisofs.magic_cnt;
7532 			if (l > s)
7533 				l = s;
7534 			memcpy(iso9660->zisofs.magic_buffer
7535 			    + iso9660->zisofs.magic_cnt, buff, l);
7536 			iso9660->zisofs.magic_cnt += (int)l;
7537 			if (iso9660->zisofs.magic_cnt < magic_max)
7538 				return;
7539 		}
7540 		magic_buff = iso9660->zisofs.magic_buffer;
7541 	}
7542 	iso9660->zisofs.detect_magic = 0;
7543 	p = magic_buff;
7544 
7545 	/* Check the magic code of zisofs. */
7546 	if (memcmp(p, zisofs_magic, sizeof(zisofs_magic)) != 0)
7547 		/* This is not zisofs file which made by mkzftree. */
7548 		return;
7549 	p += sizeof(zisofs_magic);
7550 
7551 	/* Read a zisofs header. */
7552 	uncompressed_size = archive_le32dec(p);
7553 	header_size = p[4];
7554 	log2_bs = p[5];
7555 	if (uncompressed_size < 24 || header_size != 4 ||
7556 	    log2_bs > 30 || log2_bs < 7)
7557 		return;/* Invalid or not supported header. */
7558 
7559 	/* Calculate a size of Block Pointers of zisofs. */
7560 	_ceil = (uncompressed_size +
7561 	        (ARCHIVE_LITERAL_LL(1) << log2_bs) -1) >> log2_bs;
7562 	doff = (_ceil + 1) * 4 + 16;
7563 	if (entry_size < (int64_t)doff)
7564 		return;/* Invalid data. */
7565 
7566 	/* Check every Block Pointer has valid value. */
7567 	p = magic_buff + 16;
7568 	endp = magic_buff + magic_max;
7569 	while (_ceil && p + 8 <= endp) {
7570 		bst = archive_le32dec(p);
7571 		if (bst != doff)
7572 			return;/* Invalid data. */
7573 		p += 4;
7574 		bed = archive_le32dec(p);
7575 		if (bed < bst || bed > entry_size)
7576 			return;/* Invalid data. */
7577 		doff += bed - bst;
7578 		_ceil--;
7579 	}
7580 
7581 	file->zisofs.uncompressed_size = uncompressed_size;
7582 	file->zisofs.header_size = header_size;
7583 	file->zisofs.log2_bs = log2_bs;
7584 
7585 	/* Disable making a zisofs image. */
7586 	iso9660->zisofs.making = 0;
7587 }
7588 
7589 #ifdef HAVE_ZLIB_H
7590 
7591 /*
7592  * Compress data and write it to a temporary file.
7593  */
7594 static int
7595 zisofs_write_to_temp(struct archive_write *a, const void *buff, size_t s)
7596 {
7597 	struct iso9660 *iso9660 = a->format_data;
7598 	struct isofile *file = iso9660->cur_file;
7599 	const unsigned char *b;
7600 	z_stream *zstrm;
7601 	size_t avail, csize;
7602 	int flush, r;
7603 
7604 	zstrm = &(iso9660->zisofs.stream);
7605 	zstrm->next_out = wb_buffptr(a);
7606 	zstrm->avail_out = (uInt)wb_remaining(a);
7607 	b = (const unsigned char *)buff;
7608 	do {
7609 		avail = ZF_BLOCK_SIZE - zstrm->total_in;
7610 		if (s < avail) {
7611 			avail = s;
7612 			flush = Z_NO_FLUSH;
7613 		} else
7614 			flush = Z_FINISH;
7615 		iso9660->zisofs.remaining -= avail;
7616 		if (iso9660->zisofs.remaining <= 0)
7617 			flush = Z_FINISH;
7618 
7619 		zstrm->next_in = (Bytef *)(uintptr_t)(const void *)b;
7620 		zstrm->avail_in = (uInt)avail;
7621 
7622 		/*
7623 		 * Check if current data block are all zero.
7624 		 */
7625 		if (iso9660->zisofs.allzero) {
7626 			const unsigned char *nonzero = b;
7627 			const unsigned char *nonzeroend = b + avail;
7628 
7629 			while (nonzero < nonzeroend)
7630 				if (*nonzero++) {
7631 					iso9660->zisofs.allzero = 0;
7632 					break;
7633 				}
7634 		}
7635 		b += avail;
7636 		s -= avail;
7637 
7638 		/*
7639 		 * If current data block are all zero, we do not use
7640 		 * compressed data.
7641 		 */
7642 		if (flush == Z_FINISH && iso9660->zisofs.allzero &&
7643 		    avail + zstrm->total_in == ZF_BLOCK_SIZE) {
7644 			if (iso9660->zisofs.block_offset !=
7645 			    file->cur_content->size) {
7646 				int64_t diff;
7647 
7648 				r = wb_set_offset(a,
7649 				    file->cur_content->offset_of_temp +
7650 				        iso9660->zisofs.block_offset);
7651 				if (r != ARCHIVE_OK)
7652 					return (r);
7653 				diff = file->cur_content->size -
7654 				    iso9660->zisofs.block_offset;
7655 				file->cur_content->size -= diff;
7656 				iso9660->zisofs.total_size -= diff;
7657 			}
7658 			zstrm->avail_in = 0;
7659 		}
7660 
7661 		/*
7662 		 * Compress file data.
7663 		 */
7664 		while (zstrm->avail_in > 0) {
7665 			csize = zstrm->total_out;
7666 			r = deflate(zstrm, flush);
7667 			switch (r) {
7668 			case Z_OK:
7669 			case Z_STREAM_END:
7670 				csize = zstrm->total_out - csize;
7671 				if (wb_consume(a, csize) != ARCHIVE_OK)
7672 					return (ARCHIVE_FATAL);
7673 				iso9660->zisofs.total_size += csize;
7674 				iso9660->cur_file->cur_content->size += csize;
7675 				zstrm->next_out = wb_buffptr(a);
7676 				zstrm->avail_out = (uInt)wb_remaining(a);
7677 				break;
7678 			default:
7679 				archive_set_error(&a->archive,
7680 				    ARCHIVE_ERRNO_MISC,
7681 				    "Compression failed:"
7682 				    " deflate() call returned status %d",
7683 				    r);
7684 				return (ARCHIVE_FATAL);
7685 			}
7686 		}
7687 
7688 		if (flush == Z_FINISH) {
7689 			/*
7690 			 * Save the information of one zisofs block.
7691 			 */
7692 			iso9660->zisofs.block_pointers_idx ++;
7693 			archive_le32enc(&(iso9660->zisofs.block_pointers[
7694 			    iso9660->zisofs.block_pointers_idx]),
7695 				(uint32_t)iso9660->zisofs.total_size);
7696 			r = zisofs_init_zstream(a);
7697 			if (r != ARCHIVE_OK)
7698 				return (ARCHIVE_FATAL);
7699 			iso9660->zisofs.allzero = 1;
7700 			iso9660->zisofs.block_offset = file->cur_content->size;
7701 		}
7702 	} while (s);
7703 
7704 	return (ARCHIVE_OK);
7705 }
7706 
7707 static int
7708 zisofs_finish_entry(struct archive_write *a)
7709 {
7710 	struct iso9660 *iso9660 = a->format_data;
7711 	struct isofile *file = iso9660->cur_file;
7712 	unsigned char buff[16];
7713 	size_t s;
7714 	int64_t tail;
7715 
7716 	/* Direct temp file stream to zisofs temp file stream. */
7717 	archive_entry_set_size(file->entry, iso9660->zisofs.total_size);
7718 
7719 	/*
7720 	 * Save a file pointer which points the end of current zisofs data.
7721 	 */
7722 	tail = wb_offset(a);
7723 
7724 	/*
7725 	 * Make a header.
7726 	 *
7727 	 * +-----------------+----------------+-----------------+
7728 	 * | Header 16 bytes | Block Pointers | Compressed data |
7729 	 * +-----------------+----------------+-----------------+
7730 	 * 0                16               +X
7731 	 * Block Pointers :
7732 	 *   4 * (((Uncompressed file size + block_size -1) / block_size) + 1)
7733 	 *
7734 	 * Write zisofs header.
7735 	 *    Magic number
7736 	 * +----+----+----+----+----+----+----+----+
7737 	 * | 37 | E4 | 53 | 96 | C9 | DB | D6 | 07 |
7738 	 * +----+----+----+----+----+----+----+----+
7739 	 * 0    1    2    3    4    5    6    7    8
7740 	 *
7741 	 * +------------------------+------------------+
7742 	 * | Uncompressed file size | header_size >> 2 |
7743 	 * +------------------------+------------------+
7744 	 * 8                       12                 13
7745 	 *
7746 	 * +-----------------+----------------+
7747 	 * | log2 block_size | Reserved(0000) |
7748 	 * +-----------------+----------------+
7749 	 * 13               14               16
7750 	 */
7751 	memcpy(buff, zisofs_magic, 8);
7752 	set_num_731(buff+8, file->zisofs.uncompressed_size);
7753 	buff[12] = file->zisofs.header_size;
7754 	buff[13] = file->zisofs.log2_bs;
7755 	buff[14] = buff[15] = 0;/* Reserved */
7756 
7757 	/* Move to the right position to write the header. */
7758 	wb_set_offset(a, file->content.offset_of_temp);
7759 
7760 	/* Write the header. */
7761 	if (wb_write_to_temp(a, buff, 16) != ARCHIVE_OK)
7762 		return (ARCHIVE_FATAL);
7763 
7764 	/*
7765 	 * Write zisofs Block Pointers.
7766 	 */
7767 	s = iso9660->zisofs.block_pointers_cnt *
7768 	    sizeof(iso9660->zisofs.block_pointers[0]);
7769 	if (wb_write_to_temp(a, iso9660->zisofs.block_pointers, s)
7770 	    != ARCHIVE_OK)
7771 		return (ARCHIVE_FATAL);
7772 
7773 	/* Set a file pointer back to the end of the temporary file. */
7774 	wb_set_offset(a, tail);
7775 
7776 	return (ARCHIVE_OK);
7777 }
7778 
7779 static int
7780 zisofs_free(struct archive_write *a)
7781 {
7782 	struct iso9660 *iso9660 = a->format_data;
7783 	int ret = ARCHIVE_OK;
7784 
7785 	free(iso9660->zisofs.block_pointers);
7786 	if (iso9660->zisofs.stream_valid &&
7787 	    deflateEnd(&(iso9660->zisofs.stream)) != Z_OK) {
7788 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
7789 		    "Failed to clean up compressor");
7790 		ret = ARCHIVE_FATAL;
7791 	}
7792 	iso9660->zisofs.block_pointers = NULL;
7793 	iso9660->zisofs.stream_valid = 0;
7794 	return (ret);
7795 }
7796 
7797 struct zisofs_extract {
7798 	int		 pz_log2_bs; /* Log2 of block size */
7799 	uint64_t	 pz_uncompressed_size;
7800 	size_t		 uncompressed_buffer_size;
7801 
7802 	signed int	 initialized:1;
7803 	signed int	 header_passed:1;
7804 
7805 	uint32_t	 pz_offset;
7806 	unsigned char	*block_pointers;
7807 	size_t		 block_pointers_size;
7808 	size_t		 block_pointers_avail;
7809 	size_t		 block_off;
7810 	uint32_t	 block_avail;
7811 
7812 	z_stream	 stream;
7813 	int		 stream_valid;
7814 };
7815 
7816 static ssize_t
7817 zisofs_extract_init(struct archive_write *a, struct zisofs_extract *zisofs,
7818     const unsigned char *p, size_t bytes)
7819 {
7820 	size_t avail = bytes;
7821 	size_t _ceil, xsize;
7822 
7823 	/* Allocate block pointers buffer. */
7824 	_ceil = (size_t)((zisofs->pz_uncompressed_size +
7825 		(((int64_t)1) << zisofs->pz_log2_bs) - 1)
7826 		>> zisofs->pz_log2_bs);
7827 	xsize = (_ceil + 1) * 4;
7828 	if (zisofs->block_pointers == NULL) {
7829 		size_t alloc = ((xsize >> 10) + 1) << 10;
7830 		zisofs->block_pointers = malloc(alloc);
7831 		if (zisofs->block_pointers == NULL) {
7832 			archive_set_error(&a->archive, ENOMEM,
7833 			    "No memory for zisofs decompression");
7834 			return (ARCHIVE_FATAL);
7835 		}
7836 	}
7837 	zisofs->block_pointers_size = xsize;
7838 
7839 	/* Allocate uncompressed data buffer. */
7840 	zisofs->uncompressed_buffer_size = (size_t)1UL << zisofs->pz_log2_bs;
7841 
7842 	/*
7843 	 * Read the file header, and check the magic code of zisofs.
7844 	 */
7845 	if (!zisofs->header_passed) {
7846 		int err = 0;
7847 		if (avail < 16) {
7848 			archive_set_error(&a->archive,
7849 			    ARCHIVE_ERRNO_FILE_FORMAT,
7850 			    "Illegal zisofs file body");
7851 			return (ARCHIVE_FATAL);
7852 		}
7853 
7854 		if (memcmp(p, zisofs_magic, sizeof(zisofs_magic)) != 0)
7855 			err = 1;
7856 		else if (archive_le32dec(p + 8) != zisofs->pz_uncompressed_size)
7857 			err = 1;
7858 		else if (p[12] != 4 || p[13] != zisofs->pz_log2_bs)
7859 			err = 1;
7860 		if (err) {
7861 			archive_set_error(&a->archive,
7862 			    ARCHIVE_ERRNO_FILE_FORMAT,
7863 			    "Illegal zisofs file body");
7864 			return (ARCHIVE_FATAL);
7865 		}
7866 		avail -= 16;
7867 		p += 16;
7868 		zisofs->header_passed = 1;
7869 	}
7870 
7871 	/*
7872 	 * Read block pointers.
7873 	 */
7874 	if (zisofs->header_passed &&
7875 	    zisofs->block_pointers_avail < zisofs->block_pointers_size) {
7876 		xsize = zisofs->block_pointers_size
7877 		    - zisofs->block_pointers_avail;
7878 		if (avail < xsize)
7879 			xsize = avail;
7880 		memcpy(zisofs->block_pointers
7881 		    + zisofs->block_pointers_avail, p, xsize);
7882 		zisofs->block_pointers_avail += xsize;
7883 		avail -= xsize;
7884 	    	if (zisofs->block_pointers_avail
7885 		    == zisofs->block_pointers_size) {
7886 			/* We've got all block pointers and initialize
7887 			 * related variables.	*/
7888 			zisofs->block_off = 0;
7889 			zisofs->block_avail = 0;
7890 			/* Complete a initialization */
7891 			zisofs->initialized = 1;
7892 		}
7893 	}
7894 	return ((ssize_t)avail);
7895 }
7896 
7897 static ssize_t
7898 zisofs_extract(struct archive_write *a, struct zisofs_extract *zisofs,
7899     const unsigned char *p, size_t bytes)
7900 {
7901 	size_t avail;
7902 	int r;
7903 
7904 	if (!zisofs->initialized) {
7905 		ssize_t rs = zisofs_extract_init(a, zisofs, p, bytes);
7906 		if (rs < 0)
7907 			return (rs);
7908 		if (!zisofs->initialized) {
7909 			/* We need more data. */
7910 			zisofs->pz_offset += (uint32_t)bytes;
7911 			return (bytes);
7912 		}
7913 		avail = rs;
7914 		p += bytes - avail;
7915 	} else
7916 		avail = bytes;
7917 
7918 	/*
7919 	 * Get block offsets from block pointers.
7920 	 */
7921 	if (zisofs->block_avail == 0) {
7922 		uint32_t bst, bed;
7923 
7924 		if (zisofs->block_off + 4 >= zisofs->block_pointers_size) {
7925 			/* There isn't a pair of offsets. */
7926 			archive_set_error(&a->archive,
7927 			    ARCHIVE_ERRNO_FILE_FORMAT,
7928 			    "Illegal zisofs block pointers");
7929 			return (ARCHIVE_FATAL);
7930 		}
7931 		bst = archive_le32dec(
7932 		    zisofs->block_pointers + zisofs->block_off);
7933 		if (bst != zisofs->pz_offset + (bytes - avail)) {
7934 			archive_set_error(&a->archive,
7935 			    ARCHIVE_ERRNO_FILE_FORMAT,
7936 			    "Illegal zisofs block pointers(cannot seek)");
7937 			return (ARCHIVE_FATAL);
7938 		}
7939 		bed = archive_le32dec(
7940 		    zisofs->block_pointers + zisofs->block_off + 4);
7941 		if (bed < bst) {
7942 			archive_set_error(&a->archive,
7943 			    ARCHIVE_ERRNO_FILE_FORMAT,
7944 			    "Illegal zisofs block pointers");
7945 			return (ARCHIVE_FATAL);
7946 		}
7947 		zisofs->block_avail = bed - bst;
7948 		zisofs->block_off += 4;
7949 
7950 		/* Initialize compression library for new block. */
7951 		if (zisofs->stream_valid)
7952 			r = inflateReset(&zisofs->stream);
7953 		else
7954 			r = inflateInit(&zisofs->stream);
7955 		if (r != Z_OK) {
7956 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
7957 			    "Can't initialize zisofs decompression.");
7958 			return (ARCHIVE_FATAL);
7959 		}
7960 		zisofs->stream_valid = 1;
7961 		zisofs->stream.total_in = 0;
7962 		zisofs->stream.total_out = 0;
7963 	}
7964 
7965 	/*
7966 	 * Make uncompressed data.
7967 	 */
7968 	if (zisofs->block_avail == 0) {
7969 		/*
7970 		 * It's basically 32K bytes NUL data.
7971 		 */
7972 		unsigned char *wb;
7973 		size_t size, wsize;
7974 
7975 		size = zisofs->uncompressed_buffer_size;
7976 		while (size) {
7977 			wb = wb_buffptr(a);
7978 			if (size > wb_remaining(a))
7979 				wsize = wb_remaining(a);
7980 			else
7981 				wsize = size;
7982 			memset(wb, 0, wsize);
7983 			r = wb_consume(a, wsize);
7984 			if (r < 0)
7985 				return (r);
7986 			size -= wsize;
7987 		}
7988 	} else {
7989 		zisofs->stream.next_in = (Bytef *)(uintptr_t)(const void *)p;
7990 		if (avail > zisofs->block_avail)
7991 			zisofs->stream.avail_in = zisofs->block_avail;
7992 		else
7993 			zisofs->stream.avail_in = (uInt)avail;
7994 		zisofs->stream.next_out = wb_buffptr(a);
7995 		zisofs->stream.avail_out = (uInt)wb_remaining(a);
7996 
7997 		r = inflate(&zisofs->stream, 0);
7998 		switch (r) {
7999 		case Z_OK: /* Decompressor made some progress.*/
8000 		case Z_STREAM_END: /* Found end of stream. */
8001 			break;
8002 		default:
8003 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
8004 			    "zisofs decompression failed (%d)", r);
8005 			return (ARCHIVE_FATAL);
8006 		}
8007 		avail -= zisofs->stream.next_in - p;
8008 		zisofs->block_avail -= (uint32_t)(zisofs->stream.next_in - p);
8009 		r = wb_consume(a, wb_remaining(a) - zisofs->stream.avail_out);
8010 		if (r < 0)
8011 			return (r);
8012 	}
8013 	zisofs->pz_offset += (uint32_t)bytes;
8014 	return (bytes - avail);
8015 }
8016 
8017 static int
8018 zisofs_rewind_boot_file(struct archive_write *a)
8019 {
8020 	struct iso9660 *iso9660 = a->format_data;
8021 	struct isofile *file;
8022 	unsigned char *rbuff;
8023 	ssize_t r;
8024 	size_t remaining, rbuff_size;
8025 	struct zisofs_extract zext;
8026 	int64_t read_offset, write_offset, new_offset;
8027 	int fd, ret = ARCHIVE_OK;
8028 
8029 	file = iso9660->el_torito.boot->file;
8030 	/*
8031 	 * There is nothing to do if this boot file does not have
8032 	 * zisofs header.
8033 	 */
8034 	if (file->zisofs.header_size == 0)
8035 		return (ARCHIVE_OK);
8036 
8037 	/*
8038 	 * Uncompress the zisofs'ed file contents.
8039 	 */
8040 	memset(&zext, 0, sizeof(zext));
8041 	zext.pz_uncompressed_size = file->zisofs.uncompressed_size;
8042 	zext.pz_log2_bs = file->zisofs.log2_bs;
8043 
8044 	fd = iso9660->temp_fd;
8045 	new_offset = wb_offset(a);
8046 	read_offset = file->content.offset_of_temp;
8047 	remaining = (size_t)file->content.size;
8048 	if (remaining > 1024 * 32)
8049 		rbuff_size = 1024 * 32;
8050 	else
8051 		rbuff_size = remaining;
8052 
8053 	rbuff = malloc(rbuff_size);
8054 	if (rbuff == NULL) {
8055 		archive_set_error(&a->archive, ENOMEM, "Can't allocate memory");
8056 		return (ARCHIVE_FATAL);
8057 	}
8058 	while (remaining) {
8059 		size_t rsize;
8060 		ssize_t rs;
8061 
8062 		/* Get the current file pointer. */
8063 		write_offset = lseek(fd, 0, SEEK_CUR);
8064 
8065 		/* Change the file pointer to read. */
8066 		lseek(fd, read_offset, SEEK_SET);
8067 
8068 		rsize = rbuff_size;
8069 		if (rsize > remaining)
8070 			rsize = remaining;
8071 		rs = read(iso9660->temp_fd, rbuff, rsize);
8072 		if (rs <= 0) {
8073 			archive_set_error(&a->archive, errno,
8074 			    "Can't read temporary file(%jd)", (intmax_t)rs);
8075 			ret = ARCHIVE_FATAL;
8076 			break;
8077 		}
8078 		remaining -= rs;
8079 		read_offset += rs;
8080 
8081 		/* Put the file pointer back to write. */
8082 		lseek(fd, write_offset, SEEK_SET);
8083 
8084 		r = zisofs_extract(a, &zext, rbuff, rs);
8085 		if (r < 0) {
8086 			ret = (int)r;
8087 			break;
8088 		}
8089 	}
8090 
8091 	if (ret == ARCHIVE_OK) {
8092 		/*
8093 		 * Change the boot file content from zisofs'ed data
8094 		 * to plain data.
8095 		 */
8096 		file->content.offset_of_temp = new_offset;
8097 		file->content.size = file->zisofs.uncompressed_size;
8098 		archive_entry_set_size(file->entry, file->content.size);
8099 		/* Set to be no zisofs. */
8100 		file->zisofs.header_size = 0;
8101 		file->zisofs.log2_bs = 0;
8102 		file->zisofs.uncompressed_size = 0;
8103 		r = wb_write_padding_to_temp(a, file->content.size);
8104 		if (r < 0)
8105 			ret = ARCHIVE_FATAL;
8106 	}
8107 
8108 	/*
8109 	 * Free the resource we used in this function only.
8110 	 */
8111 	free(rbuff);
8112 	free(zext.block_pointers);
8113 	if (zext.stream_valid && inflateEnd(&(zext.stream)) != Z_OK) {
8114         	archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
8115 		    "Failed to clean up compressor");
8116 		ret = ARCHIVE_FATAL;
8117 	}
8118 
8119 	return (ret);
8120 }
8121 
8122 #else
8123 
8124 static int
8125 zisofs_write_to_temp(struct archive_write *a, const void *buff, size_t s)
8126 {
8127 	(void)buff; /* UNUSED */
8128 	(void)s; /* UNUSED */
8129 	archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Programming error");
8130 	return (ARCHIVE_FATAL);
8131 }
8132 
8133 static int
8134 zisofs_rewind_boot_file(struct archive_write *a)
8135 {
8136 	struct iso9660 *iso9660 = a->format_data;
8137 
8138 	if (iso9660->el_torito.boot->file->zisofs.header_size != 0) {
8139 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
8140 		    "We cannot extract the zisofs imaged boot file;"
8141 		    " this may not boot in being zisofs imaged");
8142 		return (ARCHIVE_FAILED);
8143 	}
8144 	return (ARCHIVE_OK);
8145 }
8146 
8147 static int
8148 zisofs_finish_entry(struct archive_write *a)
8149 {
8150 	(void)a; /* UNUSED */
8151 	return (ARCHIVE_OK);
8152 }
8153 
8154 static int
8155 zisofs_free(struct archive_write *a)
8156 {
8157 	(void)a; /* UNUSED */
8158 	return (ARCHIVE_OK);
8159 }
8160 
8161 #endif /* HAVE_ZLIB_H */
8162 
8163