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