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