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