Import libarchive-3.0.3.
[dragonfly.git] / contrib / libarchive / libarchive / archive_write_set_format_iso9660.c
1 /*-
2  * Copyright (c) 2009-2011 Michihiro NAKAJIMA
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "archive_platform.h"
27
28 #ifdef HAVE_SYS_TYPES_H
29 #include <sys/types.h>
30 #endif
31 #ifdef HAVE_SYS_UTSNAME_H
32 #include <sys/utsname.h>
33 #endif
34 #ifdef HAVE_ERRNO_H
35 #include <errno.h>
36 #endif
37 #ifdef HAVE_LIMITS_H
38 #include <limits.h>
39 #endif
40 #include <stdio.h>
41 #include <stdarg.h>
42 #ifdef HAVE_STDLIB_H
43 #include <stdlib.h>
44 #endif
45 #include <time.h>
46 #ifdef HAVE_UNISTD_H
47 #include <unistd.h>
48 #endif
49 #ifdef HAVE_ZLIB_H
50 #include <zlib.h>
51 #endif
52
53 #include "archive.h"
54 #include "archive_endian.h"
55 #include "archive_entry.h"
56 #include "archive_entry_locale.h"
57 #include "archive_private.h"
58 #include "archive_rb.h"
59 #include "archive_write_private.h"
60
61 #if defined(_WIN32) && !defined(__CYGWIN__)
62 #define getuid()                        0
63 #define getgid()                        0
64 #endif
65
66 /*#define DEBUG 1*/
67 #ifdef DEBUG
68 /* To compare to the ISO image file made by mkisofs. */
69 #define COMPAT_MKISOFS          1
70 #endif
71
72 #define LOGICAL_BLOCK_BITS                      11
73 #define LOGICAL_BLOCK_SIZE                      2048
74 #define PATH_TABLE_BLOCK_SIZE                   4096
75
76 #define SYSTEM_AREA_BLOCK                       16
77 #define PRIMARY_VOLUME_DESCRIPTOR_BLOCK         1
78 #define SUPPLEMENTARY_VOLUME_DESCRIPTOR_BLOCK   1
79 #define BOOT_RECORD_DESCRIPTOR_BLOCK            1
80 #define VOLUME_DESCRIPTOR_SET_TERMINATOR_BLOCK  1
81 #define NON_ISO_FILE_SYSTEM_INFORMATION_BLOCK   1
82 #define RRIP_ER_BLOCK                           1
83 #define PADDING_BLOCK                           150
84
85 #define FD_1_2M_SIZE            (1024 * 1200)
86 #define FD_1_44M_SIZE           (1024 * 1440)
87 #define FD_2_88M_SIZE           (1024 * 2880)
88 #define MULTI_EXTENT_SIZE       (ARCHIVE_LITERAL_LL(1) << 32)   /* 4Gi bytes. */
89 #define MAX_DEPTH               8
90 #define RR_CE_SIZE              28              /* SUSP "CE" extension size */
91
92 #define FILE_FLAG_EXISTENCE     0x01
93 #define FILE_FLAG_DIRECTORY     0x02
94 #define FILE_FLAG_ASSOCIATED    0x04
95 #define FILE_FLAG_RECORD        0x08
96 #define FILE_FLAG_PROTECTION    0x10
97 #define FILE_FLAG_MULTI_EXTENT  0x80
98
99 static const char rrip_identifier[] =
100         "RRIP_1991A";
101 static const char rrip_descriptor[] =
102         "THE ROCK RIDGE INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR "
103         "POSIX FILE SYSTEM SEMANTICS";
104 static const char rrip_source[] =
105         "PLEASE CONTACT DISC PUBLISHER FOR SPECIFICATION SOURCE.  "
106         "SEE PUBLISHER IDENTIFIER IN PRIMARY VOLUME DESCRIPTOR FOR "
107         "CONTACT INFORMATION.";
108 #define RRIP_ER_ID_SIZE         (sizeof(rrip_identifier)-1)
109 #define RRIP_ER_DSC_SIZE        (sizeof(rrip_descriptor)-1)
110 #define RRIP_ER_SRC_SIZE        (sizeof(rrip_source)-1)
111 #define RRIP_ER_SIZE            (8 + RRIP_ER_ID_SIZE + \
112                                 RRIP_ER_DSC_SIZE + RRIP_ER_SRC_SIZE)
113
114 static const unsigned char zisofs_magic[8] = {
115         0x37, 0xE4, 0x53, 0x96, 0xC9, 0xDB, 0xD6, 0x07
116 };
117
118 #define ZF_HEADER_SIZE  16      /* zisofs header size. */
119 #define ZF_LOG2_BS      15      /* log2 block size; 32K bytes. */
120 #define ZF_BLOCK_SIZE   (1UL << ZF_LOG2_BS)
121
122 /*
123  * Manage extra records.
124  */
125 struct extr_rec {
126         int              location;
127         int              offset;
128         unsigned char    buf[LOGICAL_BLOCK_SIZE];
129         struct extr_rec *next;
130 };
131
132 struct ctl_extr_rec {
133         int              use_extr;
134         unsigned char   *bp;
135         struct isoent   *isoent;
136         unsigned char   *ce_ptr;
137         int              cur_len;
138         int              dr_len;
139         int              limit;
140         int              extr_off;
141         int              extr_loc;
142 };
143 #define DR_SAFETY       RR_CE_SIZE
144 #define DR_LIMIT        (254 - DR_SAFETY)
145
146 /*
147  * The relation of struct isofile and isoent and archive_entry.
148  *
149  * Primary volume tree  --> struct isoent
150  *                                |
151  *                                v
152  *                          struct isofile --> archive_entry
153  *                                ^
154  *                                |
155  * Joliet volume tree   --> struct isoent
156  *
157  * struct isoent has specific information for volume.
158  */
159
160 struct isofile {
161         /* Used for managing struct isofile list. */
162         struct isofile          *allnext;
163         struct isofile          *datanext;
164         /* Used for managing a hardlined struct isofile list. */
165         struct isofile          *hlnext;
166         struct isofile          *hardlink_target;
167
168         struct archive_entry    *entry;
169
170         /*
171          * Used for making a directory tree.
172          */
173         struct archive_string    parentdir;
174         struct archive_string    basename;
175         struct archive_string    basename_utf16;
176         struct archive_string    symlink;
177         int                      dircnt;        /* The number of elements of
178                                                  * its parent directory */
179
180         /*
181          * Used for a Directory Record.
182          */
183         struct content {
184                 int64_t          offset_of_temp;
185                 int64_t          size;
186                 int              blocks;
187                 uint32_t         location;
188                 /*
189                  * One extent equals one content.
190                  * If this entry has multi extent, `next' variable points
191                  * next content data.
192                  */
193                 struct content  *next;          /* next content */
194         } content, *cur_content;
195         int                      write_content;
196
197         enum {
198                 NO = 0,
199                 BOOT_CATALOG,
200                 BOOT_IMAGE,
201         } boot;
202
203         /*
204          * Used for a zisofs.
205          */
206         struct {
207                 unsigned char    header_size;
208                 unsigned char    log2_bs;
209                 uint32_t         uncompressed_size;
210         } zisofs;
211 };
212
213 struct isoent {
214         /* Keep `rbnode' at the first member of struct isoent. */
215         struct archive_rb_node   rbnode;
216
217         struct isofile          *file;
218
219         struct isoent           *parent;
220         /* A list of children.(use chnext) */
221         struct {
222                 struct isoent   *first;
223                 struct isoent   **last;
224                 int              cnt;
225         }                        children;
226         struct archive_rb_tree   rbtree;
227
228         /* A list of sub directories.(use drnext) */
229         struct {
230                 struct isoent   *first;
231                 struct isoent   **last;
232                 int              cnt;
233         }                        subdirs;
234         /* A sorted list of sub directories. */
235         struct isoent           **children_sorted;
236         /* Used for managing struct isoent list. */
237         struct isoent           *chnext;
238         struct isoent           *drnext;
239         struct isoent           *ptnext;
240
241         /*
242          * Used for making a Directory Record.
243          */
244         int                      dir_number;
245         struct {
246                 int              vd;
247                 int              self;
248                 int              parent;
249                 int              normal;
250         }                        dr_len;
251         uint32_t                 dir_location;
252         int                      dir_block;
253
254         /*
255          * Identifier:
256          *   on primary, ISO9660 file/directory name.
257          *   on joliet, UCS2 file/directory name.
258          * ext_off   : offset of identifier extension.
259          * ext_len   : length of identifier extension.
260          * id_len    : byte size of identifier.
261          *   on primary, this is ext_off + ext_len + version length.
262          *   on joliet, this is ext_off + ext_len.
263          * mb_len    : length of multibyte-character of identifier.
264          *   on primary, mb_len and id_len are always the same.
265          *   on joliet, mb_len and id_len are different.
266          */
267         char                    *identifier;
268         int                      ext_off;
269         int                      ext_len;
270         int                      id_len;
271         int                      mb_len;
272
273         /*
274          * Used for making a Rockridge extension.
275          * This is a part of Directory Records.
276          */
277         struct isoent           *rr_parent;
278         struct isoent           *rr_child;
279
280         /* Extra Record.(which we call in this source file)
281          * A maximum size of the Directory Record is 254.
282          * so, if generated RRIP data of a file cannot into a Directory
283          * Record because of its size, that surplus data relocate this
284          * Extra Record.
285          */
286         struct {
287                 struct extr_rec *first;
288                 struct extr_rec **last;
289                 struct extr_rec *current;
290         }                        extr_rec_list;
291
292         int                      virtual:1;
293         /* If set to one, this file type is a directory.
294          * A convenience flag to be used as
295          * "archive_entry_filetype(isoent->file->entry) == AE_IFDIR".
296          */
297         int                      dir:1;
298 };
299
300 struct hardlink {
301         struct archive_rb_node   rbnode;
302         int                      nlink;
303         struct {
304                 struct isofile  *first;
305                 struct isofile  **last;
306         }                        file_list;
307 };
308
309 /*
310  * ISO writer options
311  */
312 struct iso_option {
313         /*
314          * Usage  : abstract-file=<value>
315          * Type   : string, max 37 bytes
316          * Default: Not specified
317          * COMPAT : mkisofs -abstract <value>
318          *
319          * Specifies Abstract Filename.
320          * This file shall be described in the Root Directory
321          * and containing a abstract statement.
322          */
323         unsigned int     abstract_file:1;
324 #define OPT_ABSTRACT_FILE_DEFAULT       0       /* Not specified */
325 #define ABSTRACT_FILE_SIZE              37
326
327         /*
328          * Usage  : application-id=<value>
329          * Type   : string, max 128 bytes
330          * Default: Not specified
331          * COMPAT : mkisofs -A/-appid <value>.
332          *
333          * Specifies Application Identifier.
334          * If the first byte is set to '_'(5F), the remaining
335          * bytes of this option shall specify an identifier
336          * for a file containing the identification of the
337          * application.
338          * This file shall be described in the Root Directory.
339          */
340         unsigned int     application_id:1;
341 #define OPT_APPLICATION_ID_DEFAULT      0       /* Use default identifier */
342 #define APPLICATION_IDENTIFIER_SIZE     128
343
344         /*
345          * Usage : !allow-vernum
346          * Type  : boolean
347          * Default: Enabled
348          *        : Violates the ISO9660 standard if disable.
349          * COMPAT: mkisofs -N
350          *
351          * Allow filenames to use version numbers.
352          */
353         unsigned int     allow_vernum:1;
354 #define OPT_ALLOW_VERNUM_DEFAULT        1       /* Enabled */
355
356         /*
357          * Usage  : biblio-file=<value>
358          * Type   : string, max 37 bytes
359          * Default: Not specified
360          * COMPAT : mkisofs -biblio <value>
361          *
362          * Specifies Bibliographic Filename.
363          * This file shall be described in the Root Directory
364          * and containing bibliographic records.
365          */
366         unsigned int     biblio_file:1;
367 #define OPT_BIBLIO_FILE_DEFAULT         0       /* Not specified */
368 #define BIBLIO_FILE_SIZE                37
369
370         /*
371          * Usage  : boot=<value>
372          * Type   : string
373          * Default: Not specified
374          * COMPAT : mkisofs -b/-eltorito-boot <value>
375          *
376          * Specifies "El Torito" boot image file to make
377          * a bootable CD.
378          */
379         unsigned int     boot:1;
380 #define OPT_BOOT_DEFAULT                0       /* Not specified */
381
382         /*
383          * Usage  : boot-catalog=<value>
384          * Type   : string
385          * Default: "boot.catalog"
386          * COMPAT : mkisofs -c/-eltorito-catalog <value>
387          *
388          * Specifies a fullpath of El Torito boot catalog.
389          */
390         unsigned int     boot_catalog:1;
391 #define OPT_BOOT_CATALOG_DEFAULT        0       /* Not specified */
392
393         /*
394          * Usage  : boot-info-table
395          * Type   : boolean
396          * Default: Disabled
397          * COMPAT : mkisofs -boot-info-table
398          *
399          * Modify the boot image file specified by `boot'
400          * option; ISO writer stores boot file information
401          * into the boot file in ISO image at offset 8
402          * through offset 64.
403          */
404         unsigned int     boot_info_table:1;
405 #define OPT_BOOT_INFO_TABLE_DEFAULT     0       /* Disabled */
406
407         /*
408          * Usage  : boot-load-seg=<value>
409          * Type   : hexadecimal
410          * Default: Not specified
411          * COMPAT : mkisofs -boot-load-seg <value>
412          *
413          * Specifies a load segment for boot image.
414          * This is used with no-emulation mode.
415          */
416         unsigned int     boot_load_seg:1;
417 #define OPT_BOOT_LOAD_SEG_DEFAULT       0       /* Not specified */
418
419         /*
420          * Usage  : boot-load-size=<value>
421          * Type   : decimal
422          * Default: Not specified
423          * COMPAT : mkisofs -boot-load-size <value>
424          *
425          * Specifies a sector count for boot image.
426          * This is used with no-emulation mode.
427          */
428         unsigned int     boot_load_size:1;
429 #define OPT_BOOT_LOAD_SIZE_DEFAULT      0       /* Not specified */
430
431         /*
432          * Usage  : boot-type=<boot-media-type>
433          *        : 'no-emulation' : 'no emulation' image
434          *        :           'fd' : floppy disk image
435          *        :    'hard-disk' : hard disk image
436          * Type   : string
437          * Default: Auto detect
438          *        : We check a size of boot image;
439          *        : If ths size is just 1.22M/1.44M/2.88M,
440          *        : we assume boot_type is 'fd';
441          *        : otherwise boot_type is 'no-emulation'.
442          * COMPAT :
443          *    boot=no-emulation
444          *      mkisofs -no-emul-boot
445          *    boot=fd
446          *      This is a default on the mkisofs.
447          *    boot=hard-disk
448          *      mkisofs -hard-disk-boot
449          *
450          * Specifies a type of "El Torito" boot image.
451          */
452         unsigned int     boot_type:2;
453 #define OPT_BOOT_TYPE_AUTO              0       /* auto detect            */
454 #define OPT_BOOT_TYPE_NO_EMU            1       /* ``no emulation'' image */
455 #define OPT_BOOT_TYPE_FD                2       /* floppy disk image      */
456 #define OPT_BOOT_TYPE_HARD_DISK         3       /* hard disk image        */
457 #define OPT_BOOT_TYPE_DEFAULT           OPT_BOOT_TYPE_AUTO
458
459         /*
460          * Usage  : compression-level=<value>
461          * Type   : decimal
462          * Default: Not specified
463          * COMPAT : NONE
464          *
465          * Specifies compression level for option zisofs=direct.
466          */
467         unsigned int     compression_level:1;
468 #define OPT_COMPRESSION_LEVEL_DEFAULT   0       /* Not specified */
469
470         /*
471          * Usage  : copyright-file=<value>
472          * Type   : string, max 37 bytes
473          * Default: Not specified
474          * COMPAT : mkisofs -copyright <value>
475          *
476          * Specifies Copyright Filename.
477          * This file shall be described in the Root Directory
478          * and containing a copyright statement.
479          */
480         unsigned int     copyright_file:1;
481 #define OPT_COPYRIGHT_FILE_DEFAULT      0       /* Not specified */
482 #define COPYRIGHT_FILE_SIZE             37
483
484         /*
485          * Usage  : gid=<value>
486          * Type   : decimal
487          * Default: Not specified
488          * COMPAT : mkisofs -gid <value>
489          *
490          * Specifies a group id to rewrite the group id of all files.
491          */
492         unsigned int     gid:1;
493 #define OPT_GID_DEFAULT                 0       /* Not specified */
494
495         /*
496          * Usage  : iso-level=[1234]
497          * Type   : decimal
498          * Default: 1
499          * COMPAT : mkisofs -iso-level <value>
500          *
501          * Specifies ISO9600 Level.
502          * Level 1: [DEFAULT]
503          *   - limits each file size less than 4Gi bytes;
504          *   - a File Name shall not contain more than eight
505          *     d-characters or eight d1-characters;
506          *   - a File Name Extension shall not contain more than
507          *     three d-characters or three d1-characters;
508          *   - a Directory Identifier shall not contain more
509          *     than eight d-characters or eight d1-characters.
510          * Level 2:
511          *   - limits each file size less than 4Giga bytes;
512          *   - a File Name shall not contain more than thirty
513          *     d-characters or thirty d1-characters;
514          *   - a File Name Extension shall not contain more than
515          *     thirty d-characters or thirty d1-characters;
516          *   - a Directory Identifier shall not contain more
517          *     than thirty-one d-characters or thirty-one
518          *     d1-characters.
519          * Level 3:
520          *   - no limit of file size; use multi extent.
521          * Level 4:
522          *   - this level 4 simulates mkisofs option
523          *     '-iso-level 4';
524          *   - crate a enhanced volume as mkisofs doing;
525          *   - allow a File Name to have leading dot;
526          *   - allow a File Name to have all ASCII letters;
527          *   - allow a File Name to have multiple dots;
528          *   - allow more then 8 depths of directory trees;
529          *   - disable a version number to a File Name;
530          *   - disable a forced period to the tail of a File Name;
531          *   - the maxinum length of files and directories is raised to 193.
532          *     if rockridge option is disabled, raised to 207.
533          */
534         unsigned int     iso_level:3;
535 #define OPT_ISO_LEVEL_DEFAULT           1       /* ISO Level 1 */
536
537         /*
538          * Usage  : joliet[=long]
539          *        : !joliet
540          *        :   Do not generate Joliet Volume and Records.
541          *        : joliet [DEFAULT]
542          *        :   Generates Joliet Volume and Directory Records.
543          *        :   [COMPAT: mkisofs -J/-joliet]
544          *        : joliet=long
545          *        :   The joliet filenames are up to 103 Unicode
546          *        :   characters.
547          *        :   This option breaks the Joliet specification.
548          *        :   [COMPAT: mkisofs -J -joliet-long]
549          * Type   : boolean/string
550          * Default: Enabled
551          * COMPAT : mkisofs -J / -joliet-long
552          *
553          * Generates Joliet Volume and Directory Records.
554          */
555         unsigned int     joliet:2;
556 #define OPT_JOLIET_DISABLE              0       /* Not generate Joliet Records. */
557 #define OPT_JOLIET_ENABLE               1       /* Generate Joliet Records.  */
558 #define OPT_JOLIET_LONGNAME             2       /* Use long joliet filenames.*/
559 #define OPT_JOLIET_DEFAULT              OPT_JOLIET_ENABLE
560
561         /*
562          * Usage  : !limit-depth
563          * Type   : boolean
564          * Default: Enabled
565          *        : Violates the ISO9660 standard if disable.
566          * COMPAT : mkisofs -D/-disable-deep-relocation
567          *
568          * The number of levels in hierarchy cannot exceed eight.
569          */
570         unsigned int     limit_depth:1;
571 #define OPT_LIMIT_DEPTH_DEFAULT         1       /* Enabled */
572
573         /*
574          * Usage  : !limit-dirs
575          * Type   : boolean
576          * Default: Enabled
577          *        : Violates the ISO9660 standard if disable.
578          * COMPAT : mkisofs -no-limit-pathtables
579          *
580          * Limits the number of directories less than 65536 due
581          * to the size of the Parent Directory Number of Path
582          * Table.
583          */
584         unsigned int     limit_dirs:1;
585 #define OPT_LIMIT_DIRS_DEFAULT          1       /* Enabled */
586
587         /*
588          * Usage  : !pad
589          * Type   : boolean
590          * Default: Enabled
591          * COMPAT : -pad/-no-pad
592          *
593          * Pads the end of the ISO image by null of 300Ki bytes.
594          */
595         unsigned int     pad:1;
596 #define OPT_PAD_DEFAULT                 1       /* Enabled */
597
598         /*
599          * Usage  : publisher=<value>
600          * Type   : string, max 128 bytes
601          * Default: Not specified
602          * COMPAT : mkisofs -publisher <value>
603          *
604          * Specifies Publisher Identifier.
605          * If the first byte is set to '_'(5F), the remaining
606          * bytes of this option shall specify an identifier
607          * for a file containing the identification of the user.
608          * This file shall be described in the Root Directory.
609          */
610         unsigned int     publisher:1;
611 #define OPT_PUBLISHER_DEFAULT           0       /* Not specified */
612 #define PUBLISHER_IDENTIFIER_SIZE       128
613
614         /*
615          * Usage  : rockridge
616          *        : !rockridge
617          *        :    disable to generate SUSP and RR records.
618          *        : rockridge
619          *        :    the same as 'rockridge=useful'.
620          *        : rockridge=strict
621          *        :    generate SUSP and RR records.
622          *        :    [COMPAT: mkisofs -R]
623          *        : rockridge=useful [DEFAULT]
624          *        :    generate SUSP and RR records.
625          *        :    [COMPAT: mkisofs -r]
626          *        :    NOTE  Our rockridge=useful option does not set a zero
627          *        :          to uid and gid, you should use application
628          *        :          option such as --gid,--gname,--uid and --uname
629          *        :          badtar options instead.
630          * Type   : boolean/string
631          * Default: Enabled as rockridge=useful
632          * COMPAT : mkisofs -r / -R
633          *
634          * Generates SUSP and RR records.
635          */
636         unsigned int     rr:2;
637 #define OPT_RR_DISABLED                 0
638 #define OPT_RR_STRICT                   1
639 #define OPT_RR_USEFUL                   2
640 #define OPT_RR_DEFAULT                  OPT_RR_USEFUL
641
642         /*
643          * Usage  : volume-id=<value>
644          * Type   : string, max 32 bytes
645          * Default: Not specified
646          * COMPAT : mkisofs -V <value>
647          *
648          * Specifies Volume Identifier.
649          */
650         unsigned int     volume_id:1;
651 #define OPT_VOLUME_ID_DEFAULT           0       /* Use default identifier */
652 #define VOLUME_IDENTIFIER_SIZE          32
653
654         /*
655          * Usage  : !zisofs [DEFAULT] 
656          *        :    Disable to generate RRIP 'ZF' extension.
657          *        : zisofs
658          *        :    Make files zisofs file and generate RRIP 'ZF'
659          *        :    extension. So you do not need mkzftree utility
660          *        :    for making zisofs.
661          *        :    When the file size is less than one Logical Block
662          *        :    size, that file will not zisofs'ed since it does
663          *        :    reduece an ISO-image size.
664          *        :
665          *        :    When you specify option 'boot=<boot-image>', that
666          *        :    'boot-image' file won't be converted to zisofs file.
667          * Type   : boolean
668          * Default: Disabled
669          *
670          * Generates RRIP 'ZF' System Use Entry.
671          */
672         unsigned int     zisofs:1;
673 #define OPT_ZISOFS_DISABLED             0
674 #define OPT_ZISOFS_DIRECT               1
675 #define OPT_ZISOFS_DEFAULT              OPT_ZISOFS_DISABLED
676
677 };
678
679 struct iso9660 {
680         /* The creation time of ISO image. */
681         time_t                   birth_time;
682         /* A file stream of a temporary file, which file contents
683          * save to until ISO iamge can be created. */
684         int                      temp_fd;
685
686         struct isofile          *cur_file;
687         struct isoent           *cur_dirent;
688         struct archive_string    cur_dirstr;
689         uint64_t                 bytes_remaining;
690         int                      need_multi_extent;
691
692         /* Temporary string buffer for Joliet extension. */ 
693         struct archive_string    utf16be;
694         struct archive_string    mbs;
695
696         struct archive_string_conv *sconv_to_utf16be;
697         struct archive_string_conv *sconv_from_utf16be;
698
699         /* A list of all of struct isofile entries. */
700         struct {
701                 struct isofile  *first;
702                 struct isofile  **last;
703         }                        all_file_list;
704
705         /* A list of struct isofile entries which have its
706          * contents and are not a directory, a hardlined file
707          * and a symlink file. */
708         struct {
709                 struct isofile  *first;
710                 struct isofile  **last;
711         }                        data_file_list;
712
713         /* Used for managing to find hardlinking files. */
714         struct archive_rb_tree   hardlink_rbtree;
715
716         /* Used for making the Path Table Record. */
717         struct vdd {
718                 /* the root of entry tree. */
719                 struct isoent   *rootent;
720                 enum vdd_type {
721                         VDD_PRIMARY,
722                         VDD_JOLIET,
723                         VDD_ENHANCED
724                 } vdd_type;
725
726                 struct path_table {
727                         struct isoent           *first;
728                         struct isoent           **last;
729                         struct isoent           **sorted;
730                         int                      cnt;
731                 } *pathtbl;
732                 int                              max_depth;
733
734                 int              path_table_block;
735                 int              path_table_size;
736                 int              location_type_L_path_table;
737                 int              location_type_M_path_table;
738                 int              total_dir_block;
739         } primary, joliet;
740
741         /* Used for making a Volume Descriptor. */
742         int                      volume_space_size;
743         int                      volume_sequence_number;
744         int                      total_file_block;
745         struct archive_string    volume_identifier;
746         struct archive_string    publisher_identifier;
747         struct archive_string    data_preparer_identifier;
748         struct archive_string    application_identifier;
749         struct archive_string    copyright_file_identifier;
750         struct archive_string    abstract_file_identifier;
751         struct archive_string    bibliographic_file_identifier;
752
753         /* Used for making rockridge extensions. */
754         int                      location_rrip_er;
755
756         /* Used for making zisofs. */
757         struct {
758                 int              detect_magic:1;
759                 int              making:1;
760                 int              allzero:1;
761                 unsigned char    magic_buffer[64];
762                 int              magic_cnt;
763
764 #ifdef HAVE_ZLIB_H
765                 /*
766                  * Copy a compressed file to iso9660.zisofs.temp_fd
767                  * and also copy a uncompressed file(original file) to
768                  * iso9660.temp_fd . If the number of logical block
769                  * of the compressed file is less than the number of
770                  * logical block of the uncompressed file, use it and
771                  * remove the copy of the uncompressed file.
772                  * but if not, we use uncompressed file and remove
773                  * the copy of the compressed file.
774                  */
775                 uint32_t        *block_pointers;
776                 size_t           block_pointers_allocated;
777                 int              block_pointers_cnt;
778                 int              block_pointers_idx;
779                 int64_t          total_size;
780                 int64_t          block_offset;
781
782                 z_stream         stream;
783                 int              stream_valid;
784                 int64_t          remaining;
785                 int              compression_level;
786 #endif
787         } zisofs;
788
789         struct isoent           *directories_too_deep;
790         int                      dircnt_max;
791
792         /* Write buffer. */
793 #define wb_buffmax()    (LOGICAL_BLOCK_SIZE * 32)
794 #define wb_remaining(a) (((struct iso9660 *)(a)->format_data)->wbuff_remaining)
795 #define wb_offset(a)    (((struct iso9660 *)(a)->format_data)->wbuff_offset \
796                 + wb_buffmax() - wb_remaining(a))
797         unsigned char            wbuff[LOGICAL_BLOCK_SIZE * 32];
798         size_t                   wbuff_remaining;
799         enum {
800                 WB_TO_STREAM,
801                 WB_TO_TEMP
802         }                        wbuff_type;
803         int64_t                  wbuff_offset;
804         int64_t                  wbuff_written;
805         int64_t                  wbuff_tail;
806
807         /* 'El Torito' boot data. */
808         struct {
809                 /* boot catalog file */
810                 struct archive_string    catalog_filename;
811                 struct isoent           *catalog;
812                 /* boot image file */
813                 struct archive_string    boot_filename;
814                 struct isoent           *boot;
815
816                 unsigned char            platform_id;
817 #define BOOT_PLATFORM_X86       0
818 #define BOOT_PLATFORM_PPC       1
819 #define BOOT_PLATFORM_MAC       2
820                 struct archive_string    id;
821                 unsigned char            media_type;
822 #define BOOT_MEDIA_NO_EMULATION         0
823 #define BOOT_MEDIA_1_2M_DISKETTE        1
824 #define BOOT_MEDIA_1_44M_DISKETTE       2
825 #define BOOT_MEDIA_2_88M_DISKETTE       3
826 #define BOOT_MEDIA_HARD_DISK            4
827                 unsigned char            system_type;
828                 uint16_t                 boot_load_seg;
829                 uint16_t                 boot_load_size;
830 #define BOOT_LOAD_SIZE          4
831         } el_torito;
832
833         struct iso_option        opt;
834 };
835
836 /*
837  * Types of Volume Descriptor
838  */
839 enum VD_type {
840         VDT_BOOT_RECORD=0,      /* Boot Record Volume Descriptor        */
841         VDT_PRIMARY=1,          /* Primary Volume Descriptor            */
842         VDT_SUPPLEMENTARY=2,    /* Supplementary Volume Descriptor      */
843         VDT_TERMINATOR=255      /* Volume Descriptor Set Terminator     */
844 };
845
846 /*
847  * Types of Directory Record
848  */
849 enum dir_rec_type {
850         DIR_REC_VD,             /* Stored in Volume Descriptor. */
851         DIR_REC_SELF,           /* Stored as Current Directory. */
852         DIR_REC_PARENT,         /* Stored as Parent Directory.  */
853         DIR_REC_NORMAL,         /* Stored as Child.             */
854 };
855
856 /*
857  * Kinds of Volume Descriptor Character
858  */
859 enum vdc {
860         VDC_STD,
861         VDC_LOWERCASE,
862         VDC_UCS2,
863         VDC_UCS2_DIRECT,
864 };
865
866 /*
867  * IDentifier Resolver.
868  * Used for resolving duplicated filenames.
869  */
870 struct idr {
871         struct idrent {
872                 struct archive_rb_node  rbnode;
873                 /* Used in wait_list. */
874                 struct idrent           *wnext;
875                 struct idrent           *avail;
876
877                 struct isoent           *isoent;
878                 int                      weight;
879                 int                      noff;
880                 int                      rename_num;
881         } *idrent_pool;
882
883         struct archive_rb_tree           rbtree;
884
885         struct {
886                 struct idrent           *first;
887                 struct idrent           **last;
888         } wait_list;
889
890         int                              pool_size;
891         int                              pool_idx;
892         int                              num_size;
893         int                              null_size;
894
895         char                             char_map[0x80];
896 };
897
898 enum char_type {
899         A_CHAR,
900         D_CHAR,
901 };
902
903
904 static int      iso9660_options(struct archive_write *,
905                     const char *, const char *);
906 static int      iso9660_write_header(struct archive_write *,
907                     struct archive_entry *);
908 static ssize_t  iso9660_write_data(struct archive_write *,
909                     const void *, size_t);
910 static int      iso9660_finish_entry(struct archive_write *);
911 static int      iso9660_close(struct archive_write *);
912 static int      iso9660_free(struct archive_write *);
913
914 static void     get_system_identitier(char *, size_t);
915 static void     set_str(unsigned char *, const char *, size_t, char,
916                     const char *);
917 static inline int joliet_allowed_char(unsigned char, unsigned char);
918 static int      set_str_utf16be(struct archive_write *, unsigned char *,
919                         const char *, size_t, uint16_t, enum vdc);
920 static int      set_str_a_characters_bp(struct archive_write *,
921                         unsigned char *, int, int, const char *, enum vdc);
922 static int      set_str_d_characters_bp(struct archive_write *,
923                         unsigned char *, int, int, const char *, enum  vdc);
924 static void     set_VD_bp(unsigned char *, enum VD_type, unsigned char);
925 static inline void set_unused_field_bp(unsigned char *, int, int);
926
927 static unsigned char *extra_open_record(unsigned char *, int,
928                     struct isoent *, struct ctl_extr_rec *);
929 static void     extra_close_record(struct ctl_extr_rec *, int);
930 static unsigned char * extra_next_record(struct ctl_extr_rec *, int);
931 static unsigned char *extra_get_record(struct isoent *, int *, int *, int *);
932 static void     extra_tell_used_size(struct ctl_extr_rec *, int);
933 static int      extra_setup_location(struct isoent *, int);
934 static int      set_directory_record_rr(unsigned char *, int,
935                     struct isoent *, struct iso9660 *, enum dir_rec_type);
936 static int      set_directory_record(unsigned char *, size_t,
937                     struct isoent *, struct iso9660 *, enum dir_rec_type,
938                     enum vdd_type);
939 static inline int get_dir_rec_size(struct iso9660 *, struct isoent *,
940                     enum dir_rec_type, enum vdd_type);
941 static inline unsigned char *wb_buffptr(struct archive_write *);
942 static int      wb_write_out(struct archive_write *);
943 static int      wb_consume(struct archive_write *, size_t);
944 #ifdef HAVE_ZLIB_H
945 static int      wb_set_offset(struct archive_write *, int64_t);
946 #endif
947 static int      write_null(struct archive_write *, size_t);
948 static int      write_VD_terminator(struct archive_write *);
949 static int      set_file_identifier(unsigned char *, int, int, enum vdc,
950                     struct archive_write *, struct vdd *,
951                     struct archive_string *, const char *, int,
952                     enum char_type);
953 static int      write_VD(struct archive_write *, struct vdd *);
954 static int      write_VD_boot_record(struct archive_write *);
955 static int      write_information_block(struct archive_write *);
956 static int      write_path_table(struct archive_write *, int,
957                     struct vdd *);
958 static int      write_directory_descriptors(struct archive_write *,
959                     struct vdd *);
960 static int      write_file_descriptors(struct archive_write *);
961 static int      write_rr_ER(struct archive_write *);
962 static void     calculate_path_table_size(struct vdd *);
963
964 static void     isofile_init_entry_list(struct iso9660 *);
965 static void     isofile_add_entry(struct iso9660 *, struct isofile *);
966 static void     isofile_free_all_entries(struct iso9660 *);
967 static void     isofile_init_entry_data_file_list(struct iso9660 *);
968 static void     isofile_add_data_file(struct iso9660 *, struct isofile *);
969 static struct isofile * isofile_new(struct archive_write *,
970                     struct archive_entry *);
971 static void     isofile_free(struct isofile *);
972 static int      isofile_gen_utility_names(struct archive_write *,
973                     struct isofile *);
974 static int      isofile_register_hardlink(struct archive_write *,
975                     struct isofile *);
976 static void     isofile_connect_hardlink_files(struct iso9660 *);
977 static void     isofile_init_hardlinks(struct iso9660 *);
978 static void     isofile_free_hardlinks(struct iso9660 *);
979
980 static struct isoent *isoent_new(struct isofile *);
981 static int      isoent_clone_tree(struct archive_write *,
982                     struct isoent **, struct isoent *);
983 static void     _isoent_free(struct isoent *isoent);
984 static void     isoent_free_all(struct isoent *);
985 static struct isoent * isoent_create_virtual_dir(struct archive_write *,
986                     struct iso9660 *, const char *);
987 static int      isoent_cmp_node(const struct archive_rb_node *,
988                     const struct archive_rb_node *);
989 static int      isoent_cmp_key(const struct archive_rb_node *,
990                     const void *);
991 static int      isoent_add_child_head(struct isoent *, struct isoent *);
992 static int      isoent_add_child_tail(struct isoent *, struct isoent *);
993 static void     isoent_remove_child(struct isoent *, struct isoent *);
994 static void     isoent_setup_directory_location(struct iso9660 *,
995                     int, struct vdd *);
996 static void     isoent_setup_file_location(struct iso9660 *, int);
997 static int      get_path_component(char *, int, const char *);
998 static int      isoent_tree(struct archive_write *, struct isoent **);
999 static struct isoent *isoent_find_child(struct isoent *, const char *);
1000 static struct isoent *isoent_find_entry(struct isoent *, const char *);
1001 static void     idr_relaxed_filenames(char *);
1002 static void     idr_init(struct iso9660 *, struct vdd *, struct idr *);
1003 static void     idr_cleanup(struct idr *);
1004 static int      idr_ensure_poolsize(struct archive_write *, struct idr *,
1005                     int);
1006 static int      idr_start(struct archive_write *, struct idr *,
1007                     int, int, int, int, const struct archive_rb_tree_ops *);
1008 static void     idr_register(struct idr *, struct isoent *, int,
1009                     int);
1010 static void     idr_extend_identifier(struct idrent *, int, int);
1011 static void     idr_resolve(struct idr *, void (*)(unsigned char *, int));
1012 static void     idr_set_num(unsigned char *, int);
1013 static void     idr_set_num_beutf16(unsigned char *, int);
1014 static int      isoent_gen_iso9660_identifier(struct archive_write *,
1015                     struct isoent *, struct idr *);
1016 static int      isoent_gen_joliet_identifier(struct archive_write *,
1017                     struct isoent *, struct idr *);
1018 static int      isoent_cmp_iso9660_identifier(const struct isoent *,
1019                     const struct isoent *);
1020 static int      isoent_cmp_node_iso9660(const struct archive_rb_node *,
1021                     const struct archive_rb_node *);
1022 static int      isoent_cmp_key_iso9660(const struct archive_rb_node *,
1023                     const void *);
1024 static int      isoent_cmp_joliet_identifier(const struct isoent *,
1025                     const struct isoent *);
1026 static int      isoent_cmp_node_joliet(const struct archive_rb_node *,
1027                     const struct archive_rb_node *);
1028 static int      isoent_cmp_key_joliet(const struct archive_rb_node *,
1029                     const void *);
1030 static inline void path_table_add_entry(struct path_table *, struct isoent *);
1031 static inline struct isoent * path_table_last_entry(struct path_table *);
1032 static int      isoent_make_path_table(struct archive_write *);
1033 static int      isoent_find_out_boot_file(struct archive_write *,
1034                     struct isoent *);
1035 static int      isoent_create_boot_catalog(struct archive_write *,
1036                     struct isoent *);
1037 static size_t   fd_boot_image_size(int);
1038 static int      make_boot_catalog(struct archive_write *);
1039 static int      setup_boot_information(struct archive_write *);
1040
1041 static int      zisofs_init(struct archive_write *, struct isofile *);
1042 static void     zisofs_detect_magic(struct archive_write *,
1043                     const void *, size_t);
1044 static int      zisofs_write_to_temp(struct archive_write *,
1045                     const void *, size_t);
1046 static int      zisofs_finish_entry(struct archive_write *);
1047 static int      zisofs_rewind_boot_file(struct archive_write *);
1048 static int      zisofs_free(struct archive_write *);
1049
1050 int
1051 archive_write_set_format_iso9660(struct archive *_a)
1052 {
1053         struct archive_write *a = (struct archive_write *)_a;
1054         struct iso9660 *iso9660;
1055
1056         archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
1057             ARCHIVE_STATE_NEW, "archive_write_set_format_iso9660");
1058
1059         /* If another format was already registered, unregister it. */
1060         if (a->format_free != NULL)
1061                 (a->format_free)(a);
1062
1063         iso9660 = calloc(1, sizeof(*iso9660));
1064         if (iso9660 == NULL) {
1065                 archive_set_error(&a->archive, ENOMEM,
1066                     "Can't allocate iso9660 data");
1067                 return (ARCHIVE_FATAL);
1068         }
1069         iso9660->birth_time = 0;
1070         iso9660->temp_fd = -1;
1071         iso9660->cur_file = NULL;
1072         iso9660->primary.max_depth = 0;
1073         iso9660->primary.vdd_type = VDD_PRIMARY;
1074         iso9660->primary.pathtbl = NULL;
1075         iso9660->joliet.rootent = NULL;
1076         iso9660->joliet.max_depth = 0;
1077         iso9660->joliet.vdd_type = VDD_JOLIET;
1078         iso9660->joliet.pathtbl = NULL;
1079         isofile_init_entry_list(iso9660);
1080         isofile_init_entry_data_file_list(iso9660);
1081         isofile_init_hardlinks(iso9660);
1082         iso9660->directories_too_deep = NULL;
1083         iso9660->dircnt_max = 1;
1084         iso9660->wbuff_remaining = wb_buffmax();
1085         iso9660->wbuff_type = WB_TO_TEMP;
1086         iso9660->wbuff_offset = 0;
1087         iso9660->wbuff_written = 0;
1088         iso9660->wbuff_tail = 0;
1089         archive_string_init(&(iso9660->utf16be));
1090         archive_string_init(&(iso9660->mbs));
1091
1092         /*
1093          * Init Identifiers used for PVD and SVD.
1094          */
1095         archive_string_init(&(iso9660->volume_identifier));
1096         archive_strcpy(&(iso9660->volume_identifier), "CDROM");
1097         archive_string_init(&(iso9660->publisher_identifier));
1098         archive_string_init(&(iso9660->data_preparer_identifier));
1099         archive_string_init(&(iso9660->application_identifier));
1100         archive_strcpy(&(iso9660->application_identifier),
1101             archive_version_string());
1102         archive_string_init(&(iso9660->copyright_file_identifier));
1103         archive_string_init(&(iso9660->abstract_file_identifier));
1104         archive_string_init(&(iso9660->bibliographic_file_identifier));
1105
1106         /*
1107          * Init El Torito bootable CD variables.
1108          */
1109         archive_string_init(&(iso9660->el_torito.catalog_filename));
1110         iso9660->el_torito.catalog = NULL;
1111         /* Set default file name of boot catalog  */
1112         archive_strcpy(&(iso9660->el_torito.catalog_filename),
1113             "boot.catalog");
1114         archive_string_init(&(iso9660->el_torito.boot_filename));
1115         iso9660->el_torito.boot = NULL;
1116         iso9660->el_torito.platform_id = BOOT_PLATFORM_X86;
1117         archive_string_init(&(iso9660->el_torito.id));
1118         iso9660->el_torito.boot_load_seg = 0;
1119         iso9660->el_torito.boot_load_size = BOOT_LOAD_SIZE;
1120
1121         /*
1122          * Init zisofs variables.
1123          */
1124 #ifdef HAVE_ZLIB_H
1125         iso9660->zisofs.block_pointers = NULL;
1126         iso9660->zisofs.block_pointers_allocated = 0;
1127         iso9660->zisofs.stream_valid = 0;
1128         iso9660->zisofs.compression_level = 9;
1129         memset(&(iso9660->zisofs.stream), 0,
1130             sizeof(iso9660->zisofs.stream));
1131 #endif
1132
1133         /*
1134          * Set default value of iso9660 options.
1135          */
1136         iso9660->opt.abstract_file = OPT_ABSTRACT_FILE_DEFAULT;
1137         iso9660->opt.application_id = OPT_APPLICATION_ID_DEFAULT;
1138         iso9660->opt.allow_vernum = OPT_ALLOW_VERNUM_DEFAULT;
1139         iso9660->opt.biblio_file = OPT_BIBLIO_FILE_DEFAULT;
1140         iso9660->opt.boot = OPT_BOOT_DEFAULT;
1141         iso9660->opt.boot_catalog = OPT_BOOT_CATALOG_DEFAULT;
1142         iso9660->opt.boot_info_table = OPT_BOOT_INFO_TABLE_DEFAULT;
1143         iso9660->opt.boot_load_seg = OPT_BOOT_LOAD_SEG_DEFAULT;
1144         iso9660->opt.boot_load_size = OPT_BOOT_LOAD_SIZE_DEFAULT;
1145         iso9660->opt.boot_type = OPT_BOOT_TYPE_DEFAULT;
1146         iso9660->opt.compression_level = OPT_COMPRESSION_LEVEL_DEFAULT;
1147         iso9660->opt.copyright_file = OPT_COPYRIGHT_FILE_DEFAULT;
1148         iso9660->opt.iso_level = OPT_ISO_LEVEL_DEFAULT;
1149         iso9660->opt.joliet = OPT_JOLIET_DEFAULT;
1150         iso9660->opt.limit_depth = OPT_LIMIT_DEPTH_DEFAULT;
1151         iso9660->opt.limit_dirs = OPT_LIMIT_DIRS_DEFAULT;
1152         iso9660->opt.pad = OPT_PAD_DEFAULT;
1153         iso9660->opt.publisher = OPT_PUBLISHER_DEFAULT;
1154         iso9660->opt.rr = OPT_RR_DEFAULT;
1155         iso9660->opt.volume_id = OPT_VOLUME_ID_DEFAULT;
1156         iso9660->opt.zisofs = OPT_ZISOFS_DEFAULT;
1157
1158         /* Create the root directory. */
1159         iso9660->primary.rootent =
1160             isoent_create_virtual_dir(a, iso9660, "");
1161         if (iso9660->primary.rootent == NULL) {
1162                 free(iso9660);
1163                 archive_set_error(&a->archive, ENOMEM,
1164                     "Can't allocate memory");
1165                 return (ARCHIVE_FATAL);
1166         }
1167         iso9660->primary.rootent->parent = iso9660->primary.rootent;
1168         iso9660->cur_dirent = iso9660->primary.rootent;
1169         archive_string_init(&(iso9660->cur_dirstr));
1170         archive_string_ensure(&(iso9660->cur_dirstr), 1);
1171         iso9660->cur_dirstr.s[0] = 0;
1172         iso9660->sconv_to_utf16be = NULL;
1173         iso9660->sconv_from_utf16be = NULL;
1174
1175         a->format_data = iso9660;
1176         a->format_name = "iso9660";
1177         a->format_options = iso9660_options;
1178         a->format_write_header = iso9660_write_header;
1179         a->format_write_data = iso9660_write_data;
1180         a->format_finish_entry = iso9660_finish_entry;
1181         a->format_close = iso9660_close;
1182         a->format_free = iso9660_free;
1183         a->archive.archive_format = ARCHIVE_FORMAT_ISO9660;
1184         a->archive.archive_format_name = "ISO9660";
1185
1186         return (ARCHIVE_OK);
1187 }
1188
1189 static int
1190 get_str_opt(struct archive_write *a, struct archive_string *s,
1191     size_t maxsize, const char *key, const char *value)
1192 {
1193
1194         if (strlen(value) > maxsize) {
1195                 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1196                     "Value is longer than %zu characters "
1197                     "for option ``%s''", maxsize, key);
1198                 return (ARCHIVE_FATAL);
1199         }
1200         archive_strcpy(s, value);
1201         return (ARCHIVE_OK);
1202 }
1203
1204 static int
1205 get_num_opt(struct archive_write *a, int *num, int high, int low,
1206     const char *key, const char *value)
1207 {
1208         const char *p = value;
1209         int data = 0;
1210         int neg = 0;
1211
1212         if (p == NULL) {
1213                 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1214                     "Invalid value(empty) for option ``%s''", key);
1215                 return (ARCHIVE_FATAL);
1216         }
1217         if (*p == '-') {
1218                 neg = 1;
1219                 p++;
1220         }
1221         while (*p) {
1222                 if (*p >= '0' && *p <= '9')
1223                         data = data * 10 + *p - '0';
1224                 else {
1225                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1226                             "Invalid value for option ``%s''", key);
1227                         return (ARCHIVE_FATAL);
1228                 }
1229                 if (data > high) {
1230                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1231                             "Invalid value(over %d) for "
1232                             "option ``%s''", high, key);
1233                         return (ARCHIVE_FATAL);
1234                 }
1235                 if (data < low) {
1236                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1237                             "Invalid value(under %d) for "
1238                             "option ``%s''", low, key);
1239                         return (ARCHIVE_FATAL);
1240                 }
1241                 p++;
1242         }
1243         if (neg)
1244                 data *= -1;
1245         *num = data;
1246
1247         return (ARCHIVE_OK);
1248 }
1249
1250 static int
1251 iso9660_options(struct archive_write *a, const char *key, const char *value)
1252 {
1253         struct iso9660 *iso9660 = a->format_data;
1254         const char *p;
1255         int r;
1256
1257         switch (key[0]) {
1258         case 'a':
1259                 if (strcmp(key, "abstract-file") == 0) {
1260                         r = get_str_opt(a,
1261                             &(iso9660->abstract_file_identifier),
1262                             ABSTRACT_FILE_SIZE, key, value);
1263                         iso9660->opt.abstract_file = r == ARCHIVE_OK;
1264                         return (r);
1265                 }
1266                 if (strcmp(key, "application-id") == 0) {
1267                         r = get_str_opt(a,
1268                             &(iso9660->application_identifier),
1269                             APPLICATION_IDENTIFIER_SIZE, key, value);
1270                         iso9660->opt.application_id = r == ARCHIVE_OK;
1271                         return (r);
1272                 }
1273                 if (strcmp(key, "allow-vernum") == 0) {
1274                         iso9660->opt.allow_vernum = value != NULL;
1275                         return (ARCHIVE_OK);
1276                 }
1277                 break;
1278         case 'b':
1279                 if (strcmp(key, "biblio-file") == 0) {
1280                         r = get_str_opt(a,
1281                             &(iso9660->bibliographic_file_identifier),
1282                             BIBLIO_FILE_SIZE, key, value);
1283                         iso9660->opt.biblio_file = r == ARCHIVE_OK;
1284                         return (r);
1285                 }
1286                 if (strcmp(key, "boot") == 0) {
1287                         if (value == NULL)
1288                                 iso9660->opt.boot = 0;
1289                         else {
1290                                 iso9660->opt.boot = 1;
1291                                 archive_strcpy(
1292                                     &(iso9660->el_torito.boot_filename),
1293                                     value);
1294                         }
1295                         return (ARCHIVE_OK);
1296                 }
1297                 if (strcmp(key, "boot-catalog") == 0) {
1298                         r = get_str_opt(a,
1299                             &(iso9660->el_torito.catalog_filename),
1300                             1024, key, value);
1301                         iso9660->opt.boot_catalog = r == ARCHIVE_OK;
1302                         return (r);
1303                 }
1304                 if (strcmp(key, "boot-info-table") == 0) {
1305                         iso9660->opt.boot_info_table = value != NULL;
1306                         return (ARCHIVE_OK);
1307                 }
1308                 if (strcmp(key, "boot-load-seg") == 0) {
1309                         uint32_t seg;
1310
1311                         iso9660->opt.boot_load_seg = 0;
1312                         if (value == NULL)
1313                                 goto invalid_value;
1314                         seg = 0;
1315                         p = value;
1316                         if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X'))
1317                                 p += 2;
1318                         while (*p) {
1319                                 if (seg)
1320                                         seg <<= 4;
1321                                 if (*p >= 'A' && *p <= 'F')
1322                                         seg += *p - 'A' + 0x0a;
1323                                 else if (*p >= 'a' && *p <= 'f')
1324                                         seg += *p - 'a' + 0x0a;
1325                                 else if (*p >= '0' && *p <= '9')
1326                                         seg += *p - '0';
1327                                 else
1328                                         goto invalid_value;
1329                                 if (seg > 0xffff) {
1330                                         archive_set_error(&a->archive,
1331                                             ARCHIVE_ERRNO_MISC,
1332                                             "Invalid value(over 0xffff) for "
1333                                             "option ``%s''", key);
1334                                         return (ARCHIVE_FATAL);
1335                                 }
1336                                 p++;
1337                         }
1338                         iso9660->el_torito.boot_load_seg = (uint16_t)seg;
1339                         iso9660->opt.boot_load_seg = 1;
1340                         return (ARCHIVE_OK);
1341                 }
1342                 if (strcmp(key, "boot-load-size") == 0) {
1343                         int num = 0;
1344                         r = get_num_opt(a, &num, 0xffff, 1, key, value);
1345                         iso9660->opt.boot_load_size = r == ARCHIVE_OK;
1346                         if (r != ARCHIVE_OK)
1347                                 return (ARCHIVE_FATAL);
1348                         iso9660->el_torito.boot_load_size = (uint16_t)num;
1349                         return (ARCHIVE_OK);
1350                 }
1351                 if (strcmp(key, "boot-type") == 0) {
1352                         if (value == NULL)
1353                                 goto invalid_value;
1354                         if (strcmp(value, "no-emulation") == 0)
1355                                 iso9660->opt.boot_type = OPT_BOOT_TYPE_NO_EMU;
1356                         else if (strcmp(value, "fd") == 0)
1357                                 iso9660->opt.boot_type = OPT_BOOT_TYPE_FD;
1358                         else if (strcmp(value, "hard-disk") == 0)
1359                                 iso9660->opt.boot_type = OPT_BOOT_TYPE_HARD_DISK;
1360                         else
1361                                 goto invalid_value;
1362                         return (ARCHIVE_OK);
1363                 }
1364                 break;
1365         case 'c':
1366                 if (strcmp(key, "compression-level") == 0) {
1367 #ifdef HAVE_ZLIB_H
1368                         if (value == NULL ||
1369                             !(value[0] >= '0' && value[0] <= '9') ||
1370                             value[1] != '\0')
1371                                 goto invalid_value;
1372                         iso9660->zisofs.compression_level = value[0] - '0';
1373                         iso9660->opt.compression_level = 1;
1374                         return (ARCHIVE_OK);
1375 #else
1376                         archive_set_error(&a->archive,
1377                             ARCHIVE_ERRNO_MISC,
1378                             "Option ``%s'' "
1379                             "is not supported on this platform.", key);
1380                         return (ARCHIVE_FATAL);
1381 #endif
1382                 }
1383                 if (strcmp(key, "copyright-file") == 0) {
1384                         r = get_str_opt(a,
1385                             &(iso9660->copyright_file_identifier),
1386                             COPYRIGHT_FILE_SIZE, key, value);
1387                         iso9660->opt.copyright_file = r == ARCHIVE_OK;
1388                         return (r);
1389                 }
1390 #ifdef DEBUG
1391                 /* Specifies Volume creation date and time;
1392                  * year(4),month(2),day(2),hour(2),minute(2),second(2).
1393                  * e.g. "20090929033757"
1394                  */
1395                 if (strcmp(key, "creation") == 0) {
1396                         struct tm tm;
1397                         char buf[5];
1398
1399                         p = value;
1400                         if (p == NULL || strlen(p) < 14)
1401                                 goto invalid_value;
1402                         memset(&tm, 0, sizeof(tm));
1403                         memcpy(buf, p, 4); buf[4] = '\0'; p += 4;
1404                         tm.tm_year = strtol(buf, NULL, 10) - 1900;
1405                         memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
1406                         tm.tm_mon = strtol(buf, NULL, 10) - 1;
1407                         memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
1408                         tm.tm_mday = strtol(buf, NULL, 10);
1409                         memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
1410                         tm.tm_hour = strtol(buf, NULL, 10);
1411                         memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
1412                         tm.tm_min = strtol(buf, NULL, 10);
1413                         memcpy(buf, p, 2); buf[2] = '\0';
1414                         tm.tm_sec = strtol(buf, NULL, 10);
1415                         iso9660->birth_time = mktime(&tm);
1416                         return (ARCHIVE_OK);
1417                 }
1418 #endif
1419                 break;
1420         case 'i':
1421                 if (strcmp(key, "iso-level") == 0) {
1422                         if (value != NULL && value[1] == '\0' &&
1423                             (value[0] >= '1' && value[0] <= '4')) {
1424                                 iso9660->opt.iso_level = value[0]-'0';
1425                                 return (ARCHIVE_OK);
1426                         }
1427                         goto invalid_value;
1428                 }
1429                 break;
1430         case 'j':
1431                 if (strcmp(key, "joliet") == 0) {
1432                         if (value == NULL)
1433                                 iso9660->opt.joliet = OPT_JOLIET_DISABLE;
1434                         else if (strcmp(value, "1") == 0)
1435                                 iso9660->opt.joliet = OPT_JOLIET_ENABLE;
1436                         else if (strcmp(value, "long") == 0)
1437                                 iso9660->opt.joliet = OPT_JOLIET_LONGNAME;
1438                         else
1439                                 goto invalid_value;
1440                         return (ARCHIVE_OK);
1441                 }
1442                 break;
1443         case 'l':
1444                 if (strcmp(key, "limit-depth") == 0) {
1445                         iso9660->opt.limit_depth = value != NULL;
1446                         return (ARCHIVE_OK);
1447                 }
1448                 if (strcmp(key, "limit-dirs") == 0) {
1449                         iso9660->opt.limit_dirs = value != NULL;
1450                         return (ARCHIVE_OK);
1451                 }
1452                 break;
1453         case 'p':
1454                 if (strcmp(key, "pad") == 0) {
1455                         iso9660->opt.pad = value != NULL;
1456                         return (ARCHIVE_OK);
1457                 }
1458                 if (strcmp(key, "publisher") == 0) {
1459                         r = get_str_opt(a,
1460                             &(iso9660->publisher_identifier),
1461                             PUBLISHER_IDENTIFIER_SIZE, key, value);
1462                         iso9660->opt.publisher = r == ARCHIVE_OK;
1463                         return (r);
1464                 }
1465                 break;
1466         case 'r':
1467                 if (strcmp(key, "rockridge") == 0 ||
1468                     strcmp(key, "Rockridge") == 0) {
1469                         if (value == NULL)
1470                                 iso9660->opt.rr = OPT_RR_DISABLED;
1471                         else if (strcmp(value, "1") == 0)
1472                                 iso9660->opt.rr = OPT_RR_USEFUL;
1473                         else if (strcmp(value, "strict") == 0)
1474                                 iso9660->opt.rr = OPT_RR_STRICT;
1475                         else if (strcmp(value, "useful") == 0)
1476                                 iso9660->opt.rr = OPT_RR_USEFUL;
1477                         else
1478                                 goto invalid_value;
1479                         return (ARCHIVE_OK);
1480                 }
1481                 break;
1482         case 'v':
1483                 if (strcmp(key, "volume-id") == 0) {
1484                         r = get_str_opt(a, &(iso9660->volume_identifier),
1485                             VOLUME_IDENTIFIER_SIZE, key, value);
1486                         iso9660->opt.volume_id = r == ARCHIVE_OK;
1487                         return (r);
1488                 }
1489                 break;
1490         case 'z':
1491                 if (strcmp(key, "zisofs") == 0) {
1492                         if (value == NULL)
1493                                 iso9660->opt.zisofs = OPT_ZISOFS_DISABLED;
1494                         else {
1495 #ifdef HAVE_ZLIB_H
1496                                 iso9660->opt.zisofs = OPT_ZISOFS_DIRECT;
1497 #else
1498                                 archive_set_error(&a->archive,
1499                                     ARCHIVE_ERRNO_MISC,
1500                                     "``zisofs'' "
1501                                     "is not supported on this platform.");
1502                                 return (ARCHIVE_FATAL);
1503 #endif
1504                         }
1505                         return (ARCHIVE_OK);
1506                 }
1507                 break;
1508         }
1509
1510 invalid_value:
1511         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1512             "Invalid value for option ``%s''", key);
1513         return (ARCHIVE_FAILED);
1514 }
1515
1516 static int
1517 iso9660_write_header(struct archive_write *a, struct archive_entry *entry)
1518 {
1519         struct iso9660 *iso9660;
1520         struct isofile *file;
1521         struct isoent *isoent;
1522         int r, ret = ARCHIVE_OK;
1523
1524         iso9660 = a->format_data;
1525
1526         iso9660->cur_file = NULL;
1527         iso9660->bytes_remaining = 0;
1528         iso9660->need_multi_extent = 0;
1529         if (archive_entry_filetype(entry) == AE_IFLNK
1530             && iso9660->opt.rr == OPT_RR_DISABLED) {
1531                 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1532                     "Ignore symlink file.");
1533                 iso9660->cur_file = NULL;
1534                 return (ARCHIVE_WARN);
1535         }
1536         if (archive_entry_filetype(entry) == AE_IFREG &&
1537             archive_entry_size(entry) >= MULTI_EXTENT_SIZE) {
1538                 if (iso9660->opt.iso_level < 3) {
1539                         archive_set_error(&a->archive,
1540                             ARCHIVE_ERRNO_MISC,
1541                             "Ignore over %lld bytes file. "
1542                             "This file too large.",
1543                             MULTI_EXTENT_SIZE);
1544                                 iso9660->cur_file = NULL;
1545                         return (ARCHIVE_WARN);
1546                 }
1547                 iso9660->need_multi_extent = 1;
1548         }
1549
1550         file = isofile_new(a, entry);
1551         if (file == NULL) {
1552                 archive_set_error(&a->archive, ENOMEM,
1553                     "Can't allocate data");
1554                 return (ARCHIVE_FATAL);
1555         }
1556         r = isofile_gen_utility_names(a, file);
1557         if (r < ARCHIVE_WARN) {
1558                 isofile_free(file);
1559                 return (r);
1560         }
1561         else if (r < ret)
1562                 ret = r;
1563
1564         /*
1565          * Ignore a path which looks like the top of directory name
1566          * since we have already made the root directory of an ISO image.
1567          */
1568         if (archive_strlen(&(file->parentdir)) == 0 &&
1569             archive_strlen(&(file->basename)) == 0) {
1570                 isofile_free(file);
1571                 return (r);
1572         }
1573
1574         isofile_add_entry(iso9660, file);
1575         isoent = isoent_new(file);
1576         if (isoent == NULL) {
1577                 archive_set_error(&a->archive, ENOMEM,
1578                     "Can't allocate data");
1579                 return (ARCHIVE_FATAL);
1580         }
1581         if (isoent->file->dircnt > iso9660->dircnt_max)
1582                 iso9660->dircnt_max = isoent->file->dircnt;
1583
1584         /* Add the current file into tree */
1585         r = isoent_tree(a, &isoent);
1586         if (r != ARCHIVE_OK)
1587                 return (r);
1588
1589         /* If there is the same file in tree and
1590          * the current file is older than the file in tree.
1591          * So we don't need the current file data anymore. */
1592         if (isoent->file != file)
1593                 return (ARCHIVE_OK);
1594
1595         /* Non regular files contents are unneeded to be saved to
1596          * temporary files. */
1597         if (archive_entry_filetype(file->entry) != AE_IFREG)
1598                 return (ret);
1599
1600         /*
1601          * Set the current file to cur_file to read its contents.
1602          */
1603         iso9660->cur_file = file;
1604
1605         if (archive_entry_nlink(file->entry) > 1) {
1606                 r = isofile_register_hardlink(a, file);
1607                 if (r != ARCHIVE_OK)
1608                         return (ARCHIVE_FATAL);
1609         }
1610
1611         /*
1612          * Prepare to save the contents of the file.
1613          */
1614         if (iso9660->temp_fd < 0) {
1615                 iso9660->temp_fd = __archive_mktemp(NULL);
1616                 if (iso9660->temp_fd < 0) {
1617                         archive_set_error(&a->archive, errno,
1618                             "Couldn't create temporary file");
1619                         return (ARCHIVE_FATAL);
1620                 }
1621         }
1622
1623         /* Save an offset of current file in temporary file. */
1624         file->content.offset_of_temp = wb_offset(a);
1625         file->cur_content = &(file->content);
1626         r = zisofs_init(a, file);
1627         if (r < ret)
1628                 ret = r;
1629         iso9660->bytes_remaining =  archive_entry_size(file->entry);
1630
1631         return (ret);
1632 }
1633
1634 static int
1635 write_to_temp(struct archive_write *a, const void *buff, size_t s)
1636 {
1637         struct iso9660 *iso9660 = a->format_data;
1638         ssize_t written;
1639         const unsigned char *b;
1640
1641         b = (const unsigned char *)buff;
1642         while (s) {
1643                 written = write(iso9660->temp_fd, b, s);
1644                 if (written < 0) {
1645                         archive_set_error(&a->archive, errno,
1646                             "Can't write to temporary file");
1647                         return (ARCHIVE_FATAL);
1648                 }
1649                 s -= written;
1650                 b += written;
1651         }
1652         return (ARCHIVE_OK);
1653 }
1654
1655 static int
1656 wb_write_to_temp(struct archive_write *a, const void *buff, size_t s)
1657 {
1658         const char *xp = buff;
1659         size_t xs = s;
1660
1661         /*
1662          * If a written data size is big enough to use system-call
1663          * and there is no waiting data, this calls write_to_temp() in
1664          * order to reduce a extra memory copy.
1665          */
1666         if (wb_remaining(a) == wb_buffmax() && s > (1024 * 16)) {
1667                 struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
1668                 xs = s % LOGICAL_BLOCK_SIZE;
1669                 iso9660->wbuff_offset += s - xs;
1670                 if (write_to_temp(a, buff, s - xs) != ARCHIVE_OK)
1671                         return (ARCHIVE_FATAL);
1672                 if (xs == 0)
1673                         return (ARCHIVE_OK);
1674                 xp += s - xs;
1675         }
1676
1677         while (xs) {
1678                 size_t size = xs;
1679                 if (size > wb_remaining(a))
1680                         size = wb_remaining(a);
1681                 memcpy(wb_buffptr(a), xp, size);
1682                 if (wb_consume(a, size) != ARCHIVE_OK)
1683                         return (ARCHIVE_FATAL);
1684                 xs -= size;
1685                 xp += size;
1686         }
1687         return (ARCHIVE_OK);
1688 }
1689
1690 static int
1691 wb_write_padding_to_temp(struct archive_write *a, int64_t csize)
1692 {
1693         size_t ns;
1694         int ret;
1695
1696         ns = csize % LOGICAL_BLOCK_SIZE;
1697         if (ns != 0)
1698                 ret = write_null(a, LOGICAL_BLOCK_SIZE - ns);
1699         else
1700                 ret = ARCHIVE_OK;
1701         return (ret);
1702 }
1703
1704 static ssize_t
1705 write_iso9660_data(struct archive_write *a, const void *buff, size_t s)
1706 {
1707         struct iso9660 *iso9660 = a->format_data;
1708         size_t ws;
1709
1710         if (iso9660->temp_fd < 0) {
1711                 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1712                     "Couldn't create temporary file");
1713                 return (ARCHIVE_FATAL);
1714         }
1715
1716         ws = s;
1717         if (iso9660->need_multi_extent &&
1718             (iso9660->cur_file->cur_content->size + ws) >=
1719               (MULTI_EXTENT_SIZE - LOGICAL_BLOCK_SIZE)) {
1720                 struct content *con;
1721                 size_t ts;
1722
1723                 ts = MULTI_EXTENT_SIZE - LOGICAL_BLOCK_SIZE -
1724                     iso9660->cur_file->cur_content->size;
1725
1726                 if (iso9660->zisofs.detect_magic)
1727                         zisofs_detect_magic(a, buff, ts);
1728
1729                 if (iso9660->zisofs.making) {
1730                         if (zisofs_write_to_temp(a, buff, ts) != ARCHIVE_OK)
1731                                 return (ARCHIVE_FATAL);
1732                 } else {
1733                         if (wb_write_to_temp(a, buff, ts) != ARCHIVE_OK)
1734                                 return (ARCHIVE_FATAL);
1735                         iso9660->cur_file->cur_content->size += ts;
1736                 }
1737
1738                 /* Write padding. */
1739                 if (wb_write_padding_to_temp(a,
1740                     iso9660->cur_file->cur_content->size) != ARCHIVE_OK)
1741                         return (ARCHIVE_FATAL);
1742
1743                 /* Compute the logical block number. */
1744                 iso9660->cur_file->cur_content->blocks =
1745                     (iso9660->cur_file->cur_content->size
1746                      + LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS;
1747
1748                 /*
1749                  * Make next extent.
1750                  */
1751                 ws -= ts;
1752                 buff = (const void *)(((const unsigned char *)buff) + ts);
1753                 /* Make a content for next extent. */
1754                 con = calloc(1, sizeof(*con));
1755                 if (con == NULL) {
1756                         archive_set_error(&a->archive, ENOMEM,
1757                             "Can't allocate content data");
1758                         return (ARCHIVE_FATAL);
1759                 }
1760                 con->offset_of_temp = wb_offset(a);
1761                 iso9660->cur_file->cur_content->next = con;
1762                 iso9660->cur_file->cur_content = con;
1763 #ifdef HAVE_ZLIB_H
1764                 iso9660->zisofs.block_offset = 0;
1765 #endif
1766         }
1767
1768         if (iso9660->zisofs.detect_magic)
1769                 zisofs_detect_magic(a, buff, ws);
1770
1771         if (iso9660->zisofs.making) {
1772                 if (zisofs_write_to_temp(a, buff, ws) != ARCHIVE_OK)
1773                         return (ARCHIVE_FATAL);
1774         } else {
1775                 if (wb_write_to_temp(a, buff, ws) != ARCHIVE_OK)
1776                         return (ARCHIVE_FATAL);
1777                 iso9660->cur_file->cur_content->size += ws;
1778         }
1779
1780         return (s);
1781 }
1782
1783 static ssize_t
1784 iso9660_write_data(struct archive_write *a, const void *buff, size_t s)
1785 {
1786         struct iso9660 *iso9660 = a->format_data;
1787         ssize_t r;
1788
1789         if (iso9660->cur_file == NULL)
1790                 return (0);
1791         if (archive_entry_filetype(iso9660->cur_file->entry) != AE_IFREG)
1792                 return (0);
1793         if (s > iso9660->bytes_remaining)
1794                 s = iso9660->bytes_remaining;
1795         if (s == 0)
1796                 return (0);
1797
1798         r = write_iso9660_data(a, buff, s);
1799         if (r > 0)
1800                 iso9660->bytes_remaining -= r;
1801         return (r);
1802 }
1803
1804 static int
1805 iso9660_finish_entry(struct archive_write *a)
1806 {
1807         struct iso9660 *iso9660 = a->format_data;
1808
1809         if (iso9660->cur_file == NULL)
1810                 return (ARCHIVE_OK);
1811         if (archive_entry_filetype(iso9660->cur_file->entry) != AE_IFREG)
1812                 return (ARCHIVE_OK);
1813         if (iso9660->cur_file->content.size == 0)
1814                 return (ARCHIVE_OK);
1815
1816         /* If there are unwritten data, write null data instead. */
1817         while (iso9660->bytes_remaining > 0) {
1818                 size_t s;
1819
1820                 s = (iso9660->bytes_remaining > a->null_length)?
1821                     a->null_length: (size_t)iso9660->bytes_remaining;
1822                 if (write_iso9660_data(a, a->nulls, s) < 0)
1823                         return (ARCHIVE_FATAL);
1824                 iso9660->bytes_remaining -= s;
1825         }
1826
1827         if (iso9660->zisofs.making && zisofs_finish_entry(a) != ARCHIVE_OK)
1828                 return (ARCHIVE_FATAL);
1829
1830         /* Write padding. */
1831         if (wb_write_padding_to_temp(a, iso9660->cur_file->cur_content->size)
1832             != ARCHIVE_OK)
1833                 return (ARCHIVE_FATAL);
1834
1835         /* Compute the logical block number. */
1836         iso9660->cur_file->cur_content->blocks =
1837             (iso9660->cur_file->cur_content->size
1838              + LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS;
1839
1840         /* Add the current file to data file list. */
1841         isofile_add_data_file(iso9660, iso9660->cur_file);
1842
1843         return (ARCHIVE_OK);
1844 }
1845
1846 static int
1847 iso9660_close(struct archive_write *a)
1848 {
1849         struct iso9660 *iso9660;
1850         int ret, blocks;
1851
1852         iso9660 = a->format_data;
1853
1854         /*
1855          * Write remaining data out to the temporary file.
1856          */
1857         if (wb_remaining(a) > 0) {
1858                 ret = wb_write_out(a);
1859                 if (ret < 0)
1860                         return (ret);
1861         }
1862
1863         /*
1864          * Preparations...
1865          */
1866 #ifdef DEBUG
1867         if (iso9660->birth_time == 0)
1868 #endif
1869                 time(&(iso9660->birth_time));
1870
1871         /*
1872          * Prepare a bootable ISO image.
1873          */
1874         if (iso9660->opt.boot) {
1875                 /* Find out the boot file entry. */
1876                 ret = isoent_find_out_boot_file(a, iso9660->primary.rootent);
1877                 if (ret < 0)
1878                         return (ret);
1879                 /* Reconvert the boot file from zisofs'ed form to
1880                  * plain form. */
1881                 ret = zisofs_rewind_boot_file(a);
1882                 if (ret < 0)
1883                         return (ret);
1884                 /* Write remaining data out to the temporary file. */
1885                 if (wb_remaining(a) > 0) {
1886                         ret = wb_write_out(a);
1887                         if (ret < 0)
1888                                 return (ret);
1889                 }
1890                 /* Create the boot catalog. */
1891                 ret = isoent_create_boot_catalog(a, iso9660->primary.rootent);
1892                 if (ret < 0)
1893                         return (ret);
1894         }
1895
1896         /*
1897          * Prepare joliet extensions.
1898          */
1899         if (iso9660->opt.joliet) {
1900                 /* Make a new tree for joliet. */
1901                 ret = isoent_clone_tree(a, &(iso9660->joliet.rootent),
1902                     iso9660->primary.rootent);
1903                 if (ret < 0)
1904                         return (ret);
1905                 /* Make sure we have UTF-16BE convertors.
1906                  * if there is no file entry, convertors are still
1907                  * uninitilized. */
1908                 if (iso9660->sconv_to_utf16be == NULL) {
1909                         iso9660->sconv_to_utf16be =
1910                             archive_string_conversion_to_charset(
1911                                 &(a->archive), "UTF-16BE", 1);
1912                         if (iso9660->sconv_to_utf16be == NULL)
1913                                 /* Couldn't allocate memory */
1914                                 return (ARCHIVE_FATAL);
1915                         iso9660->sconv_from_utf16be =
1916                             archive_string_conversion_from_charset(
1917                                 &(a->archive), "UTF-16BE", 1);
1918                         if (iso9660->sconv_from_utf16be == NULL)
1919                                 /* Couldn't allocate memory */
1920                                 return (ARCHIVE_FATAL);
1921                 }
1922         }
1923
1924         /*
1925          * Make Path Tables.
1926          */
1927         ret = isoent_make_path_table(a);
1928         if (ret < 0)
1929                 return (ret);
1930
1931         /*
1932          * Calculate a total volume size and setup all locations of
1933          * contents of an iso9660 image.
1934          */
1935         blocks = SYSTEM_AREA_BLOCK
1936                 + PRIMARY_VOLUME_DESCRIPTOR_BLOCK
1937                 + VOLUME_DESCRIPTOR_SET_TERMINATOR_BLOCK
1938                 + NON_ISO_FILE_SYSTEM_INFORMATION_BLOCK;
1939         if (iso9660->opt.boot)
1940                 blocks += BOOT_RECORD_DESCRIPTOR_BLOCK;
1941         if (iso9660->opt.joliet)
1942                 blocks += SUPPLEMENTARY_VOLUME_DESCRIPTOR_BLOCK;
1943         if (iso9660->opt.iso_level == 4)
1944                 blocks += SUPPLEMENTARY_VOLUME_DESCRIPTOR_BLOCK;
1945
1946         /* Setup the locations of Path Table. */
1947         iso9660->primary.location_type_L_path_table = blocks;
1948         blocks += iso9660->primary.path_table_block;
1949         iso9660->primary.location_type_M_path_table = blocks;
1950         blocks += iso9660->primary.path_table_block;
1951         if (iso9660->opt.joliet) {
1952                 iso9660->joliet.location_type_L_path_table = blocks;
1953                 blocks += iso9660->joliet.path_table_block;
1954                 iso9660->joliet.location_type_M_path_table = blocks;
1955                 blocks += iso9660->joliet.path_table_block;
1956         }
1957
1958         /* Setup the locations of directories. */
1959         isoent_setup_directory_location(iso9660, blocks,
1960             &(iso9660->primary));
1961         blocks += iso9660->primary.total_dir_block;
1962         if (iso9660->opt.joliet) {
1963                 isoent_setup_directory_location(iso9660, blocks,
1964                     &(iso9660->joliet));
1965                 blocks += iso9660->joliet.total_dir_block;
1966         }
1967
1968         if (iso9660->opt.rr) {
1969                 iso9660->location_rrip_er = blocks;
1970                 blocks += RRIP_ER_BLOCK;
1971         }
1972
1973         /* Setup the locations of all file contents. */
1974         isoent_setup_file_location(iso9660, blocks);
1975         blocks += iso9660->total_file_block;
1976         if (iso9660->opt.boot && iso9660->opt.boot_info_table) {
1977                 ret = setup_boot_information(a);
1978                 if (ret < 0)
1979                         return (ret);
1980         }
1981
1982         /* Now we have a total volume size. */
1983         iso9660->volume_space_size = blocks;
1984         if (iso9660->opt.pad)
1985                 iso9660->volume_space_size += PADDING_BLOCK;
1986         iso9660->volume_sequence_number = 1;
1987
1988
1989         /*
1990          * Write an ISO 9660 image.
1991          */
1992
1993         /* Switc to start using wbuff as file buffer. */
1994         iso9660->wbuff_remaining = wb_buffmax();
1995         iso9660->wbuff_type = WB_TO_STREAM;
1996         iso9660->wbuff_offset = 0;
1997         iso9660->wbuff_written = 0;
1998         iso9660->wbuff_tail = 0;
1999
2000         /* Write The System Area */
2001         ret = write_null(a, SYSTEM_AREA_BLOCK * LOGICAL_BLOCK_SIZE);
2002         if (ret != ARCHIVE_OK)
2003                 return (ARCHIVE_FATAL);
2004
2005         /* Write Primary Volume Descriptor */
2006         ret = write_VD(a, &(iso9660->primary));
2007         if (ret != ARCHIVE_OK)
2008                 return (ARCHIVE_FATAL);
2009
2010         if (iso9660->opt.boot) {
2011                 /* Write Boot Record Volume Descriptor */
2012                 ret = write_VD_boot_record(a);
2013                 if (ret != ARCHIVE_OK)
2014                         return (ARCHIVE_FATAL);
2015         }
2016
2017         if (iso9660->opt.iso_level == 4) {
2018                 /* Write Enhanced Volume Descriptor */
2019                 iso9660->primary.vdd_type = VDD_ENHANCED;
2020                 ret = write_VD(a, &(iso9660->primary));
2021                 iso9660->primary.vdd_type = VDD_PRIMARY;
2022                 if (ret != ARCHIVE_OK)
2023                         return (ARCHIVE_FATAL);
2024         }
2025
2026         if (iso9660->opt.joliet) {
2027                 ret = write_VD(a, &(iso9660->joliet));
2028                 if (ret != ARCHIVE_OK)
2029                         return (ARCHIVE_FATAL);
2030         }
2031
2032         /* Write Volume Descriptor Set Terminator */
2033         ret = write_VD_terminator(a);
2034         if (ret != ARCHIVE_OK)
2035                 return (ARCHIVE_FATAL);
2036
2037         /* Write Non-ISO File System Information */
2038         ret = write_information_block(a);
2039         if (ret != ARCHIVE_OK)
2040                 return (ARCHIVE_FATAL);
2041
2042         /* Write Type L Path Table */
2043         ret = write_path_table(a, 0, &(iso9660->primary));
2044         if (ret != ARCHIVE_OK)
2045                 return (ARCHIVE_FATAL);
2046
2047         /* Write Type M Path Table */
2048         ret = write_path_table(a, 1, &(iso9660->primary));
2049         if (ret != ARCHIVE_OK)
2050                 return (ARCHIVE_FATAL);
2051
2052         if (iso9660->opt.joliet) {
2053                 /* Write Type L Path Table */
2054                 ret = write_path_table(a, 0, &(iso9660->joliet));
2055                 if (ret != ARCHIVE_OK)
2056                         return (ARCHIVE_FATAL);
2057
2058                 /* Write Type M Path Table */
2059                 ret = write_path_table(a, 1, &(iso9660->joliet));
2060                 if (ret != ARCHIVE_OK)
2061                         return (ARCHIVE_FATAL);
2062         }
2063
2064         /* Write Directory Descriptors */
2065         ret = write_directory_descriptors(a, &(iso9660->primary));
2066         if (ret != ARCHIVE_OK)
2067                 return (ARCHIVE_FATAL);
2068
2069         if (iso9660->opt.joliet) {
2070                 ret = write_directory_descriptors(a, &(iso9660->joliet));
2071                 if (ret != ARCHIVE_OK)
2072                         return (ARCHIVE_FATAL);
2073         }
2074
2075         if (iso9660->opt.rr) {
2076                 /* Write Rockridge ER(Extensions Reference) */
2077                 ret = write_rr_ER(a);
2078                 if (ret != ARCHIVE_OK)
2079                         return (ARCHIVE_FATAL);
2080         }
2081
2082         /* Write File Descriptors */
2083         ret = write_file_descriptors(a);
2084         if (ret != ARCHIVE_OK)
2085                 return (ARCHIVE_FATAL);
2086
2087         /* Write Padding  */
2088         if (iso9660->opt.pad) {
2089                 ret = write_null(a, PADDING_BLOCK * LOGICAL_BLOCK_SIZE);
2090                 if (ret != ARCHIVE_OK)
2091                         return (ARCHIVE_FATAL);
2092         }
2093
2094         if (iso9660->directories_too_deep != NULL) {
2095                 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
2096                     "%s: Directories too deep.",
2097                     archive_entry_pathname(
2098                         iso9660->directories_too_deep->file->entry));
2099                 return (ARCHIVE_WARN);
2100         }
2101
2102         /* Write remaining data out. */
2103         ret = wb_write_out(a);
2104
2105         return (ret);
2106 }
2107
2108 static int
2109 iso9660_free(struct archive_write *a)
2110 {
2111         struct iso9660 *iso9660;
2112         int i, ret;
2113
2114         iso9660 = a->format_data;
2115
2116         /* Close the temporary file. */
2117         if (iso9660->temp_fd >= 0)
2118                 close(iso9660->temp_fd);
2119
2120         /* Free some stuff for zisofs operations. */
2121         ret = zisofs_free(a);
2122
2123         /* Remove directory entries in tree which includes file entries. */
2124         isoent_free_all(iso9660->primary.rootent);
2125         for (i = 0; i < iso9660->primary.max_depth; i++)
2126                 free(iso9660->primary.pathtbl[i].sorted);
2127         free(iso9660->primary.pathtbl);
2128
2129         if (iso9660->opt.joliet) {
2130                 isoent_free_all(iso9660->joliet.rootent);
2131                 for (i = 0; i < iso9660->joliet.max_depth; i++)
2132                         free(iso9660->joliet.pathtbl[i].sorted);
2133                 free(iso9660->joliet.pathtbl);
2134         }
2135
2136         /* Remove isofile entries. */
2137         isofile_free_all_entries(iso9660);
2138         isofile_free_hardlinks(iso9660);
2139
2140         archive_string_free(&(iso9660->cur_dirstr));
2141         archive_string_free(&(iso9660->volume_identifier));
2142         archive_string_free(&(iso9660->publisher_identifier));
2143         archive_string_free(&(iso9660->data_preparer_identifier));
2144         archive_string_free(&(iso9660->application_identifier));
2145         archive_string_free(&(iso9660->copyright_file_identifier));
2146         archive_string_free(&(iso9660->abstract_file_identifier));
2147         archive_string_free(&(iso9660->bibliographic_file_identifier));
2148         archive_string_free(&(iso9660->el_torito.catalog_filename));
2149         archive_string_free(&(iso9660->el_torito.boot_filename));
2150         archive_string_free(&(iso9660->el_torito.id));
2151         archive_string_free(&(iso9660->utf16be));
2152         archive_string_free(&(iso9660->mbs));
2153
2154         free(iso9660);
2155         a->format_data = NULL;
2156
2157         return (ret);
2158 }
2159
2160 /*
2161  * Get the System Identifier
2162  */
2163 static void
2164 get_system_identitier(char *system_id, size_t size)
2165 {
2166 #if defined(HAVE_SYS_UTSNAME_H)
2167         struct utsname u;
2168
2169         uname(&u);
2170         strncpy(system_id, u.sysname, size-1);
2171         system_id[size-1] = '\0';
2172 #elif defined(_WIN32) && !defined(__CYGWIN__)
2173         strncpy(system_id, "Windows", size-1);
2174         system_id[size-1] = '\0';
2175 #else
2176 #error no way to get the system identifier on your platform.
2177 #endif
2178 }
2179
2180 static void
2181 set_str(unsigned char *p, const char *s, size_t l, char f, const char *map)
2182 {
2183         unsigned char c;
2184
2185         if (s == NULL)
2186                 s = "";
2187         while ((c = *s++) != 0 && l > 0) {
2188                 if (c >= 0x80 || map[c] == 0)
2189                  {
2190                         /* illegal character */
2191                         if (c >= 'a' && c <= 'z') {
2192                                 /* convert c from a-z to A-Z */
2193                                 c -= 0x20;
2194                         } else
2195                                 c = 0x5f;
2196                 }
2197                 *p++ = c;
2198                 l--;
2199         }
2200         /* If l isn't zero, fill p buffer by the character
2201          * which indicated by f. */
2202         if (l > 0)
2203                 memset(p , f, l);
2204 }
2205
2206 static inline int
2207 joliet_allowed_char(unsigned char high, unsigned char low)
2208 {
2209         int utf16 = (high << 8) | low;
2210
2211         if (utf16 <= 0x001F)
2212                 return (0);
2213
2214         switch (utf16) {
2215         case 0x002A: /* '*' */
2216         case 0x002F: /* '/' */
2217         case 0x003A: /* ':' */
2218         case 0x003B: /* ';' */
2219         case 0x003F: /* '?' */
2220         case 0x005C: /* '\' */
2221                 return (0);/* Not allowed. */
2222         }
2223         return (1);
2224 }
2225
2226 static int
2227 set_str_utf16be(struct archive_write *a, unsigned char *p, const char *s,
2228     size_t l, uint16_t uf, enum vdc vdc)
2229 {
2230         size_t size, i;
2231         int onepad;
2232
2233         if (s == NULL)
2234                 s = "";
2235         if (l & 0x01) {
2236                 onepad = 1;
2237                 l &= ~1;
2238         } else
2239                 onepad = 0;
2240         if (vdc == VDC_UCS2) {
2241                 struct iso9660 *iso9660 = a->format_data;
2242                 if (archive_strncpy_in_locale(&iso9660->utf16be, s, strlen(s),
2243                     iso9660->sconv_to_utf16be) != 0 && errno == ENOMEM) {
2244                         archive_set_error(&a->archive, ENOMEM,
2245                             "Can't allocate memory for UTF-16BE");
2246                         return (ARCHIVE_FATAL);
2247                 }
2248                 size = iso9660->utf16be.length;
2249                 if (size > l)
2250                         size = l;
2251                 memcpy(p, iso9660->utf16be.s, size);
2252         } else {
2253                 const uint16_t *u16 = (const uint16_t *)s;
2254
2255                 size = 0;
2256                 while (*u16++)
2257                         size += 2;
2258                 if (size > l)
2259                         size = l;
2260                 memcpy(p, s, size);
2261         }
2262         for (i = 0; i < size; i += 2, p += 2) {
2263                 if (!joliet_allowed_char(p[0], p[1]))
2264                         archive_be16enc(p, 0x005F);/* '_' */
2265         }
2266         l -= size;
2267         while (l > 0) {
2268                 archive_be16enc(p, uf);
2269                 p += 2;
2270                 l -= 2;
2271         }
2272         if (onepad)
2273                 *p = 0;
2274         return (ARCHIVE_OK);
2275 }
2276
2277 static const char a_characters_map[0x80] = {
2278 /*  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F          */
2279     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
2280     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
2281     1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20-2F */
2282     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30-3F */
2283     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
2284     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
2285     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 60-6F */
2286     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 70-7F */
2287 };
2288
2289 static const char a1_characters_map[0x80] = {
2290 /*  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F          */
2291     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
2292     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
2293     1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20-2F */
2294     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30-3F */
2295     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
2296     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
2297     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60-6F */
2298     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,/* 70-7F */
2299 };
2300
2301 static const char d_characters_map[0x80] = {
2302 /*  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F          */
2303     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
2304     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
2305     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 20-2F */
2306     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,/* 30-3F */
2307     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
2308     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
2309     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 60-6F */
2310     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 70-7F */
2311 };
2312
2313 static const char d1_characters_map[0x80] = {
2314 /*  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F          */
2315     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
2316     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
2317     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 20-2F */
2318     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,/* 30-3F */
2319     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
2320     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
2321     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60-6F */
2322     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,/* 70-7F */
2323 };
2324
2325 static int
2326 set_str_a_characters_bp(struct archive_write *a, unsigned char *bp,
2327     int from, int to, const char *s, enum vdc vdc)
2328 {
2329         int r;
2330
2331         switch (vdc) {
2332         case VDC_STD:
2333                 set_str(bp+from, s, to - from + 1, 0x20,
2334                     a_characters_map);
2335                 r = ARCHIVE_OK;
2336                 break;
2337         case VDC_LOWERCASE:
2338                 set_str(bp+from, s, to - from + 1, 0x20,
2339                     a1_characters_map);
2340                 r = ARCHIVE_OK;
2341                 break;
2342         case VDC_UCS2:
2343         case VDC_UCS2_DIRECT:
2344                 r = set_str_utf16be(a, bp+from, s, to - from + 1,
2345                     0x0020, vdc);
2346                 break;
2347         default:
2348                 r = ARCHIVE_FATAL;
2349         }
2350         return (r);
2351 }
2352
2353 static int
2354 set_str_d_characters_bp(struct archive_write *a, unsigned char *bp,
2355     int from, int to, const char *s, enum  vdc vdc)
2356 {
2357         int r;
2358
2359         switch (vdc) {
2360         case VDC_STD:
2361                 set_str(bp+from, s, to - from + 1, 0x20,
2362                     d_characters_map);
2363                 r = ARCHIVE_OK;
2364                 break;
2365         case VDC_LOWERCASE:
2366                 set_str(bp+from, s, to - from + 1, 0x20,
2367                     d1_characters_map);
2368                 r = ARCHIVE_OK;
2369                 break;
2370         case VDC_UCS2:
2371         case VDC_UCS2_DIRECT:
2372                 r = set_str_utf16be(a, bp+from, s, to - from + 1,
2373                     0x0020, vdc);
2374                 break;
2375         default:
2376                 r = ARCHIVE_FATAL;
2377         }
2378         return (r);
2379 }
2380
2381 static void
2382 set_VD_bp(unsigned char *bp, enum VD_type type, unsigned char ver)
2383 {
2384
2385         /* Volume Descriptor Type */
2386         bp[1] = (unsigned char)type;
2387         /* Standard Identifier */
2388         memcpy(bp + 2, "CD001", 5);
2389         /* Volume Descriptor Version */
2390         bp[7] = ver;
2391 }
2392
2393 static inline void
2394 set_unused_field_bp(unsigned char *bp, int from, int to)
2395 {
2396         memset(bp + from, 0, to - from + 1);
2397 }
2398
2399 /*
2400  * 8-bit unsigned numerical values.
2401  * ISO9660 Standard 7.1.1
2402  */
2403 static inline void
2404 set_num_711(unsigned char *p, unsigned char value)
2405 {
2406         *p = value;
2407 }
2408
2409 /*
2410  * 8-bit signed numerical values.
2411  * ISO9660 Standard 7.1.2
2412  */
2413 static inline void
2414 set_num_712(unsigned char *p, char value)
2415 {
2416         *((char *)p) = value;
2417 }
2418
2419 /*
2420  * Least significant byte first.
2421  * ISO9660 Standard 7.2.1
2422  */
2423 static inline void
2424 set_num_721(unsigned char *p, uint16_t value)
2425 {
2426         archive_le16enc(p, value);
2427 }
2428
2429 /*
2430  * Most significant byte first.
2431  * ISO9660 Standard 7.2.2
2432  */
2433 static inline void
2434 set_num_722(unsigned char *p, uint16_t value)
2435 {
2436         archive_be16enc(p, value);
2437 }
2438
2439 /*
2440  * Both-byte orders.
2441  * ISO9660 Standard 7.2.3
2442  */
2443 static void
2444 set_num_723(unsigned char *p, uint16_t value)
2445 {
2446         archive_le16enc(p, value);
2447         archive_be16enc(p+2, value);
2448 }
2449
2450 /*
2451  * Least significant byte first.
2452  * ISO9660 Standard 7.3.1
2453  */
2454 static inline void
2455 set_num_731(unsigned char *p, uint32_t value)
2456 {
2457         archive_le32enc(p, value);
2458 }
2459
2460 /*
2461  * Most significant byte first.
2462  * ISO9660 Standard 7.3.2
2463  */
2464 static inline void
2465 set_num_732(unsigned char *p, uint32_t value)
2466 {
2467         archive_be32enc(p, value);
2468 }
2469
2470 /*
2471  * Both-byte orders.
2472  * ISO9660 Standard 7.3.3
2473  */
2474 static inline void
2475 set_num_733(unsigned char *p, uint32_t value)
2476 {
2477         archive_le32enc(p, value);
2478         archive_be32enc(p+4, value);
2479 }
2480
2481 static void
2482 set_digit(unsigned char *p, size_t s, int value)
2483 {
2484
2485         while (s--) {
2486                 p[s] = '0' + (value % 10);
2487                 value /= 10;
2488         }
2489 }
2490
2491 #if defined(HAVE_STRUCT_TM_TM_GMTOFF)
2492 #define get_gmoffset(tm)        ((tm)->tm_gmtoff)
2493 #elif defined(HAVE_STRUCT_TM___TM_GMTOFF)
2494 #define get_gmoffset(tm)        ((tm)->__tm_gmtoff)
2495 #else
2496 static long
2497 get_gmoffset(struct tm *tm)
2498 {
2499         long offset;
2500
2501 #if defined(HAVE__GET_TIMEZONE)
2502         _get_timezone(&offset);
2503 #elif defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
2504         offset = _timezone;
2505 #else
2506         offset = timezone;
2507 #endif
2508         offset *= -1;
2509         if (tm->tm_isdst)
2510                 offset += 3600;
2511         return (offset);
2512 }
2513 #endif
2514
2515 static void
2516 get_tmfromtime(struct tm *tm, time_t *t)
2517 {
2518 #if HAVE_LOCALTIME_R
2519         tzset();
2520         localtime_r(t, tm);
2521 #elif HAVE__LOCALTIME64_S
2522         _localtime64_s(tm, t);
2523 #else
2524         memcpy(tm, localtime(t), sizeof(*tm));
2525 #endif
2526 }
2527
2528 /*
2529  * Date and Time Format.
2530  * ISO9660 Standard 8.4.26.1
2531  */
2532 static void
2533 set_date_time(unsigned char *p, time_t t)
2534 {
2535         struct tm tm;
2536
2537         get_tmfromtime(&tm, &t);
2538         set_digit(p, 4, tm.tm_year + 1900);
2539         set_digit(p+4, 2, tm.tm_mon + 1);
2540         set_digit(p+6, 2, tm.tm_mday);
2541         set_digit(p+8, 2, tm.tm_hour);
2542         set_digit(p+10, 2, tm.tm_min);
2543         set_digit(p+12, 2, tm.tm_sec);
2544         set_digit(p+14, 2, 0);
2545         set_num_712(p+16, get_gmoffset(&tm)/(60*15));
2546 }
2547
2548 static void
2549 set_date_time_null(unsigned char *p)
2550 {
2551         memset(p, '0', 16);
2552         p[16] = 0;
2553 }
2554
2555 static void
2556 set_time_915(unsigned char *p, time_t t)
2557 {
2558         struct tm tm;
2559
2560         get_tmfromtime(&tm, &t);
2561         set_num_711(p+0, tm.tm_year);
2562         set_num_711(p+1, tm.tm_mon+1);
2563         set_num_711(p+2, tm.tm_mday);
2564         set_num_711(p+3, tm.tm_hour);
2565         set_num_711(p+4, tm.tm_min);
2566         set_num_711(p+5, tm.tm_sec);
2567         set_num_712(p+6, get_gmoffset(&tm)/(60*15));
2568 }
2569
2570
2571 /*
2572  * Write SUSP "CE" System Use Entry.
2573  */
2574 static int
2575 set_SUSP_CE(unsigned char *p, int location, int offset, int size)
2576 {
2577         unsigned char *bp = p -1;
2578         /*  Extend the System Use Area
2579          *   "CE" Format:
2580          *               len  ver
2581          *    +----+----+----+----+-----------+-----------+
2582          *    | 'C'| 'E'| 1C | 01 | LOCATION1 | LOCATION2 |
2583          *    +----+----+----+----+-----------+-----------+
2584          *    0    1    2    3    4          12          20
2585          *    +-----------+
2586          *    | LOCATION3 |
2587          *    +-----------+
2588          *   20          28
2589          *   LOCATION1 : Location of Continuation of System Use Area.
2590          *   LOCATION2 : Offset to Start of Continuation.
2591          *   LOCATION3 : Length of the Continuation.
2592          */
2593
2594         bp[1] = 'C';
2595         bp[2] = 'E';
2596         bp[3] = RR_CE_SIZE;     /* length       */
2597         bp[4] = 1;              /* version      */
2598         set_num_733(bp+5, location);
2599         set_num_733(bp+13, offset);
2600         set_num_733(bp+21, size);
2601         return (RR_CE_SIZE);
2602 }
2603
2604 /*
2605  * The functions, which names are beginning with extra_, are used to
2606  * control extra records.
2607  * The maximum size of a Directory Record is 254. When a filename is
2608  * very long, all of RRIP data of a file won't stored to the Directory
2609  * Record and so remaining RRIP data store to an extra record instead.
2610  */
2611 static unsigned char *
2612 extra_open_record(unsigned char *bp, int dr_len, struct isoent *isoent,
2613     struct ctl_extr_rec *ctl)
2614 {
2615         ctl->bp = bp;
2616         if (bp != NULL)
2617                 bp += dr_len;
2618         ctl->use_extr = 0;
2619         ctl->isoent = isoent;
2620         ctl->ce_ptr = NULL;
2621         ctl->cur_len = ctl->dr_len = dr_len;
2622         ctl->limit = DR_LIMIT;
2623
2624         return (bp);
2625 }
2626
2627 static void
2628 extra_close_record(struct ctl_extr_rec *ctl, int ce_size)
2629 {
2630         int padding = 0;
2631
2632         if (ce_size > 0)
2633                 extra_tell_used_size(ctl, ce_size);
2634         /* Padding. */
2635         if (ctl->cur_len & 0x01) {
2636                 ctl->cur_len++;
2637                 if (ctl->bp != NULL)
2638                         ctl->bp[ctl->cur_len] = 0;
2639                 padding = 1;
2640         }
2641         if (ctl->use_extr) {
2642                 if (ctl->ce_ptr != NULL)
2643                         set_SUSP_CE(ctl->ce_ptr, ctl->extr_loc,
2644                             ctl->extr_off, ctl->cur_len - padding);
2645         } else
2646                 ctl->dr_len = ctl->cur_len;
2647 }
2648
2649 #define extra_space(ctl)        ((ctl)->limit - (ctl)->cur_len)
2650
2651 static unsigned char *
2652 extra_next_record(struct ctl_extr_rec *ctl, int length)
2653 {
2654         int cur_len = ctl->cur_len;/* save cur_len */
2655
2656         /* Close the current extra record or Directory Record. */
2657         extra_close_record(ctl, RR_CE_SIZE);
2658
2659         /* Get a next extra record. */
2660         ctl->use_extr = 1;
2661         if (ctl->bp != NULL) {
2662                 /* Storing data into an extra record. */
2663                 unsigned char *p;
2664
2665                 /* Save the pointer where a CE extension will be
2666                  * stored to. */
2667                 ctl->ce_ptr = &ctl->bp[cur_len+1];
2668                 p = extra_get_record(ctl->isoent,
2669                     &ctl->limit, &ctl->extr_off, &ctl->extr_loc);
2670                 ctl->bp = p - 1;/* the base of bp offset is 1. */
2671         } else
2672                 /* Calculating the size of an extra record. */
2673                 (void)extra_get_record(ctl->isoent,
2674                     &ctl->limit, NULL, NULL);
2675         ctl->cur_len = 0;
2676         /* Check if an extra record is almost full.
2677          * If so, get a next one. */
2678         if (extra_space(ctl) < length)
2679                 (void)extra_next_record(ctl, length);
2680
2681         return (ctl->bp);
2682 }
2683
2684 static inline struct extr_rec *
2685 extra_last_record(struct isoent *isoent)
2686 {
2687         if (isoent->extr_rec_list.first == NULL)
2688                 return (NULL);
2689         return ((struct extr_rec *)(void *)
2690                 ((char *)(isoent->extr_rec_list.last)
2691                     - offsetof(struct extr_rec, next)));
2692 }
2693
2694 static unsigned char *
2695 extra_get_record(struct isoent *isoent, int *space, int *off, int *loc)
2696 {
2697         struct extr_rec *rec;
2698
2699         isoent = isoent->parent;
2700         if (off != NULL) {
2701                 /* Storing data into an extra record. */
2702                 rec = isoent->extr_rec_list.current;
2703                 if (DR_SAFETY > LOGICAL_BLOCK_SIZE - rec->offset)
2704                         rec = rec->next;
2705         } else {
2706                 /* Calculating the size of an extra record. */
2707                 rec = extra_last_record(isoent);
2708                 if (rec == NULL ||
2709                     DR_SAFETY > LOGICAL_BLOCK_SIZE - rec->offset) {
2710                         rec = malloc(sizeof(*rec));
2711                         if (rec == NULL)
2712                                 return (NULL);
2713                         rec->location = 0;
2714                         rec->offset = 0;
2715                         /* Insert `rec` into the tail of isoent->extr_rec_list */
2716                         rec->next = NULL;
2717                         *isoent->extr_rec_list.last = rec;
2718                         isoent->extr_rec_list.last = &(rec->next);
2719                 }
2720         }
2721         *space = LOGICAL_BLOCK_SIZE - rec->offset - DR_SAFETY;
2722         if (*space & 0x01)
2723                 *space -= 1;/* Keep padding space. */
2724         if (off != NULL)
2725                 *off = rec->offset;
2726         if (loc != NULL)
2727                 *loc = rec->location;
2728         isoent->extr_rec_list.current = rec;
2729
2730         return (&rec->buf[rec->offset]);
2731 }
2732
2733 static void
2734 extra_tell_used_size(struct ctl_extr_rec *ctl, int size)
2735 {
2736         struct isoent *isoent;
2737         struct extr_rec *rec;
2738
2739         if (ctl->use_extr) {
2740                 isoent = ctl->isoent->parent;
2741                 rec = isoent->extr_rec_list.current;
2742                 if (rec != NULL)
2743                         rec->offset += size;
2744         }
2745         ctl->cur_len += size;
2746 }
2747
2748 static int
2749 extra_setup_location(struct isoent *isoent, int location)
2750 {
2751         struct extr_rec *rec;
2752         int cnt;
2753
2754         cnt = 0;
2755         rec = isoent->extr_rec_list.first;
2756         isoent->extr_rec_list.current = rec;
2757         while (rec) {
2758                 cnt++;
2759                 rec->location = location++;
2760                 rec->offset = 0;
2761                 rec = rec->next;
2762         }
2763         return (cnt);
2764 }
2765
2766 /*
2767  * Create the RRIP entries.
2768  */
2769 static int
2770 set_directory_record_rr(unsigned char *bp, int dr_len,
2771     struct isoent *isoent, struct iso9660 *iso9660, enum dir_rec_type t)
2772 {
2773         /* Flags(BP 5) of the Rockridge "RR" System Use Field */
2774         unsigned char rr_flag;
2775 #define RR_USE_PX       0x01
2776 #define RR_USE_PN       0x02
2777 #define RR_USE_SL       0x04
2778 #define RR_USE_NM       0x08
2779 #define RR_USE_CL       0x10
2780 #define RR_USE_PL       0x20
2781 #define RR_USE_RE       0x40
2782 #define RR_USE_TF       0x80
2783         int length;
2784         struct ctl_extr_rec ctl;
2785         struct isoent *rr_parent, *pxent;
2786         struct isofile *file;
2787
2788         bp = extra_open_record(bp, dr_len, isoent, &ctl);
2789
2790         if (t == DIR_REC_PARENT) {
2791                 rr_parent = isoent->rr_parent;
2792                 pxent = isoent->parent;
2793                 if (rr_parent != NULL)
2794                         isoent = rr_parent;
2795                 else
2796                         isoent = isoent->parent;
2797         } else {
2798                 rr_parent = NULL;
2799                 pxent = isoent;
2800         }
2801         file = isoent->file;
2802
2803         if (t != DIR_REC_NORMAL) {
2804                 rr_flag = RR_USE_PX | RR_USE_TF;
2805                 if (rr_parent != NULL)
2806                         rr_flag |= RR_USE_PL;
2807         } else {
2808                 rr_flag = RR_USE_PX | RR_USE_NM | RR_USE_TF;
2809                 if (archive_entry_filetype(file->entry) == AE_IFLNK)
2810                         rr_flag |= RR_USE_SL;
2811                 if (isoent->rr_parent != NULL)
2812                         rr_flag |= RR_USE_RE;
2813                 if (isoent->rr_child != NULL)
2814                         rr_flag |= RR_USE_CL;
2815                 if (archive_entry_filetype(file->entry) == AE_IFCHR ||
2816                     archive_entry_filetype(file->entry) == AE_IFBLK)
2817                         rr_flag |= RR_USE_PN;
2818 #ifdef COMPAT_MKISOFS
2819                 /*
2820                  * mkisofs 2.01.01a63 records "RE" extension to
2821                  * the entry of "rr_moved" directory.
2822                  * I don't understand this behavior.
2823                  */
2824                 if (isoent->virtual &&
2825                     isoent->parent == iso9660->primary.rootent &&
2826                     strcmp(isoent->file->basename.s, "rr_moved") == 0)
2827                         rr_flag |= RR_USE_RE;
2828 #endif
2829         }
2830
2831         /* Write "SP" System Use Entry. */
2832         if (t == DIR_REC_SELF && isoent == isoent->parent) {
2833                 length = 7;
2834                 if (bp != NULL) {
2835                         bp[1] = 'S';
2836                         bp[2] = 'P';
2837                         bp[3] = length;
2838                         bp[4] = 1;      /* version      */
2839                         bp[5] = 0xBE;  /* Check Byte    */
2840                         bp[6] = 0xEF;  /* Check Byte    */
2841                         bp[7] = 0;
2842                         bp += length;
2843                 }
2844                 extra_tell_used_size(&ctl, length);
2845         }
2846
2847         /* Write "RR" System Use Entry. */
2848         length = 5;
2849         if (extra_space(&ctl) < length)
2850                 bp = extra_next_record(&ctl, length);
2851         if (bp != NULL) {
2852                 bp[1] = 'R';
2853                 bp[2] = 'R';
2854                 bp[3] = length;
2855                 bp[4] = 1;      /* version */
2856                 bp[5] = rr_flag;
2857                 bp += length;
2858         }
2859         extra_tell_used_size(&ctl, length);
2860
2861         /* Write "NM" System Use Entry. */
2862         if (rr_flag & RR_USE_NM) {
2863                 /*
2864                  *   "NM" Format:
2865                  *     e.g. a basename is 'foo'
2866                  *               len  ver  flg
2867                  *    +----+----+----+----+----+----+----+----+
2868                  *    | 'N'| 'M'| 08 | 01 | 00 | 'f'| 'o'| 'o'|
2869                  *    +----+----+----+----+----+----+----+----+
2870                  *    <----------------- len ----------------->
2871                  */
2872                 size_t nmlen = file->basename.length;
2873                 const char *nm = file->basename.s;
2874                 size_t nmmax;
2875
2876                 if (extra_space(&ctl) < 6)
2877                         bp = extra_next_record(&ctl, 6);
2878                 if (bp != NULL) {
2879                         bp[1] = 'N';
2880                         bp[2] = 'M';
2881                         bp[4] = 1;          /* version  */
2882                 }
2883                 nmmax = extra_space(&ctl);
2884                 if (nmmax > 0xff)
2885                         nmmax = 0xff;
2886                 while (nmlen + 5 > nmmax) {
2887                         length = nmmax;
2888                         if (bp != NULL) {
2889                                 bp[3] = length;
2890                                 bp[5] = 0x01;/* Alternate Name continues
2891                                                * in next "NM" field */
2892                                 memcpy(bp+6, nm, length - 5);
2893                                 bp += length;
2894                         }
2895                         nmlen -= length - 5;
2896                         nm += length - 5;
2897                         extra_tell_used_size(&ctl, length);
2898                         if (extra_space(&ctl) < 6) {
2899                                 bp = extra_next_record(&ctl, 6);
2900                                 nmmax = extra_space(&ctl);
2901                                 if (nmmax > 0xff)
2902                                         nmmax = 0xff;
2903                         }
2904                         if (bp != NULL) {
2905                                 bp[1] = 'N';
2906                                 bp[2] = 'M';
2907                                 bp[4] = 1;    /* version */
2908                         }
2909                 }
2910                 length = 5 + nmlen;
2911                 if (bp != NULL) {
2912                         bp[3] = length;
2913                         bp[5] = 0;
2914                         memcpy(bp+6, nm, nmlen);
2915                         bp += length;
2916                 }
2917                 extra_tell_used_size(&ctl, length);
2918         }
2919
2920         /* Write "PX" System Use Entry. */
2921         if (rr_flag & RR_USE_PX) {
2922                 /*
2923                  *   "PX" Format:
2924                  *               len  ver
2925                  *    +----+----+----+----+-----------+-----------+
2926                  *    | 'P'| 'X'| 2C | 01 | FILE MODE |   LINKS   |
2927                  *    +----+----+----+----+-----------+-----------+
2928                  *    0    1    2    3    4          12          20
2929                  *    +-----------+-----------+------------------+
2930                  *    |  USER ID  | GROUP ID  |FILE SERIAL NUMBER|
2931                  *    +-----------+-----------+------------------+
2932                  *   20          28          36                 44
2933                  */
2934                 length = 44;
2935                 if (extra_space(&ctl) < length)
2936                         bp = extra_next_record(&ctl, length);
2937                 if (bp != NULL) {
2938                         mode_t mode;
2939                         uid_t uid;
2940                         gid_t gid;
2941
2942                         mode = archive_entry_mode(file->entry);
2943                         uid = archive_entry_uid(file->entry);
2944                         gid = archive_entry_gid(file->entry);
2945                         if (iso9660->opt.rr == OPT_RR_USEFUL) {
2946                                 /*
2947                                  * This action is simular mkisofs -r option
2948                                  * but our rockridge=useful option does not
2949                                  * set a zero to uid and gid.
2950                                  */
2951                                 /* set all read bit ON */
2952                                 mode |= 0444;
2953 #if !defined(_WIN32) && !defined(__CYGWIN__)
2954                                 if (mode & 0111)
2955 #endif
2956                                         /* set all exec bit ON */
2957                                         mode |= 0111;
2958                                 /* clear all write bits. */
2959                                 mode &= ~0222;
2960                                 /* clear setuid,setgid,sticky bits. */
2961                                 mode &= ~07000;
2962                         }
2963
2964                         bp[1] = 'P';
2965                         bp[2] = 'X';
2966                         bp[3] = length;
2967                         bp[4] = 1;      /* version      */
2968                         /* file mode */
2969                         set_num_733(bp+5, mode);
2970                         /* file links (stat.st_nlink) */
2971                         set_num_733(bp+13,
2972                             archive_entry_nlink(file->entry));
2973                         set_num_733(bp+21, uid);
2974                         set_num_733(bp+29, gid);
2975                         /* File Serial Number */
2976                         if (pxent->dir)
2977                                 set_num_733(bp+37, pxent->dir_location);
2978                         else if (file->hardlink_target != NULL)
2979                                 set_num_733(bp+37,
2980                                     file->hardlink_target->cur_content->location);
2981                         else
2982                                 set_num_733(bp+37,
2983                                     file->cur_content->location);
2984                         bp += length;
2985                 }
2986                 extra_tell_used_size(&ctl, length);
2987         }
2988
2989         /* Write "SL" System Use Entry. */
2990         if (rr_flag & RR_USE_SL) {
2991                 /*
2992                  *   "SL" Format:
2993                  *     e.g. a symbolic name is 'foo/bar'
2994                  *               len  ver  flg
2995                  *    +----+----+----+----+----+------------+
2996                  *    | 'S'| 'L'| 0F | 01 | 00 | components |
2997                  *    +----+----+----+----+----+-----+------+
2998                  *    0    1    2    3    4    5  ...|...  15
2999                  *    <----------------- len --------+------>
3000                  *    components :                   |
3001                  *     cflg clen                     |
3002                  *    +----+----+----+----+----+     |
3003                  *    | 00 | 03 | 'f'| 'o'| 'o'| <---+
3004                  *    +----+----+----+----+----+     |
3005                  *    5    6    7    8    9   10     |
3006                  *     cflg clen                     |
3007                  *    +----+----+----+----+----+     |
3008                  *    | 00 | 03 | 'b'| 'a'| 'r'| <---+
3009                  *    +----+----+----+----+----+
3010                  *   10   11   12   13   14   15
3011                  *
3012                  *    - cflg : flag of componet
3013                  *    - clen : length of componet
3014                  */
3015                 const char *sl;
3016                 char sl_last;
3017
3018                 if (extra_space(&ctl) < 7)
3019                         bp = extra_next_record(&ctl, 7);
3020                 sl = file->symlink.s;
3021                 sl_last = '\0';
3022                 if (bp != NULL) {
3023                         bp[1] = 'S';
3024                         bp[2] = 'L';
3025                         bp[4] = 1;      /* version      */
3026                 }
3027                 for (;;) {
3028                         unsigned char *nc, *cf,  *cl, cldmy = 0;
3029                         int sllen, slmax;
3030
3031                         slmax = extra_space(&ctl);
3032                         if (slmax > 0xff)
3033                                 slmax = 0xff;
3034                         if (bp != NULL)
3035                                 nc = &bp[6];
3036                         else
3037                                 nc = NULL;
3038                         cf = cl = NULL;
3039                         sllen = 0;
3040                         while (*sl && sllen + 11 < slmax) {
3041                                 if (sl_last == '\0' && sl[0] == '/') {
3042                                         /*
3043                                          *     flg  len
3044                                          *    +----+----+
3045                                          *    | 08 | 00 | ROOT component.
3046                                          *    +----+----+ ("/")
3047                                          *
3048                                          * Root component has to appear
3049                                          * at the first component only.
3050                                          */
3051                                         if (nc != NULL) {
3052                                                 cf = nc++;
3053                                                 *cf = 0x08; /* ROOT */
3054                                                 *nc++ = 0;
3055                                         }
3056                                         sllen += 2;
3057                                         sl++;
3058                                         sl_last = '/';
3059                                         cl = NULL;
3060                                         continue;
3061                                 }
3062                                 if (((sl_last == '\0' || sl_last == '/') &&
3063                                       sl[0] == '.' && sl[1] == '.' &&
3064                                      (sl[2] == '/' || sl[2] == '\0')) ||
3065                                     (sl[0] == '/' &&
3066                                       sl[1] == '.' && sl[2] == '.' &&
3067                                      (sl[3] == '/' || sl[3] == '\0'))) {
3068                                         /*
3069                                          *     flg  len
3070                                          *    +----+----+
3071                                          *    | 04 | 00 | PARENT component.
3072                                          *    +----+----+ ("..")
3073                                          */
3074                                         if (nc != NULL) {
3075                                                 cf = nc++;
3076                                                 *cf = 0x04; /* PARENT */
3077                                                 *nc++ = 0;
3078                                         }
3079                                         sllen += 2;
3080                                         if (sl[0] == '/')
3081                                                 sl += 3;/* skip "/.." */
3082                                         else
3083                                                 sl += 2;/* skip ".." */
3084                                         sl_last = '.';
3085                                         cl = NULL;
3086                                         continue;
3087                                 }
3088                                 if (((sl_last == '\0' || sl_last == '/') &&
3089                                       sl[0] == '.' &&
3090                                      (sl[1] == '/' || sl[1] == '\0')) ||
3091                                     (sl[0] == '/' && sl[1] == '.' &&
3092                                      (sl[2] == '/' || sl[2] == '\0'))) {
3093                                         /*
3094                                          *     flg  len
3095                                          *    +----+----+
3096                                          *    | 02 | 00 | CURREENT component.
3097                                          *    +----+----+ (".")
3098                                          */
3099                                         if (nc != NULL) {
3100                                                 cf = nc++;
3101                                                 *cf = 0x02; /* CURRENT */
3102                                                 *nc++ = 0;
3103                                         }
3104                                         sllen += 2;
3105                                         if (sl[0] == '/')
3106                                                 sl += 2;/* skip "/." */
3107                                         else
3108                                                 sl ++;  /* skip "." */
3109                                         sl_last = '.';
3110                                         cl = NULL;
3111                                         continue;
3112                                 }
3113                                 if (sl[0] == '/' || cl == NULL) {
3114                                         if (nc != NULL) {
3115                                                 cf = nc++;
3116                                                 *cf = 0;
3117                                                 cl = nc++;
3118                                                 *cl = 0;
3119                                         } else
3120                                                 cl = &cldmy;
3121                                         sllen += 2;
3122                                         if (sl[0] == '/') {
3123                                                 sl_last = *sl++;
3124                                                 continue;
3125                                         }
3126                                 }
3127                                 sl_last = *sl++;
3128                                 if (nc != NULL) {
3129                                         *nc++ = sl_last;
3130                                         (*cl) ++;
3131                                 }
3132                                 sllen++;
3133                         }
3134                         if (*sl) {
3135                                 length = 5 + sllen;
3136                                 if (bp != NULL) {
3137                                         /*
3138                                          * Mark flg as CONTINUE component.
3139                                          */
3140                                         *cf |= 0x01;
3141                                         /*
3142                                          *               len  ver  flg
3143                                          *    +----+----+----+----+----+-
3144                                          *    | 'S'| 'L'| XX | 01 | 01 |
3145                                          *    +----+----+----+----+----+-
3146                                          *                           ^
3147                                          *           continues in next "SL"
3148                                          */
3149                                         bp[3] = length;
3150                                         bp[5] = 0x01;/* This Symbolic Link
3151                                                       * continues in next
3152                                                       * "SL" field */
3153                                         bp += length;
3154                                 }
3155                                 extra_tell_used_size(&ctl, length);
3156                                 if (extra_space(&ctl) < 11)
3157                                         bp = extra_next_record(&ctl, 11);
3158                                 if (bp != NULL) {
3159                                         /* Next 'SL' */
3160                                         bp[1] = 'S';
3161                                         bp[2] = 'L';
3162                                         bp[4] = 1;    /* version */
3163                                 }
3164                         } else {
3165                                 length = 5 + sllen;
3166                                 if (bp != NULL) {
3167                                         bp[3] = length;
3168                                         bp[5] = 0;
3169                                         bp += length;
3170                                 }
3171                                 extra_tell_used_size(&ctl, length);
3172                                 break;
3173                         }
3174                 }
3175         }
3176
3177         /* Write "TF" System Use Entry. */
3178         if (rr_flag & RR_USE_TF) {
3179                 /*
3180                  *   "TF" Format:
3181                  *               len  ver
3182                  *    +----+----+----+----+-----+-------------+
3183                  *    | 'T'| 'F'| XX | 01 |FLAGS| TIME STAMPS |
3184                  *    +----+----+----+----+-----+-------------+
3185                  *    0    1    2    3    4     5            XX
3186                  *    TIME STAMPS : ISO 9660 Standard 9.1.5.
3187                  *                  If TF_LONG_FORM FLAGS is set,
3188                  *                  use ISO9660 Standard 8.4.26.1.
3189                  */
3190 #define TF_CREATION     0x01    /* Creation time recorded               */
3191 #define TF_MODIFY       0x02    /* Modification time recorded           */
3192 #define TF_ACCESS       0x04    /* Last Access time recorded            */
3193 #define TF_ATTRIBUTES   0x08    /* Last Attribute Change time recorded  */
3194 #define TF_BACKUP       0x10    /* Last Backup time recorded            */
3195 #define TF_EXPIRATION   0x20    /* Expiration time recorded             */
3196 #define TF_EFFECTIVE    0x40    /* Effective time recorded              */
3197 #define TF_LONG_FORM    0x80    /* ISO 9660 17-byte time format used    */
3198                 unsigned char tf_flags;
3199
3200                 length = 5;
3201                 tf_flags = 0;
3202 #ifndef COMPAT_MKISOFS
3203                 if (archive_entry_birthtime_is_set(file->entry) &&
3204                     archive_entry_birthtime(file->entry) <=
3205                     archive_entry_mtime(file->entry)) {
3206                         length += 7;
3207                         tf_flags |= TF_CREATION;
3208                 }
3209 #endif
3210                 if (archive_entry_mtime_is_set(file->entry)) {
3211                         length += 7;
3212                         tf_flags |= TF_MODIFY;
3213                 }
3214                 if (archive_entry_atime_is_set(file->entry)) {
3215                         length += 7;
3216                         tf_flags |= TF_ACCESS;
3217                 }
3218                 if (archive_entry_ctime_is_set(file->entry)) {
3219                         length += 7;
3220                         tf_flags |= TF_ATTRIBUTES;
3221                 }
3222                 if (extra_space(&ctl) < length)
3223                         bp = extra_next_record(&ctl, length);
3224                 if (bp != NULL) {
3225                         bp[1] = 'T';
3226                         bp[2] = 'F';
3227                         bp[3] = length;
3228                         bp[4] = 1;      /* version      */