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