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