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 	strncpy(system_id, "Unknown", size-1);
2182 	system_id[size-1] = '\0';
2183 #endif
2184 }
2185 
2186 static void
2187 set_str(unsigned char *p, const char *s, size_t l, char f, const char *map)
2188 {
2189 	unsigned char c;
2190 
2191 	if (s == NULL)
2192 		s = "";
2193 	while ((c = *s++) != 0 && l > 0) {
2194 		if (c >= 0x80 || map[c] == 0)
2195 		 {
2196 			/* illegal character */
2197 			if (c >= 'a' && c <= 'z') {
2198 				/* convert c from a-z to A-Z */
2199 				c -= 0x20;
2200 			} else
2201 				c = 0x5f;
2202 		}
2203 		*p++ = c;
2204 		l--;
2205 	}
2206 	/* If l isn't zero, fill p buffer by the character
2207 	 * which indicated by f. */
2208 	if (l > 0)
2209 		memset(p , f, l);
2210 }
2211 
2212 static inline int
2213 joliet_allowed_char(unsigned char high, unsigned char low)
2214 {
2215 	int utf16 = (high << 8) | low;
2216 
2217 	if (utf16 <= 0x001F)
2218 		return (0);
2219 
2220 	switch (utf16) {
2221 	case 0x002A: /* '*' */
2222 	case 0x002F: /* '/' */
2223 	case 0x003A: /* ':' */
2224 	case 0x003B: /* ';' */
2225 	case 0x003F: /* '?' */
2226 	case 0x005C: /* '\' */
2227 		return (0);/* Not allowed. */
2228 	}
2229 	return (1);
2230 }
2231 
2232 static int
2233 set_str_utf16be(struct archive_write *a, unsigned char *p, const char *s,
2234     size_t l, uint16_t uf, enum vdc vdc)
2235 {
2236 	size_t size, i;
2237 	int onepad;
2238 
2239 	if (s == NULL)
2240 		s = "";
2241 	if (l & 0x01) {
2242 		onepad = 1;
2243 		l &= ~1;
2244 	} else
2245 		onepad = 0;
2246 	if (vdc == VDC_UCS2) {
2247 		struct iso9660 *iso9660 = a->format_data;
2248 		if (archive_strncpy_l(&iso9660->utf16be, s, strlen(s),
2249 		    iso9660->sconv_to_utf16be) != 0 && errno == ENOMEM) {
2250 			archive_set_error(&a->archive, ENOMEM,
2251 			    "Can't allocate memory for UTF-16BE");
2252 			return (ARCHIVE_FATAL);
2253 		}
2254 		size = iso9660->utf16be.length;
2255 		if (size > l)
2256 			size = l;
2257 		memcpy(p, iso9660->utf16be.s, size);
2258 	} else {
2259 		const uint16_t *u16 = (const uint16_t *)s;
2260 
2261 		size = 0;
2262 		while (*u16++)
2263 			size += 2;
2264 		if (size > l)
2265 			size = l;
2266 		memcpy(p, s, size);
2267 	}
2268 	for (i = 0; i < size; i += 2, p += 2) {
2269 		if (!joliet_allowed_char(p[0], p[1]))
2270 			archive_be16enc(p, 0x005F);/* '_' */
2271 	}
2272 	l -= size;
2273 	while (l > 0) {
2274 		archive_be16enc(p, uf);
2275 		p += 2;
2276 		l -= 2;
2277 	}
2278 	if (onepad)
2279 		*p = 0;
2280 	return (ARCHIVE_OK);
2281 }
2282 
2283 static const char a_characters_map[0x80] = {
2284 /*  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F          */
2285     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
2286     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
2287     1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20-2F */
2288     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30-3F */
2289     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
2290     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
2291     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 60-6F */
2292     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 70-7F */
2293 };
2294 
2295 static const char a1_characters_map[0x80] = {
2296 /*  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F          */
2297     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
2298     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
2299     1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20-2F */
2300     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30-3F */
2301     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
2302     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
2303     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60-6F */
2304     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,/* 70-7F */
2305 };
2306 
2307 static const char d_characters_map[0x80] = {
2308 /*  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F          */
2309     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
2310     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
2311     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 20-2F */
2312     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,/* 30-3F */
2313     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
2314     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
2315     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 60-6F */
2316     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 70-7F */
2317 };
2318 
2319 static const char d1_characters_map[0x80] = {
2320 /*  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F          */
2321     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
2322     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
2323     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 20-2F */
2324     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,/* 30-3F */
2325     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
2326     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
2327     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60-6F */
2328     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,/* 70-7F */
2329 };
2330 
2331 static int
2332 set_str_a_characters_bp(struct archive_write *a, unsigned char *bp,
2333     int from, int to, const char *s, enum vdc vdc)
2334 {
2335 	int r;
2336 
2337 	switch (vdc) {
2338 	case VDC_STD:
2339 		set_str(bp+from, s, to - from + 1, 0x20,
2340 		    a_characters_map);
2341 		r = ARCHIVE_OK;
2342 		break;
2343 	case VDC_LOWERCASE:
2344 		set_str(bp+from, s, to - from + 1, 0x20,
2345 		    a1_characters_map);
2346 		r = ARCHIVE_OK;
2347 		break;
2348 	case VDC_UCS2:
2349 	case VDC_UCS2_DIRECT:
2350 		r = set_str_utf16be(a, bp+from, s, to - from + 1,
2351 		    0x0020, vdc);
2352 		break;
2353 	default:
2354 		r = ARCHIVE_FATAL;
2355 	}
2356 	return (r);
2357 }
2358 
2359 static int
2360 set_str_d_characters_bp(struct archive_write *a, unsigned char *bp,
2361     int from, int to, const char *s, enum  vdc vdc)
2362 {
2363 	int r;
2364 
2365 	switch (vdc) {
2366 	case VDC_STD:
2367 		set_str(bp+from, s, to - from + 1, 0x20,
2368 		    d_characters_map);
2369 		r = ARCHIVE_OK;
2370 		break;
2371 	case VDC_LOWERCASE:
2372 		set_str(bp+from, s, to - from + 1, 0x20,
2373 		    d1_characters_map);
2374 		r = ARCHIVE_OK;
2375 		break;
2376 	case VDC_UCS2:
2377 	case VDC_UCS2_DIRECT:
2378 		r = set_str_utf16be(a, bp+from, s, to - from + 1,
2379 		    0x0020, vdc);
2380 		break;
2381 	default:
2382 		r = ARCHIVE_FATAL;
2383 	}
2384 	return (r);
2385 }
2386 
2387 static void
2388 set_VD_bp(unsigned char *bp, enum VD_type type, unsigned char ver)
2389 {
2390 
2391 	/* Volume Descriptor Type */
2392 	bp[1] = (unsigned char)type;
2393 	/* Standard Identifier */
2394 	memcpy(bp + 2, "CD001", 5);
2395 	/* Volume Descriptor Version */
2396 	bp[7] = ver;
2397 }
2398 
2399 static inline void
2400 set_unused_field_bp(unsigned char *bp, int from, int to)
2401 {
2402 	memset(bp + from, 0, to - from + 1);
2403 }
2404 
2405 /*
2406  * 8-bit unsigned numerical values.
2407  * ISO9660 Standard 7.1.1
2408  */
2409 static inline void
2410 set_num_711(unsigned char *p, unsigned char value)
2411 {
2412 	*p = value;
2413 }
2414 
2415 /*
2416  * 8-bit signed numerical values.
2417  * ISO9660 Standard 7.1.2
2418  */
2419 static inline void
2420 set_num_712(unsigned char *p, char value)
2421 {
2422 	*((char *)p) = value;
2423 }
2424 
2425 /*
2426  * Least significant byte first.
2427  * ISO9660 Standard 7.2.1
2428  */
2429 static inline void
2430 set_num_721(unsigned char *p, uint16_t value)
2431 {
2432 	archive_le16enc(p, value);
2433 }
2434 
2435 /*
2436  * Most significant byte first.
2437  * ISO9660 Standard 7.2.2
2438  */
2439 static inline void
2440 set_num_722(unsigned char *p, uint16_t value)
2441 {
2442 	archive_be16enc(p, value);
2443 }
2444 
2445 /*
2446  * Both-byte orders.
2447  * ISO9660 Standard 7.2.3
2448  */
2449 static void
2450 set_num_723(unsigned char *p, uint16_t value)
2451 {
2452 	archive_le16enc(p, value);
2453 	archive_be16enc(p+2, value);
2454 }
2455 
2456 /*
2457  * Least significant byte first.
2458  * ISO9660 Standard 7.3.1
2459  */
2460 static inline void
2461 set_num_731(unsigned char *p, uint32_t value)
2462 {
2463 	archive_le32enc(p, value);
2464 }
2465 
2466 /*
2467  * Most significant byte first.
2468  * ISO9660 Standard 7.3.2
2469  */
2470 static inline void
2471 set_num_732(unsigned char *p, uint32_t value)
2472 {
2473 	archive_be32enc(p, value);
2474 }
2475 
2476 /*
2477  * Both-byte orders.
2478  * ISO9660 Standard 7.3.3
2479  */
2480 static inline void
2481 set_num_733(unsigned char *p, uint32_t value)
2482 {
2483 	archive_le32enc(p, value);
2484 	archive_be32enc(p+4, value);
2485 }
2486 
2487 static void
2488 set_digit(unsigned char *p, size_t s, int value)
2489 {
2490 
2491 	while (s--) {
2492 		p[s] = '0' + (value % 10);
2493 		value /= 10;
2494 	}
2495 }
2496 
2497 #if defined(HAVE_STRUCT_TM_TM_GMTOFF)
2498 #define get_gmoffset(tm)	((tm)->tm_gmtoff)
2499 #elif defined(HAVE_STRUCT_TM___TM_GMTOFF)
2500 #define get_gmoffset(tm)	((tm)->__tm_gmtoff)
2501 #else
2502 static long
2503 get_gmoffset(struct tm *tm)
2504 {
2505 	long offset;
2506 
2507 #if defined(HAVE__GET_TIMEZONE)
2508 	_get_timezone(&offset);
2509 #elif defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
2510 	offset = _timezone;
2511 #else
2512 	offset = timezone;
2513 #endif
2514 	offset *= -1;
2515 	if (tm->tm_isdst)
2516 		offset += 3600;
2517 	return (offset);
2518 }
2519 #endif
2520 
2521 static void
2522 get_tmfromtime(struct tm *tm, time_t *t)
2523 {
2524 #if HAVE_LOCALTIME_R
2525 	tzset();
2526 	localtime_r(t, tm);
2527 #elif HAVE__LOCALTIME64_S
2528 	__time64_t tmp_t = (__time64_t) *t; //time_t may be shorter than 64 bits
2529 	_localtime64_s(tm, &tmp_t);
2530 #else
2531 	memcpy(tm, localtime(t), sizeof(*tm));
2532 #endif
2533 }
2534 
2535 /*
2536  * Date and Time Format.
2537  * ISO9660 Standard 8.4.26.1
2538  */
2539 static void
2540 set_date_time(unsigned char *p, time_t t)
2541 {
2542 	struct tm tm;
2543 
2544 	get_tmfromtime(&tm, &t);
2545 	set_digit(p, 4, tm.tm_year + 1900);
2546 	set_digit(p+4, 2, tm.tm_mon + 1);
2547 	set_digit(p+6, 2, tm.tm_mday);
2548 	set_digit(p+8, 2, tm.tm_hour);
2549 	set_digit(p+10, 2, tm.tm_min);
2550 	set_digit(p+12, 2, tm.tm_sec);
2551 	set_digit(p+14, 2, 0);
2552 	set_num_712(p+16, (char)(get_gmoffset(&tm)/(60*15)));
2553 }
2554 
2555 static void
2556 set_date_time_null(unsigned char *p)
2557 {
2558 	memset(p, (int)'0', 16);
2559 	p[16] = 0;
2560 }
2561 
2562 static void
2563 set_time_915(unsigned char *p, time_t t)
2564 {
2565 	struct tm tm;
2566 
2567 	get_tmfromtime(&tm, &t);
2568 	set_num_711(p+0, tm.tm_year);
2569 	set_num_711(p+1, tm.tm_mon+1);
2570 	set_num_711(p+2, tm.tm_mday);
2571 	set_num_711(p+3, tm.tm_hour);
2572 	set_num_711(p+4, tm.tm_min);
2573 	set_num_711(p+5, tm.tm_sec);
2574 	set_num_712(p+6, (char)(get_gmoffset(&tm)/(60*15)));
2575 }
2576 
2577 
2578 /*
2579  * Write SUSP "CE" System Use Entry.
2580  */
2581 static int
2582 set_SUSP_CE(unsigned char *p, int location, int offset, int size)
2583 {
2584 	unsigned char *bp = p -1;
2585 	/*  Extend the System Use Area
2586 	 *   "CE" Format:
2587 	 *               len  ver
2588 	 *    +----+----+----+----+-----------+-----------+
2589 	 *    | 'C'| 'E'| 1C | 01 | LOCATION1 | LOCATION2 |
2590 	 *    +----+----+----+----+-----------+-----------+
2591 	 *    0    1    2    3    4          12          20
2592 	 *    +-----------+
2593 	 *    | LOCATION3 |
2594 	 *    +-----------+
2595 	 *   20          28
2596 	 *   LOCATION1 : Location of Continuation of System Use Area.
2597 	 *   LOCATION2 : Offset to Start of Continuation.
2598 	 *   LOCATION3 : Length of the Continuation.
2599 	 */
2600 
2601 	bp[1] = 'C';
2602 	bp[2] = 'E';
2603 	bp[3] = RR_CE_SIZE;	/* length	*/
2604 	bp[4] = 1;		/* version	*/
2605 	set_num_733(bp+5, location);
2606 	set_num_733(bp+13, offset);
2607 	set_num_733(bp+21, size);
2608 	return (RR_CE_SIZE);
2609 }
2610 
2611 /*
2612  * The functions, which names are beginning with extra_, are used to
2613  * control extra records.
2614  * The maximum size of a Directory Record is 254. When a filename is
2615  * very long, all of RRIP data of a file won't stored to the Directory
2616  * Record and so remaining RRIP data store to an extra record instead.
2617  */
2618 static unsigned char *
2619 extra_open_record(unsigned char *bp, int dr_len, struct isoent *isoent,
2620     struct ctl_extr_rec *ctl)
2621 {
2622 	ctl->bp = bp;
2623 	if (bp != NULL)
2624 		bp += dr_len;
2625 	ctl->use_extr = 0;
2626 	ctl->isoent = isoent;
2627 	ctl->ce_ptr = NULL;
2628 	ctl->cur_len = ctl->dr_len = dr_len;
2629 	ctl->limit = DR_LIMIT;
2630 
2631 	return (bp);
2632 }
2633 
2634 static void
2635 extra_close_record(struct ctl_extr_rec *ctl, int ce_size)
2636 {
2637 	int padding = 0;
2638 
2639 	if (ce_size > 0)
2640 		extra_tell_used_size(ctl, ce_size);
2641 	/* Padding. */
2642 	if (ctl->cur_len & 0x01) {
2643 		ctl->cur_len++;
2644 		if (ctl->bp != NULL)
2645 			ctl->bp[ctl->cur_len] = 0;
2646 		padding = 1;
2647 	}
2648 	if (ctl->use_extr) {
2649 		if (ctl->ce_ptr != NULL)
2650 			set_SUSP_CE(ctl->ce_ptr, ctl->extr_loc,
2651 			    ctl->extr_off, ctl->cur_len - padding);
2652 	} else
2653 		ctl->dr_len = ctl->cur_len;
2654 }
2655 
2656 #define extra_space(ctl)	((ctl)->limit - (ctl)->cur_len)
2657 
2658 static unsigned char *
2659 extra_next_record(struct ctl_extr_rec *ctl, int length)
2660 {
2661 	int cur_len = ctl->cur_len;/* save cur_len */
2662 
2663 	/* Close the current extra record or Directory Record. */
2664 	extra_close_record(ctl, RR_CE_SIZE);
2665 
2666 	/* Get a next extra record. */
2667 	ctl->use_extr = 1;
2668 	if (ctl->bp != NULL) {
2669 		/* Storing data into an extra record. */
2670 		unsigned char *p;
2671 
2672 		/* Save the pointer where a CE extension will be
2673 		 * stored to. */
2674 		ctl->ce_ptr = &ctl->bp[cur_len+1];
2675 		p = extra_get_record(ctl->isoent,
2676 		    &ctl->limit, &ctl->extr_off, &ctl->extr_loc);
2677 		ctl->bp = p - 1;/* the base of bp offset is 1. */
2678 	} else
2679 		/* Calculating the size of an extra record. */
2680 		(void)extra_get_record(ctl->isoent,
2681 		    &ctl->limit, NULL, NULL);
2682 	ctl->cur_len = 0;
2683 	/* Check if an extra record is almost full.
2684 	 * If so, get a next one. */
2685 	if (extra_space(ctl) < length)
2686 		(void)extra_next_record(ctl, length);
2687 
2688 	return (ctl->bp);
2689 }
2690 
2691 static inline struct extr_rec *
2692 extra_last_record(struct isoent *isoent)
2693 {
2694 	if (isoent->extr_rec_list.first == NULL)
2695 		return (NULL);
2696 	return ((struct extr_rec *)(void *)
2697 		((char *)(isoent->extr_rec_list.last)
2698 		    - offsetof(struct extr_rec, next)));
2699 }
2700 
2701 static unsigned char *
2702 extra_get_record(struct isoent *isoent, int *space, int *off, int *loc)
2703 {
2704 	struct extr_rec *rec;
2705 
2706 	isoent = isoent->parent;
2707 	if (off != NULL) {
2708 		/* Storing data into an extra record. */
2709 		rec = isoent->extr_rec_list.current;
2710 		if (DR_SAFETY > LOGICAL_BLOCK_SIZE - rec->offset)
2711 			rec = rec->next;
2712 	} else {
2713 		/* Calculating the size of an extra record. */
2714 		rec = extra_last_record(isoent);
2715 		if (rec == NULL ||
2716 		    DR_SAFETY > LOGICAL_BLOCK_SIZE - rec->offset) {
2717 			rec = malloc(sizeof(*rec));
2718 			if (rec == NULL)
2719 				return (NULL);
2720 			rec->location = 0;
2721 			rec->offset = 0;
2722 			/* Insert `rec` into the tail of isoent->extr_rec_list */
2723 			rec->next = NULL;
2724 			/*
2725 			 * Note: testing isoent->extr_rec_list.last == NULL
2726 			 * here is really unneeded since it has been already
2727 			 * initialized at isoent_new function but Clang Static
2728 			 * Analyzer claims that it is dereference of null
2729 			 * pointer.
2730 			 */
2731 			if (isoent->extr_rec_list.last == NULL)
2732 				isoent->extr_rec_list.last =
2733 					&(isoent->extr_rec_list.first);
2734 			*isoent->extr_rec_list.last = rec;
2735 			isoent->extr_rec_list.last = &(rec->next);
2736 		}
2737 	}
2738 	*space = LOGICAL_BLOCK_SIZE - rec->offset - DR_SAFETY;
2739 	if (*space & 0x01)
2740 		*space -= 1;/* Keep padding space. */
2741 	if (off != NULL)
2742 		*off = rec->offset;
2743 	if (loc != NULL)
2744 		*loc = rec->location;
2745 	isoent->extr_rec_list.current = rec;
2746 
2747 	return (&rec->buf[rec->offset]);
2748 }
2749 
2750 static void
2751 extra_tell_used_size(struct ctl_extr_rec *ctl, int size)
2752 {
2753 	struct isoent *isoent;
2754 	struct extr_rec *rec;
2755 
2756 	if (ctl->use_extr) {
2757 		isoent = ctl->isoent->parent;
2758 		rec = isoent->extr_rec_list.current;
2759 		if (rec != NULL)
2760 			rec->offset += size;
2761 	}
2762 	ctl->cur_len += size;
2763 }
2764 
2765 static int
2766 extra_setup_location(struct isoent *isoent, int location)
2767 {
2768 	struct extr_rec *rec;
2769 	int cnt;
2770 
2771 	cnt = 0;
2772 	rec = isoent->extr_rec_list.first;
2773 	isoent->extr_rec_list.current = rec;
2774 	while (rec) {
2775 		cnt++;
2776 		rec->location = location++;
2777 		rec->offset = 0;
2778 		rec = rec->next;
2779 	}
2780 	return (cnt);
2781 }
2782 
2783 /*
2784  * Create the RRIP entries.
2785  */
2786 static int
2787 set_directory_record_rr(unsigned char *bp, int dr_len,
2788     struct isoent *isoent, struct iso9660 *iso9660, enum dir_rec_type t)
2789 {
2790 	/* Flags(BP 5) of the Rockridge "RR" System Use Field */
2791 	unsigned char rr_flag;
2792 #define RR_USE_PX	0x01
2793 #define RR_USE_PN	0x02
2794 #define RR_USE_SL	0x04
2795 #define RR_USE_NM	0x08
2796 #define RR_USE_CL	0x10
2797 #define RR_USE_PL	0x20
2798 #define RR_USE_RE	0x40
2799 #define RR_USE_TF	0x80
2800 	int length;
2801 	struct ctl_extr_rec ctl;
2802 	struct isoent *rr_parent, *pxent;
2803 	struct isofile *file;
2804 
2805 	bp = extra_open_record(bp, dr_len, isoent, &ctl);
2806 
2807 	if (t == DIR_REC_PARENT) {
2808 		rr_parent = isoent->rr_parent;
2809 		pxent = isoent->parent;
2810 		if (rr_parent != NULL)
2811 			isoent = rr_parent;
2812 		else
2813 			isoent = isoent->parent;
2814 	} else {
2815 		rr_parent = NULL;
2816 		pxent = isoent;
2817 	}
2818 	file = isoent->file;
2819 
2820 	if (t != DIR_REC_NORMAL) {
2821 		rr_flag = RR_USE_PX | RR_USE_TF;
2822 		if (rr_parent != NULL)
2823 			rr_flag |= RR_USE_PL;
2824 	} else {
2825 		rr_flag = RR_USE_PX | RR_USE_NM | RR_USE_TF;
2826 		if (archive_entry_filetype(file->entry) == AE_IFLNK)
2827 			rr_flag |= RR_USE_SL;
2828 		if (isoent->rr_parent != NULL)
2829 			rr_flag |= RR_USE_RE;
2830 		if (isoent->rr_child != NULL)
2831 			rr_flag |= RR_USE_CL;
2832 		if (archive_entry_filetype(file->entry) == AE_IFCHR ||
2833 		    archive_entry_filetype(file->entry) == AE_IFBLK)
2834 			rr_flag |= RR_USE_PN;
2835 #ifdef COMPAT_MKISOFS
2836 		/*
2837 		 * mkisofs 2.01.01a63 records "RE" extension to
2838 		 * the entry of "rr_moved" directory.
2839 		 * I don't understand this behavior.
2840 		 */
2841 		if (isoent->virtual &&
2842 		    isoent->parent == iso9660->primary.rootent &&
2843 		    strcmp(isoent->file->basename.s, "rr_moved") == 0)
2844 			rr_flag |= RR_USE_RE;
2845 #endif
2846 	}
2847 
2848 	/* Write "SP" System Use Entry. */
2849 	if (t == DIR_REC_SELF && isoent == isoent->parent) {
2850 		length = 7;
2851 		if (bp != NULL) {
2852 			bp[1] = 'S';
2853 			bp[2] = 'P';
2854 			bp[3] = length;
2855 			bp[4] = 1;	/* version	*/
2856 			bp[5] = 0xBE;  /* Check Byte	*/
2857 			bp[6] = 0xEF;  /* Check Byte	*/
2858 			bp[7] = 0;
2859 			bp += length;
2860 		}
2861 		extra_tell_used_size(&ctl, length);
2862 	}
2863 
2864 	/* Write "RR" System Use Entry. */
2865 	length = 5;
2866 	if (extra_space(&ctl) < length)
2867 		bp = extra_next_record(&ctl, length);
2868 	if (bp != NULL) {
2869 		bp[1] = 'R';
2870 		bp[2] = 'R';
2871 		bp[3] = length;
2872 		bp[4] = 1;	/* version */
2873 		bp[5] = rr_flag;
2874 		bp += length;
2875 	}
2876 	extra_tell_used_size(&ctl, length);
2877 
2878 	/* Write "NM" System Use Entry. */
2879 	if (rr_flag & RR_USE_NM) {
2880 		/*
2881 		 *   "NM" Format:
2882 		 *     e.g. a basename is 'foo'
2883 		 *               len  ver  flg
2884 		 *    +----+----+----+----+----+----+----+----+
2885 		 *    | 'N'| 'M'| 08 | 01 | 00 | 'f'| 'o'| 'o'|
2886 		 *    +----+----+----+----+----+----+----+----+
2887 		 *    <----------------- len ----------------->
2888 		 */
2889 		size_t nmlen = file->basename.length;
2890 		const char *nm = file->basename.s;
2891 		size_t nmmax;
2892 
2893 		if (extra_space(&ctl) < 6)
2894 			bp = extra_next_record(&ctl, 6);
2895 		if (bp != NULL) {
2896 			bp[1] = 'N';
2897 			bp[2] = 'M';
2898 			bp[4] = 1;	    /* version	*/
2899 		}
2900 		nmmax = extra_space(&ctl);
2901 		if (nmmax > 0xff)
2902 			nmmax = 0xff;
2903 		while (nmlen + 5 > nmmax) {
2904 			length = (int)nmmax;
2905 			if (bp != NULL) {
2906 				bp[3] = length;
2907 				bp[5] = 0x01;/* Alternate Name continues
2908 					       * in next "NM" field */
2909 				memcpy(bp+6, nm, length - 5);
2910 				bp += length;
2911 			}
2912 			nmlen -= length - 5;
2913 			nm += length - 5;
2914 			extra_tell_used_size(&ctl, length);
2915 			if (extra_space(&ctl) < 6) {
2916 				bp = extra_next_record(&ctl, 6);
2917 				nmmax = extra_space(&ctl);
2918 				if (nmmax > 0xff)
2919 					nmmax = 0xff;
2920 			}
2921 			if (bp != NULL) {
2922 				bp[1] = 'N';
2923 				bp[2] = 'M';
2924 				bp[4] = 1;    /* version */
2925 			}
2926 		}
2927 		length = 5 + (int)nmlen;
2928 		if (bp != NULL) {
2929 			bp[3] = length;
2930 			bp[5] = 0;
2931 			memcpy(bp+6, nm, nmlen);
2932 			bp += length;
2933 		}
2934 		extra_tell_used_size(&ctl, length);
2935 	}
2936 
2937 	/* Write "PX" System Use Entry. */
2938 	if (rr_flag & RR_USE_PX) {
2939 		/*
2940 		 *   "PX" Format:
2941 		 *               len  ver
2942 		 *    +----+----+----+----+-----------+-----------+
2943 		 *    | 'P'| 'X'| 2C | 01 | FILE MODE |   LINKS   |
2944 		 *    +----+----+----+----+-----------+-----------+
2945 		 *    0    1    2    3    4          12          20
2946 		 *    +-----------+-----------+------------------+
2947 		 *    |  USER ID  | GROUP ID  |FILE SERIAL NUMBER|
2948 		 *    +-----------+-----------+------------------+
2949 		 *   20          28          36                 44
2950 		 */
2951 		length = 44;
2952 		if (extra_space(&ctl) < length)
2953 			bp = extra_next_record(&ctl, length);
2954 		if (bp != NULL) {
2955 			mode_t mode;
2956 			int64_t uid;
2957 			int64_t gid;
2958 
2959 			mode = archive_entry_mode(file->entry);
2960 			uid = archive_entry_uid(file->entry);
2961 			gid = archive_entry_gid(file->entry);
2962 			if (iso9660->opt.rr == OPT_RR_USEFUL) {
2963 				/*
2964 				 * This action is similar to mkisofs -r option
2965 				 * but our rockridge=useful option does not
2966 				 * set a zero to uid and gid.
2967 				 */
2968 				/* set all read bit ON */
2969 				mode |= 0444;
2970 #if !defined(_WIN32) && !defined(__CYGWIN__)
2971 				if (mode & 0111)
2972 #endif
2973 					/* set all exec bit ON */
2974 					mode |= 0111;
2975 				/* clear all write bits. */
2976 				mode &= ~0222;
2977 				/* clear setuid,setgid,sticky bits. */
2978 				mode &= ~07000;
2979 			}
2980 
2981 			bp[1] = 'P';
2982 			bp[2] = 'X';
2983 			bp[3] = length;
2984 			bp[4] = 1;	/* version	*/
2985 			/* file mode */
2986 			set_num_733(bp+5, mode);
2987 			/* file links (stat.st_nlink) */
2988 			set_num_733(bp+13,
2989 			    archive_entry_nlink(file->entry));
2990 			set_num_733(bp+21, (uint32_t)uid);
2991 			set_num_733(bp+29, (uint32_t)gid);
2992 			/* File Serial Number */
2993 			if (pxent->dir)
2994 				set_num_733(bp+37, pxent->dir_location);
2995 			else if (file->hardlink_target != NULL)
2996 				set_num_733(bp+37,
2997 				    file->hardlink_target->cur_content->location);
2998 			else
2999 				set_num_733(bp+37,
3000 				    file->cur_content->location);
3001 			bp += length;
3002 		}
3003 		extra_tell_used_size(&ctl, length);
3004 	}
3005 
3006 	/* Write "SL" System Use Entry. */
3007 	if (rr_flag & RR_USE_SL) {
3008 		/*
3009 		 *   "SL" Format:
3010 		 *     e.g. a symbolic name is 'foo/bar'
3011 		 *               len  ver  flg
3012 		 *    +----+----+----+----+----+------------+
3013 		 *    | 'S'| 'L'| 0F | 01 | 00 | components |
3014 		 *    +----+----+----+----+----+-----+------+
3015 		 *    0    1    2    3    4    5  ...|...  15
3016 		 *    <----------------- len --------+------>
3017 		 *    components :                   |
3018 		 *     cflg clen                     |
3019 		 *    +----+----+----+----+----+     |
3020 		 *    | 00 | 03 | 'f'| 'o'| 'o'| <---+
3021 		 *    +----+----+----+----+----+     |
3022 		 *    5    6    7    8    9   10     |
3023 		 *     cflg clen                     |
3024 		 *    +----+----+----+----+----+     |
3025 		 *    | 00 | 03 | 'b'| 'a'| 'r'| <---+
3026 		 *    +----+----+----+----+----+
3027 		 *   10   11   12   13   14   15
3028 		 *
3029 		 *    - cflg : flag of component
3030 		 *    - clen : length of component
3031 		 */
3032 		const char *sl;
3033 		char sl_last;
3034 
3035 		if (extra_space(&ctl) < 7)
3036 			bp = extra_next_record(&ctl, 7);
3037 		sl = file->symlink.s;
3038 		sl_last = '\0';
3039 		if (bp != NULL) {
3040 			bp[1] = 'S';
3041 			bp[2] = 'L';
3042 			bp[4] = 1;	/* version	*/
3043 		}
3044 		for (;;) {
3045 			unsigned char *nc, *cf,  *cl, cldmy = 0;
3046 			int sllen, slmax;
3047 
3048 			slmax = extra_space(&ctl);
3049 			if (slmax > 0xff)
3050 				slmax = 0xff;
3051 			if (bp != NULL)
3052 				nc = &bp[6];
3053 			else
3054 				nc = NULL;
3055 			cf = cl = NULL;
3056 			sllen = 0;
3057 			while (*sl && sllen + 11 < slmax) {
3058 				if (sl_last == '\0' && sl[0] == '/') {
3059 					/*
3060 					 *     flg  len
3061 					 *    +----+----+
3062 					 *    | 08 | 00 | ROOT component.
3063 					 *    +----+----+ ("/")
3064 					 *
3065 				 	 * Root component has to appear
3066 				 	 * at the first component only.
3067 					 */
3068 					if (nc != NULL) {
3069 						cf = nc++;
3070 						*cf = 0x08; /* ROOT */
3071 						*nc++ = 0;
3072 					}
3073 					sllen += 2;
3074 					sl++;
3075 					sl_last = '/';
3076 					cl = NULL;
3077 					continue;
3078 				}
3079 				if (((sl_last == '\0' || sl_last == '/') &&
3080 				      sl[0] == '.' && sl[1] == '.' &&
3081 				     (sl[2] == '/' || sl[2] == '\0')) ||
3082 				    (sl[0] == '/' &&
3083 				      sl[1] == '.' && sl[2] == '.' &&
3084 				     (sl[3] == '/' || sl[3] == '\0'))) {
3085 					/*
3086 					 *     flg  len
3087 					 *    +----+----+
3088 					 *    | 04 | 00 | PARENT component.
3089 					 *    +----+----+ ("..")
3090 					 */
3091 					if (nc != NULL) {
3092 						cf = nc++;
3093 						*cf = 0x04; /* PARENT */
3094 						*nc++ = 0;
3095 					}
3096 					sllen += 2;
3097 					if (sl[0] == '/')
3098 						sl += 3;/* skip "/.." */
3099 					else
3100 						sl += 2;/* skip ".." */
3101 					sl_last = '.';
3102 					cl = NULL;
3103 					continue;
3104 				}
3105 				if (((sl_last == '\0' || sl_last == '/') &&
3106 				      sl[0] == '.' &&
3107 				     (sl[1] == '/' || sl[1] == '\0')) ||
3108 				    (sl[0] == '/' && sl[1] == '.' &&
3109 				     (sl[2] == '/' || sl[2] == '\0'))) {
3110 					/*
3111 					 *     flg  len
3112 					 *    +----+----+
3113 					 *    | 02 | 00 | CURRENT component.
3114 					 *    +----+----+ (".")
3115 					 */
3116 					if (nc != NULL) {
3117 						cf = nc++;
3118 						*cf = 0x02; /* CURRENT */
3119 						*nc++ = 0;
3120 					}
3121 					sllen += 2;
3122 					if (sl[0] == '/')
3123 						sl += 2;/* skip "/." */
3124 					else
3125 						sl ++;  /* skip "." */
3126 					sl_last = '.';
3127 					cl = NULL;
3128 					continue;
3129 				}
3130 				if (sl[0] == '/' || cl == NULL) {
3131 					if (nc != NULL) {
3132 						cf = nc++;
3133 						*cf = 0;
3134 						cl = nc++;
3135 						*cl = 0;
3136 					} else
3137 						cl = &cldmy;
3138 					sllen += 2;
3139 					if (sl[0] == '/') {
3140 						sl_last = *sl++;
3141 						continue;
3142 					}
3143 				}
3144 				sl_last = *sl++;
3145 				if (nc != NULL) {
3146 					*nc++ = sl_last;
3147 					(*cl) ++;
3148 				}
3149 				sllen++;
3150 			}
3151 			if (*sl) {
3152 				length = 5 + sllen;
3153 				if (bp != NULL) {
3154 					/*
3155 					 * Mark flg as CONTINUE component.
3156 					 */
3157 					*cf |= 0x01;
3158 					/*
3159 					 *               len  ver  flg
3160 					 *    +----+----+----+----+----+-
3161 					 *    | 'S'| 'L'| XX | 01 | 01 |
3162 					 *    +----+----+----+----+----+-
3163 					 *                           ^
3164 					 *           continues in next "SL"
3165 					 */
3166 					bp[3] = length;
3167 					bp[5] = 0x01;/* This Symbolic Link
3168 						      * continues in next
3169 						      * "SL" field */
3170 					bp += length;
3171 				}
3172 				extra_tell_used_size(&ctl, length);
3173 				if (extra_space(&ctl) < 11)
3174 					bp = extra_next_record(&ctl, 11);
3175 				if (bp != NULL) {
3176 					/* Next 'SL' */
3177 					bp[1] = 'S';
3178 					bp[2] = 'L';
3179 					bp[4] = 1;    /* version */
3180 				}
3181 			} else {
3182 				length = 5 + sllen;
3183 				if (bp != NULL) {
3184 					bp[3] = length;
3185 					bp[5] = 0;
3186 					bp += length;
3187 				}
3188 				extra_tell_used_size(&ctl, length);
3189 				break;
3190 			}
3191 		}
3192 	}
3193 
3194 	/* Write "TF" System Use Entry. */
3195 	if (rr_flag & RR_USE_TF) {
3196 		/*
3197 		 *   "TF" Format:
3198 		 *               len  ver
3199 		 *    +----+----+----+----+-----+-------------+
3200 		 *    | 'T'| 'F'| XX | 01 |FLAGS| TIME STAMPS |
3201 		 *    +----+----+----+----+-----+-------------+
3202 		 *    0    1    2    3    4     5            XX
3203 		 *    TIME STAMPS : ISO 9660 Standard 9.1.5.
3204 		 *                  If TF_LONG_FORM FLAGS is set,
3205 		 *                  use ISO9660 Standard 8.4.26.1.
3206 		 */
3207 #define TF_CREATION	0x01	/* Creation time recorded		*/
3208 #define TF_MODIFY	0x02	/* Modification time recorded		*/
3209 #define TF_ACCESS	0x04	/* Last Access time recorded		*/
3210 #define TF_ATTRIBUTES	0x08	/* Last Attribute Change time recorded  */
3211 #define TF_BACKUP	0x10	/* Last Backup time recorded		*/
3212 #define TF_EXPIRATION	0x20	/* Expiration time recorded		*/
3213 #define TF_EFFECTIVE	0x40	/* Effective time recorded		*/
3214 #define TF_LONG_FORM	0x80	/* ISO 9660 17-byte time format used	*/
3215 		unsigned char tf_flags;
3216 
3217 		length = 5;
3218 		tf_flags = 0;
3219 #ifndef COMPAT_MKISOFS
3220 		if (archive_entry_birthtime_is_set(file->entry) &&
3221 		    archive_entry_birthtime(file->entry) <=
3222 		    archive_entry_mtime(file->entry)) {
3223 			length += 7;
3224 			tf_flags |= TF_CREATION;
3225 		}
3226 #endif
3227 		if (archive_entry_mtime_is_set(file->entry)) {
3228 			length += 7;
3229 			tf_flags |= TF_MODIFY;
3230 		}
3231 		if (archive_entry_atime_is_set(file->entry)) {
3232 			length += 7;
3233 			tf_flags |= TF_ACCESS;
3234 		}
3235 		if (archive_entry_ctime_is_set(file->entry)) {
3236 			length += 7;
3237 			tf_flags |= TF_ATTRIBUTES;
3238 		}
3239 		if (extra_space(&ctl) < length)
3240 			bp = extra_next_record(&ctl, length);
3241 		if (bp != NULL) {
3242 			bp[1] = 'T';
3243 			bp[2] = 'F';
3244 			bp[3] = length;
3245 			bp[4] = 1;	/* version	*/
3246 			bp[5] = tf_flags;
3247 			bp += 5;
3248 			/* Creation time */
3249 			if (tf_flags & TF_CREATION) {
3250 				set_time_915(bp+1,
3251 				    archive_entry_birthtime(file->entry));
3252 				bp += 7;
3253 			}
3254 			/* Modification time */
3255 			if (tf_flags & TF_MODIFY) {
3256 				set_time_915(bp+1,
3257 				    archive_entry_mtime(file->entry));
3258 				bp += 7;
3259 			}
3260 			/* Last Access time */
3261 			if (tf_flags & TF_ACCESS) {
3262 				set_time_915(bp+1,
3263 				    archive_entry_atime(file->entry));
3264 				bp += 7;
3265 			}
3266 			/* Last Attribute Change time */
3267 			if (tf_flags & TF_ATTRIBUTES) {
3268 				set_time_915(bp+1,
3269 				    archive_entry_ctime(file->entry));
3270 				bp += 7;
3271 			}
3272 		}
3273 		extra_tell_used_size(&ctl, length);
3274 	}
3275 
3276 	/* Write "RE" System Use Entry. */
3277 	if (rr_flag & RR_USE_RE) {
3278 		/*
3279 		 *   "RE" Format:
3280 		 *               len  ver
3281 		 *    +----+----+----+----+
3282 		 *    | 'R'| 'E'| 04 | 01 |
3283 		 *    +----+----+----+----+
3284 		 *    0    1    2    3    4
3285 		 */
3286 		length = 4;
3287 		if (extra_space(&ctl) < length)
3288 			bp = extra_next_record(&ctl, length);
3289 		if (bp != NULL) {
3290 			bp[1] = 'R';
3291 			bp[2] = 'E';
3292 			bp[3] = length;
3293 			bp[4] = 1;	/* version	*/
3294 			bp += length;
3295 		}
3296 		extra_tell_used_size(&ctl, length);
3297 	}
3298 
3299 	/* Write "PL" System Use Entry. */
3300 	if (rr_flag & RR_USE_PL) {
3301 		/*
3302 		 *   "PL" Format:
3303 		 *               len  ver
3304 		 *    +----+----+----+----+------------+
3305 		 *    | 'P'| 'L'| 0C | 01 | *LOCATION  |
3306 		 *    +----+----+----+----+------------+
3307 		 *    0    1    2    3    4           12
3308 		 *    *LOCATION: location of parent directory
3309 		 */
3310 		length = 12;
3311 		if (extra_space(&ctl) < length)
3312 			bp = extra_next_record(&ctl, length);
3313 		if (bp != NULL) {
3314 			bp[1] = 'P';
3315 			bp[2] = 'L';
3316 			bp[3] = length;
3317 			bp[4] = 1;	/* version	*/
3318 			set_num_733(bp + 5,
3319 			    rr_parent->dir_location);
3320 			bp += length;
3321 		}
3322 		extra_tell_used_size(&ctl, length);
3323 	}
3324 
3325 	/* Write "CL" System Use Entry. */
3326 	if (rr_flag & RR_USE_CL) {
3327 		/*
3328 		 *   "CL" Format:
3329 		 *               len  ver
3330 		 *    +----+----+----+----+------------+
3331 		 *    | 'C'| 'L'| 0C | 01 | *LOCATION  |
3332 		 *    +----+----+----+----+------------+
3333 		 *    0    1    2    3    4           12
3334 		 *    *LOCATION: location of child directory
3335 		 */
3336 		length = 12;
3337 		if (extra_space(&ctl) < length)
3338 			bp = extra_next_record(&ctl, length);
3339 		if (bp != NULL) {
3340 			bp[1] = 'C';
3341 			bp[2] = 'L';
3342 			bp[3] = length;
3343 			bp[4] = 1;	/* version	*/
3344 			set_num_733(bp + 5,
3345 			    isoent->rr_child->dir_location);
3346 			bp += length;
3347 		}
3348 		extra_tell_used_size(&ctl, length);
3349 	}
3350 
3351 	/* Write "PN" System Use Entry. */
3352 	if (rr_flag & RR_USE_PN) {
3353 		/*
3354 		 *   "PN" Format:
3355 		 *               len  ver
3356 		 *    +----+----+----+----+------------+------------+
3357 		 *    | 'P'| 'N'| 14 | 01 | dev_t high | dev_t low  |
3358 		 *    +----+----+----+----+------------+------------+
3359 		 *    0    1    2    3    4           12           20
3360 		 */
3361 		length = 20;
3362 		if (extra_space(&ctl) < length)
3363 			bp = extra_next_record(&ctl, length);
3364 		if (bp != NULL) {
3365 			uint64_t dev;
3366 
3367 			bp[1] = 'P';
3368 			bp[2] = 'N';
3369 			bp[3] = length;
3370 			bp[4] = 1;	/* version	*/
3371 			dev = (uint64_t)archive_entry_rdev(file->entry);
3372 			set_num_733(bp + 5, (uint32_t)(dev >> 32));
3373 			set_num_733(bp + 13, (uint32_t)(dev & 0xFFFFFFFF));
3374 			bp += length;
3375 		}
3376 		extra_tell_used_size(&ctl, length);
3377 	}
3378 
3379 	/* Write "ZF" System Use Entry. */
3380 	if (file->zisofs.header_size) {
3381 		/*
3382 		 *   "ZF" Format:
3383 		 *               len  ver
3384 		 *    +----+----+----+----+----+----+-------------+
3385 		 *    | 'Z'| 'F'| 10 | 01 | 'p'| 'z'| Header Size |
3386 		 *    +----+----+----+----+----+----+-------------+
3387 		 *    0    1    2    3    4    5    6             7
3388 		 *    +--------------------+-------------------+
3389 		 *    | Log2 of block Size | Uncompressed Size |
3390 		 *    +--------------------+-------------------+
3391 		 *    7                    8                   16
3392 		 */
3393 		length = 16;
3394 		if (extra_space(&ctl) < length)
3395 			bp = extra_next_record(&ctl, length);
3396 		if (bp != NULL) {
3397 			bp[1] = 'Z';
3398 			bp[2] = 'F';
3399 			bp[3] = length;
3400 			bp[4] = 1;	/* version	*/
3401 			bp[5] = 'p';
3402 			bp[6] = 'z';
3403 			bp[7] = file->zisofs.header_size;
3404 			bp[8] = file->zisofs.log2_bs;
3405 			set_num_733(bp + 9, file->zisofs.uncompressed_size);
3406 			bp += length;
3407 		}
3408 		extra_tell_used_size(&ctl, length);
3409 	}
3410 
3411 	/* Write "CE" System Use Entry. */
3412 	if (t == DIR_REC_SELF && isoent == isoent->parent) {
3413 		length = RR_CE_SIZE;
3414 		if (bp != NULL)
3415 			set_SUSP_CE(bp+1, iso9660->location_rrip_er,
3416 			    0, RRIP_ER_SIZE);
3417 		extra_tell_used_size(&ctl, length);
3418 	}
3419 
3420 	extra_close_record(&ctl, 0);
3421 
3422 	return (ctl.dr_len);
3423 }
3424 
3425 /*
3426  * Write data of a Directory Record or calculate writing bytes itself.
3427  * If parameter `p' is NULL, calculates the size of writing data, which
3428  * a Directory Record needs to write, then it saved and return
3429  * the calculated size.
3430  * Parameter `n' is a remaining size of buffer. when parameter `p' is
3431  * not NULL, check whether that `n' is not less than the saved size.
3432  * if that `n' is small, return zero.
3433  *
3434  * This format of the Directory Record is according to
3435  * ISO9660 Standard 9.1
3436  */
3437 static int
3438 set_directory_record(unsigned char *p, size_t n, struct isoent *isoent,
3439     struct iso9660 *iso9660, enum dir_rec_type t,
3440     enum vdd_type vdd_type)
3441 {
3442 	unsigned char *bp;
3443 	size_t dr_len;
3444 	size_t fi_len;
3445 
3446 	if (p != NULL) {
3447 		/*
3448 		 * Check whether a write buffer size is less than the
3449 		 * saved size which is needed to write this Directory
3450 		 * Record.
3451 		 */
3452 		switch (t) {
3453 		case DIR_REC_VD:
3454 			dr_len = isoent->dr_len.vd; break;
3455 		case DIR_REC_SELF:
3456 			dr_len = isoent->dr_len.self; break;
3457 		case DIR_REC_PARENT:
3458 			dr_len = isoent->dr_len.parent; break;
3459 		case DIR_REC_NORMAL:
3460 		default:
3461 			dr_len = isoent->dr_len.normal; break;
3462 		}
3463 		if (dr_len > n)
3464 			return (0);/* Needs more buffer size. */
3465 	}
3466 
3467 	if (t == DIR_REC_NORMAL && isoent->identifier != NULL)
3468 		fi_len = isoent->id_len;
3469 	else
3470 		fi_len = 1;
3471 
3472 	if (p != NULL) {
3473 		struct isoent *xisoent;
3474 		struct isofile *file;
3475 		unsigned char flag;
3476 
3477 		if (t == DIR_REC_PARENT)
3478 			xisoent = isoent->parent;
3479 		else
3480 			xisoent = isoent;
3481 		file = isoent->file;
3482 		if (file->hardlink_target != NULL)
3483 			file = file->hardlink_target;
3484 		/* Make a file flag. */
3485 		if (xisoent->dir)
3486 			flag = FILE_FLAG_DIRECTORY;
3487 		else {
3488 			if (file->cur_content->next != NULL)
3489 				flag = FILE_FLAG_MULTI_EXTENT;
3490 			else
3491 				flag = 0;
3492 		}
3493 
3494 		bp = p -1;
3495 		/* Extended Attribute Record Length */
3496 		set_num_711(bp+2, 0);
3497 		/* Location of Extent */
3498 		if (xisoent->dir)
3499 			set_num_733(bp+3, xisoent->dir_location);
3500 		else
3501 			set_num_733(bp+3, file->cur_content->location);
3502 		/* Data Length */
3503 		if (xisoent->dir)
3504 			set_num_733(bp+11,
3505 			    xisoent->dir_block * LOGICAL_BLOCK_SIZE);
3506 		else
3507 			set_num_733(bp+11, (uint32_t)file->cur_content->size);
3508 		/* Recording Date and Time */
3509 		/* NOTE:
3510 		 *  If a file type is symbolic link, you are seeing this
3511 		 *  field value is different from a value mkisofs makes.
3512 		 *  libarchive uses lstat to get this one, but it
3513 		 *  seems mkisofs uses stat to get.
3514 		 */
3515 		set_time_915(bp+19,
3516 		    archive_entry_mtime(xisoent->file->entry));
3517 		/* File Flags */
3518 		bp[26] = flag;
3519 		/* File Unit Size */
3520 		set_num_711(bp+27, 0);
3521 		/* Interleave Gap Size */
3522 		set_num_711(bp+28, 0);
3523 		/* Volume Sequence Number */
3524 		set_num_723(bp+29, iso9660->volume_sequence_number);
3525 		/* Length of File Identifier */
3526 		set_num_711(bp+33, (unsigned char)fi_len);
3527 		/* File Identifier */
3528 		switch (t) {
3529 		case DIR_REC_VD:
3530 		case DIR_REC_SELF:
3531 			set_num_711(bp+34, 0);
3532 			break;
3533 		case DIR_REC_PARENT:
3534 			set_num_711(bp+34, 1);
3535 			break;
3536 		case DIR_REC_NORMAL:
3537 			if (isoent->identifier != NULL)
3538 				memcpy(bp+34, isoent->identifier, fi_len);
3539 			else
3540 				set_num_711(bp+34, 0);
3541 			break;
3542 		}
3543 	} else
3544 		bp = NULL;
3545 	dr_len = 33 + fi_len;
3546 	/* Padding Field */
3547 	if (dr_len & 0x01) {
3548 		dr_len ++;
3549 		if (p != NULL)
3550 			bp[dr_len] = 0;
3551 	}
3552 
3553 	/* Volume Descriptor does not record extension. */
3554 	if (t == DIR_REC_VD) {
3555 		if (p != NULL)
3556 			/* Length of Directory Record */
3557 			set_num_711(p, (unsigned char)dr_len);
3558 		else
3559 			isoent->dr_len.vd = (int)dr_len;
3560 		return ((int)dr_len);
3561 	}
3562 
3563 	/* Rockridge */
3564 	if (iso9660->opt.rr && vdd_type != VDD_JOLIET)
3565 		dr_len = set_directory_record_rr(bp, (int)dr_len,
3566 		    isoent, iso9660, t);
3567 
3568 	if (p != NULL)
3569 		/* Length of Directory Record */
3570 		set_num_711(p, (unsigned char)dr_len);
3571 	else {
3572 		/*
3573 		 * Save the size which is needed to write this
3574 		 * Directory Record.
3575 		 */
3576 		switch (t) {
3577 		case DIR_REC_VD:
3578 			/* This case does not come, but compiler
3579 			 * complains that DIR_REC_VD not handled
3580 			 *  in switch ....  */
3581 			break;
3582 		case DIR_REC_SELF:
3583 			isoent->dr_len.self = (int)dr_len; break;
3584 		case DIR_REC_PARENT:
3585 			isoent->dr_len.parent = (int)dr_len; break;
3586 		case DIR_REC_NORMAL:
3587 			isoent->dr_len.normal = (int)dr_len; break;
3588 		}
3589 	}
3590 
3591 	return ((int)dr_len);
3592 }
3593 
3594 /*
3595  * Calculate the size of a directory record.
3596  */
3597 static inline int
3598 get_dir_rec_size(struct iso9660 *iso9660, struct isoent *isoent,
3599     enum dir_rec_type t, enum vdd_type vdd_type)
3600 {
3601 
3602 	return (set_directory_record(NULL, SIZE_MAX,
3603 	    isoent, iso9660, t, vdd_type));
3604 }
3605 
3606 /*
3607  * Manage to write ISO-image data with wbuff to reduce calling
3608  * __archive_write_output() for performance.
3609  */
3610 
3611 
3612 static inline unsigned char *
3613 wb_buffptr(struct archive_write *a)
3614 {
3615 	struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
3616 
3617 	return (&(iso9660->wbuff[sizeof(iso9660->wbuff)
3618 		- iso9660->wbuff_remaining]));
3619 }
3620 
3621 static int
3622 wb_write_out(struct archive_write *a)
3623 {
3624 	struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
3625 	size_t wsize, nw;
3626 	int r;
3627 
3628 	wsize = sizeof(iso9660->wbuff) - iso9660->wbuff_remaining;
3629 	nw = wsize % LOGICAL_BLOCK_SIZE;
3630 	if (iso9660->wbuff_type == WB_TO_STREAM)
3631 		r = __archive_write_output(a, iso9660->wbuff, wsize - nw);
3632 	else
3633 		r = write_to_temp(a, iso9660->wbuff, wsize - nw);
3634 	/* Increase the offset. */
3635 	iso9660->wbuff_offset += wsize - nw;
3636 	if (iso9660->wbuff_offset > iso9660->wbuff_written)
3637 		iso9660->wbuff_written = iso9660->wbuff_offset;
3638 	iso9660->wbuff_remaining = sizeof(iso9660->wbuff);
3639 	if (nw) {
3640 		iso9660->wbuff_remaining -= nw;
3641 		memmove(iso9660->wbuff, iso9660->wbuff + wsize - nw, nw);
3642 	}
3643 	return (r);
3644 }
3645 
3646 static int
3647 wb_consume(struct archive_write *a, size_t size)
3648 {
3649 	struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
3650 
3651 	if (size > iso9660->wbuff_remaining ||
3652 	    iso9660->wbuff_remaining == 0) {
3653 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
3654 		    "Internal Programming error: iso9660:wb_consume()"
3655 		    " size=%jd, wbuff_remaining=%jd",
3656 		    (intmax_t)size, (intmax_t)iso9660->wbuff_remaining);
3657 		return (ARCHIVE_FATAL);
3658 	}
3659 	iso9660->wbuff_remaining -= size;
3660 	if (iso9660->wbuff_remaining < LOGICAL_BLOCK_SIZE)
3661 		return (wb_write_out(a));
3662 	return (ARCHIVE_OK);
3663 }
3664 
3665 #ifdef HAVE_ZLIB_H
3666 
3667 static int
3668 wb_set_offset(struct archive_write *a, int64_t off)
3669 {
3670 	struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
3671 	int64_t used, ext_bytes;
3672 
3673 	if (iso9660->wbuff_type != WB_TO_TEMP) {
3674 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
3675 		    "Internal Programming error: iso9660:wb_set_offset()");
3676 		return (ARCHIVE_FATAL);
3677 	}
3678 
3679 	used = sizeof(iso9660->wbuff) - iso9660->wbuff_remaining;
3680 	if (iso9660->wbuff_offset + used > iso9660->wbuff_tail)
3681 		iso9660->wbuff_tail = iso9660->wbuff_offset + used;
3682 	if (iso9660->wbuff_offset < iso9660->wbuff_written) {
3683 		if (used > 0 &&
3684 		    write_to_temp(a, iso9660->wbuff, (size_t)used) != ARCHIVE_OK)
3685 			return (ARCHIVE_FATAL);
3686 		iso9660->wbuff_offset = iso9660->wbuff_written;
3687 		lseek(iso9660->temp_fd, iso9660->wbuff_offset, SEEK_SET);
3688 		iso9660->wbuff_remaining = sizeof(iso9660->wbuff);
3689 		used = 0;
3690 	}
3691 	if (off < iso9660->wbuff_offset) {
3692 		/*
3693 		 * Write out waiting data.
3694 		 */
3695 		if (used > 0) {
3696 			if (wb_write_out(a) != ARCHIVE_OK)
3697 				return (ARCHIVE_FATAL);
3698 		}
3699 		lseek(iso9660->temp_fd, off, SEEK_SET);
3700 		iso9660->wbuff_offset = off;
3701 		iso9660->wbuff_remaining = sizeof(iso9660->wbuff);
3702 	} else if (off <= iso9660->wbuff_tail) {
3703 		iso9660->wbuff_remaining = (size_t)
3704 		    (sizeof(iso9660->wbuff) - (off - iso9660->wbuff_offset));
3705 	} else {
3706 		ext_bytes = off - iso9660->wbuff_tail;
3707 		iso9660->wbuff_remaining = (size_t)(sizeof(iso9660->wbuff)
3708 		   - (iso9660->wbuff_tail - iso9660->wbuff_offset));
3709 		while (ext_bytes >= (int64_t)iso9660->wbuff_remaining) {
3710 			if (write_null(a, (size_t)iso9660->wbuff_remaining)
3711 			    != ARCHIVE_OK)
3712 				return (ARCHIVE_FATAL);
3713 			ext_bytes -= iso9660->wbuff_remaining;
3714 		}
3715 		if (ext_bytes > 0) {
3716 			if (write_null(a, (size_t)ext_bytes) != ARCHIVE_OK)
3717 				return (ARCHIVE_FATAL);
3718 		}
3719 	}
3720 	return (ARCHIVE_OK);
3721 }
3722 
3723 #endif /* HAVE_ZLIB_H */
3724 
3725 static int
3726 write_null(struct archive_write *a, size_t size)
3727 {
3728 	size_t remaining;
3729 	unsigned char *p, *old;
3730 	int r;
3731 
3732 	remaining = wb_remaining(a);
3733 	p = wb_buffptr(a);
3734 	if (size <= remaining) {
3735 		memset(p, 0, size);
3736 		return (wb_consume(a, size));
3737 	}
3738 	memset(p, 0, remaining);
3739 	r = wb_consume(a, remaining);
3740 	if (r != ARCHIVE_OK)
3741 		return (r);
3742 	size -= remaining;
3743 	old = p;
3744 	p = wb_buffptr(a);
3745 	memset(p, 0, old - p);
3746 	remaining = wb_remaining(a);
3747 	while (size) {
3748 		size_t wsize = size;
3749 
3750 		if (wsize > remaining)
3751 			wsize = remaining;
3752 		r = wb_consume(a, wsize);
3753 		if (r != ARCHIVE_OK)
3754 			return (r);
3755 		size -= wsize;
3756 	}
3757 	return (ARCHIVE_OK);
3758 }
3759 
3760 /*
3761  * Write Volume Descriptor Set Terminator
3762  */
3763 static int
3764 write_VD_terminator(struct archive_write *a)
3765 {
3766 	unsigned char *bp;
3767 
3768 	bp = wb_buffptr(a) -1;
3769 	set_VD_bp(bp, VDT_TERMINATOR, 1);
3770 	set_unused_field_bp(bp, 8, LOGICAL_BLOCK_SIZE);
3771 
3772 	return (wb_consume(a, LOGICAL_BLOCK_SIZE));
3773 }
3774 
3775 static int
3776 set_file_identifier(unsigned char *bp, int from, int to, enum vdc vdc,
3777     struct archive_write *a, struct vdd *vdd, struct archive_string *id,
3778     const char *label, int leading_under, enum char_type char_type)
3779 {
3780 	char identifier[256];
3781 	struct isoent *isoent;
3782 	const char *ids;
3783 	size_t len;
3784 	int r;
3785 
3786 	if (id->length > 0 && leading_under && id->s[0] != '_') {
3787 		if (char_type == A_CHAR)
3788 			r = set_str_a_characters_bp(a, bp, from, to, id->s, vdc);
3789 		else
3790 			r = set_str_d_characters_bp(a, bp, from, to, id->s, vdc);
3791 	} else if (id->length > 0) {
3792 		ids = id->s;
3793 		if (leading_under)
3794 			ids++;
3795 		isoent = isoent_find_entry(vdd->rootent, ids);
3796 		if (isoent == NULL) {
3797 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
3798 			    "Not Found %s `%s'.",
3799 			    label, ids);
3800 			return (ARCHIVE_FATAL);
3801 		}
3802 		len = isoent->ext_off + isoent->ext_len;
3803 		if (vdd->vdd_type == VDD_JOLIET) {
3804 			if (len > sizeof(identifier)-2)
3805 				len = sizeof(identifier)-2;
3806 		} else {
3807 			if (len > sizeof(identifier)-1)
3808 				len = sizeof(identifier)-1;
3809 		}
3810 		memcpy(identifier, isoent->identifier, len);
3811 		identifier[len] = '\0';
3812 		if (vdd->vdd_type == VDD_JOLIET) {
3813 			identifier[len+1] = 0;
3814 			vdc = VDC_UCS2_DIRECT;
3815 		}
3816 		if (char_type == A_CHAR)
3817 			r = set_str_a_characters_bp(a, bp, from, to,
3818 			    identifier, vdc);
3819 		else
3820 			r = set_str_d_characters_bp(a, bp, from, to,
3821 			    identifier, vdc);
3822 	} else {
3823 		if (char_type == A_CHAR)
3824 			r = set_str_a_characters_bp(a, bp, from, to, NULL, vdc);
3825 		else
3826 			r = set_str_d_characters_bp(a, bp, from, to, NULL, vdc);
3827 	}
3828 	return (r);
3829 }
3830 
3831 /*
3832  * Write Primary/Supplementary Volume Descriptor
3833  */
3834 static int
3835 write_VD(struct archive_write *a, struct vdd *vdd)
3836 {
3837 	struct iso9660 *iso9660;
3838 	unsigned char *bp;
3839 	uint16_t volume_set_size = 1;
3840 	char identifier[256];
3841 	enum VD_type vdt;
3842 	enum vdc vdc;
3843 	unsigned char vd_ver, fst_ver;
3844 	int r;
3845 
3846 	iso9660 = a->format_data;
3847 	switch (vdd->vdd_type) {
3848 	case VDD_JOLIET:
3849 		vdt = VDT_SUPPLEMENTARY;
3850 		vd_ver = fst_ver = 1;
3851 		vdc = VDC_UCS2;
3852 		break;
3853 	case VDD_ENHANCED:
3854 		vdt = VDT_SUPPLEMENTARY;
3855 		vd_ver = fst_ver = 2;
3856 		vdc = VDC_LOWERCASE;
3857 		break;
3858 	case VDD_PRIMARY:
3859 	default:
3860 		vdt = VDT_PRIMARY;
3861 		vd_ver = fst_ver = 1;
3862 #ifdef COMPAT_MKISOFS
3863 		vdc = VDC_LOWERCASE;
3864 #else
3865 		vdc = VDC_STD;
3866 #endif
3867 		break;
3868 	}
3869 
3870 	bp = wb_buffptr(a) -1;
3871 	/* Volume Descriptor Type */
3872 	set_VD_bp(bp, vdt, vd_ver);
3873 	/* Unused Field */
3874 	set_unused_field_bp(bp, 8, 8);
3875 	/* System Identifier */
3876 	get_system_identitier(identifier, sizeof(identifier));
3877 	r = set_str_a_characters_bp(a, bp, 9, 40, identifier, vdc);
3878 	if (r != ARCHIVE_OK)
3879 		return (r);
3880 	/* Volume Identifier */
3881 	r = set_str_d_characters_bp(a, bp, 41, 72,
3882 	    iso9660->volume_identifier.s, vdc);
3883 	if (r != ARCHIVE_OK)
3884 		return (r);
3885 	/* Unused Field */
3886 	set_unused_field_bp(bp, 73, 80);
3887 	/* Volume Space Size */
3888 	set_num_733(bp+81, iso9660->volume_space_size);
3889 	if (vdd->vdd_type == VDD_JOLIET) {
3890 		/* Escape Sequences */
3891 		bp[89] = 0x25;/* UCS-2 Level 3 */
3892 		bp[90] = 0x2F;
3893 		bp[91] = 0x45;
3894 		memset(bp + 92, 0, 120 - 92 + 1);
3895 	} else {
3896 		/* Unused Field */
3897 		set_unused_field_bp(bp, 89, 120);
3898 	}
3899 	/* Volume Set Size */
3900 	set_num_723(bp+121, volume_set_size);
3901 	/* Volume Sequence Number */
3902 	set_num_723(bp+125, iso9660->volume_sequence_number);
3903 	/* Logical Block Size */
3904 	set_num_723(bp+129, LOGICAL_BLOCK_SIZE);
3905 	/* Path Table Size */
3906 	set_num_733(bp+133, vdd->path_table_size);
3907 	/* Location of Occurrence of Type L Path Table */
3908 	set_num_731(bp+141, vdd->location_type_L_path_table);
3909 	/* Location of Optional Occurrence of Type L Path Table */
3910 	set_num_731(bp+145, 0);
3911 	/* Location of Occurrence of Type M Path Table */
3912 	set_num_732(bp+149, vdd->location_type_M_path_table);
3913 	/* Location of Optional Occurrence of Type M Path Table */
3914 	set_num_732(bp+153, 0);
3915 	/* Directory Record for Root Directory(BP 157 to 190) */
3916 	set_directory_record(bp+157, 190-157+1, vdd->rootent,
3917 	    iso9660, DIR_REC_VD, vdd->vdd_type);
3918 	/* Volume Set Identifier */
3919 	r = set_str_d_characters_bp(a, bp, 191, 318, "", vdc);
3920 	if (r != ARCHIVE_OK)
3921 		return (r);
3922 	/* Publisher Identifier */
3923 	r = set_file_identifier(bp, 319, 446, vdc, a, vdd,
3924 	    &(iso9660->publisher_identifier),
3925 	    "Publisher File", 1, A_CHAR);
3926 	if (r != ARCHIVE_OK)
3927 		return (r);
3928 	/* Data Preparer Identifier */
3929 	r = set_file_identifier(bp, 447, 574, vdc, a, vdd,
3930 	    &(iso9660->data_preparer_identifier),
3931 	    "Data Preparer File", 1, A_CHAR);
3932 	if (r != ARCHIVE_OK)
3933 		return (r);
3934 	/* Application Identifier */
3935 	r = set_file_identifier(bp, 575, 702, vdc, a, vdd,
3936 	    &(iso9660->application_identifier),
3937 	    "Application File", 1, A_CHAR);
3938 	if (r != ARCHIVE_OK)
3939 		return (r);
3940 	/* Copyright File Identifier */
3941 	r = set_file_identifier(bp, 703, 739, vdc, a, vdd,
3942 	    &(iso9660->copyright_file_identifier),
3943 	    "Copyright File", 0, D_CHAR);
3944 	if (r != ARCHIVE_OK)
3945 		return (r);
3946 	/* Abstract File Identifier */
3947 	r = set_file_identifier(bp, 740, 776, vdc, a, vdd,
3948 	    &(iso9660->abstract_file_identifier),
3949 	    "Abstract File", 0, D_CHAR);
3950 	if (r != ARCHIVE_OK)
3951 		return (r);
3952 	/* Bibliographic File Identifier */
3953 	r = set_file_identifier(bp, 777, 813, vdc, a, vdd,
3954 	    &(iso9660->bibliographic_file_identifier),
3955 	    "Bibliongraphic File", 0, D_CHAR);
3956 	if (r != ARCHIVE_OK)
3957 		return (r);
3958 	/* Volume Creation Date and Time */
3959 	set_date_time(bp+814, iso9660->birth_time);
3960 	/* Volume Modification Date and Time */
3961 	set_date_time(bp+831, iso9660->birth_time);
3962 	/* Volume Expiration Date and Time(obsolete) */
3963 	set_date_time_null(bp+848);
3964 	/* Volume Effective Date and Time */
3965 	set_date_time(bp+865, iso9660->birth_time);
3966 	/* File Structure Version */
3967 	bp[882] = fst_ver;
3968 	/* Reserved */
3969 	bp[883] = 0;
3970 	/* Application Use */
3971 	memset(bp + 884, 0x20, 1395 - 884 + 1);
3972 	/* Reserved */
3973 	set_unused_field_bp(bp, 1396, LOGICAL_BLOCK_SIZE);
3974 
3975 	return (wb_consume(a, LOGICAL_BLOCK_SIZE));
3976 }
3977 
3978 /*
3979  * Write Boot Record Volume Descriptor
3980  */
3981 static int
3982 write_VD_boot_record(struct archive_write *a)
3983 {
3984 	struct iso9660 *iso9660;
3985 	unsigned char *bp;
3986 
3987 	iso9660 = a->format_data;
3988 	bp = wb_buffptr(a) -1;
3989 	/* Volume Descriptor Type */
3990 	set_VD_bp(bp, VDT_BOOT_RECORD, 1);
3991 	/* Boot System Identifier */
3992 	memcpy(bp+8, "EL TORITO SPECIFICATION", 23);
3993 	set_unused_field_bp(bp, 8+23, 39);
3994 	/* Unused */
3995 	set_unused_field_bp(bp, 40, 71);
3996 	/* Absolute pointer to first sector of Boot Catalog */
3997 	set_num_731(bp+72,
3998 	    iso9660->el_torito.catalog->file->content.location);
3999 	/* Unused */
4000 	set_unused_field_bp(bp, 76, LOGICAL_BLOCK_SIZE);
4001 
4002 	return (wb_consume(a, LOGICAL_BLOCK_SIZE));
4003 }
4004 
4005 enum keytype {
4006 	KEY_FLG,
4007 	KEY_STR,
4008 	KEY_INT,
4009 	KEY_HEX
4010 };
4011 static void
4012 set_option_info(struct archive_string *info, int *opt, const char *key,
4013     enum keytype type,  ...)
4014 {
4015 	va_list ap;
4016 	char prefix;
4017 	const char *s;
4018 	int d;
4019 
4020 	prefix = (*opt==0)? ' ':',';
4021 	va_start(ap, type);
4022 	switch (type) {
4023 	case KEY_FLG:
4024 		d = va_arg(ap, int);
4025 		archive_string_sprintf(info, "%c%s%s",
4026 		    prefix, (d == 0)?"!":"", key);
4027 		break;
4028 	case KEY_STR:
4029 		s = va_arg(ap, const char *);
4030 		archive_string_sprintf(info, "%c%s=%s",
4031 		    prefix, key, s);
4032 		break;
4033 	case KEY_INT:
4034 		d = va_arg(ap, int);
4035 		archive_string_sprintf(info, "%c%s=%d",
4036 		    prefix, key, d);
4037 		break;
4038 	case KEY_HEX:
4039 		d = va_arg(ap, int);
4040 		archive_string_sprintf(info, "%c%s=%x",
4041 		    prefix, key, d);
4042 		break;
4043 	}
4044 	va_end(ap);
4045 
4046 	*opt = 1;
4047 }
4048 
4049 /*
4050  * Make Non-ISO File System Information
4051  */
4052 static int
4053 write_information_block(struct archive_write *a)
4054 {
4055 	struct iso9660 *iso9660;
4056 	char buf[128];
4057 	const char *v;
4058 	int opt, r;
4059 	struct archive_string info;
4060 	size_t info_size = LOGICAL_BLOCK_SIZE *
4061 			       NON_ISO_FILE_SYSTEM_INFORMATION_BLOCK;
4062 
4063 	iso9660 = (struct iso9660 *)a->format_data;
4064 	if (info_size > wb_remaining(a)) {
4065 		r = wb_write_out(a);
4066 		if (r != ARCHIVE_OK)
4067 			return (r);
4068 	}
4069 	archive_string_init(&info);
4070 	if (archive_string_ensure(&info, info_size) == NULL) {
4071 		archive_set_error(&a->archive, ENOMEM,
4072 		    "Can't allocate memory");
4073 		return (ARCHIVE_FATAL);
4074 	}
4075 	memset(info.s, 0, info_size);
4076 	opt = 0;
4077 #if defined(HAVE__CTIME64_S)
4078 	{
4079 		__time64_t iso9660_birth_time_tmp = (__time64_t) iso9660->birth_time; //time_t may be shorter than 64 bits
4080 		_ctime64_s(buf, sizeof(buf), &(iso9660_birth_time_tmp));
4081 	}
4082 #elif defined(HAVE_CTIME_R)
4083 	ctime_r(&(iso9660->birth_time), buf);
4084 #else
4085 	strncpy(buf, ctime(&(iso9660->birth_time)), sizeof(buf)-1);
4086 	buf[sizeof(buf)-1] = '\0';
4087 #endif
4088 	archive_string_sprintf(&info,
4089 	    "INFO %s%s", buf, archive_version_string());
4090 	if (iso9660->opt.abstract_file != OPT_ABSTRACT_FILE_DEFAULT)
4091 		set_option_info(&info, &opt, "abstract-file",
4092 		    KEY_STR, iso9660->abstract_file_identifier.s);
4093 	if (iso9660->opt.application_id != OPT_APPLICATION_ID_DEFAULT)
4094 		set_option_info(&info, &opt, "application-id",
4095 		    KEY_STR, iso9660->application_identifier.s);
4096 	if (iso9660->opt.allow_vernum != OPT_ALLOW_VERNUM_DEFAULT)
4097 		set_option_info(&info, &opt, "allow-vernum",
4098 		    KEY_FLG, iso9660->opt.allow_vernum);
4099 	if (iso9660->opt.biblio_file != OPT_BIBLIO_FILE_DEFAULT)
4100 		set_option_info(&info, &opt, "biblio-file",
4101 		    KEY_STR, iso9660->bibliographic_file_identifier.s);
4102 	if (iso9660->opt.boot != OPT_BOOT_DEFAULT)
4103 		set_option_info(&info, &opt, "boot",
4104 		    KEY_STR, iso9660->el_torito.boot_filename.s);
4105 	if (iso9660->opt.boot_catalog != OPT_BOOT_CATALOG_DEFAULT)
4106 		set_option_info(&info, &opt, "boot-catalog",
4107 		    KEY_STR, iso9660->el_torito.catalog_filename.s);
4108 	if (iso9660->opt.boot_info_table != OPT_BOOT_INFO_TABLE_DEFAULT)
4109 		set_option_info(&info, &opt, "boot-info-table",
4110 		    KEY_FLG, iso9660->opt.boot_info_table);
4111 	if (iso9660->opt.boot_load_seg != OPT_BOOT_LOAD_SEG_DEFAULT)
4112 		set_option_info(&info, &opt, "boot-load-seg",
4113 		    KEY_HEX, iso9660->el_torito.boot_load_seg);
4114 	if (iso9660->opt.boot_load_size != OPT_BOOT_LOAD_SIZE_DEFAULT)
4115 		set_option_info(&info, &opt, "boot-load-size",
4116 		    KEY_INT, iso9660->el_torito.boot_load_size);
4117 	if (iso9660->opt.boot_type != OPT_BOOT_TYPE_DEFAULT) {
4118 		v = "no-emulation";
4119 		if (iso9660->opt.boot_type == OPT_BOOT_TYPE_FD)
4120 			v = "fd";
4121 		if (iso9660->opt.boot_type == OPT_BOOT_TYPE_HARD_DISK)
4122 			v = "hard-disk";
4123 		set_option_info(&info, &opt, "boot-type",
4124 		    KEY_STR, v);
4125 	}
4126 #ifdef HAVE_ZLIB_H
4127 	if (iso9660->opt.compression_level != OPT_COMPRESSION_LEVEL_DEFAULT)
4128 		set_option_info(&info, &opt, "compression-level",
4129 		    KEY_INT, iso9660->zisofs.compression_level);
4130 #endif
4131 	if (iso9660->opt.copyright_file != OPT_COPYRIGHT_FILE_DEFAULT)
4132 		set_option_info(&info, &opt, "copyright-file",
4133 		    KEY_STR, iso9660->copyright_file_identifier.s);
4134 	if (iso9660->opt.iso_level != OPT_ISO_LEVEL_DEFAULT)
4135 		set_option_info(&info, &opt, "iso-level",
4136 		    KEY_INT, iso9660->opt.iso_level);
4137 	if (iso9660->opt.joliet != OPT_JOLIET_DEFAULT) {
4138 		if (iso9660->opt.joliet == OPT_JOLIET_LONGNAME)
4139 			set_option_info(&info, &opt, "joliet",
4140 			    KEY_STR, "long");
4141 		else
4142 			set_option_info(&info, &opt, "joliet",
4143 			    KEY_FLG, iso9660->opt.joliet);
4144 	}
4145 	if (iso9660->opt.limit_depth != OPT_LIMIT_DEPTH_DEFAULT)
4146 		set_option_info(&info, &opt, "limit-depth",
4147 		    KEY_FLG, iso9660->opt.limit_depth);
4148 	if (iso9660->opt.limit_dirs != OPT_LIMIT_DIRS_DEFAULT)
4149 		set_option_info(&info, &opt, "limit-dirs",
4150 		    KEY_FLG, iso9660->opt.limit_dirs);
4151 	if (iso9660->opt.pad != OPT_PAD_DEFAULT)
4152 		set_option_info(&info, &opt, "pad",
4153 		    KEY_FLG, iso9660->opt.pad);
4154 	if (iso9660->opt.publisher != OPT_PUBLISHER_DEFAULT)
4155 		set_option_info(&info, &opt, "publisher",
4156 		    KEY_STR, iso9660->publisher_identifier.s);
4157 	if (iso9660->opt.rr != OPT_RR_DEFAULT) {
4158 		if (iso9660->opt.rr == OPT_RR_DISABLED)
4159 			set_option_info(&info, &opt, "rockridge",
4160 			    KEY_FLG, iso9660->opt.rr);
4161 		else if (iso9660->opt.rr == OPT_RR_STRICT)
4162 			set_option_info(&info, &opt, "rockridge",
4163 			    KEY_STR, "strict");
4164 		else if (iso9660->opt.rr == OPT_RR_USEFUL)
4165 			set_option_info(&info, &opt, "rockridge",
4166 			    KEY_STR, "useful");
4167 	}
4168 	if (iso9660->opt.volume_id != OPT_VOLUME_ID_DEFAULT)
4169 		set_option_info(&info, &opt, "volume-id",
4170 		    KEY_STR, iso9660->volume_identifier.s);
4171 	if (iso9660->opt.zisofs != OPT_ZISOFS_DEFAULT)
4172 		set_option_info(&info, &opt, "zisofs",
4173 		    KEY_FLG, iso9660->opt.zisofs);
4174 
4175 	memcpy(wb_buffptr(a), info.s, info_size);
4176 	archive_string_free(&info);
4177 	return (wb_consume(a, info_size));
4178 }
4179 
4180 static int
4181 write_rr_ER(struct archive_write *a)
4182 {
4183 	unsigned char *p;
4184 
4185 	p = wb_buffptr(a);
4186 
4187 	memset(p, 0, LOGICAL_BLOCK_SIZE);
4188 	p[0] = 'E';
4189 	p[1] = 'R';
4190 	p[3] = 0x01;
4191 	p[2] = RRIP_ER_SIZE;
4192 	p[4] = RRIP_ER_ID_SIZE;
4193 	p[5] = RRIP_ER_DSC_SIZE;
4194 	p[6] = RRIP_ER_SRC_SIZE;
4195 	p[7] = 0x01;
4196 	memcpy(&p[8], rrip_identifier, p[4]);
4197 	memcpy(&p[8+p[4]], rrip_descriptor, p[5]);
4198 	memcpy(&p[8+p[4]+p[5]], rrip_source, p[6]);
4199 
4200 	return (wb_consume(a, LOGICAL_BLOCK_SIZE));
4201 }
4202 
4203 static void
4204 calculate_path_table_size(struct vdd *vdd)
4205 {
4206 	int depth, size;
4207 	struct path_table *pt;
4208 
4209 	pt = vdd->pathtbl;
4210 	size = 0;
4211 	for (depth = 0; depth < vdd->max_depth; depth++) {
4212 		struct isoent **ptbl;
4213 		int i, cnt;
4214 
4215 		if ((cnt = pt[depth].cnt) == 0)
4216 			break;
4217 
4218 		ptbl = pt[depth].sorted;
4219 		for (i = 0; i < cnt; i++) {
4220 			int len;
4221 
4222 			if (ptbl[i]->identifier == NULL)
4223 				len = 1; /* root directory */
4224 			else
4225 				len = ptbl[i]->id_len;
4226 			if (len & 0x01)
4227 				len++; /* Padding Field */
4228 			size += 8 + len;
4229 		}
4230 	}
4231 	vdd->path_table_size = size;
4232 	vdd->path_table_block =
4233 	    ((size + PATH_TABLE_BLOCK_SIZE -1) /
4234 	    PATH_TABLE_BLOCK_SIZE) *
4235 	    (PATH_TABLE_BLOCK_SIZE / LOGICAL_BLOCK_SIZE);
4236 }
4237 
4238 static int
4239 _write_path_table(struct archive_write *a, int type_m, int depth,
4240     struct vdd *vdd)
4241 {
4242 	unsigned char *bp, *wb;
4243 	struct isoent **ptbl;
4244 	size_t wbremaining;
4245 	int i, r, wsize;
4246 
4247 	if (vdd->pathtbl[depth].cnt == 0)
4248 		return (0);
4249 
4250 	wsize = 0;
4251 	wb = wb_buffptr(a);
4252 	wbremaining = wb_remaining(a);
4253 	bp = wb - 1;
4254 	ptbl = vdd->pathtbl[depth].sorted;
4255 	for (i = 0; i < vdd->pathtbl[depth].cnt; i++) {
4256 		struct isoent *np;
4257 		size_t len;
4258 
4259 		np = ptbl[i];
4260 		if (np->identifier == NULL)
4261 			len = 1; /* root directory */
4262 		else
4263 			len = np->id_len;
4264 		if (wbremaining - ((bp+1) - wb) < (len + 1 + 8)) {
4265 			r = wb_consume(a, (bp+1) - wb);
4266 			if (r < 0)
4267 				return (r);
4268 			wb = wb_buffptr(a);
4269 			wbremaining = wb_remaining(a);
4270 			bp = wb -1;
4271 		}
4272 		/* Length of Directory Identifier */
4273 		set_num_711(bp+1, (unsigned char)len);
4274 		/* Extended Attribute Record Length */
4275 		set_num_711(bp+2, 0);
4276 		/* Location of Extent */
4277 		if (type_m)
4278 			set_num_732(bp+3, np->dir_location);
4279 		else
4280 			set_num_731(bp+3, np->dir_location);
4281 		/* Parent Directory Number */
4282 		if (type_m)
4283 			set_num_722(bp+7, np->parent->dir_number);
4284 		else
4285 			set_num_721(bp+7, np->parent->dir_number);
4286 		/* Directory Identifier */
4287 		if (np->identifier == NULL)
4288 			bp[9] = 0;
4289 		else
4290 			memcpy(&bp[9], np->identifier, len);
4291 		if (len & 0x01) {
4292 			/* Padding Field */
4293 			bp[9+len] = 0;
4294 			len++;
4295 		}
4296 		wsize += 8 + (int)len;
4297 		bp += 8 + len;
4298 	}
4299 	if ((bp + 1) > wb) {
4300 		r = wb_consume(a, (bp+1)-wb);
4301 		if (r < 0)
4302 			return (r);
4303 	}
4304 	return (wsize);
4305 }
4306 
4307 static int
4308 write_path_table(struct archive_write *a, int type_m, struct vdd *vdd)
4309 {
4310 	int depth, r;
4311 	size_t path_table_size;
4312 
4313 	r = ARCHIVE_OK;
4314 	path_table_size = 0;
4315 	for (depth = 0; depth < vdd->max_depth; depth++) {
4316 		r = _write_path_table(a, type_m, depth, vdd);
4317 		if (r < 0)
4318 			return (r);
4319 		path_table_size += r;
4320 	}
4321 
4322 	/* Write padding data. */
4323 	path_table_size = path_table_size % PATH_TABLE_BLOCK_SIZE;
4324 	if (path_table_size > 0)
4325 		r = write_null(a, PATH_TABLE_BLOCK_SIZE - path_table_size);
4326 	return (r);
4327 }
4328 
4329 static int
4330 calculate_directory_descriptors(struct iso9660 *iso9660, struct vdd *vdd,
4331     struct isoent *isoent, int depth)
4332 {
4333 	struct isoent **enttbl;
4334 	int bs, block, i;
4335 
4336 	block = 1;
4337 	bs = get_dir_rec_size(iso9660, isoent, DIR_REC_SELF, vdd->vdd_type);
4338 	bs += get_dir_rec_size(iso9660, isoent, DIR_REC_PARENT, vdd->vdd_type);
4339 
4340 	if (isoent->children.cnt <= 0 || (vdd->vdd_type != VDD_JOLIET &&
4341 	    !iso9660->opt.rr && depth + 1 >= vdd->max_depth))
4342 		return (block);
4343 
4344 	enttbl = isoent->children_sorted;
4345 	for (i = 0; i < isoent->children.cnt; i++) {
4346 		struct isoent *np = enttbl[i];
4347 		struct isofile *file;
4348 
4349 		file = np->file;
4350 		if (file->hardlink_target != NULL)
4351 			file = file->hardlink_target;
4352 		file->cur_content = &(file->content);
4353 		do {
4354 			int dr_l;
4355 
4356 			dr_l = get_dir_rec_size(iso9660, np, DIR_REC_NORMAL,
4357 			    vdd->vdd_type);
4358 			if ((bs + dr_l) > LOGICAL_BLOCK_SIZE) {
4359 				block ++;
4360 				bs = dr_l;
4361 			} else
4362 				bs += dr_l;
4363 			file->cur_content = file->cur_content->next;
4364 		} while (file->cur_content != NULL);
4365 	}
4366 	return (block);
4367 }
4368 
4369 static int
4370 _write_directory_descriptors(struct archive_write *a, struct vdd *vdd,
4371     struct isoent *isoent, int depth)
4372 {
4373 	struct iso9660 *iso9660 = a->format_data;
4374 	struct isoent **enttbl;
4375 	unsigned char *p, *wb;
4376 	int i, r;
4377 	int dr_l;
4378 
4379 	p = wb = wb_buffptr(a);
4380 #define WD_REMAINING	(LOGICAL_BLOCK_SIZE - (p - wb))
4381 	p += set_directory_record(p, WD_REMAINING, isoent,
4382 	    iso9660, DIR_REC_SELF, vdd->vdd_type);
4383 	p += set_directory_record(p, WD_REMAINING, isoent,
4384 	    iso9660, DIR_REC_PARENT, vdd->vdd_type);
4385 
4386 	if (isoent->children.cnt <= 0 || (vdd->vdd_type != VDD_JOLIET &&
4387 	    !iso9660->opt.rr && depth + 1 >= vdd->max_depth)) {
4388 		memset(p, 0, WD_REMAINING);
4389 		return (wb_consume(a, LOGICAL_BLOCK_SIZE));
4390 	}
4391 
4392 	enttbl = isoent->children_sorted;
4393 	for (i = 0; i < isoent->children.cnt; i++) {
4394 		struct isoent *np = enttbl[i];
4395 		struct isofile *file = np->file;
4396 
4397 		if (file->hardlink_target != NULL)
4398 			file = file->hardlink_target;
4399 		file->cur_content = &(file->content);
4400 		do {
4401 			dr_l = set_directory_record(p, WD_REMAINING,
4402 			    np, iso9660, DIR_REC_NORMAL,
4403 			    vdd->vdd_type);
4404 			if (dr_l == 0) {
4405 				memset(p, 0, WD_REMAINING);
4406 				r = wb_consume(a, LOGICAL_BLOCK_SIZE);
4407 				if (r < 0)
4408 					return (r);
4409 				p = wb = wb_buffptr(a);
4410 				dr_l = set_directory_record(p,
4411 				    WD_REMAINING, np, iso9660,
4412 				    DIR_REC_NORMAL, vdd->vdd_type);
4413 			}
4414 			p += dr_l;
4415 			file->cur_content = file->cur_content->next;
4416 		} while (file->cur_content != NULL);
4417 	}
4418 	memset(p, 0, WD_REMAINING);
4419 	return (wb_consume(a, LOGICAL_BLOCK_SIZE));
4420 }
4421 
4422 static int
4423 write_directory_descriptors(struct archive_write *a, struct vdd *vdd)
4424 {
4425 	struct isoent *np;
4426 	int depth, r;
4427 
4428 	depth = 0;
4429 	np = vdd->rootent;
4430 	do {
4431 		struct extr_rec *extr;
4432 
4433 		r = _write_directory_descriptors(a, vdd, np, depth);
4434 		if (r < 0)
4435 			return (r);
4436 		if (vdd->vdd_type != VDD_JOLIET) {
4437 			/*
4438 			 * This extract record is used by SUSP,RRIP.
4439 			 * Not for joliet.
4440 			 */
4441 			for (extr = np->extr_rec_list.first;
4442 			    extr != NULL;
4443 			    extr = extr->next) {
4444 				unsigned char *wb;
4445 
4446 				wb = wb_buffptr(a);
4447 				memcpy(wb, extr->buf, extr->offset);
4448 				memset(wb + extr->offset, 0,
4449 				    LOGICAL_BLOCK_SIZE - extr->offset);
4450 				r = wb_consume(a, LOGICAL_BLOCK_SIZE);
4451 				if (r < 0)
4452 					return (r);
4453 			}
4454 		}
4455 
4456 		if (np->subdirs.first != NULL && depth + 1 < vdd->max_depth) {
4457 			/* Enter to sub directories. */
4458 			np = np->subdirs.first;
4459 			depth++;
4460 			continue;
4461 		}
4462 		while (np != np->parent) {
4463 			if (np->drnext == NULL) {
4464 				/* Return to the parent directory. */
4465 				np = np->parent;
4466 				depth--;
4467 			} else {
4468 				np = np->drnext;
4469 				break;
4470 			}
4471 		}
4472 	} while (np != np->parent);
4473 
4474 	return (ARCHIVE_OK);
4475 }
4476 
4477 /*
4478  * Read file contents from the temporary file, and write it.
4479  */
4480 static int
4481 write_file_contents(struct archive_write *a, int64_t offset, int64_t size)
4482 {
4483 	struct iso9660 *iso9660 = a->format_data;
4484 	int r;
4485 
4486 	lseek(iso9660->temp_fd, offset, SEEK_SET);
4487 
4488 	while (size) {
4489 		size_t rsize;
4490 		ssize_t rs;
4491 		unsigned char *wb;
4492 
4493 		wb = wb_buffptr(a);
4494 		rsize = wb_remaining(a);
4495 		if (rsize > (size_t)size)
4496 			rsize = (size_t)size;
4497 		rs = read(iso9660->temp_fd, wb, rsize);
4498 		if (rs <= 0) {
4499 			archive_set_error(&a->archive, errno,
4500 			    "Can't read temporary file(%jd)", (intmax_t)rs);
4501 			return (ARCHIVE_FATAL);
4502 		}
4503 		size -= rs;
4504 		r = wb_consume(a, rs);
4505 		if (r < 0)
4506 			return (r);
4507 	}
4508 	return (ARCHIVE_OK);
4509 }
4510 
4511 static int
4512 write_file_descriptors(struct archive_write *a)
4513 {
4514 	struct iso9660 *iso9660 = a->format_data;
4515 	struct isofile *file;
4516 	int64_t blocks, offset;
4517 	int r;
4518 
4519 	blocks = 0;
4520 	offset = 0;
4521 
4522 	/* Make the boot catalog contents, and write it. */
4523 	if (iso9660->el_torito.catalog != NULL) {
4524 		r = make_boot_catalog(a);
4525 		if (r < 0)
4526 			return (r);
4527 	}
4528 
4529 	/* Write the boot file contents. */
4530 	if (iso9660->el_torito.boot != NULL) {
4531 		file = iso9660->el_torito.boot->file;
4532 		blocks = file->content.blocks;
4533 		offset = file->content.offset_of_temp;
4534 		if (offset != 0) {
4535 			r = write_file_contents(a, offset,
4536 			    blocks << LOGICAL_BLOCK_BITS);
4537 			if (r < 0)
4538 				return (r);
4539 			blocks = 0;
4540 			offset = 0;
4541 		}
4542 	}
4543 
4544 	/* Write out all file contents. */
4545 	for (file = iso9660->data_file_list.first;
4546 	    file != NULL; file = file->datanext) {
4547 
4548 		if (!file->write_content)
4549 			continue;
4550 
4551 		if ((offset + (blocks << LOGICAL_BLOCK_BITS)) <
4552 		     file->content.offset_of_temp) {
4553 			if (blocks > 0) {
4554 				r = write_file_contents(a, offset,
4555 				    blocks << LOGICAL_BLOCK_BITS);
4556 				if (r < 0)
4557 					return (r);
4558 			}
4559 			blocks = 0;
4560 			offset = file->content.offset_of_temp;
4561 		}
4562 
4563 		file->cur_content = &(file->content);
4564 		do {
4565 			blocks += file->cur_content->blocks;
4566 			/* Next fragment */
4567 			file->cur_content = file->cur_content->next;
4568 		} while (file->cur_content != NULL);
4569 	}
4570 
4571 	/* Flush out remaining blocks. */
4572 	if (blocks > 0) {
4573 		r = write_file_contents(a, offset,
4574 		    blocks << LOGICAL_BLOCK_BITS);
4575 		if (r < 0)
4576 			return (r);
4577 	}
4578 
4579 	return (ARCHIVE_OK);
4580 }
4581 
4582 static void
4583 isofile_init_entry_list(struct iso9660 *iso9660)
4584 {
4585 	iso9660->all_file_list.first = NULL;
4586 	iso9660->all_file_list.last = &(iso9660->all_file_list.first);
4587 }
4588 
4589 static void
4590 isofile_add_entry(struct iso9660 *iso9660, struct isofile *file)
4591 {
4592 	file->allnext = NULL;
4593 	*iso9660->all_file_list.last = file;
4594 	iso9660->all_file_list.last = &(file->allnext);
4595 }
4596 
4597 static void
4598 isofile_free_all_entries(struct iso9660 *iso9660)
4599 {
4600 	struct isofile *file, *file_next;
4601 
4602 	file = iso9660->all_file_list.first;
4603 	while (file != NULL) {
4604 		file_next = file->allnext;
4605 		isofile_free(file);
4606 		file = file_next;
4607 	}
4608 }
4609 
4610 static void
4611 isofile_init_entry_data_file_list(struct iso9660 *iso9660)
4612 {
4613 	iso9660->data_file_list.first = NULL;
4614 	iso9660->data_file_list.last = &(iso9660->data_file_list.first);
4615 }
4616 
4617 static void
4618 isofile_add_data_file(struct iso9660 *iso9660, struct isofile *file)
4619 {
4620 	file->datanext = NULL;
4621 	*iso9660->data_file_list.last = file;
4622 	iso9660->data_file_list.last = &(file->datanext);
4623 }
4624 
4625 
4626 static struct isofile *
4627 isofile_new(struct archive_write *a, struct archive_entry *entry)
4628 {
4629 	struct isofile *file;
4630 
4631 	file = calloc(1, sizeof(*file));
4632 	if (file == NULL)
4633 		return (NULL);
4634 
4635 	if (entry != NULL)
4636 		file->entry = archive_entry_clone(entry);
4637 	else
4638 		file->entry = archive_entry_new2(&a->archive);
4639 	if (file->entry == NULL) {
4640 		free(file);
4641 		return (NULL);
4642 	}
4643 	archive_string_init(&(file->parentdir));
4644 	archive_string_init(&(file->basename));
4645 	archive_string_init(&(file->basename_utf16));
4646 	archive_string_init(&(file->symlink));
4647 	file->cur_content = &(file->content);
4648 
4649 	return (file);
4650 }
4651 
4652 static void
4653 isofile_free(struct isofile *file)
4654 {
4655 	struct content *con, *tmp;
4656 
4657 	con = file->content.next;
4658 	while (con != NULL) {
4659 		tmp = con;
4660 		con = con->next;
4661 		free(tmp);
4662 	}
4663 	archive_entry_free(file->entry);
4664 	archive_string_free(&(file->parentdir));
4665 	archive_string_free(&(file->basename));
4666 	archive_string_free(&(file->basename_utf16));
4667 	archive_string_free(&(file->symlink));
4668 	free(file);
4669 }
4670 
4671 #if defined(_WIN32) || defined(__CYGWIN__)
4672 static int
4673 cleanup_backslash_1(char *p)
4674 {
4675 	int mb, dos;
4676 
4677 	mb = dos = 0;
4678 	while (*p) {
4679 		if (*(unsigned char *)p > 127)
4680 			mb = 1;
4681 		if (*p == '\\') {
4682 			/* If we have not met any multi-byte characters,
4683 			 * we can replace '\' with '/'. */
4684 			if (!mb)
4685 				*p = '/';
4686 			dos = 1;
4687 		}
4688 		p++;
4689 	}
4690 	if (!mb || !dos)
4691 		return (0);
4692 	return (-1);
4693 }
4694 
4695 static void
4696 cleanup_backslash_2(wchar_t *p)
4697 {
4698 
4699 	/* Convert a path-separator from '\' to  '/' */
4700 	while (*p != L'\0') {
4701 		if (*p == L'\\')
4702 			*p = L'/';
4703 		p++;
4704 	}
4705 }
4706 #endif
4707 
4708 /*
4709  * Generate a parent directory name and a base name from a pathname.
4710  */
4711 static int
4712 isofile_gen_utility_names(struct archive_write *a, struct isofile *file)
4713 {
4714 	struct iso9660 *iso9660;
4715 	const char *pathname;
4716 	char *p, *dirname, *slash;
4717 	size_t len;
4718 	int ret = ARCHIVE_OK;
4719 
4720 	iso9660 = a->format_data;
4721 
4722 	archive_string_empty(&(file->parentdir));
4723 	archive_string_empty(&(file->basename));
4724 	archive_string_empty(&(file->basename_utf16));
4725 	archive_string_empty(&(file->symlink));
4726 
4727 	pathname =  archive_entry_pathname(file->entry);
4728 	if (pathname == NULL || pathname[0] == '\0') {/* virtual root */
4729 		file->dircnt = 0;
4730 		return (ret);
4731 	}
4732 
4733 	/*
4734 	 * Make a UTF-16BE basename if Joliet extension enabled.
4735 	 */
4736 	if (iso9660->opt.joliet) {
4737 		const char *u16, *ulast;
4738 		size_t u16len, ulen_last;
4739 
4740 		if (iso9660->sconv_to_utf16be == NULL) {
4741 			iso9660->sconv_to_utf16be =
4742 			    archive_string_conversion_to_charset(
4743 				&(a->archive), "UTF-16BE", 1);
4744 			if (iso9660->sconv_to_utf16be == NULL)
4745 				/* Couldn't allocate memory */
4746 				return (ARCHIVE_FATAL);
4747 			iso9660->sconv_from_utf16be =
4748 			    archive_string_conversion_from_charset(
4749 				&(a->archive), "UTF-16BE", 1);
4750 			if (iso9660->sconv_from_utf16be == NULL)
4751 				/* Couldn't allocate memory */
4752 				return (ARCHIVE_FATAL);
4753 		}
4754 
4755 		/*
4756 		 * Convert a filename to UTF-16BE.
4757 		 */
4758 		if (0 > archive_entry_pathname_l(file->entry, &u16, &u16len,
4759 		    iso9660->sconv_to_utf16be)) {
4760 			if (errno == ENOMEM) {
4761 				archive_set_error(&a->archive, ENOMEM,
4762 				    "Can't allocate memory for UTF-16BE");
4763 				return (ARCHIVE_FATAL);
4764 			}
4765 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
4766 			    "A filename cannot be converted to UTF-16BE;"
4767 			    "You should disable making Joliet extension");
4768 			ret = ARCHIVE_WARN;
4769 		}
4770 
4771 		/*
4772 		 * Make sure a path separator is not in the last;
4773 		 * Remove trailing '/'.
4774 		 */
4775 		while (u16len >= 2) {
4776 #if defined(_WIN32) || defined(__CYGWIN__)
4777 			if (u16[u16len-2] == 0 &&
4778 			    (u16[u16len-1] == '/' || u16[u16len-1] == '\\'))
4779 #else
4780 			if (u16[u16len-2] == 0 && u16[u16len-1] == '/')
4781 #endif
4782 			{
4783 				u16len -= 2;
4784 			} else
4785 				break;
4786 		}
4787 
4788 		/*
4789 		 * Find a basename in UTF-16BE.
4790 		 */
4791 		ulast = u16;
4792 		u16len >>= 1;
4793 		ulen_last = u16len;
4794 		while (u16len > 0) {
4795 #if defined(_WIN32) || defined(__CYGWIN__)
4796 			if (u16[0] == 0 && (u16[1] == '/' || u16[1] == '\\'))
4797 #else
4798 			if (u16[0] == 0 && u16[1] == '/')
4799 #endif
4800 			{
4801 				ulast = u16 + 2;
4802 				ulen_last = u16len -1;
4803 			}
4804 			u16 += 2;
4805 			u16len --;
4806 		}
4807 		ulen_last <<= 1;
4808 		if (archive_string_ensure(&(file->basename_utf16),
4809 		    ulen_last) == NULL) {
4810 			archive_set_error(&a->archive, ENOMEM,
4811 			    "Can't allocate memory for UTF-16BE");
4812 			return (ARCHIVE_FATAL);
4813 		}
4814 
4815 		/*
4816 		 * Set UTF-16BE basename.
4817 		 */
4818 		memcpy(file->basename_utf16.s, ulast, ulen_last);
4819 		file->basename_utf16.length = ulen_last;
4820 	}
4821 
4822 	archive_strcpy(&(file->parentdir), pathname);
4823 #if defined(_WIN32) || defined(__CYGWIN__)
4824 	/*
4825 	 * Convert a path-separator from '\' to  '/'
4826 	 */
4827 	if (cleanup_backslash_1(file->parentdir.s) != 0) {
4828 		const wchar_t *wp = archive_entry_pathname_w(file->entry);
4829 		struct archive_wstring ws;
4830 
4831 		if (wp != NULL) {
4832 			int r;
4833 			archive_string_init(&ws);
4834 			archive_wstrcpy(&ws, wp);
4835 			cleanup_backslash_2(ws.s);
4836 			archive_string_empty(&(file->parentdir));
4837 			r = archive_string_append_from_wcs(&(file->parentdir),
4838 			    ws.s, ws.length);
4839 			archive_wstring_free(&ws);
4840 			if (r < 0 && errno == ENOMEM) {
4841 				archive_set_error(&a->archive, ENOMEM,
4842 				    "Can't allocate memory");
4843 				return (ARCHIVE_FATAL);
4844 			}
4845 		}
4846 	}
4847 #endif
4848 
4849 	len = file->parentdir.length;
4850 	p = dirname = file->parentdir.s;
4851 
4852 	/*
4853 	 * Remove leading '/', '../' and './' elements
4854 	 */
4855 	while (*p) {
4856 		if (p[0] == '/') {
4857 			p++;
4858 			len--;
4859 		} else if (p[0] != '.')
4860 			break;
4861 		else if (p[1] == '.' && p[2] == '/') {
4862 			p += 3;
4863 			len -= 3;
4864 		} else if (p[1] == '/' || (p[1] == '.' && p[2] == '\0')) {
4865 			p += 2;
4866 			len -= 2;
4867 		} else if (p[1] == '\0') {
4868 			p++;
4869 			len--;
4870 		} else
4871 			break;
4872 	}
4873 	if (p != dirname) {
4874 		memmove(dirname, p, len+1);
4875 		p = dirname;
4876 	}
4877 	/*
4878 	 * Remove "/","/." and "/.." elements from tail.
4879 	 */
4880 	while (len > 0) {
4881 		size_t ll = len;
4882 
4883 		if (len > 0 && p[len-1] == '/') {
4884 			p[len-1] = '\0';
4885 			len--;
4886 		}
4887 		if (len > 1 && p[len-2] == '/' && p[len-1] == '.') {
4888 			p[len-2] = '\0';
4889 			len -= 2;
4890 		}
4891 		if (len > 2 && p[len-3] == '/' && p[len-2] == '.' &&
4892 		    p[len-1] == '.') {
4893 			p[len-3] = '\0';
4894 			len -= 3;
4895 		}
4896 		if (ll == len)
4897 			break;
4898 	}
4899 	while (*p) {
4900 		if (p[0] == '/') {
4901 			if (p[1] == '/')
4902 				/* Convert '//' --> '/' */
4903 				memmove(p, p+1, strlen(p+1) + 1);
4904 			else if (p[1] == '.' && p[2] == '/')
4905 				/* Convert '/./' --> '/' */
4906 				memmove(p, p+2, strlen(p+2) + 1);
4907 			else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
4908 				/* Convert 'dir/dir1/../dir2/'
4909 				 *     --> 'dir/dir2/'
4910 				 */
4911 				char *rp = p -1;
4912 				while (rp >= dirname) {
4913 					if (*rp == '/')
4914 						break;
4915 					--rp;
4916 				}
4917 				if (rp > dirname) {
4918 					strcpy(rp, p+3);
4919 					p = rp;
4920 				} else {
4921 					strcpy(dirname, p+4);
4922 					p = dirname;
4923 				}
4924 			} else
4925 				p++;
4926 		} else
4927 			p++;
4928 	}
4929 	p = dirname;
4930 	len = strlen(p);
4931 
4932 	if (archive_entry_filetype(file->entry) == AE_IFLNK) {
4933 		/* Convert symlink name too. */
4934 		pathname = archive_entry_symlink(file->entry);
4935 		archive_strcpy(&(file->symlink),  pathname);
4936 #if defined(_WIN32) || defined(__CYGWIN__)
4937 		/*
4938 		 * Convert a path-separator from '\' to  '/'
4939 		 */
4940 		if (archive_strlen(&(file->symlink)) > 0 &&
4941 		    cleanup_backslash_1(file->symlink.s) != 0) {
4942 			const wchar_t *wp =
4943 			    archive_entry_symlink_w(file->entry);
4944 			struct archive_wstring ws;
4945 
4946 			if (wp != NULL) {
4947 				int r;
4948 				archive_string_init(&ws);
4949 				archive_wstrcpy(&ws, wp);
4950 				cleanup_backslash_2(ws.s);
4951 				archive_string_empty(&(file->symlink));
4952 				r = archive_string_append_from_wcs(
4953 				    &(file->symlink),
4954 				    ws.s, ws.length);
4955 				archive_wstring_free(&ws);
4956 				if (r < 0 && errno == ENOMEM) {
4957 					archive_set_error(&a->archive, ENOMEM,
4958 					    "Can't allocate memory");
4959 					return (ARCHIVE_FATAL);
4960 				}
4961 			}
4962 		}
4963 #endif
4964 	}
4965 	/*
4966 	 * - Count up directory elements.
4967 	 * - Find out the position which points the last position of
4968 	 *   path separator('/').
4969 	 */
4970 	slash = NULL;
4971 	file->dircnt = 0;
4972 	for (; *p != '\0'; p++)
4973 		if (*p == '/') {
4974 			slash = p;
4975 			file->dircnt++;
4976 		}
4977 	if (slash == NULL) {
4978 		/* The pathname doesn't have a parent directory. */
4979 		file->parentdir.length = len;
4980 		archive_string_copy(&(file->basename), &(file->parentdir));
4981 		archive_string_empty(&(file->parentdir));
4982 		*file->parentdir.s = '\0';
4983 		return (ret);
4984 	}
4985 
4986 	/* Make a basename from dirname and slash */
4987 	*slash  = '\0';
4988 	file->parentdir.length = slash - dirname;
4989 	archive_strcpy(&(file->basename),  slash + 1);
4990 	if (archive_entry_filetype(file->entry) == AE_IFDIR)
4991 		file->dircnt ++;
4992 	return (ret);
4993 }
4994 
4995 /*
4996  * Register a entry to get a hardlink target.
4997  */
4998 static int
4999 isofile_register_hardlink(struct archive_write *a, struct isofile *file)
5000 {
5001 	struct iso9660 *iso9660 = a->format_data;
5002 	struct hardlink *hl;
5003 	const char *pathname;
5004 
5005 	archive_entry_set_nlink(file->entry, 1);
5006 	pathname = archive_entry_hardlink(file->entry);
5007 	if (pathname == NULL) {
5008 		/* This `file` is a hardlink target. */
5009 		hl = malloc(sizeof(*hl));
5010 		if (hl == NULL) {
5011 			archive_set_error(&a->archive, ENOMEM,
5012 			    "Can't allocate memory");
5013 			return (ARCHIVE_FATAL);
5014 		}
5015 		hl->nlink = 1;
5016 		/* A hardlink target must be the first position. */
5017 		file->hlnext = NULL;
5018 		hl->file_list.first = file;
5019 		hl->file_list.last = &(file->hlnext);
5020 		__archive_rb_tree_insert_node(&(iso9660->hardlink_rbtree),
5021 		    (struct archive_rb_node *)hl);
5022 	} else {
5023 		hl = (struct hardlink *)__archive_rb_tree_find_node(
5024 		    &(iso9660->hardlink_rbtree), pathname);
5025 		if (hl != NULL) {
5026 			/* Insert `file` entry into the tail. */
5027 			file->hlnext = NULL;
5028 			*hl->file_list.last = file;
5029 			hl->file_list.last = &(file->hlnext);
5030 			hl->nlink++;
5031 		}
5032 		archive_entry_unset_size(file->entry);
5033 	}
5034 
5035 	return (ARCHIVE_OK);
5036 }
5037 
5038 /*
5039  * Hardlinked files have to have the same location of extent.
5040  * We have to find out hardlink target entries for the entries
5041  * which have a hardlink target name.
5042  */
5043 static void
5044 isofile_connect_hardlink_files(struct iso9660 *iso9660)
5045 {
5046 	struct archive_rb_node *n;
5047 	struct hardlink *hl;
5048 	struct isofile *target, *nf;
5049 
5050 	ARCHIVE_RB_TREE_FOREACH(n, &(iso9660->hardlink_rbtree)) {
5051 		hl = (struct hardlink *)n;
5052 
5053 		/* The first entry must be a hardlink target. */
5054 		target = hl->file_list.first;
5055 		archive_entry_set_nlink(target->entry, hl->nlink);
5056 		/* Set a hardlink target to reference entries. */
5057 		for (nf = target->hlnext;
5058 		    nf != NULL; nf = nf->hlnext) {
5059 			nf->hardlink_target = target;
5060 			archive_entry_set_nlink(nf->entry, hl->nlink);
5061 		}
5062 	}
5063 }
5064 
5065 static int
5066 isofile_hd_cmp_node(const struct archive_rb_node *n1,
5067     const struct archive_rb_node *n2)
5068 {
5069 	const struct hardlink *h1 = (const struct hardlink *)n1;
5070 	const struct hardlink *h2 = (const struct hardlink *)n2;
5071 
5072 	return (strcmp(archive_entry_pathname(h1->file_list.first->entry),
5073 		       archive_entry_pathname(h2->file_list.first->entry)));
5074 }
5075 
5076 static int
5077 isofile_hd_cmp_key(const struct archive_rb_node *n, const void *key)
5078 {
5079 	const struct hardlink *h = (const struct hardlink *)n;
5080 
5081 	return (strcmp(archive_entry_pathname(h->file_list.first->entry),
5082 		       (const char *)key));
5083 }
5084 
5085 static void
5086 isofile_init_hardlinks(struct iso9660 *iso9660)
5087 {
5088 	static const struct archive_rb_tree_ops rb_ops = {
5089 		isofile_hd_cmp_node, isofile_hd_cmp_key,
5090 	};
5091 
5092 	__archive_rb_tree_init(&(iso9660->hardlink_rbtree), &rb_ops);
5093 }
5094 
5095 static void
5096 isofile_free_hardlinks(struct iso9660 *iso9660)
5097 {
5098 	struct archive_rb_node *n, *tmp;
5099 
5100 	ARCHIVE_RB_TREE_FOREACH_SAFE(n, &(iso9660->hardlink_rbtree), tmp) {
5101 		__archive_rb_tree_remove_node(&(iso9660->hardlink_rbtree), n);
5102 		free(n);
5103 	}
5104 }
5105 
5106 static struct isoent *
5107 isoent_new(struct isofile *file)
5108 {
5109 	struct isoent *isoent;
5110 	static const struct archive_rb_tree_ops rb_ops = {
5111 		isoent_cmp_node, isoent_cmp_key,
5112 	};
5113 
5114 	isoent = calloc(1, sizeof(*isoent));
5115 	if (isoent == NULL)
5116 		return (NULL);
5117 	isoent->file = file;
5118 	isoent->children.first = NULL;
5119 	isoent->children.last = &(isoent->children.first);
5120 	__archive_rb_tree_init(&(isoent->rbtree), &rb_ops);
5121 	isoent->subdirs.first = NULL;
5122 	isoent->subdirs.last = &(isoent->subdirs.first);
5123 	isoent->extr_rec_list.first = NULL;
5124 	isoent->extr_rec_list.last = &(isoent->extr_rec_list.first);
5125 	isoent->extr_rec_list.current = NULL;
5126 	if (archive_entry_filetype(file->entry) == AE_IFDIR)
5127 		isoent->dir = 1;
5128 
5129 	return (isoent);
5130 }
5131 
5132 static inline struct isoent *
5133 isoent_clone(struct isoent *src)
5134 {
5135 	return (isoent_new(src->file));
5136 }
5137 
5138 static void
5139 _isoent_free(struct isoent *isoent)
5140 {
5141 	struct extr_rec *er, *er_next;
5142 
5143 	free(isoent->children_sorted);
5144 	free(isoent->identifier);
5145 	er = isoent->extr_rec_list.first;
5146 	while (er != NULL) {
5147 		er_next = er->next;
5148 		free(er);
5149 		er = er_next;
5150 	}
5151 	free(isoent);
5152 }
5153 
5154 static void
5155 isoent_free_all(struct isoent *isoent)
5156 {
5157 	struct isoent *np, *np_temp;
5158 
5159 	if (isoent == NULL)
5160 		return;
5161 	np = isoent;
5162 	for (;;) {
5163 		if (np->dir) {
5164 			if (np->children.first != NULL) {
5165 				/* Enter to sub directories. */
5166 				np = np->children.first;
5167 				continue;
5168 			}
5169 		}
5170 		for (;;) {
5171 			np_temp = np;
5172 			if (np->chnext == NULL) {
5173 				/* Return to the parent directory. */
5174 				np = np->parent;
5175 				_isoent_free(np_temp);
5176 				if (np == np_temp)
5177 					return;
5178 			} else {
5179 				np = np->chnext;
5180 				_isoent_free(np_temp);
5181 				break;
5182 			}
5183 		}
5184 	}
5185 }
5186 
5187 static struct isoent *
5188 isoent_create_virtual_dir(struct archive_write *a, struct iso9660 *iso9660, const char *pathname)
5189 {
5190 	struct isofile *file;
5191 	struct isoent *isoent;
5192 
5193 	file = isofile_new(a, NULL);
5194 	if (file == NULL)
5195 		return (NULL);
5196 	archive_entry_set_pathname(file->entry, pathname);
5197 	archive_entry_unset_mtime(file->entry);
5198 	archive_entry_unset_atime(file->entry);
5199 	archive_entry_unset_ctime(file->entry);
5200 	archive_entry_set_uid(file->entry, getuid());
5201 	archive_entry_set_gid(file->entry, getgid());
5202 	archive_entry_set_mode(file->entry, 0555 | AE_IFDIR);
5203 	archive_entry_set_nlink(file->entry, 2);
5204 	if (isofile_gen_utility_names(a, file) < ARCHIVE_WARN) {
5205 		isofile_free(file);
5206 		return (NULL);
5207 	}
5208 	isofile_add_entry(iso9660, file);
5209 
5210 	isoent = isoent_new(file);
5211 	if (isoent == NULL)
5212 		return (NULL);
5213 	isoent->dir = 1;
5214 	isoent->virtual = 1;
5215 
5216 	return (isoent);
5217 }
5218 
5219 static int
5220 isoent_cmp_node(const struct archive_rb_node *n1,
5221     const struct archive_rb_node *n2)
5222 {
5223 	const struct isoent *e1 = (const struct isoent *)n1;
5224 	const struct isoent *e2 = (const struct isoent *)n2;
5225 
5226 	return (strcmp(e1->file->basename.s, e2->file->basename.s));
5227 }
5228 
5229 static int
5230 isoent_cmp_key(const struct archive_rb_node *n, const void *key)
5231 {
5232 	const struct isoent *e = (const struct isoent *)n;
5233 
5234 	return (strcmp(e->file->basename.s, (const char *)key));
5235 }
5236 
5237 static int
5238 isoent_add_child_head(struct isoent *parent, struct isoent *child)
5239 {
5240 
5241 	if (!__archive_rb_tree_insert_node(
5242 	    &(parent->rbtree), (struct archive_rb_node *)child))
5243 		return (0);
5244 	if ((child->chnext = parent->children.first) == NULL)
5245 		parent->children.last = &(child->chnext);
5246 	parent->children.first = child;
5247 	parent->children.cnt++;
5248 	child->parent = parent;
5249 
5250 	/* Add a child to a sub-directory chain */
5251 	if (child->dir) {
5252 		if ((child->drnext = parent->subdirs.first) == NULL)
5253 			parent->subdirs.last = &(child->drnext);
5254 		parent->subdirs.first = child;
5255 		parent->subdirs.cnt++;
5256 		child->parent = parent;
5257 	} else
5258 		child->drnext = NULL;
5259 	return (1);
5260 }
5261 
5262 static int
5263 isoent_add_child_tail(struct isoent *parent, struct isoent *child)
5264 {
5265 
5266 	if (!__archive_rb_tree_insert_node(
5267 	    &(parent->rbtree), (struct archive_rb_node *)child))
5268 		return (0);
5269 	child->chnext = NULL;
5270 	*parent->children.last = child;
5271 	parent->children.last = &(child->chnext);
5272 	parent->children.cnt++;
5273 	child->parent = parent;
5274 
5275 	/* Add a child to a sub-directory chain */
5276 	child->drnext = NULL;
5277 	if (child->dir) {
5278 		*parent->subdirs.last = child;
5279 		parent->subdirs.last = &(child->drnext);
5280 		parent->subdirs.cnt++;
5281 		child->parent = parent;
5282 	}
5283 	return (1);
5284 }
5285 
5286 static void
5287 isoent_remove_child(struct isoent *parent, struct isoent *child)
5288 {
5289 	struct isoent *ent;
5290 
5291 	/* Remove a child entry from children chain. */
5292 	ent = parent->children.first;
5293 	while (ent->chnext != child)
5294 		ent = ent->chnext;
5295 	if ((ent->chnext = ent->chnext->chnext) == NULL)
5296 		parent->children.last = &(ent->chnext);
5297 	parent->children.cnt--;
5298 
5299 	if (child->dir) {
5300 		/* Remove a child entry from sub-directory chain. */
5301 		ent = parent->subdirs.first;
5302 		while (ent->drnext != child)
5303 			ent = ent->drnext;
5304 		if ((ent->drnext = ent->drnext->drnext) == NULL)
5305 			parent->subdirs.last = &(ent->drnext);
5306 		parent->subdirs.cnt--;
5307 	}
5308 
5309 	__archive_rb_tree_remove_node(&(parent->rbtree),
5310 	    (struct archive_rb_node *)child);
5311 }
5312 
5313 static int
5314 isoent_clone_tree(struct archive_write *a, struct isoent **nroot,
5315     struct isoent *root)
5316 {
5317 	struct isoent *np, *xroot, *newent;
5318 
5319 	np = root;
5320 	xroot = NULL;
5321 	do {
5322 		newent = isoent_clone(np);
5323 		if (newent == NULL) {
5324 			archive_set_error(&a->archive, ENOMEM,
5325 			    "Can't allocate memory");
5326 			return (ARCHIVE_FATAL);
5327 		}
5328 		if (xroot == NULL) {
5329 			*nroot = xroot = newent;
5330 			newent->parent = xroot;
5331 		} else
5332 			isoent_add_child_tail(xroot, newent);
5333 		if (np->dir && np->children.first != NULL) {
5334 			/* Enter to sub directories. */
5335 			np = np->children.first;
5336 			xroot = newent;
5337 			continue;
5338 		}
5339 		while (np != np->parent) {
5340 			if (np->chnext == NULL) {
5341 				/* Return to the parent directory. */
5342 				np = np->parent;
5343 				xroot = xroot->parent;
5344 			} else {
5345 				np = np->chnext;
5346 				break;
5347 			}
5348 		}
5349 	} while (np != np->parent);
5350 
5351 	return (ARCHIVE_OK);
5352 }
5353 
5354 /*
5355  * Setup directory locations.
5356  */
5357 static void
5358 isoent_setup_directory_location(struct iso9660 *iso9660, int location,
5359     struct vdd *vdd)
5360 {
5361 	struct isoent *np;
5362 	int depth;
5363 
5364 	vdd->total_dir_block = 0;
5365 	depth = 0;
5366 	np = vdd->rootent;
5367 	do {
5368 		int block;
5369 
5370 		np->dir_block = calculate_directory_descriptors(
5371 		    iso9660, vdd, np, depth);
5372 		vdd->total_dir_block += np->dir_block;
5373 		np->dir_location = location;
5374 		location += np->dir_block;
5375 		block = extra_setup_location(np, location);
5376 		vdd->total_dir_block += block;
5377 		location += block;
5378 
5379 		if (np->subdirs.first != NULL && depth + 1 < vdd->max_depth) {
5380 			/* Enter to sub directories. */
5381 			np = np->subdirs.first;
5382 			depth++;
5383 			continue;
5384 		}
5385 		while (np != np->parent) {
5386 			if (np->drnext == NULL) {
5387 				/* Return to the parent directory. */
5388 				np = np->parent;
5389 				depth--;
5390 			} else {
5391 				np = np->drnext;
5392 				break;
5393 			}
5394 		}
5395 	} while (np != np->parent);
5396 }
5397 
5398 static void
5399 _isoent_file_location(struct iso9660 *iso9660, struct isoent *isoent,
5400     int *symlocation)
5401 {
5402 	struct isoent **children;
5403 	int n;
5404 
5405 	if (isoent->children.cnt == 0)
5406 		return;
5407 
5408 	children = isoent->children_sorted;
5409 	for (n = 0; n < isoent->children.cnt; n++) {
5410 		struct isoent *np;
5411 		struct isofile *file;
5412 
5413 		np = children[n];
5414 		if (np->dir)
5415 			continue;
5416 		if (np == iso9660->el_torito.boot)
5417 			continue;
5418 		file = np->file;
5419 		if (file->boot || file->hardlink_target != NULL)
5420 			continue;
5421 		if (archive_entry_filetype(file->entry) == AE_IFLNK ||
5422 		    file->content.size == 0) {
5423 			/*
5424 			 * Do not point a valid location.
5425 			 * Make sure entry is not hardlink file.
5426 			 */
5427 			file->content.location = (*symlocation)--;
5428 			continue;
5429 		}
5430 
5431 		file->write_content = 1;
5432 	}
5433 }
5434 
5435 /*
5436  * Setup file locations.
5437  */
5438 static void
5439 isoent_setup_file_location(struct iso9660 *iso9660, int location)
5440 {
5441 	struct isoent *isoent;
5442 	struct isoent *np;
5443 	struct isofile *file;
5444 	size_t size;
5445 	int block;
5446 	int depth;
5447 	int joliet;
5448 	int symlocation;
5449 	int total_block;
5450 
5451 	iso9660->total_file_block = 0;
5452 	if ((isoent = iso9660->el_torito.catalog) != NULL) {
5453 		isoent->file->content.location = location;
5454 		block = (int)((archive_entry_size(isoent->file->entry) +
5455 		    LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS);
5456 		location += block;
5457 		iso9660->total_file_block += block;
5458 	}
5459 	if ((isoent = iso9660->el_torito.boot) != NULL) {
5460 		isoent->file->content.location = location;
5461 		size = fd_boot_image_size(iso9660->el_torito.media_type);
5462 		if (size == 0)
5463 			size = (size_t)archive_entry_size(isoent->file->entry);
5464 		block = ((int)size + LOGICAL_BLOCK_SIZE -1)
5465 		    >> LOGICAL_BLOCK_BITS;
5466 		location += block;
5467 		iso9660->total_file_block += block;
5468 		isoent->file->content.blocks = block;
5469 	}
5470 
5471 	depth = 0;
5472 	symlocation = -16;
5473 	if (!iso9660->opt.rr && iso9660->opt.joliet) {
5474 		joliet = 1;
5475 		np = iso9660->joliet.rootent;
5476 	} else {
5477 		joliet = 0;
5478 		np = iso9660->primary.rootent;
5479 	}
5480 	do {
5481 		_isoent_file_location(iso9660, np, &symlocation);
5482 
5483 		if (np->subdirs.first != NULL &&
5484 		    (joliet ||
5485 		    ((iso9660->opt.rr == OPT_RR_DISABLED &&
5486 		      depth + 2 < iso9660->primary.max_depth) ||
5487 		     (iso9660->opt.rr &&
5488 		      depth + 1 < iso9660->primary.max_depth)))) {
5489 			/* Enter to sub directories. */
5490 			np = np->subdirs.first;
5491 			depth++;
5492 			continue;
5493 		}
5494 		while (np != np->parent) {
5495 			if (np->drnext == NULL) {
5496 				/* Return to the parent directory. */
5497 				np = np->parent;
5498 				depth--;
5499 			} else {
5500 				np = np->drnext;
5501 				break;
5502 			}
5503 		}
5504 	} while (np != np->parent);
5505 
5506 	total_block = 0;
5507 	for (file = iso9660->data_file_list.first;
5508 	    file != NULL; file = file->datanext) {
5509 
5510 		if (!file->write_content)
5511 			continue;
5512 
5513 		file->cur_content = &(file->content);
5514 		do {
5515 			file->cur_content->location = location;
5516 			location += file->cur_content->blocks;
5517 			total_block += file->cur_content->blocks;
5518 			/* Next fragment */
5519 			file->cur_content = file->cur_content->next;
5520 		} while (file->cur_content != NULL);
5521 	}
5522 	iso9660->total_file_block += total_block;
5523 }
5524 
5525 static int
5526 get_path_component(char *name, size_t n, const char *fn)
5527 {
5528 	char *p;
5529 	size_t l;
5530 
5531 	p = strchr(fn, '/');
5532 	if (p == NULL) {
5533 		if ((l = strlen(fn)) == 0)
5534 			return (0);
5535 	} else
5536 		l = p - fn;
5537 	if (l > n -1)
5538 		return (-1);
5539 	memcpy(name, fn, l);
5540 	name[l] = '\0';
5541 
5542 	return ((int)l);
5543 }
5544 
5545 /*
5546  * Add a new entry into the tree.
5547  */
5548 static int
5549 isoent_tree(struct archive_write *a, struct isoent **isoentpp)
5550 {
5551 #if defined(_WIN32) && !defined(__CYGWIN__)
5552 	char name[_MAX_FNAME];/* Included null terminator size. */
5553 #elif defined(NAME_MAX) && NAME_MAX >= 255
5554 	char name[NAME_MAX+1];
5555 #else
5556 	char name[256];
5557 #endif
5558 	struct iso9660 *iso9660 = a->format_data;
5559 	struct isoent *dent, *isoent, *np;
5560 	struct isofile *f1, *f2;
5561 	const char *fn, *p;
5562 	int l;
5563 
5564 	isoent = *isoentpp;
5565 	dent = iso9660->primary.rootent;
5566 	if (isoent->file->parentdir.length > 0)
5567 		fn = p = isoent->file->parentdir.s;
5568 	else
5569 		fn = p = "";
5570 
5571 	/*
5572 	 * If the path of the parent directory of `isoent' entry is
5573 	 * the same as the path of `cur_dirent', add isoent to
5574 	 * `cur_dirent'.
5575 	 */
5576 	if (archive_strlen(&(iso9660->cur_dirstr))
5577 	      == archive_strlen(&(isoent->file->parentdir)) &&
5578 	    strcmp(iso9660->cur_dirstr.s, fn) == 0) {
5579 		if (!isoent_add_child_tail(iso9660->cur_dirent, isoent)) {
5580 			np = (struct isoent *)__archive_rb_tree_find_node(
5581 			    &(iso9660->cur_dirent->rbtree),
5582 			    isoent->file->basename.s);
5583 			goto same_entry;
5584 		}
5585 		return (ARCHIVE_OK);
5586 	}
5587 
5588 	for (;;) {
5589 		l = get_path_component(name, sizeof(name), fn);
5590 		if (l == 0) {
5591 			np = NULL;
5592 			break;
5593 		}
5594 		if (l < 0) {
5595 			archive_set_error(&a->archive,
5596 			    ARCHIVE_ERRNO_MISC,
5597 			    "A name buffer is too small");
5598 			_isoent_free(isoent);
5599 			return (ARCHIVE_FATAL);
5600 		}
5601 
5602 		np = isoent_find_child(dent, name);
5603 		if (np == NULL || fn[0] == '\0')
5604 			break;
5605 
5606 		/* Find next subdirectory. */
5607 		if (!np->dir) {
5608 			/* NOT Directory! */
5609 			archive_set_error(&a->archive,
5610 			    ARCHIVE_ERRNO_MISC,
5611 			    "`%s' is not directory, we cannot insert `%s' ",
5612 			    archive_entry_pathname(np->file->entry),
5613 			    archive_entry_pathname(isoent->file->entry));
5614 			_isoent_free(isoent);
5615 			*isoentpp = NULL;
5616 			return (ARCHIVE_FAILED);
5617 		}
5618 		fn += l;
5619 		if (fn[0] == '/')
5620 			fn++;
5621 		dent = np;
5622 	}
5623 	if (np == NULL) {
5624 		/*
5625 		 * Create virtual parent directories.
5626 		 */
5627 		while (fn[0] != '\0') {
5628 			struct isoent *vp;
5629 			struct archive_string as;
5630 
5631 			archive_string_init(&as);
5632 			archive_strncat(&as, p, fn - p + l);
5633 			if (as.s[as.length-1] == '/') {
5634 				as.s[as.length-1] = '\0';
5635 				as.length--;
5636 			}
5637 			vp = isoent_create_virtual_dir(a, iso9660, as.s);
5638 			if (vp == NULL) {
5639 				archive_string_free(&as);
5640 				archive_set_error(&a->archive, ENOMEM,
5641 				    "Can't allocate memory");
5642 				_isoent_free(isoent);
5643 				*isoentpp = NULL;
5644 				return (ARCHIVE_FATAL);
5645 			}
5646 			archive_string_free(&as);
5647 
5648 			if (vp->file->dircnt > iso9660->dircnt_max)
5649 				iso9660->dircnt_max = vp->file->dircnt;
5650 			isoent_add_child_tail(dent, vp);
5651 			np = vp;
5652 
5653 			fn += l;
5654 			if (fn[0] == '/')
5655 				fn++;
5656 			l = get_path_component(name, sizeof(name), fn);
5657 			if (l < 0) {
5658 				archive_string_free(&as);
5659 				archive_set_error(&a->archive,
5660 				    ARCHIVE_ERRNO_MISC,
5661 				    "A name buffer is too small");
5662 				_isoent_free(isoent);
5663 				*isoentpp = NULL;
5664 				return (ARCHIVE_FATAL);
5665 			}
5666 			dent = np;
5667 		}
5668 
5669 		/* Found out the parent directory where isoent can be
5670 		 * inserted. */
5671 		iso9660->cur_dirent = dent;
5672 		archive_string_empty(&(iso9660->cur_dirstr));
5673 		archive_string_ensure(&(iso9660->cur_dirstr),
5674 		    archive_strlen(&(dent->file->parentdir)) +
5675 		    archive_strlen(&(dent->file->basename)) + 2);
5676 		if (archive_strlen(&(dent->file->parentdir)) +
5677 		    archive_strlen(&(dent->file->basename)) == 0)
5678 			iso9660->cur_dirstr.s[0] = 0;
5679 		else {
5680 			if (archive_strlen(&(dent->file->parentdir)) > 0) {
5681 				archive_string_copy(&(iso9660->cur_dirstr),
5682 				    &(dent->file->parentdir));
5683 				archive_strappend_char(&(iso9660->cur_dirstr), '/');
5684 			}
5685 			archive_string_concat(&(iso9660->cur_dirstr),
5686 			    &(dent->file->basename));
5687 		}
5688 
5689 		if (!isoent_add_child_tail(dent, isoent)) {
5690 			np = (struct isoent *)__archive_rb_tree_find_node(
5691 			    &(dent->rbtree), isoent->file->basename.s);
5692 			goto same_entry;
5693 		}
5694 		return (ARCHIVE_OK);
5695 	}
5696 
5697 same_entry:
5698 	/*
5699 	 * We have already has the entry the filename of which is
5700 	 * the same.
5701 	 */
5702 	f1 = np->file;
5703 	f2 = isoent->file;
5704 
5705 	/* If the file type of entries is different,
5706 	 * we cannot handle it. */
5707 	if (archive_entry_filetype(f1->entry) !=
5708 	    archive_entry_filetype(f2->entry)) {
5709 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
5710 		    "Found duplicate entries `%s' and its file type is "
5711 		    "different",
5712 		    archive_entry_pathname(f1->entry));
5713 		_isoent_free(isoent);
5714 		*isoentpp = NULL;
5715 		return (ARCHIVE_FAILED);
5716 	}
5717 
5718 	/* Swap file entries. */
5719 	np->file = f2;
5720 	isoent->file = f1;
5721 	np->virtual = 0;
5722 
5723 	_isoent_free(isoent);
5724 	*isoentpp = np;
5725 	return (ARCHIVE_OK);
5726 }
5727 
5728 /*
5729  * Find a entry from `isoent'
5730  */
5731 static struct isoent *
5732 isoent_find_child(struct isoent *isoent, const char *child_name)
5733 {
5734 	struct isoent *np;
5735 
5736 	np = (struct isoent *)__archive_rb_tree_find_node(
5737 	    &(isoent->rbtree), child_name);
5738 	return (np);
5739 }
5740 
5741 /*
5742  * Find a entry full-path of which is specified by `fn' parameter,
5743  * in the tree.
5744  */
5745 static struct isoent *
5746 isoent_find_entry(struct isoent *rootent, const char *fn)
5747 {
5748 #if defined(_WIN32) && !defined(__CYGWIN__)
5749 	char name[_MAX_FNAME];/* Included null terminator size. */
5750 #elif defined(NAME_MAX) && NAME_MAX >= 255
5751 	char name[NAME_MAX+1];
5752 #else
5753 	char name[256];
5754 #endif
5755 	struct isoent *isoent, *np;
5756 	int l;
5757 
5758 	isoent = rootent;
5759 	np = NULL;
5760 	for (;;) {
5761 		l = get_path_component(name, sizeof(name), fn);
5762 		if (l == 0)
5763 			break;
5764 		fn += l;
5765 		if (fn[0] == '/')
5766 			fn++;
5767 
5768 		np = isoent_find_child(isoent, name);
5769 		if (np == NULL)
5770 			break;
5771 		if (fn[0] == '\0')
5772 			break;/* We found out the entry */
5773 
5774 		/* Try sub directory. */
5775 		isoent = np;
5776 		np = NULL;
5777 		if (!isoent->dir)
5778 			break;/* Not directory */
5779 	}
5780 
5781 	return (np);
5782 }
5783 
5784 /*
5785  * Following idr_* functions are used for resolving duplicated filenames
5786  * and unreceivable filenames to generate ISO9660/Joliet Identifiers.
5787  */
5788 
5789 static void
5790 idr_relaxed_filenames(char *map)
5791 {
5792 	int i;
5793 
5794 	for (i = 0x21; i <= 0x2F; i++)
5795 		map[i] = 1;
5796 	for (i = 0x3A; i <= 0x41; i++)
5797 		map[i] = 1;
5798 	for (i = 0x5B; i <= 0x5E; i++)
5799 		map[i] = 1;
5800 	map[0x60] = 1;
5801 	for (i = 0x7B; i <= 0x7E; i++)
5802 		map[i] = 1;
5803 }
5804 
5805 static void
5806 idr_init(struct iso9660 *iso9660, struct vdd *vdd, struct idr *idr)
5807 {
5808 
5809 	idr->idrent_pool = NULL;
5810 	idr->pool_size = 0;
5811 	if (vdd->vdd_type != VDD_JOLIET) {
5812 		if (iso9660->opt.iso_level <= 3) {
5813 			memcpy(idr->char_map, d_characters_map,
5814 			    sizeof(idr->char_map));
5815 		} else {
5816 			memcpy(idr->char_map, d1_characters_map,
5817 			    sizeof(idr->char_map));
5818 			idr_relaxed_filenames(idr->char_map);
5819 		}
5820 	}
5821 }
5822 
5823 static void
5824 idr_cleanup(struct idr *idr)
5825 {
5826 	free(idr->idrent_pool);
5827 }
5828 
5829 static int
5830 idr_ensure_poolsize(struct archive_write *a, struct idr *idr,
5831     int cnt)
5832 {
5833 
5834 	if (idr->pool_size < cnt) {
5835 		void *p;
5836 		const int bk = (1 << 7) - 1;
5837 		int psize;
5838 
5839 		psize = (cnt + bk) & ~bk;
5840 		p = realloc(idr->idrent_pool, sizeof(struct idrent) * psize);
5841 		if (p == NULL) {
5842 			archive_set_error(&a->archive, ENOMEM,
5843 			    "Can't allocate memory");
5844 			return (ARCHIVE_FATAL);
5845 		}
5846 		idr->idrent_pool = (struct idrent *)p;
5847 		idr->pool_size = psize;
5848 	}
5849 	return (ARCHIVE_OK);
5850 }
5851 
5852 static int
5853 idr_start(struct archive_write *a, struct idr *idr, int cnt, int ffmax,
5854     int num_size, int null_size, const struct archive_rb_tree_ops *rbt_ops)
5855 {
5856 	int r;
5857 
5858 	(void)ffmax; /* UNUSED */
5859 
5860 	r = idr_ensure_poolsize(a, idr, cnt);
5861 	if (r != ARCHIVE_OK)
5862 		return (r);
5863 	__archive_rb_tree_init(&(idr->rbtree), rbt_ops);
5864 	idr->wait_list.first = NULL;
5865 	idr->wait_list.last = &(idr->wait_list.first);
5866 	idr->pool_idx = 0;
5867 	idr->num_size = num_size;
5868 	idr->null_size = null_size;
5869 	return (ARCHIVE_OK);
5870 }
5871 
5872 static void
5873 idr_register(struct idr *idr, struct isoent *isoent, int weight, int noff)
5874 {
5875 	struct idrent *idrent, *n;
5876 
5877 	idrent = &(idr->idrent_pool[idr->pool_idx++]);
5878 	idrent->wnext = idrent->avail = NULL;
5879 	idrent->isoent = isoent;
5880 	idrent->weight = weight;
5881 	idrent->noff = noff;
5882 	idrent->rename_num = 0;
5883 
5884 	if (!__archive_rb_tree_insert_node(&(idr->rbtree), &(idrent->rbnode))) {
5885 		n = (struct idrent *)__archive_rb_tree_find_node(
5886 		    &(idr->rbtree), idrent->isoent);
5887 		if (n != NULL) {
5888 			/* this `idrent' needs to rename. */
5889 			idrent->avail = n;
5890 			*idr->wait_list.last = idrent;
5891 			idr->wait_list.last = &(idrent->wnext);
5892 		}
5893 	}
5894 }
5895 
5896 static void
5897 idr_extend_identifier(struct idrent *wnp, int numsize, int nullsize)
5898 {
5899 	unsigned char *p;
5900 	int wnp_ext_off;
5901 
5902 	wnp_ext_off = wnp->isoent->ext_off;
5903 	if (wnp->noff + numsize != wnp_ext_off) {
5904 		p = (unsigned char *)wnp->isoent->identifier;
5905 		/* Extend the filename; foo.c --> foo___.c */
5906 		memmove(p + wnp->noff + numsize, p + wnp_ext_off,
5907 		    wnp->isoent->ext_len + nullsize);
5908 		wnp->isoent->ext_off = wnp_ext_off = wnp->noff + numsize;
5909 		wnp->isoent->id_len = wnp_ext_off + wnp->isoent->ext_len;
5910 	}
5911 }
5912 
5913 static void
5914 idr_resolve(struct idr *idr, void (*fsetnum)(unsigned char *p, int num))
5915 {
5916 	struct idrent *n;
5917 	unsigned char *p;
5918 
5919 	for (n = idr->wait_list.first; n != NULL; n = n->wnext) {
5920 		idr_extend_identifier(n, idr->num_size, idr->null_size);
5921 		p = (unsigned char *)n->isoent->identifier + n->noff;
5922 		do {
5923 			fsetnum(p, n->avail->rename_num++);
5924 		} while (!__archive_rb_tree_insert_node(
5925 		    &(idr->rbtree), &(n->rbnode)));
5926 	}
5927 }
5928 
5929 static void
5930 idr_set_num(unsigned char *p, int num)
5931 {
5932 	static const char xdig[] = {
5933 		'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
5934 		'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
5935 		'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
5936 		'U', 'V', 'W', 'X', 'Y', 'Z'
5937 	};
5938 
5939 	num %= sizeof(xdig) * sizeof(xdig) * sizeof(xdig);
5940 	p[0] = xdig[(num / (sizeof(xdig) * sizeof(xdig)))];
5941 	num %= sizeof(xdig) * sizeof(xdig);
5942 	p[1] = xdig[ (num / sizeof(xdig))];
5943 	num %= sizeof(xdig);
5944 	p[2] = xdig[num];
5945 }
5946 
5947 static void
5948 idr_set_num_beutf16(unsigned char *p, int num)
5949 {
5950 	static const uint16_t xdig[] = {
5951 		0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
5952 		0x0036, 0x0037, 0x0038, 0x0039,
5953 		0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046,
5954 		0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C,
5955 		0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052,
5956 		0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
5957 		0x0059, 0x005A
5958 	};
5959 #define XDIG_CNT	(sizeof(xdig)/sizeof(xdig[0]))
5960 
5961 	num %= XDIG_CNT * XDIG_CNT * XDIG_CNT;
5962 	archive_be16enc(p, xdig[(num / (XDIG_CNT * XDIG_CNT))]);
5963 	num %= XDIG_CNT * XDIG_CNT;
5964 	archive_be16enc(p+2, xdig[ (num / XDIG_CNT)]);
5965 	num %= XDIG_CNT;
5966 	archive_be16enc(p+4, xdig[num]);
5967 }
5968 
5969 /*
5970  * Generate ISO9660 Identifier.
5971  */
5972 static int
5973 isoent_gen_iso9660_identifier(struct archive_write *a, struct isoent *isoent,
5974     struct idr *idr)
5975 {
5976 	struct iso9660 *iso9660;
5977 	struct isoent *np;
5978 	char *p;
5979 	int l, r;
5980 	const char *char_map;
5981 	char allow_ldots, allow_multidot, allow_period, allow_vernum;
5982 	int fnmax, ffmax, dnmax;
5983 	static const struct archive_rb_tree_ops rb_ops = {
5984 		isoent_cmp_node_iso9660, isoent_cmp_key_iso9660
5985 	};
5986 
5987 	if (isoent->children.cnt == 0)
5988 		return (0);
5989 
5990 	iso9660 = a->format_data;
5991 	char_map = idr->char_map;
5992 	if (iso9660->opt.iso_level <= 3) {
5993 		allow_ldots = 0;
5994 		allow_multidot = 0;
5995 		allow_period = 1;
5996 		allow_vernum = iso9660->opt.allow_vernum;
5997 		if (iso9660->opt.iso_level == 1) {
5998 			fnmax = 8;
5999 			ffmax = 12;/* fnmax + '.' + 3 */
6000 			dnmax = 8;
6001 		} else {
6002 			fnmax = 30;
6003 			ffmax = 31;
6004 			dnmax = 31;
6005 		}
6006 	} else {
6007 		allow_ldots = allow_multidot = 1;
6008 		allow_period = allow_vernum = 0;
6009 		if (iso9660->opt.rr)
6010 			/*
6011 			 * MDR : The maximum size of Directory Record(254).
6012 			 * DRL : A Directory Record Length(33).
6013 			 * CE  : A size of SUSP CE System Use Entry(28).
6014 			 * MDR - DRL - CE = 254 - 33 - 28 = 193.
6015 			 */
6016 			fnmax = ffmax = dnmax = 193;
6017 		else
6018 			/*
6019 			 * XA  : CD-ROM XA System Use Extension
6020 			 *       Information(14).
6021 			 * MDR - DRL - XA = 254 - 33 -14 = 207.
6022 			 */
6023 			fnmax = ffmax = dnmax = 207;
6024 	}
6025 
6026 	r = idr_start(a, idr, isoent->children.cnt, ffmax, 3, 1, &rb_ops);
6027 	if (r < 0)
6028 		return (r);
6029 
6030 	for (np = isoent->children.first; np != NULL; np = np->chnext) {
6031 		char *dot, *xdot;
6032 		int ext_off, noff, weight;
6033 
6034 		l = (int)np->file->basename.length;
6035 		p = malloc(l+31+2+1);
6036 		if (p == NULL) {
6037 			archive_set_error(&a->archive, ENOMEM,
6038 			    "Can't allocate memory");
6039 			return (ARCHIVE_FATAL);
6040 		}
6041 		memcpy(p, np->file->basename.s, l);
6042 		p[l] = '\0';
6043 		np->identifier = p;
6044 
6045 		dot = xdot = NULL;
6046 		if (!allow_ldots) {
6047 			/*
6048 			 * If there is a '.' character at the first byte,
6049 			 * it has to be replaced by '_' character.
6050 			 */
6051 			if (*p == '.')
6052 				*p++ = '_';
6053 		}
6054 		for (;*p; p++) {
6055 			if (*p & 0x80) {
6056 				*p = '_';
6057 				continue;
6058 			}
6059 			if (char_map[(unsigned char)*p]) {
6060 				/* if iso-level is '4', a character '.' is
6061 				 * allowed by char_map. */
6062 				if (*p == '.') {
6063 					xdot = dot;
6064 					dot = p;
6065 				}
6066 				continue;
6067 			}
6068 			if (*p >= 'a' && *p <= 'z') {
6069 				*p -= 'a' - 'A';
6070 				continue;
6071 			}
6072 			if (*p == '.') {
6073 				xdot = dot;
6074 				dot = p;
6075 				if (allow_multidot)
6076 					continue;
6077 			}
6078 			*p = '_';
6079 		}
6080 		p = np->identifier;
6081 		weight = -1;
6082 		if (dot == NULL) {
6083 			int nammax;
6084 
6085 			if (np->dir)
6086 				nammax = dnmax;
6087 			else
6088 				nammax = fnmax;
6089 
6090 			if (l > nammax) {
6091 				p[nammax] = '\0';
6092 				weight = nammax;
6093 				ext_off = nammax;
6094 			} else
6095 				ext_off = l;
6096 		} else {
6097 			*dot = '.';
6098 			ext_off = (int)(dot - p);
6099 
6100 			if (iso9660->opt.iso_level == 1) {
6101 				if (dot - p <= 8) {
6102 					if (strlen(dot) > 4) {
6103 						/* A length of a file extension
6104 						 * must be less than 4 */
6105 						dot[4] = '\0';
6106 						weight = 0;
6107 					}
6108 				} else {
6109 					p[8] = dot[0];
6110 					p[9] = dot[1];
6111 					p[10] = dot[2];
6112 					p[11] = dot[3];
6113 					p[12] = '\0';
6114 					weight = 8;
6115 					ext_off = 8;
6116 				}
6117 			} else if (np->dir) {
6118 				if (l > dnmax) {
6119 					p[dnmax] = '\0';
6120 					weight = dnmax;
6121 					if (ext_off > dnmax)
6122 						ext_off = dnmax;
6123 				}
6124 			} else if (l > ffmax) {
6125 				int extlen = (int)strlen(dot);
6126 				int xdoff;
6127 
6128 				if (xdot != NULL)
6129 					xdoff = (int)(xdot - p);
6130 				else
6131 					xdoff = 0;
6132 
6133 				if (extlen > 1 && xdoff < fnmax-1) {
6134 					int off;
6135 
6136 					if (extlen > ffmax)
6137 						extlen = ffmax;
6138 					off = ffmax - extlen;
6139 					if (off == 0) {
6140 						/* A dot('.')  character
6141 						 * doesn't place to the first
6142 						 * byte of identifier. */
6143 						off ++;
6144 						extlen --;
6145 					}
6146 					memmove(p+off, dot, extlen);
6147 					p[ffmax] = '\0';
6148 					ext_off = off;
6149 					weight = off;
6150 #ifdef COMPAT_MKISOFS
6151 				} else if (xdoff >= fnmax-1) {
6152 					/* Simulate a bug(?) of mkisofs. */
6153 					p[fnmax-1] = '\0';
6154 					ext_off = fnmax-1;
6155 					weight = fnmax-1;
6156 #endif
6157 				} else {
6158 					p[fnmax] = '\0';
6159 					ext_off = fnmax;
6160 					weight = fnmax;
6161 				}
6162 			}
6163 		}
6164 		/* Save an offset of a file name extension to sort files. */
6165 		np->ext_off = ext_off;
6166 		np->ext_len = (int)strlen(&p[ext_off]);
6167 		np->id_len = l = ext_off + np->ext_len;
6168 
6169 		/* Make an offset of the number which is used to be set
6170 		 * hexadecimal number to avoid duplicate identifier. */
6171 		if (iso9660->opt.iso_level == 1) {
6172 			if (ext_off >= 5)
6173 				noff = 5;
6174 			else
6175 				noff = ext_off;
6176 		} else {
6177 			if (l == ffmax)
6178 				noff = ext_off - 3;
6179 			else if (l == ffmax-1)
6180 				noff = ext_off - 2;
6181 			else if (l == ffmax-2)
6182 				noff = ext_off - 1;
6183 			else
6184 				noff = ext_off;
6185 		}
6186 		/* Register entry to the identifier resolver. */
6187 		idr_register(idr, np, weight, noff);
6188 	}
6189 
6190 	/* Resolve duplicate identifier. */
6191 	idr_resolve(idr, idr_set_num);
6192 
6193 	/* Add a period and a version number to identifiers. */
6194 	for (np = isoent->children.first; np != NULL; np = np->chnext) {
6195 		if (!np->dir && np->rr_child == NULL) {
6196 			p = np->identifier + np->ext_off + np->ext_len;
6197 			if (np->ext_len == 0 && allow_period) {
6198 				*p++ = '.';
6199 				np->ext_len = 1;
6200 			}
6201 			if (np->ext_len == 1 && !allow_period) {
6202 				*--p = '\0';
6203 				np->ext_len = 0;
6204 			}
6205 			np->id_len = np->ext_off + np->ext_len;
6206 			if (allow_vernum) {
6207 				*p++ = ';';
6208 				*p++ = '1';
6209 				np->id_len += 2;
6210 			}
6211 			*p = '\0';
6212 		} else
6213 			np->id_len = np->ext_off + np->ext_len;
6214 		np->mb_len = np->id_len;
6215 	}
6216 	return (ARCHIVE_OK);
6217 }
6218 
6219 /*
6220  * Generate Joliet Identifier.
6221  */
6222 static int
6223 isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
6224     struct idr *idr)
6225 {
6226 	struct iso9660 *iso9660;
6227 	struct isoent *np;
6228 	unsigned char *p;
6229 	size_t l;
6230 	int r;
6231 	size_t ffmax, parent_len;
6232 	static const struct archive_rb_tree_ops rb_ops = {
6233 		isoent_cmp_node_joliet, isoent_cmp_key_joliet
6234 	};
6235 
6236 	if (isoent->children.cnt == 0)
6237 		return (0);
6238 
6239 	iso9660 = a->format_data;
6240 	if (iso9660->opt.joliet == OPT_JOLIET_LONGNAME)
6241 		ffmax = 206;
6242 	else
6243 		ffmax = 128;
6244 
6245 	r = idr_start(a, idr, isoent->children.cnt, (int)ffmax, 6, 2, &rb_ops);
6246 	if (r < 0)
6247 		return (r);
6248 
6249 	parent_len = 1;
6250 	for (np = isoent; np->parent != np; np = np->parent)
6251 		parent_len += np->mb_len + 1;
6252 
6253 	for (np = isoent->children.first; np != NULL; np = np->chnext) {
6254 		unsigned char *dot;
6255 		int ext_off, noff, weight;
6256 		size_t lt;
6257 
6258 		if ((l = np->file->basename_utf16.length) > ffmax)
6259 			l = ffmax;
6260 
6261 		p = malloc((l+1)*2);
6262 		if (p == NULL) {
6263 			archive_set_error(&a->archive, ENOMEM,
6264 			    "Can't allocate memory");
6265 			return (ARCHIVE_FATAL);
6266 		}
6267 		memcpy(p, np->file->basename_utf16.s, l);
6268 		p[l] = 0;
6269 		p[l+1] = 0;
6270 
6271 		np->identifier = (char *)p;
6272 		lt = l;
6273 		dot = p + l;
6274 		weight = 0;
6275 		while (lt > 0) {
6276 			if (!joliet_allowed_char(p[0], p[1]))
6277 				archive_be16enc(p, 0x005F); /* '_' */
6278 			else if (p[0] == 0 && p[1] == 0x2E) /* '.' */
6279 				dot = p;
6280 			p += 2;
6281 			lt -= 2;
6282 		}
6283 		ext_off = (int)(dot - (unsigned char *)np->identifier);
6284 		np->ext_off = ext_off;
6285 		np->ext_len = (int)l - ext_off;
6286 		np->id_len = (int)l;
6287 
6288 		/*
6289 		 * Get a length of MBS of a full-pathname.
6290 		 */
6291 		if (np->file->basename_utf16.length > ffmax) {
6292 			if (archive_strncpy_l(&iso9660->mbs,
6293 			    (const char *)np->identifier, l,
6294 				iso9660->sconv_from_utf16be) != 0 &&
6295 			    errno == ENOMEM) {
6296 				archive_set_error(&a->archive, errno,
6297 				    "No memory");
6298 				return (ARCHIVE_FATAL);
6299 			}
6300 			np->mb_len = (int)iso9660->mbs.length;
6301 			if (np->mb_len != (int)np->file->basename.length)
6302 				weight = np->mb_len;
6303 		} else
6304 			np->mb_len = (int)np->file->basename.length;
6305 
6306 		/* If a length of full-pathname is longer than 240 bytes,
6307 		 * it violates Joliet extensions regulation. */
6308 		if (parent_len > 240
6309 		    || np->mb_len > 240
6310 		    || parent_len + np->mb_len > 240) {
6311 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
6312 			    "The regulation of Joliet extensions;"
6313 			    " A length of a full-pathname of `%s' is "
6314 			    "longer than 240 bytes, (p=%d, b=%d)",
6315 			    archive_entry_pathname(np->file->entry),
6316 			    (int)parent_len, (int)np->mb_len);
6317 			return (ARCHIVE_FATAL);
6318 		}
6319 
6320 		/* Make an offset of the number which is used to be set
6321 		 * hexadecimal number to avoid duplicate identifier. */
6322 		if (l == ffmax)
6323 			noff = ext_off - 6;
6324 		else if (l == ffmax-2)
6325 			noff = ext_off - 4;
6326 		else if (l == ffmax-4)
6327 			noff = ext_off - 2;
6328 		else
6329 			noff = ext_off;
6330 		/* Register entry to the identifier resolver. */
6331 		idr_register(idr, np, weight, noff);
6332 	}
6333 
6334 	/* Resolve duplicate identifier with Joliet Volume. */
6335 	idr_resolve(idr, idr_set_num_beutf16);
6336 
6337 	return (ARCHIVE_OK);
6338 }
6339 
6340 /*
6341  * This comparing rule is according to ISO9660 Standard 9.3
6342  */
6343 static int
6344 isoent_cmp_iso9660_identifier(const struct isoent *p1, const struct isoent *p2)
6345 {
6346 	const char *s1, *s2;
6347 	int cmp;
6348 	int l;
6349 
6350 	s1 = p1->identifier;
6351 	s2 = p2->identifier;
6352 
6353 	/* Compare File Name */
6354 	l = p1->ext_off;
6355 	if (l > p2->ext_off)
6356 		l = p2->ext_off;
6357 	cmp = memcmp(s1, s2, l);
6358 	if (cmp != 0)
6359 		return (cmp);
6360 	if (p1->ext_off < p2->ext_off) {
6361 		s2 += l;
6362 		l = p2->ext_off - p1->ext_off;
6363 		while (l--)
6364 			if (0x20 != *s2++)
6365 				return (0x20
6366 				    - *(const unsigned char *)(s2 - 1));
6367 	} else if (p1->ext_off > p2->ext_off) {
6368 		s1 += l;
6369 		l = p1->ext_off - p2->ext_off;
6370 		while (l--)
6371 			if (0x20 != *s1++)
6372 				return (*(const unsigned char *)(s1 - 1)
6373 				    - 0x20);
6374 	}
6375 	/* Compare File Name Extension */
6376 	if (p1->ext_len == 0 && p2->ext_len == 0)
6377 		return (0);
6378 	if (p1->ext_len == 1 && p2->ext_len == 1)
6379 		return (0);
6380 	if (p1->ext_len <= 1)
6381 		return (-1);
6382 	if (p2->ext_len <= 1)
6383 		return (1);
6384 	l = p1->ext_len;
6385 	if (l > p2->ext_len)
6386 		l = p2->ext_len;
6387 	s1 = p1->identifier + p1->ext_off;
6388 	s2 = p2->identifier + p2->ext_off;
6389 	if (l > 1) {
6390 		cmp = memcmp(s1, s2, l);
6391 		if (cmp != 0)
6392 			return (cmp);
6393 	}
6394 	if (p1->ext_len < p2->ext_len) {
6395 		s2 += l;
6396 		l = p2->ext_len - p1->ext_len;
6397 		while (l--)
6398 			if (0x20 != *s2++)
6399 				return (0x20
6400 				    - *(const unsigned char *)(s2 - 1));
6401 	} else if (p1->ext_len > p2->ext_len) {
6402 		s1 += l;
6403 		l = p1->ext_len - p2->ext_len;
6404 		while (l--)
6405 			if (0x20 != *s1++)
6406 				return (*(const unsigned char *)(s1 - 1)
6407 				    - 0x20);
6408 	}
6409 	/* Compare File Version Number */
6410 	/* No operation. The File Version Number is always one. */
6411 
6412 	return (cmp);
6413 }
6414 
6415 static int
6416 isoent_cmp_node_iso9660(const struct archive_rb_node *n1,
6417     const struct archive_rb_node *n2)
6418 {
6419 	const struct idrent *e1 = (const struct idrent *)n1;
6420 	const struct idrent *e2 = (const struct idrent *)n2;
6421 
6422 	return (isoent_cmp_iso9660_identifier(e2->isoent, e1->isoent));
6423 }
6424 
6425 static int
6426 isoent_cmp_key_iso9660(const struct archive_rb_node *node, const void *key)
6427 {
6428 	const struct isoent *isoent = (const struct isoent *)key;
6429 	const struct idrent *idrent = (const struct idrent *)node;
6430 
6431 	return (isoent_cmp_iso9660_identifier(isoent, idrent->isoent));
6432 }
6433 
6434 static int
6435 isoent_cmp_joliet_identifier(const struct isoent *p1, const struct isoent *p2)
6436 {
6437 	const unsigned char *s1, *s2;
6438 	int cmp;
6439 	int l;
6440 
6441 	s1 = (const unsigned char *)p1->identifier;
6442 	s2 = (const unsigned char *)p2->identifier;
6443 
6444 	/* Compare File Name */
6445 	l = p1->ext_off;
6446 	if (l > p2->ext_off)
6447 		l = p2->ext_off;
6448 	cmp = memcmp(s1, s2, l);
6449 	if (cmp != 0)
6450 		return (cmp);
6451 	if (p1->ext_off < p2->ext_off) {
6452 		s2 += l;
6453 		l = p2->ext_off - p1->ext_off;
6454 		while (l--)
6455 			if (0 != *s2++)
6456 				return (- *(const unsigned char *)(s2 - 1));
6457 	} else if (p1->ext_off > p2->ext_off) {
6458 		s1 += l;
6459 		l = p1->ext_off - p2->ext_off;
6460 		while (l--)
6461 			if (0 != *s1++)
6462 				return (*(const unsigned char *)(s1 - 1));
6463 	}
6464 	/* Compare File Name Extension */
6465 	if (p1->ext_len == 0 && p2->ext_len == 0)
6466 		return (0);
6467 	if (p1->ext_len == 2 && p2->ext_len == 2)
6468 		return (0);
6469 	if (p1->ext_len <= 2)
6470 		return (-1);
6471 	if (p2->ext_len <= 2)
6472 		return (1);
6473 	l = p1->ext_len;
6474 	if (l > p2->ext_len)
6475 		l = p2->ext_len;
6476 	s1 = (unsigned char *)(p1->identifier + p1->ext_off);
6477 	s2 = (unsigned char *)(p2->identifier + p2->ext_off);
6478 	if (l > 1) {
6479 		cmp = memcmp(s1, s2, l);
6480 		if (cmp != 0)
6481 			return (cmp);
6482 	}
6483 	if (p1->ext_len < p2->ext_len) {
6484 		s2 += l;
6485 		l = p2->ext_len - p1->ext_len;
6486 		while (l--)
6487 			if (0 != *s2++)
6488 				return (- *(const unsigned char *)(s2 - 1));
6489 	} else if (p1->ext_len > p2->ext_len) {
6490 		s1 += l;
6491 		l = p1->ext_len - p2->ext_len;
6492 		while (l--)
6493 			if (0 != *s1++)
6494 				return (*(const unsigned char *)(s1 - 1));
6495 	}
6496 	/* Compare File Version Number */
6497 	/* No operation. The File Version Number is always one. */
6498 
6499 	return (cmp);
6500 }
6501 
6502 static int
6503 isoent_cmp_node_joliet(const struct archive_rb_node *n1,
6504     const struct archive_rb_node *n2)
6505 {
6506 	const struct idrent *e1 = (const struct idrent *)n1;
6507 	const struct idrent *e2 = (const struct idrent *)n2;
6508 
6509 	return (isoent_cmp_joliet_identifier(e2->isoent, e1->isoent));
6510 }
6511 
6512 static int
6513 isoent_cmp_key_joliet(const struct archive_rb_node *node, const void *key)
6514 {
6515 	const struct isoent *isoent = (const struct isoent *)key;
6516 	const struct idrent *idrent = (const struct idrent *)node;
6517 
6518 	return (isoent_cmp_joliet_identifier(isoent, idrent->isoent));
6519 }
6520 
6521 static int
6522 isoent_make_sorted_files(struct archive_write *a, struct isoent *isoent,
6523     struct idr *idr)
6524 {
6525 	struct archive_rb_node *rn;
6526 	struct isoent **children;
6527 
6528 	children = malloc(isoent->children.cnt * sizeof(struct isoent *));
6529 	if (children == NULL) {
6530 		archive_set_error(&a->archive, ENOMEM,
6531 		    "Can't allocate memory");
6532 		return (ARCHIVE_FATAL);
6533 	}
6534 	isoent->children_sorted = children;
6535 
6536 	ARCHIVE_RB_TREE_FOREACH(rn, &(idr->rbtree)) {
6537 		struct idrent *idrent = (struct idrent *)rn;
6538 		*children ++ = idrent->isoent;
6539 	}
6540 	return (ARCHIVE_OK);
6541 }
6542 
6543 /*
6544  * - Generate ISO9660 and Joliet identifiers from basenames.
6545  * - Sort files by each directory.
6546  */
6547 static int
6548 isoent_traverse_tree(struct archive_write *a, struct vdd* vdd)
6549 {
6550 	struct iso9660 *iso9660 = a->format_data;
6551 	struct isoent *np;
6552 	struct idr idr;
6553 	int depth;
6554 	int r;
6555 	int (*genid)(struct archive_write *, struct isoent *, struct idr *);
6556 
6557 	idr_init(iso9660, vdd, &idr);
6558 	np = vdd->rootent;
6559 	depth = 0;
6560 	if (vdd->vdd_type == VDD_JOLIET)
6561 		genid = isoent_gen_joliet_identifier;
6562 	else
6563 		genid = isoent_gen_iso9660_identifier;
6564 	do {
6565 		if (np->virtual &&
6566 		    !archive_entry_mtime_is_set(np->file->entry)) {
6567 			/* Set properly times to virtual directory */
6568 			archive_entry_set_mtime(np->file->entry,
6569 			    iso9660->birth_time, 0);
6570 			archive_entry_set_atime(np->file->entry,
6571 			    iso9660->birth_time, 0);
6572 			archive_entry_set_ctime(np->file->entry,
6573 			    iso9660->birth_time, 0);
6574 		}
6575 		if (np->children.first != NULL) {
6576 			if (vdd->vdd_type != VDD_JOLIET &&
6577 			    !iso9660->opt.rr && depth + 1 >= vdd->max_depth) {
6578 				if (np->children.cnt > 0)
6579 					iso9660->directories_too_deep = np;
6580 			} else {
6581 				/* Generate Identifier */
6582 				r = genid(a, np, &idr);
6583 				if (r < 0)
6584 					goto exit_traverse_tree;
6585 				r = isoent_make_sorted_files(a, np, &idr);
6586 				if (r < 0)
6587 					goto exit_traverse_tree;
6588 
6589 				if (np->subdirs.first != NULL &&
6590 				    depth + 1 < vdd->max_depth) {
6591 					/* Enter to sub directories. */
6592 					np = np->subdirs.first;
6593 					depth++;
6594 					continue;
6595 				}
6596 			}
6597 		}
6598 		while (np != np->parent) {
6599 			if (np->drnext == NULL) {
6600 				/* Return to the parent directory. */
6601 				np = np->parent;
6602 				depth--;
6603 			} else {
6604 				np = np->drnext;
6605 				break;
6606 			}
6607 		}
6608 	} while (np != np->parent);
6609 
6610 	r = ARCHIVE_OK;
6611 exit_traverse_tree:
6612 	idr_cleanup(&idr);
6613 
6614 	return (r);
6615 }
6616 
6617 /*
6618  * Collect directory entries into path_table by a directory depth.
6619  */
6620 static int
6621 isoent_collect_dirs(struct vdd *vdd, struct isoent *rootent, int depth)
6622 {
6623 	struct isoent *np;
6624 
6625 	if (rootent == NULL)
6626 		rootent = vdd->rootent;
6627 	np = rootent;
6628 	do {
6629 		/* Register current directory to pathtable. */
6630 		path_table_add_entry(&(vdd->pathtbl[depth]), np);
6631 
6632 		if (np->subdirs.first != NULL && depth + 1 < vdd->max_depth) {
6633 			/* Enter to sub directories. */
6634 			np = np->subdirs.first;
6635 			depth++;
6636 			continue;
6637 		}
6638 		while (np != rootent) {
6639 			if (np->drnext == NULL) {
6640 				/* Return to the parent directory. */
6641 				np = np->parent;
6642 				depth--;
6643 			} else {
6644 				np = np->drnext;
6645 				break;
6646 			}
6647 		}
6648 	} while (np != rootent);
6649 
6650 	return (ARCHIVE_OK);
6651 }
6652 
6653 /*
6654  * The entry whose number of levels in a directory hierarchy is
6655  * large than eight relocate to rr_move directory.
6656  */
6657 static int
6658 isoent_rr_move_dir(struct archive_write *a, struct isoent **rr_moved,
6659     struct isoent *curent, struct isoent **newent)
6660 {
6661 	struct iso9660 *iso9660 = a->format_data;
6662 	struct isoent *rrmoved, *mvent, *np;
6663 
6664 	if ((rrmoved = *rr_moved) == NULL) {
6665 		struct isoent *rootent = iso9660->primary.rootent;
6666 		/* There isn't rr_move entry.
6667 		 * Create rr_move entry and insert it into the root entry.
6668 		 */
6669 		rrmoved = isoent_create_virtual_dir(a, iso9660, "rr_moved");
6670 		if (rrmoved == NULL) {
6671 			archive_set_error(&a->archive, ENOMEM,
6672 			    "Can't allocate memory");
6673 			return (ARCHIVE_FATAL);
6674 		}
6675 		/* Add "rr_moved" entry to the root entry. */
6676 		isoent_add_child_head(rootent, rrmoved);
6677 		archive_entry_set_nlink(rootent->file->entry,
6678 		    archive_entry_nlink(rootent->file->entry) + 1);
6679 		/* Register "rr_moved" entry to second level pathtable. */
6680 		path_table_add_entry(&(iso9660->primary.pathtbl[1]), rrmoved);
6681 		/* Save rr_moved. */
6682 		*rr_moved = rrmoved;
6683 	}
6684 	/*
6685 	 * Make a clone of curent which is going to be relocated
6686 	 * to rr_moved.
6687 	 */
6688 	mvent = isoent_clone(curent);
6689 	if (mvent == NULL) {
6690 		archive_set_error(&a->archive, ENOMEM,
6691 		    "Can't allocate memory");
6692 		return (ARCHIVE_FATAL);
6693 	}
6694 	/* linking..  and use for creating "CL", "PL" and "RE" */
6695 	mvent->rr_parent = curent->parent;
6696 	curent->rr_child = mvent;
6697 	/*
6698 	 * Move subdirectories from the curent to mvent
6699 	 */
6700 	if (curent->children.first != NULL) {
6701 		*mvent->children.last = curent->children.first;
6702 		mvent->children.last = curent->children.last;
6703 	}
6704 	for (np = mvent->children.first; np != NULL; np = np->chnext)
6705 		np->parent = mvent;
6706 	mvent->children.cnt = curent->children.cnt;
6707 	curent->children.cnt = 0;
6708 	curent->children.first = NULL;
6709 	curent->children.last = &curent->children.first;
6710 
6711 	if (curent->subdirs.first != NULL) {
6712 		*mvent->subdirs.last = curent->subdirs.first;
6713 		mvent->subdirs.last = curent->subdirs.last;
6714 	}
6715 	mvent->subdirs.cnt = curent->subdirs.cnt;
6716 	curent->subdirs.cnt = 0;
6717 	curent->subdirs.first = NULL;
6718 	curent->subdirs.last = &curent->subdirs.first;
6719 
6720 	/*
6721 	 * The mvent becomes a child of the rr_moved entry.
6722 	 */
6723 	isoent_add_child_tail(rrmoved, mvent);
6724 	archive_entry_set_nlink(rrmoved->file->entry,
6725 	    archive_entry_nlink(rrmoved->file->entry) + 1);
6726 	/*
6727 	 * This entry which relocated to the rr_moved directory
6728 	 * has to set the flag as a file.
6729 	 * See also RRIP 4.1.5.1 Description of the "CL" System Use Entry.
6730 	 */
6731 	curent->dir = 0;
6732 
6733 	*newent = mvent;
6734 
6735 	return (ARCHIVE_OK);
6736 }
6737 
6738 static int
6739 isoent_rr_move(struct archive_write *a)
6740 {
6741 	struct iso9660 *iso9660 = a->format_data;
6742 	struct path_table *pt;
6743 	struct isoent *rootent, *rr_moved;
6744 	struct isoent *np, *last;
6745 	int r;
6746 
6747 	pt = &(iso9660->primary.pathtbl[MAX_DEPTH-1]);
6748 	/* There aren't level 8 directories reaching a deeper level. */
6749 	if (pt->cnt == 0)
6750 		return (ARCHIVE_OK);
6751 
6752 	rootent = iso9660->primary.rootent;
6753 	/* If "rr_moved" directory is already existing,
6754 	 * we have to use it. */
6755 	rr_moved = isoent_find_child(rootent, "rr_moved");
6756 	if (rr_moved != NULL &&
6757 	    rr_moved != rootent->children.first) {
6758 		/*
6759 		 * It's necessary that rr_move is the first entry
6760 		 * of the root.
6761 		 */
6762 		/* Remove "rr_moved" entry from children chain. */
6763 		isoent_remove_child(rootent, rr_moved);
6764 
6765 		/* Add "rr_moved" entry into the head of children chain. */
6766 		isoent_add_child_head(rootent, rr_moved);
6767 	}
6768 
6769 	/*
6770 	 * Check level 8 path_table.
6771 	 * If find out sub directory entries, that entries move to rr_move.
6772 	 */
6773 	np = pt->first;
6774 	while (np != NULL) {
6775 		last = path_table_last_entry(pt);
6776 		for (; np != NULL; np = np->ptnext) {
6777 			struct isoent *mvent;
6778 			struct isoent *newent;
6779 
6780 			if (!np->dir)
6781 				continue;
6782 			for (mvent = np->subdirs.first;
6783 			    mvent != NULL; mvent = mvent->drnext) {
6784 				r = isoent_rr_move_dir(a, &rr_moved,
6785 				    mvent, &newent);
6786 				if (r < 0)
6787 					return (r);
6788 				isoent_collect_dirs(&(iso9660->primary),
6789 				    newent, 2);
6790 			}
6791 		}
6792 		/* If new entries are added to level 8 path_talbe,
6793 		 * its sub directory entries move to rr_move too.
6794 		 */
6795 		np = last->ptnext;
6796 	}
6797 
6798 	return (ARCHIVE_OK);
6799 }
6800 
6801 /*
6802  * This comparing rule is according to ISO9660 Standard 6.9.1
6803  */
6804 static int
6805 __LA_LIBC_CC
6806 _compare_path_table(const void *v1, const void *v2)
6807 {
6808 	const struct isoent *p1, *p2;
6809 	const char *s1, *s2;
6810 	int cmp, l;
6811 
6812 	p1 = *((const struct isoent **)(uintptr_t)v1);
6813 	p2 = *((const struct isoent **)(uintptr_t)v2);
6814 
6815 	/* Compare parent directory number */
6816 	cmp = p1->parent->dir_number - p2->parent->dir_number;
6817 	if (cmp != 0)
6818 		return (cmp);
6819 
6820 	/* Compare identifier */
6821 	s1 = p1->identifier;
6822 	s2 = p2->identifier;
6823 	l = p1->ext_off;
6824 	if (l > p2->ext_off)
6825 		l = p2->ext_off;
6826 	cmp = strncmp(s1, s2, l);
6827 	if (cmp != 0)
6828 		return (cmp);
6829 	if (p1->ext_off < p2->ext_off) {
6830 		s2 += l;
6831 		l = p2->ext_off - p1->ext_off;
6832 		while (l--)
6833 			if (0x20 != *s2++)
6834 				return (0x20
6835 				    - *(const unsigned char *)(s2 - 1));
6836 	} else if (p1->ext_off > p2->ext_off) {
6837 		s1 += l;
6838 		l = p1->ext_off - p2->ext_off;
6839 		while (l--)
6840 			if (0x20 != *s1++)
6841 				return (*(const unsigned char *)(s1 - 1)
6842 				    - 0x20);
6843 	}
6844 	return (0);
6845 }
6846 
6847 static int
6848 __LA_LIBC_CC
6849 _compare_path_table_joliet(const void *v1, const void *v2)
6850 {
6851 	const struct isoent *p1, *p2;
6852 	const unsigned char *s1, *s2;
6853 	int cmp, l;
6854 
6855 	p1 = *((const struct isoent **)(uintptr_t)v1);
6856 	p2 = *((const struct isoent **)(uintptr_t)v2);
6857 
6858 	/* Compare parent directory number */
6859 	cmp = p1->parent->dir_number - p2->parent->dir_number;
6860 	if (cmp != 0)
6861 		return (cmp);
6862 
6863 	/* Compare identifier */
6864 	s1 = (const unsigned char *)p1->identifier;
6865 	s2 = (const unsigned char *)p2->identifier;
6866 	l = p1->ext_off;
6867 	if (l > p2->ext_off)
6868 		l = p2->ext_off;
6869 	cmp = memcmp(s1, s2, l);
6870 	if (cmp != 0)
6871 		return (cmp);
6872 	if (p1->ext_off < p2->ext_off) {
6873 		s2 += l;
6874 		l = p2->ext_off - p1->ext_off;
6875 		while (l--)
6876 			if (0 != *s2++)
6877 				return (- *(const unsigned char *)(s2 - 1));
6878 	} else if (p1->ext_off > p2->ext_off) {
6879 		s1 += l;
6880 		l = p1->ext_off - p2->ext_off;
6881 		while (l--)
6882 			if (0 != *s1++)
6883 				return (*(const unsigned char *)(s1 - 1));
6884 	}
6885 	return (0);
6886 }
6887 
6888 static inline void
6889 path_table_add_entry(struct path_table *pathtbl, struct isoent *ent)
6890 {
6891 	ent->ptnext = NULL;
6892 	*pathtbl->last = ent;
6893 	pathtbl->last = &(ent->ptnext);
6894 	pathtbl->cnt ++;
6895 }
6896 
6897 static inline struct isoent *
6898 path_table_last_entry(struct path_table *pathtbl)
6899 {
6900 	if (pathtbl->first == NULL)
6901 		return (NULL);
6902 	return (((struct isoent *)(void *)
6903 		((char *)(pathtbl->last) - offsetof(struct isoent, ptnext))));
6904 }
6905 
6906 /*
6907  * Sort directory entries in path_table
6908  * and assign directory number to each entries.
6909  */
6910 static int
6911 isoent_make_path_table_2(struct archive_write *a, struct vdd *vdd,
6912     int depth, int *dir_number)
6913 {
6914 	struct isoent *np;
6915 	struct isoent **enttbl;
6916 	struct path_table *pt;
6917 	int i;
6918 
6919 	pt = &vdd->pathtbl[depth];
6920 	if (pt->cnt == 0) {
6921 		pt->sorted = NULL;
6922 		return (ARCHIVE_OK);
6923 	}
6924 	enttbl = malloc(pt->cnt * sizeof(struct isoent *));
6925 	if (enttbl == NULL) {
6926 		archive_set_error(&a->archive, ENOMEM,
6927 		    "Can't allocate memory");
6928 		return (ARCHIVE_FATAL);
6929 	}
6930 	pt->sorted = enttbl;
6931 	for (np = pt->first; np != NULL; np = np->ptnext)
6932 		*enttbl ++ = np;
6933 	enttbl = pt->sorted;
6934 
6935 	switch (vdd->vdd_type) {
6936 	case VDD_PRIMARY:
6937 	case VDD_ENHANCED:
6938 #ifdef __COMPAR_FN_T
6939 		qsort(enttbl, pt->cnt, sizeof(struct isoent *),
6940 		    (__compar_fn_t)_compare_path_table);
6941 #else
6942 		qsort(enttbl, pt->cnt, sizeof(struct isoent *),
6943 		    _compare_path_table);
6944 #endif
6945 		break;
6946 	case VDD_JOLIET:
6947 #ifdef __COMPAR_FN_T
6948 		qsort(enttbl, pt->cnt, sizeof(struct isoent *),
6949 		    (__compar_fn_t)_compare_path_table_joliet);
6950 #else
6951 		qsort(enttbl, pt->cnt, sizeof(struct isoent *),
6952 		    _compare_path_table_joliet);
6953 #endif
6954 		break;
6955 	}
6956 	for (i = 0; i < pt->cnt; i++)
6957 		enttbl[i]->dir_number = (*dir_number)++;
6958 
6959 	return (ARCHIVE_OK);
6960 }
6961 
6962 static int
6963 isoent_alloc_path_table(struct archive_write *a, struct vdd *vdd,
6964     int max_depth)
6965 {
6966 	int i;
6967 
6968 	vdd->max_depth = max_depth;
6969 	vdd->pathtbl = malloc(sizeof(*vdd->pathtbl) * vdd->max_depth);
6970 	if (vdd->pathtbl == NULL) {
6971 		archive_set_error(&a->archive, ENOMEM,
6972 		    "Can't allocate memory");
6973 		return (ARCHIVE_FATAL);
6974 	}
6975 	for (i = 0; i < vdd->max_depth; i++) {
6976 		vdd->pathtbl[i].first = NULL;
6977 		vdd->pathtbl[i].last = &(vdd->pathtbl[i].first);
6978 		vdd->pathtbl[i].sorted = NULL;
6979 		vdd->pathtbl[i].cnt = 0;
6980 	}
6981 	return (ARCHIVE_OK);
6982 }
6983 
6984 /*
6985  * Make Path Tables
6986  */
6987 static int
6988 isoent_make_path_table(struct archive_write *a)
6989 {
6990 	struct iso9660 *iso9660 = a->format_data;
6991 	int depth, r;
6992 	int dir_number;
6993 
6994 	/*
6995 	 * Init Path Table.
6996 	 */
6997 	if (iso9660->dircnt_max >= MAX_DEPTH &&
6998 	    (!iso9660->opt.limit_depth || iso9660->opt.iso_level == 4))
6999 		r = isoent_alloc_path_table(a, &(iso9660->primary),
7000 		    iso9660->dircnt_max + 1);
7001 	else
7002 		/* The number of levels in the hierarchy cannot exceed
7003 		 * eight. */
7004 		r = isoent_alloc_path_table(a, &(iso9660->primary),
7005 		    MAX_DEPTH);
7006 	if (r < 0)
7007 		return (r);
7008 	if (iso9660->opt.joliet) {
7009 		r = isoent_alloc_path_table(a, &(iso9660->joliet),
7010 		    iso9660->dircnt_max + 1);
7011 		if (r < 0)
7012 			return (r);
7013 	}
7014 
7015 	/* Step 0.
7016 	 * - Collect directories for primary and joliet.
7017 	 */
7018 	isoent_collect_dirs(&(iso9660->primary), NULL, 0);
7019 	if (iso9660->opt.joliet)
7020 		isoent_collect_dirs(&(iso9660->joliet), NULL, 0);
7021 	/*
7022 	 * Rockridge; move deeper depth directories to rr_moved.
7023 	 */
7024 	if (iso9660->opt.rr) {
7025 		r = isoent_rr_move(a);
7026 		if (r < 0)
7027 			return (r);
7028 	}
7029 
7030  	/* Update nlink. */
7031 	isofile_connect_hardlink_files(iso9660);
7032 
7033 	/* Step 1.
7034 	 * - Renew a value of the depth of that directories.
7035 	 * - Resolve hardlinks.
7036  	 * - Convert pathnames to ISO9660 name or UCS2(joliet).
7037 	 * - Sort files by each directory.
7038 	 */
7039 	r = isoent_traverse_tree(a, &(iso9660->primary));
7040 	if (r < 0)
7041 		return (r);
7042 	if (iso9660->opt.joliet) {
7043 		r = isoent_traverse_tree(a, &(iso9660->joliet));
7044 		if (r < 0)
7045 			return (r);
7046 	}
7047 
7048 	/* Step 2.
7049 	 * - Sort directories.
7050 	 * - Assign all directory number.
7051 	 */
7052 	dir_number = 1;
7053 	for (depth = 0; depth < iso9660->primary.max_depth; depth++) {
7054 		r = isoent_make_path_table_2(a, &(iso9660->primary),
7055 		    depth, &dir_number);
7056 		if (r < 0)
7057 			return (r);
7058 	}
7059 	if (iso9660->opt.joliet) {
7060 		dir_number = 1;
7061 		for (depth = 0; depth < iso9660->joliet.max_depth; depth++) {
7062 			r = isoent_make_path_table_2(a, &(iso9660->joliet),
7063 			    depth, &dir_number);
7064 			if (r < 0)
7065 				return (r);
7066 		}
7067 	}
7068 	if (iso9660->opt.limit_dirs && dir_number > 0xffff) {
7069 		/*
7070 		 * Maximum number of directories is 65535(0xffff)
7071 		 * doe to size(16bit) of Parent Directory Number of
7072 		 * the Path Table.
7073 		 * See also ISO9660 Standard 9.4.
7074 		 */
7075 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
7076 		    "Too many directories(%d) over 65535.", dir_number);
7077 		return (ARCHIVE_FATAL);
7078 	}
7079 
7080 	/* Get the size of the Path Table. */
7081 	calculate_path_table_size(&(iso9660->primary));
7082 	if (iso9660->opt.joliet)
7083 		calculate_path_table_size(&(iso9660->joliet));
7084 
7085 	return (ARCHIVE_OK);
7086 }
7087 
7088 static int
7089 isoent_find_out_boot_file(struct archive_write *a, struct isoent *rootent)
7090 {
7091 	struct iso9660 *iso9660 = a->format_data;
7092 
7093 	/* Find a isoent of the boot file. */
7094 	iso9660->el_torito.boot = isoent_find_entry(rootent,
7095 	    iso9660->el_torito.boot_filename.s);
7096 	if (iso9660->el_torito.boot == NULL) {
7097 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
7098 		    "Can't find the boot image file ``%s''",
7099 		    iso9660->el_torito.boot_filename.s);
7100 		return (ARCHIVE_FATAL);
7101 	}
7102 	iso9660->el_torito.boot->file->boot = BOOT_IMAGE;
7103 	return (ARCHIVE_OK);
7104 }
7105 
7106 static int
7107 isoent_create_boot_catalog(struct archive_write *a, struct isoent *rootent)
7108 {
7109 	struct iso9660 *iso9660 = a->format_data;
7110 	struct isofile *file;
7111 	struct isoent *isoent;
7112 	struct archive_entry *entry;
7113 
7114 	(void)rootent; /* UNUSED */
7115 	/*
7116 	 * Create the entry which is the "boot.catalog" file.
7117 	 */
7118 	file = isofile_new(a, NULL);
7119 	if (file == NULL) {
7120 		archive_set_error(&a->archive, ENOMEM,
7121 		    "Can't allocate memory");
7122 		return (ARCHIVE_FATAL);
7123 	}
7124 	archive_entry_set_pathname(file->entry,
7125 	    iso9660->el_torito.catalog_filename.s);
7126 	archive_entry_set_size(file->entry, LOGICAL_BLOCK_SIZE);
7127 	archive_entry_set_mtime(file->entry, iso9660->birth_time, 0);
7128 	archive_entry_set_atime(file->entry, iso9660->birth_time, 0);
7129 	archive_entry_set_ctime(file->entry, iso9660->birth_time, 0);
7130 	archive_entry_set_uid(file->entry, getuid());
7131 	archive_entry_set_gid(file->entry, getgid());
7132 	archive_entry_set_mode(file->entry, AE_IFREG | 0444);
7133 	archive_entry_set_nlink(file->entry, 1);
7134 
7135 	if (isofile_gen_utility_names(a, file) < ARCHIVE_WARN) {
7136 		isofile_free(file);
7137 		return (ARCHIVE_FATAL);
7138 	}
7139 	file->boot = BOOT_CATALOG;
7140 	file->content.size = LOGICAL_BLOCK_SIZE;
7141 	isofile_add_entry(iso9660, file);
7142 
7143 	isoent = isoent_new(file);
7144 	if (isoent == NULL) {
7145 		archive_set_error(&a->archive, ENOMEM,
7146 		    "Can't allocate memory");
7147 		return (ARCHIVE_FATAL);
7148 	}
7149 	isoent->virtual = 1;
7150 
7151 	/* Add the "boot.catalog" entry into tree */
7152 	if (isoent_tree(a, &isoent) != ARCHIVE_OK)
7153 		return (ARCHIVE_FATAL);
7154 
7155 	iso9660->el_torito.catalog = isoent;
7156 	/*
7157 	 * Get a boot media type.
7158 	 */
7159 	switch (iso9660->opt.boot_type) {
7160 	default:
7161 	case OPT_BOOT_TYPE_AUTO:
7162 		/* Try detecting a media type of the boot image. */
7163 		entry = iso9660->el_torito.boot->file->entry;
7164 		if (archive_entry_size(entry) == FD_1_2M_SIZE)
7165 			iso9660->el_torito.media_type =
7166 			    BOOT_MEDIA_1_2M_DISKETTE;
7167 		else if (archive_entry_size(entry) == FD_1_44M_SIZE)
7168 			iso9660->el_torito.media_type =
7169 			    BOOT_MEDIA_1_44M_DISKETTE;
7170 		else if (archive_entry_size(entry) == FD_2_88M_SIZE)
7171 			iso9660->el_torito.media_type =
7172 			    BOOT_MEDIA_2_88M_DISKETTE;
7173 		else
7174 			/* We cannot decide whether the boot image is
7175 			 * hard-disk. */
7176 			iso9660->el_torito.media_type =
7177 			    BOOT_MEDIA_NO_EMULATION;
7178 		break;
7179 	case OPT_BOOT_TYPE_NO_EMU:
7180 		iso9660->el_torito.media_type = BOOT_MEDIA_NO_EMULATION;
7181 		break;
7182 	case OPT_BOOT_TYPE_HARD_DISK:
7183 		iso9660->el_torito.media_type = BOOT_MEDIA_HARD_DISK;
7184 		break;
7185 	case OPT_BOOT_TYPE_FD:
7186 		entry = iso9660->el_torito.boot->file->entry;
7187 		if (archive_entry_size(entry) <= FD_1_2M_SIZE)
7188 			iso9660->el_torito.media_type =
7189 			    BOOT_MEDIA_1_2M_DISKETTE;
7190 		else if (archive_entry_size(entry) <= FD_1_44M_SIZE)
7191 			iso9660->el_torito.media_type =
7192 			    BOOT_MEDIA_1_44M_DISKETTE;
7193 		else if (archive_entry_size(entry) <= FD_2_88M_SIZE)
7194 			iso9660->el_torito.media_type =
7195 			    BOOT_MEDIA_2_88M_DISKETTE;
7196 		else {
7197 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
7198 			    "Boot image file(``%s'') size is too big "
7199 			    "for fd type.",
7200 			    iso9660->el_torito.boot_filename.s);
7201 			return (ARCHIVE_FATAL);
7202 		}
7203 		break;
7204 	}
7205 
7206 	/*
7207 	 * Get a system type.
7208 	 * TODO: `El Torito' specification says "A copy of byte 5 from the
7209 	 *       Partition Table found in the boot image".
7210 	 */
7211 	iso9660->el_torito.system_type = 0;
7212 
7213 	/*
7214 	 * Get an ID.
7215 	 */
7216 	if (iso9660->opt.publisher)
7217 		archive_string_copy(&(iso9660->el_torito.id),
7218 		    &(iso9660->publisher_identifier));
7219 
7220 
7221 	return (ARCHIVE_OK);
7222 }
7223 
7224 /*
7225  * If a media type is floppy, return its image size.
7226  * otherwise return 0.
7227  */
7228 static size_t
7229 fd_boot_image_size(int media_type)
7230 {
7231 	switch (media_type) {
7232 	case BOOT_MEDIA_1_2M_DISKETTE:
7233 		return (FD_1_2M_SIZE);
7234 	case BOOT_MEDIA_1_44M_DISKETTE:
7235 		return (FD_1_44M_SIZE);
7236 	case BOOT_MEDIA_2_88M_DISKETTE:
7237 		return (FD_2_88M_SIZE);
7238 	default:
7239 		return (0);
7240 	}
7241 }
7242 
7243 /*
7244  * Make a boot catalog image data.
7245  */
7246 static int
7247 make_boot_catalog(struct archive_write *a)
7248 {
7249 	struct iso9660 *iso9660 = a->format_data;
7250 	unsigned char *block;
7251 	unsigned char *p;
7252 	uint16_t sum, *wp;
7253 
7254 	block = wb_buffptr(a);
7255 	memset(block, 0, LOGICAL_BLOCK_SIZE);
7256 	p = block;
7257 	/*
7258 	 * Validation Entry
7259 	 */
7260 	/* Header ID */
7261 	p[0] = 1;
7262 	/* Platform ID */
7263 	p[1] = iso9660->el_torito.platform_id;
7264 	/* Reserved */
7265 	p[2] = p[3] = 0;
7266 	/* ID */
7267 	if (archive_strlen(&(iso9660->el_torito.id)) > 0)
7268 		strncpy((char *)p+4, iso9660->el_torito.id.s, 23);
7269 	p[27] = 0;
7270 	/* Checksum */
7271 	p[28] = p[29] = 0;
7272 	/* Key */
7273 	p[30] = 0x55;
7274 	p[31] = 0xAA;
7275 
7276 	sum = 0;
7277 	wp = (uint16_t *)block;
7278 	while (wp < (uint16_t *)&block[32])
7279 		sum += archive_le16dec(wp++);
7280 	set_num_721(&block[28], (~sum) + 1);
7281 
7282 	/*
7283 	 * Initial/Default Entry
7284 	 */
7285 	p = &block[32];
7286 	/* Boot Indicator */
7287 	p[0] = 0x88;
7288 	/* Boot media type */
7289 	p[1] = iso9660->el_torito.media_type;
7290 	/* Load Segment */
7291 	if (iso9660->el_torito.media_type == BOOT_MEDIA_NO_EMULATION)
7292 		set_num_721(&p[2], iso9660->el_torito.boot_load_seg);
7293 	else
7294 		set_num_721(&p[2], 0);
7295 	/* System Type */
7296 	p[4] = iso9660->el_torito.system_type;
7297 	/* Unused */
7298 	p[5] = 0;
7299 	/* Sector Count */
7300 	if (iso9660->el_torito.media_type == BOOT_MEDIA_NO_EMULATION)
7301 		set_num_721(&p[6], iso9660->el_torito.boot_load_size);
7302 	else
7303 		set_num_721(&p[6], 1);
7304 	/* Load RBA */
7305 	set_num_731(&p[8],
7306 	    iso9660->el_torito.boot->file->content.location);
7307 	/* Unused */
7308 	memset(&p[12], 0, 20);
7309 
7310 	return (wb_consume(a, LOGICAL_BLOCK_SIZE));
7311 }
7312 
7313 static int
7314 setup_boot_information(struct archive_write *a)
7315 {
7316 	struct iso9660 *iso9660 = a->format_data;
7317 	struct isoent *np;
7318 	int64_t size;
7319 	uint32_t sum;
7320 	unsigned char buff[4096];
7321 
7322 	np = iso9660->el_torito.boot;
7323 	lseek(iso9660->temp_fd,
7324 	    np->file->content.offset_of_temp + 64, SEEK_SET);
7325 	size = archive_entry_size(np->file->entry) - 64;
7326 	if (size <= 0) {
7327 		archive_set_error(&a->archive, errno,
7328 		    "Boot file(%jd) is too small", (intmax_t)size + 64);
7329 		return (ARCHIVE_FATAL);
7330 	}
7331 	sum = 0;
7332 	while (size > 0) {
7333 		size_t rsize;
7334 		ssize_t i, rs;
7335 
7336 		if (size > (int64_t)sizeof(buff))
7337 			rsize = sizeof(buff);
7338 		else
7339 			rsize = (size_t)size;
7340 
7341 		rs = read(iso9660->temp_fd, buff, rsize);
7342 		if (rs <= 0) {
7343 			archive_set_error(&a->archive, errno,
7344 			    "Can't read temporary file(%jd)",
7345 			    (intmax_t)rs);
7346 			return (ARCHIVE_FATAL);
7347 		}
7348 		for (i = 0; i < rs; i += 4)
7349 			sum += archive_le32dec(buff + i);
7350 		size -= rs;
7351 	}
7352 	/* Set the location of Primary Volume Descriptor. */
7353 	set_num_731(buff, SYSTEM_AREA_BLOCK);
7354 	/* Set the location of the boot file. */
7355 	set_num_731(buff+4, np->file->content.location);
7356 	/* Set the size of the boot file. */
7357 	size = fd_boot_image_size(iso9660->el_torito.media_type);
7358 	if (size == 0)
7359 		size = archive_entry_size(np->file->entry);
7360 	set_num_731(buff+8, (uint32_t)size);
7361 	/* Set the sum of the boot file. */
7362 	set_num_731(buff+12, sum);
7363 	/* Clear reserved bytes. */
7364 	memset(buff+16, 0, 40);
7365 
7366 	/* Overwrite the boot file. */
7367 	lseek(iso9660->temp_fd,
7368 	    np->file->content.offset_of_temp + 8, SEEK_SET);
7369 	return (write_to_temp(a, buff, 56));
7370 }
7371 
7372 #ifdef HAVE_ZLIB_H
7373 
7374 static int
7375 zisofs_init_zstream(struct archive_write *a)
7376 {
7377 	struct iso9660 *iso9660 = a->format_data;
7378 	int r;
7379 
7380 	iso9660->zisofs.stream.next_in = NULL;
7381 	iso9660->zisofs.stream.avail_in = 0;
7382 	iso9660->zisofs.stream.total_in = 0;
7383 	iso9660->zisofs.stream.total_out = 0;
7384 	if (iso9660->zisofs.stream_valid)
7385 		r = deflateReset(&(iso9660->zisofs.stream));
7386 	else {
7387 		r = deflateInit(&(iso9660->zisofs.stream),
7388 		    iso9660->zisofs.compression_level);
7389 		iso9660->zisofs.stream_valid = 1;
7390 	}
7391 	switch (r) {
7392 	case Z_OK:
7393 		break;
7394 	default:
7395 	case Z_STREAM_ERROR:
7396 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
7397 		    "Internal error initializing "
7398 		    "compression library: invalid setup parameter");
7399 		return (ARCHIVE_FATAL);
7400 	case Z_MEM_ERROR:
7401 		archive_set_error(&a->archive, ENOMEM,
7402 		    "Internal error initializing "
7403 		    "compression library");
7404 		return (ARCHIVE_FATAL);
7405 	case Z_VERSION_ERROR:
7406 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
7407 		    "Internal error initializing "
7408 		    "compression library: invalid library version");
7409 		return (ARCHIVE_FATAL);
7410 	}
7411 	return (ARCHIVE_OK);
7412 }
7413 
7414 #endif /* HAVE_ZLIB_H */
7415 
7416 static int
7417 zisofs_init(struct archive_write *a,  struct isofile *file)
7418 {
7419 	struct iso9660 *iso9660 = a->format_data;
7420 #ifdef HAVE_ZLIB_H
7421 	uint64_t tsize;
7422 	size_t _ceil, bpsize;
7423 	int r;
7424 #endif
7425 
7426 	iso9660->zisofs.detect_magic = 0;
7427 	iso9660->zisofs.making = 0;
7428 
7429 	if (!iso9660->opt.rr || !iso9660->opt.zisofs)
7430 		return (ARCHIVE_OK);
7431 
7432 	if (archive_entry_size(file->entry) >= 24 &&
7433 	    archive_entry_size(file->entry) < MULTI_EXTENT_SIZE) {
7434 		/* Acceptable file size for zisofs. */
7435 		iso9660->zisofs.detect_magic = 1;
7436 		iso9660->zisofs.magic_cnt = 0;
7437 	}
7438 	if (!iso9660->zisofs.detect_magic)
7439 		return (ARCHIVE_OK);
7440 
7441 #ifdef HAVE_ZLIB_H
7442 	/* The number of Logical Blocks which uncompressed data
7443 	 * will use in iso-image file is the same as the number of
7444 	 * Logical Blocks which zisofs(compressed) data will use
7445 	 * in ISO-image file. It won't reduce iso-image file size. */
7446 	if (archive_entry_size(file->entry) <= LOGICAL_BLOCK_SIZE)
7447 		return (ARCHIVE_OK);
7448 
7449 	/* Initialize compression library */
7450 	r = zisofs_init_zstream(a);
7451 	if (r != ARCHIVE_OK)
7452 		return (ARCHIVE_FATAL);
7453 
7454 	/* Mark file->zisofs to create RRIP 'ZF' Use Entry. */
7455 	file->zisofs.header_size = ZF_HEADER_SIZE >> 2;
7456 	file->zisofs.log2_bs = ZF_LOG2_BS;
7457 	file->zisofs.uncompressed_size =
7458 		(uint32_t)archive_entry_size(file->entry);
7459 
7460 	/* Calculate a size of Block Pointers of zisofs. */
7461 	_ceil = (file->zisofs.uncompressed_size + ZF_BLOCK_SIZE -1)
7462 		>> file->zisofs.log2_bs;
7463 	iso9660->zisofs.block_pointers_cnt = (int)_ceil + 1;
7464 	iso9660->zisofs.block_pointers_idx = 0;
7465 
7466 	/* Ensure a buffer size used for Block Pointers */
7467 	bpsize = iso9660->zisofs.block_pointers_cnt *
7468 	    sizeof(iso9660->zisofs.block_pointers[0]);
7469 	if (iso9660->zisofs.block_pointers_allocated < bpsize) {
7470 		free(iso9660->zisofs.block_pointers);
7471 		iso9660->zisofs.block_pointers = malloc(bpsize);
7472 		if (iso9660->zisofs.block_pointers == NULL) {
7473 			archive_set_error(&a->archive, ENOMEM,
7474 			    "Can't allocate data");
7475 			return (ARCHIVE_FATAL);
7476 		}
7477 		iso9660->zisofs.block_pointers_allocated = bpsize;
7478 	}
7479 
7480 	/*
7481 	 * Skip zisofs header and Block Pointers, which we will write
7482 	 * after all compressed data of a file written to the temporary
7483 	 * file.
7484 	 */
7485 	tsize = ZF_HEADER_SIZE + bpsize;
7486 	if (write_null(a, (size_t)tsize) != ARCHIVE_OK)
7487 		return (ARCHIVE_FATAL);
7488 
7489 	/*
7490 	 * Initialize some variables to make zisofs.
7491 	 */
7492 	archive_le32enc(&(iso9660->zisofs.block_pointers[0]),
7493 		(uint32_t)tsize);
7494 	iso9660->zisofs.remaining = file->zisofs.uncompressed_size;
7495 	iso9660->zisofs.making = 1;
7496 	iso9660->zisofs.allzero = 1;
7497 	iso9660->zisofs.block_offset = tsize;
7498 	iso9660->zisofs.total_size = tsize;
7499 	iso9660->cur_file->cur_content->size = tsize;
7500 #endif
7501 
7502 	return (ARCHIVE_OK);
7503 }
7504 
7505 static void
7506 zisofs_detect_magic(struct archive_write *a, const void *buff, size_t s)
7507 {
7508 	struct iso9660 *iso9660 = a->format_data;
7509 	struct isofile *file = iso9660->cur_file;
7510 	const unsigned char *p, *endp;
7511 	const unsigned char *magic_buff;
7512 	uint32_t uncompressed_size;
7513 	unsigned char header_size;
7514 	unsigned char log2_bs;
7515 	size_t _ceil, doff;
7516 	uint32_t bst, bed;
7517 	int magic_max;
7518 	int64_t entry_size;
7519 
7520 	entry_size = archive_entry_size(file->entry);
7521 	if ((int64_t)sizeof(iso9660->zisofs.magic_buffer) > entry_size)
7522 		magic_max = (int)entry_size;
7523 	else
7524 		magic_max = sizeof(iso9660->zisofs.magic_buffer);
7525 
7526 	if (iso9660->zisofs.magic_cnt == 0 && s >= (size_t)magic_max)
7527 		/* It's unnecessary we copy buffer. */
7528 		magic_buff = buff;
7529 	else {
7530 		if (iso9660->zisofs.magic_cnt < magic_max) {
7531 			size_t l;
7532 
7533 			l = sizeof(iso9660->zisofs.magic_buffer)
7534 			    - iso9660->zisofs.magic_cnt;
7535 			if (l > s)
7536 				l = s;
7537 			memcpy(iso9660->zisofs.magic_buffer
7538 			    + iso9660->zisofs.magic_cnt, buff, l);
7539 			iso9660->zisofs.magic_cnt += (int)l;
7540 			if (iso9660->zisofs.magic_cnt < magic_max)
7541 				return;
7542 		}
7543 		magic_buff = iso9660->zisofs.magic_buffer;
7544 	}
7545 	iso9660->zisofs.detect_magic = 0;
7546 	p = magic_buff;
7547 
7548 	/* Check the magic code of zisofs. */
7549 	if (memcmp(p, zisofs_magic, sizeof(zisofs_magic)) != 0)
7550 		/* This is not zisofs file which made by mkzftree. */
7551 		return;
7552 	p += sizeof(zisofs_magic);
7553 
7554 	/* Read a zisofs header. */
7555 	uncompressed_size = archive_le32dec(p);
7556 	header_size = p[4];
7557 	log2_bs = p[5];
7558 	if (uncompressed_size < 24 || header_size != 4 ||
7559 	    log2_bs > 30 || log2_bs < 7)
7560 		return;/* Invalid or not supported header. */
7561 
7562 	/* Calculate a size of Block Pointers of zisofs. */
7563 	_ceil = (uncompressed_size +
7564 	        (ARCHIVE_LITERAL_LL(1) << log2_bs) -1) >> log2_bs;
7565 	doff = (_ceil + 1) * 4 + 16;
7566 	if (entry_size < (int64_t)doff)
7567 		return;/* Invalid data. */
7568 
7569 	/* Check every Block Pointer has valid value. */
7570 	p = magic_buff + 16;
7571 	endp = magic_buff + magic_max;
7572 	while (_ceil && p + 8 <= endp) {
7573 		bst = archive_le32dec(p);
7574 		if (bst != doff)
7575 			return;/* Invalid data. */
7576 		p += 4;
7577 		bed = archive_le32dec(p);
7578 		if (bed < bst || bed > entry_size)
7579 			return;/* Invalid data. */
7580 		doff += bed - bst;
7581 		_ceil--;
7582 	}
7583 
7584 	file->zisofs.uncompressed_size = uncompressed_size;
7585 	file->zisofs.header_size = header_size;
7586 	file->zisofs.log2_bs = log2_bs;
7587 
7588 	/* Disable making a zisofs image. */
7589 	iso9660->zisofs.making = 0;
7590 }
7591 
7592 #ifdef HAVE_ZLIB_H
7593 
7594 /*
7595  * Compress data and write it to a temporary file.
7596  */
7597 static int
7598 zisofs_write_to_temp(struct archive_write *a, const void *buff, size_t s)
7599 {
7600 	struct iso9660 *iso9660 = a->format_data;
7601 	struct isofile *file = iso9660->cur_file;
7602 	const unsigned char *b;
7603 	z_stream *zstrm;
7604 	size_t avail, csize;
7605 	int flush, r;
7606 
7607 	zstrm = &(iso9660->zisofs.stream);
7608 	zstrm->next_out = wb_buffptr(a);
7609 	zstrm->avail_out = (uInt)wb_remaining(a);
7610 	b = (const unsigned char *)buff;
7611 	do {
7612 		avail = ZF_BLOCK_SIZE - zstrm->total_in;
7613 		if (s < avail) {
7614 			avail = s;
7615 			flush = Z_NO_FLUSH;
7616 		} else
7617 			flush = Z_FINISH;
7618 		iso9660->zisofs.remaining -= avail;
7619 		if (iso9660->zisofs.remaining <= 0)
7620 			flush = Z_FINISH;
7621 
7622 		zstrm->next_in = (Bytef *)(uintptr_t)(const void *)b;
7623 		zstrm->avail_in = (uInt)avail;
7624 
7625 		/*
7626 		 * Check if current data block are all zero.
7627 		 */
7628 		if (iso9660->zisofs.allzero) {
7629 			const unsigned char *nonzero = b;
7630 			const unsigned char *nonzeroend = b + avail;
7631 
7632 			while (nonzero < nonzeroend)
7633 				if (*nonzero++) {
7634 					iso9660->zisofs.allzero = 0;
7635 					break;
7636 				}
7637 		}
7638 		b += avail;
7639 		s -= avail;
7640 
7641 		/*
7642 		 * If current data block are all zero, we do not use
7643 		 * compressed data.
7644 		 */
7645 		if (flush == Z_FINISH && iso9660->zisofs.allzero &&
7646 		    avail + zstrm->total_in == ZF_BLOCK_SIZE) {
7647 			if (iso9660->zisofs.block_offset !=
7648 			    file->cur_content->size) {
7649 				int64_t diff;
7650 
7651 				r = wb_set_offset(a,
7652 				    file->cur_content->offset_of_temp +
7653 				        iso9660->zisofs.block_offset);
7654 				if (r != ARCHIVE_OK)
7655 					return (r);
7656 				diff = file->cur_content->size -
7657 				    iso9660->zisofs.block_offset;
7658 				file->cur_content->size -= diff;
7659 				iso9660->zisofs.total_size -= diff;
7660 			}
7661 			zstrm->avail_in = 0;
7662 		}
7663 
7664 		/*
7665 		 * Compress file data.
7666 		 */
7667 		while (zstrm->avail_in > 0) {
7668 			csize = zstrm->total_out;
7669 			r = deflate(zstrm, flush);
7670 			switch (r) {
7671 			case Z_OK:
7672 			case Z_STREAM_END:
7673 				csize = zstrm->total_out - csize;
7674 				if (wb_consume(a, csize) != ARCHIVE_OK)
7675 					return (ARCHIVE_FATAL);
7676 				iso9660->zisofs.total_size += csize;
7677 				iso9660->cur_file->cur_content->size += csize;
7678 				zstrm->next_out = wb_buffptr(a);
7679 				zstrm->avail_out = (uInt)wb_remaining(a);
7680 				break;
7681 			default:
7682 				archive_set_error(&a->archive,
7683 				    ARCHIVE_ERRNO_MISC,
7684 				    "Compression failed:"
7685 				    " deflate() call returned status %d",
7686 				    r);
7687 				return (ARCHIVE_FATAL);
7688 			}
7689 		}
7690 
7691 		if (flush == Z_FINISH) {
7692 			/*
7693 			 * Save the information of one zisofs block.
7694 			 */
7695 			iso9660->zisofs.block_pointers_idx ++;
7696 			archive_le32enc(&(iso9660->zisofs.block_pointers[
7697 			    iso9660->zisofs.block_pointers_idx]),
7698 				(uint32_t)iso9660->zisofs.total_size);
7699 			r = zisofs_init_zstream(a);
7700 			if (r != ARCHIVE_OK)
7701 				return (ARCHIVE_FATAL);
7702 			iso9660->zisofs.allzero = 1;
7703 			iso9660->zisofs.block_offset = file->cur_content->size;
7704 		}
7705 	} while (s);
7706 
7707 	return (ARCHIVE_OK);
7708 }
7709 
7710 static int
7711 zisofs_finish_entry(struct archive_write *a)
7712 {
7713 	struct iso9660 *iso9660 = a->format_data;
7714 	struct isofile *file = iso9660->cur_file;
7715 	unsigned char buff[16];
7716 	size_t s;
7717 	int64_t tail;
7718 
7719 	/* Direct temp file stream to zisofs temp file stream. */
7720 	archive_entry_set_size(file->entry, iso9660->zisofs.total_size);
7721 
7722 	/*
7723 	 * Save a file pointer which points the end of current zisofs data.
7724 	 */
7725 	tail = wb_offset(a);
7726 
7727 	/*
7728 	 * Make a header.
7729 	 *
7730 	 * +-----------------+----------------+-----------------+
7731 	 * | Header 16 bytes | Block Pointers | Compressed data |
7732 	 * +-----------------+----------------+-----------------+
7733 	 * 0                16               +X
7734 	 * Block Pointers :
7735 	 *   4 * (((Uncompressed file size + block_size -1) / block_size) + 1)
7736 	 *
7737 	 * Write zisofs header.
7738 	 *    Magic number
7739 	 * +----+----+----+----+----+----+----+----+
7740 	 * | 37 | E4 | 53 | 96 | C9 | DB | D6 | 07 |
7741 	 * +----+----+----+----+----+----+----+----+
7742 	 * 0    1    2    3    4    5    6    7    8
7743 	 *
7744 	 * +------------------------+------------------+
7745 	 * | Uncompressed file size | header_size >> 2 |
7746 	 * +------------------------+------------------+
7747 	 * 8                       12                 13
7748 	 *
7749 	 * +-----------------+----------------+
7750 	 * | log2 block_size | Reserved(0000) |
7751 	 * +-----------------+----------------+
7752 	 * 13               14               16
7753 	 */
7754 	memcpy(buff, zisofs_magic, 8);
7755 	set_num_731(buff+8, file->zisofs.uncompressed_size);
7756 	buff[12] = file->zisofs.header_size;
7757 	buff[13] = file->zisofs.log2_bs;
7758 	buff[14] = buff[15] = 0;/* Reserved */
7759 
7760 	/* Move to the right position to write the header. */
7761 	wb_set_offset(a, file->content.offset_of_temp);
7762 
7763 	/* Write the header. */
7764 	if (wb_write_to_temp(a, buff, 16) != ARCHIVE_OK)
7765 		return (ARCHIVE_FATAL);
7766 
7767 	/*
7768 	 * Write zisofs Block Pointers.
7769 	 */
7770 	s = iso9660->zisofs.block_pointers_cnt *
7771 	    sizeof(iso9660->zisofs.block_pointers[0]);
7772 	if (wb_write_to_temp(a, iso9660->zisofs.block_pointers, s)
7773 	    != ARCHIVE_OK)
7774 		return (ARCHIVE_FATAL);
7775 
7776 	/* Set a file pointer back to the end of the temporary file. */
7777 	wb_set_offset(a, tail);
7778 
7779 	return (ARCHIVE_OK);
7780 }
7781 
7782 static int
7783 zisofs_free(struct archive_write *a)
7784 {
7785 	struct iso9660 *iso9660 = a->format_data;
7786 	int ret = ARCHIVE_OK;
7787 
7788 	free(iso9660->zisofs.block_pointers);
7789 	if (iso9660->zisofs.stream_valid &&
7790 	    deflateEnd(&(iso9660->zisofs.stream)) != Z_OK) {
7791 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
7792 		    "Failed to clean up compressor");
7793 		ret = ARCHIVE_FATAL;
7794 	}
7795 	iso9660->zisofs.block_pointers = NULL;
7796 	iso9660->zisofs.stream_valid = 0;
7797 	return (ret);
7798 }
7799 
7800 struct zisofs_extract {
7801 	int		 pz_log2_bs; /* Log2 of block size */
7802 	uint64_t	 pz_uncompressed_size;
7803 	size_t		 uncompressed_buffer_size;
7804 
7805 	signed int	 initialized:1;
7806 	signed int	 header_passed:1;
7807 
7808 	uint32_t	 pz_offset;
7809 	unsigned char	*block_pointers;
7810 	size_t		 block_pointers_size;
7811 	size_t		 block_pointers_avail;
7812 	size_t		 block_off;
7813 	uint32_t	 block_avail;
7814 
7815 	z_stream	 stream;
7816 	int		 stream_valid;
7817 };
7818 
7819 static ssize_t
7820 zisofs_extract_init(struct archive_write *a, struct zisofs_extract *zisofs,
7821     const unsigned char *p, size_t bytes)
7822 {
7823 	size_t avail = bytes;
7824 	size_t _ceil, xsize;
7825 
7826 	/* Allocate block pointers buffer. */
7827 	_ceil = (size_t)((zisofs->pz_uncompressed_size +
7828 		(((int64_t)1) << zisofs->pz_log2_bs) - 1)
7829 		>> zisofs->pz_log2_bs);
7830 	xsize = (_ceil + 1) * 4;
7831 	if (zisofs->block_pointers == NULL) {
7832 		size_t alloc = ((xsize >> 10) + 1) << 10;
7833 		zisofs->block_pointers = malloc(alloc);
7834 		if (zisofs->block_pointers == NULL) {
7835 			archive_set_error(&a->archive, ENOMEM,
7836 			    "No memory for zisofs decompression");
7837 			return (ARCHIVE_FATAL);
7838 		}
7839 	}
7840 	zisofs->block_pointers_size = xsize;
7841 
7842 	/* Allocate uncompressed data buffer. */
7843 	zisofs->uncompressed_buffer_size = (size_t)1UL << zisofs->pz_log2_bs;
7844 
7845 	/*
7846 	 * Read the file header, and check the magic code of zisofs.
7847 	 */
7848 	if (!zisofs->header_passed) {
7849 		int err = 0;
7850 		if (avail < 16) {
7851 			archive_set_error(&a->archive,
7852 			    ARCHIVE_ERRNO_FILE_FORMAT,
7853 			    "Illegal zisofs file body");
7854 			return (ARCHIVE_FATAL);
7855 		}
7856 
7857 		if (memcmp(p, zisofs_magic, sizeof(zisofs_magic)) != 0)
7858 			err = 1;
7859 		else if (archive_le32dec(p + 8) != zisofs->pz_uncompressed_size)
7860 			err = 1;
7861 		else if (p[12] != 4 || p[13] != zisofs->pz_log2_bs)
7862 			err = 1;
7863 		if (err) {
7864 			archive_set_error(&a->archive,
7865 			    ARCHIVE_ERRNO_FILE_FORMAT,
7866 			    "Illegal zisofs file body");
7867 			return (ARCHIVE_FATAL);
7868 		}
7869 		avail -= 16;
7870 		p += 16;
7871 		zisofs->header_passed = 1;
7872 	}
7873 
7874 	/*
7875 	 * Read block pointers.
7876 	 */
7877 	if (zisofs->header_passed &&
7878 	    zisofs->block_pointers_avail < zisofs->block_pointers_size) {
7879 		xsize = zisofs->block_pointers_size
7880 		    - zisofs->block_pointers_avail;
7881 		if (avail < xsize)
7882 			xsize = avail;
7883 		memcpy(zisofs->block_pointers
7884 		    + zisofs->block_pointers_avail, p, xsize);
7885 		zisofs->block_pointers_avail += xsize;
7886 		avail -= xsize;
7887 	    	if (zisofs->block_pointers_avail
7888 		    == zisofs->block_pointers_size) {
7889 			/* We've got all block pointers and initialize
7890 			 * related variables.	*/
7891 			zisofs->block_off = 0;
7892 			zisofs->block_avail = 0;
7893 			/* Complete a initialization */
7894 			zisofs->initialized = 1;
7895 		}
7896 	}
7897 	return ((ssize_t)avail);
7898 }
7899 
7900 static ssize_t
7901 zisofs_extract(struct archive_write *a, struct zisofs_extract *zisofs,
7902     const unsigned char *p, size_t bytes)
7903 {
7904 	size_t avail;
7905 	int r;
7906 
7907 	if (!zisofs->initialized) {
7908 		ssize_t rs = zisofs_extract_init(a, zisofs, p, bytes);
7909 		if (rs < 0)
7910 			return (rs);
7911 		if (!zisofs->initialized) {
7912 			/* We need more data. */
7913 			zisofs->pz_offset += (uint32_t)bytes;
7914 			return (bytes);
7915 		}
7916 		avail = rs;
7917 		p += bytes - avail;
7918 	} else
7919 		avail = bytes;
7920 
7921 	/*
7922 	 * Get block offsets from block pointers.
7923 	 */
7924 	if (zisofs->block_avail == 0) {
7925 		uint32_t bst, bed;
7926 
7927 		if (zisofs->block_off + 4 >= zisofs->block_pointers_size) {
7928 			/* There isn't a pair of offsets. */
7929 			archive_set_error(&a->archive,
7930 			    ARCHIVE_ERRNO_FILE_FORMAT,
7931 			    "Illegal zisofs block pointers");
7932 			return (ARCHIVE_FATAL);
7933 		}
7934 		bst = archive_le32dec(
7935 		    zisofs->block_pointers + zisofs->block_off);
7936 		if (bst != zisofs->pz_offset + (bytes - avail)) {
7937 			archive_set_error(&a->archive,
7938 			    ARCHIVE_ERRNO_FILE_FORMAT,
7939 			    "Illegal zisofs block pointers(cannot seek)");
7940 			return (ARCHIVE_FATAL);
7941 		}
7942 		bed = archive_le32dec(
7943 		    zisofs->block_pointers + zisofs->block_off + 4);
7944 		if (bed < bst) {
7945 			archive_set_error(&a->archive,
7946 			    ARCHIVE_ERRNO_FILE_FORMAT,
7947 			    "Illegal zisofs block pointers");
7948 			return (ARCHIVE_FATAL);
7949 		}
7950 		zisofs->block_avail = bed - bst;
7951 		zisofs->block_off += 4;
7952 
7953 		/* Initialize compression library for new block. */
7954 		if (zisofs->stream_valid)
7955 			r = inflateReset(&zisofs->stream);
7956 		else
7957 			r = inflateInit(&zisofs->stream);
7958 		if (r != Z_OK) {
7959 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
7960 			    "Can't initialize zisofs decompression.");
7961 			return (ARCHIVE_FATAL);
7962 		}
7963 		zisofs->stream_valid = 1;
7964 		zisofs->stream.total_in = 0;
7965 		zisofs->stream.total_out = 0;
7966 	}
7967 
7968 	/*
7969 	 * Make uncompressed data.
7970 	 */
7971 	if (zisofs->block_avail == 0) {
7972 		/*
7973 		 * It's basically 32K bytes NUL data.
7974 		 */
7975 		unsigned char *wb;
7976 		size_t size, wsize;
7977 
7978 		size = zisofs->uncompressed_buffer_size;
7979 		while (size) {
7980 			wb = wb_buffptr(a);
7981 			if (size > wb_remaining(a))
7982 				wsize = wb_remaining(a);
7983 			else
7984 				wsize = size;
7985 			memset(wb, 0, wsize);
7986 			r = wb_consume(a, wsize);
7987 			if (r < 0)
7988 				return (r);
7989 			size -= wsize;
7990 		}
7991 	} else {
7992 		zisofs->stream.next_in = (Bytef *)(uintptr_t)(const void *)p;
7993 		if (avail > zisofs->block_avail)
7994 			zisofs->stream.avail_in = zisofs->block_avail;
7995 		else
7996 			zisofs->stream.avail_in = (uInt)avail;
7997 		zisofs->stream.next_out = wb_buffptr(a);
7998 		zisofs->stream.avail_out = (uInt)wb_remaining(a);
7999 
8000 		r = inflate(&zisofs->stream, 0);
8001 		switch (r) {
8002 		case Z_OK: /* Decompressor made some progress.*/
8003 		case Z_STREAM_END: /* Found end of stream. */
8004 			break;
8005 		default:
8006 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
8007 			    "zisofs decompression failed (%d)", r);
8008 			return (ARCHIVE_FATAL);
8009 		}
8010 		avail -= zisofs->stream.next_in - p;
8011 		zisofs->block_avail -= (uint32_t)(zisofs->stream.next_in - p);
8012 		r = wb_consume(a, wb_remaining(a) - zisofs->stream.avail_out);
8013 		if (r < 0)
8014 			return (r);
8015 	}
8016 	zisofs->pz_offset += (uint32_t)bytes;
8017 	return (bytes - avail);
8018 }
8019 
8020 static int
8021 zisofs_rewind_boot_file(struct archive_write *a)
8022 {
8023 	struct iso9660 *iso9660 = a->format_data;
8024 	struct isofile *file;
8025 	unsigned char *rbuff;
8026 	ssize_t r;
8027 	size_t remaining, rbuff_size;
8028 	struct zisofs_extract zext;
8029 	int64_t read_offset, write_offset, new_offset;
8030 	int fd, ret = ARCHIVE_OK;
8031 
8032 	file = iso9660->el_torito.boot->file;
8033 	/*
8034 	 * There is nothing to do if this boot file does not have
8035 	 * zisofs header.
8036 	 */
8037 	if (file->zisofs.header_size == 0)
8038 		return (ARCHIVE_OK);
8039 
8040 	/*
8041 	 * Uncompress the zisofs'ed file contents.
8042 	 */
8043 	memset(&zext, 0, sizeof(zext));
8044 	zext.pz_uncompressed_size = file->zisofs.uncompressed_size;
8045 	zext.pz_log2_bs = file->zisofs.log2_bs;
8046 
8047 	fd = iso9660->temp_fd;
8048 	new_offset = wb_offset(a);
8049 	read_offset = file->content.offset_of_temp;
8050 	remaining = (size_t)file->content.size;
8051 	if (remaining > 1024 * 32)
8052 		rbuff_size = 1024 * 32;
8053 	else
8054 		rbuff_size = remaining;
8055 
8056 	rbuff = malloc(rbuff_size);
8057 	if (rbuff == NULL) {
8058 		archive_set_error(&a->archive, ENOMEM, "Can't allocate memory");
8059 		return (ARCHIVE_FATAL);
8060 	}
8061 	while (remaining) {
8062 		size_t rsize;
8063 		ssize_t rs;
8064 
8065 		/* Get the current file pointer. */
8066 		write_offset = lseek(fd, 0, SEEK_CUR);
8067 
8068 		/* Change the file pointer to read. */
8069 		lseek(fd, read_offset, SEEK_SET);
8070 
8071 		rsize = rbuff_size;
8072 		if (rsize > remaining)
8073 			rsize = remaining;
8074 		rs = read(iso9660->temp_fd, rbuff, rsize);
8075 		if (rs <= 0) {
8076 			archive_set_error(&a->archive, errno,
8077 			    "Can't read temporary file(%jd)", (intmax_t)rs);
8078 			ret = ARCHIVE_FATAL;
8079 			break;
8080 		}
8081 		remaining -= rs;
8082 		read_offset += rs;
8083 
8084 		/* Put the file pointer back to write. */
8085 		lseek(fd, write_offset, SEEK_SET);
8086 
8087 		r = zisofs_extract(a, &zext, rbuff, rs);
8088 		if (r < 0) {
8089 			ret = (int)r;
8090 			break;
8091 		}
8092 	}
8093 
8094 	if (ret == ARCHIVE_OK) {
8095 		/*
8096 		 * Change the boot file content from zisofs'ed data
8097 		 * to plain data.
8098 		 */
8099 		file->content.offset_of_temp = new_offset;
8100 		file->content.size = file->zisofs.uncompressed_size;
8101 		archive_entry_set_size(file->entry, file->content.size);
8102 		/* Set to be no zisofs. */
8103 		file->zisofs.header_size = 0;
8104 		file->zisofs.log2_bs = 0;
8105 		file->zisofs.uncompressed_size = 0;
8106 		r = wb_write_padding_to_temp(a, file->content.size);
8107 		if (r < 0)
8108 			ret = ARCHIVE_FATAL;
8109 	}
8110 
8111 	/*
8112 	 * Free the resource we used in this function only.
8113 	 */
8114 	free(rbuff);
8115 	free(zext.block_pointers);
8116 	if (zext.stream_valid && inflateEnd(&(zext.stream)) != Z_OK) {
8117         	archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
8118 		    "Failed to clean up compressor");
8119 		ret = ARCHIVE_FATAL;
8120 	}
8121 
8122 	return (ret);
8123 }
8124 
8125 #else
8126 
8127 static int
8128 zisofs_write_to_temp(struct archive_write *a, const void *buff, size_t s)
8129 {
8130 	(void)buff; /* UNUSED */
8131 	(void)s; /* UNUSED */
8132 	archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Programming error");
8133 	return (ARCHIVE_FATAL);
8134 }
8135 
8136 static int
8137 zisofs_rewind_boot_file(struct archive_write *a)
8138 {
8139 	struct iso9660 *iso9660 = a->format_data;
8140 
8141 	if (iso9660->el_torito.boot->file->zisofs.header_size != 0) {
8142 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
8143 		    "We cannot extract the zisofs imaged boot file;"
8144 		    " this may not boot in being zisofs imaged");
8145 		return (ARCHIVE_FAILED);
8146 	}
8147 	return (ARCHIVE_OK);
8148 }
8149 
8150 static int
8151 zisofs_finish_entry(struct archive_write *a)
8152 {
8153 	(void)a; /* UNUSED */
8154 	return (ARCHIVE_OK);
8155 }
8156 
8157 static int
8158 zisofs_free(struct archive_write *a)
8159 {
8160 	(void)a; /* UNUSED */
8161 	return (ARCHIVE_OK);
8162 }
8163 
8164 #endif /* HAVE_ZLIB_H */
8165 
8166