summaryrefslogtreecommitdiff
path: root/genisoimage/genisoimage.c
diff options
context:
space:
mode:
Diffstat (limited to 'genisoimage/genisoimage.c')
-rw-r--r--genisoimage/genisoimage.c3831
1 files changed, 3831 insertions, 0 deletions
diff --git a/genisoimage/genisoimage.c b/genisoimage/genisoimage.c
new file mode 100644
index 0000000..46f0cb7
--- /dev/null
+++ b/genisoimage/genisoimage.c
@@ -0,0 +1,3831 @@
+/*
+ * This file has been modified for the cdrkit suite.
+ *
+ * The behaviour and appearence of the program code below can differ to a major
+ * extent from the version distributed by the original author(s).
+ *
+ * For details, see Changelog file distributed with the cdrkit package. If you
+ * received this file from another source then ask the distributing person for
+ * a log of modifications.
+ *
+ */
+
+/*
+ *
+ * Patched version with stuff from the Debian's cdrtools.
+ * Replaced various warnings/disclaimers with more simple ones.
+ *
+ * Eduard Bloch <blade@debian.org>
+*/
+/* @(#)mkisofs.c 1.167 06/01/30 joerg */
+/* Parts from @(#)mkisofs.c 1.206 07/02/26 joerg */
+/*
+ * Program genisoimage.c - generate iso9660 filesystem based upon directory
+ * tree on hard disk.
+ *
+ * Written by Eric Youngdale (1993).
+ *
+ * Copyright 1993 Yggdrasil Computing, Incorporated
+ * Copyright (c) 1999,2000-2004 J. Schilling
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* APPLE_HYB James Pearson j.pearson@ge.ucl.ac.uk 22/2/2000 */
+
+#include <mconfig.h>
+#include "genisoimage.h"
+#include <errno.h>
+#include <timedefs.h>
+#include <fctldefs.h>
+#include <ctype.h>
+#include "match.h"
+#include "exclude.h"
+#include <unls.h> /* For UNICODE translation */
+#include <schily.h>
+#ifdef UDF
+#include "udf.h"
+#endif
+
+#ifdef NEED_O_BINARY
+#include <io.h> /* for setmode() prototype */
+#endif
+
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#else
+#include "getopt.h"
+extern int optind;
+extern char *optarg;
+#endif
+
+#ifdef VMS
+#include "vms.h"
+#endif
+
+#ifdef no_more_needed
+#ifdef __NetBSD__
+#include <sys/resource.h>
+#endif
+#endif /* no_more_needed */
+
+#ifdef USE_ICONV
+#include <locale.h>
+#include <langinfo.h>
+#endif
+
+struct directory *root = NULL;
+int path_ind;
+
+char version_string[] = "genisoimage " CDRKIT_VERSION;
+
+char *outfile;
+FILE *discimage;
+unsigned int next_extent = 0;
+unsigned int last_extent = 0;
+unsigned int session_start = 0;
+unsigned int path_table_size = 0;
+unsigned int path_table[4] = {0, };
+unsigned int path_blocks = 0;
+
+
+unsigned int jpath_table_size = 0;
+unsigned int jpath_table[4] = {0, };
+unsigned int jpath_blocks = 0;
+
+struct iso_directory_record root_record;
+struct iso_directory_record jroot_record;
+
+char *extension_record = NULL;
+int extension_record_extent = 0;
+int extension_record_size = 0;
+
+/* These variables are associated with command line options */
+int check_oldnames = 0;
+int check_session = 0;
+int use_eltorito = 0;
+int hard_disk_boot = 0;
+int not_bootable = 0;
+int no_emul_boot = 0;
+int load_addr = 0;
+int load_size = 0;
+int boot_info_table = 0;
+int use_alphaboot = 0;
+int use_sparcboot = 0;
+int use_hppaboot = 0;
+int use_mipsboot = 0;
+int use_mipselboot = 0;
+int use_sunx86boot = 0;
+int use_genboot = 0;
+int use_RockRidge = 0;
+int use_XA = 0;
+int osecsize = 0; /* Output-sector size, 0 means default secsize 2048 */
+int use_Joliet = 0;
+int jlen = JMAX; /* maximum Joliet file name length */
+int verbose = 1;
+int debug = 0;
+int gui = 0;
+int all_files = 1; /* New default is to include all files */
+int follow_links = 0;
+#ifdef IS_CYGWIN
+int cache_inodes = 0; /* Do not cache inodes on Cygwin by default */
+#else
+int cache_inodes = 1; /* Cache inodes if OS has unique inodes */
+#endif
+int rationalize = 0;
+int rationalize_uid = 0;
+int rationalize_gid = 0;
+int rationalize_filemode = 0;
+int rationalize_dirmode = 0;
+uid_t uid_to_use = 0; /* when rationalizing uid */
+gid_t gid_to_use = 0; /* when rationalizing gid */
+int filemode_to_use = 0; /* if non-zero, when rationalizing file mode */
+int dirmode_to_use = 0; /* if non-zero, when rationalizing dir mode */
+int new_dir_mode = 0555;
+int generate_tables = 0;
+int dopad = 1; /* Now default to do padding */
+int print_size = 0;
+int split_output = 0;
+char *icharset = NULL; /* input charset to convert to UNICODE */
+char *ocharset = NULL; /* output charset to convert from UNICODE */
+char *preparer = PREPARER_DEFAULT;
+char *publisher = PUBLISHER_DEFAULT;
+char *appid = APPID_DEFAULT;
+char *copyright = COPYRIGHT_DEFAULT;
+char *biblio = BIBLIO_DEFAULT;
+char *abstract = ABSTRACT_DEFAULT;
+char *volset_id = VOLSET_ID_DEFAULT;
+char *volume_id = VOLUME_ID_DEFAULT;
+char *system_id = SYSTEM_ID_DEFAULT;
+char *boot_catalog = BOOT_CATALOG_DEFAULT;
+char *boot_image = BOOT_IMAGE_DEFAULT;
+char *genboot_image = BOOT_IMAGE_DEFAULT;
+int ucs_level = 3; /* We now have Unicode tables so use level 3 */
+int volume_set_size = 1;
+int volume_sequence_number = 1;
+
+struct eltorito_boot_entry_info *first_boot_entry = NULL;
+struct eltorito_boot_entry_info *last_boot_entry = NULL;
+struct eltorito_boot_entry_info *current_boot_entry = NULL;
+
+int use_graft_ptrs; /* Use graft points */
+int jhide_trans_tbl; /* Hide TRANS.TBL from Joliet tree */
+int hide_rr_moved; /* Name RR_MOVED .rr_moved in Rock Ridge tree */
+int omit_period = 0; /* Violates iso9660, but these are a pain */
+int transparent_compression = 0; /* So far only works with linux */
+int omit_version_number = 0; /* May violate iso9660, but noone uses vers */
+int no_rr = 0; /* Do not use RR attributes from old session */
+int force_rr = 0; /* Force to use RR attributes from old session */
+Uint RR_relocation_depth = 6; /* Violates iso9660, but most systems work */
+int iso9660_level = 1;
+int iso9660_namelen = LEN_ISONAME; /* 31 characters, may be set to 37 */
+int full_iso9660_filenames = 0; /* Full 31 character iso9660 filenames */
+int relaxed_filenames = 0; /* For Amiga. Disc will not work with DOS */
+int allow_lowercase = 0; /* Allow lower case letters */
+int allow_multidot = 0; /* Allow more than on dot in filename */
+int iso_translate = 1; /* 1 == enables '#', '-' and '~' removal */
+int allow_leading_dots = 0; /* DOS cannot read names with leading dots */
+int allow_limited_size = 0; /* Let the user to allow the trick explicitely */
+#ifdef VMS
+int use_fileversion = 1; /* Use file version # from filesystem */
+#else
+int use_fileversion = 0; /* Use file version # from filesystem */
+#endif
+int split_SL_component = 1; /* circumvent a bug in the SunOS driver */
+int split_SL_field = 1; /* circumvent a bug in the SunOS */
+char *trans_tbl = "TRANS.TBL"; /* default name for translation table */
+int stream_media_size = 0; /* # of blocks on the media */
+char *stream_filename = NULL; /* Stream file, 0 to use default STREAM.IMG */
+
+#ifdef APPLE_HYB
+int apple_hyb = 0; /* create HFS hybrid flag */
+int apple_ext = 0; /* create HFS extensions flag */
+int apple_both = 0; /* common flag (for above) */
+int hfs_extra = 0; /* extra HFS blocks added to end of ISO vol */
+int use_mac_name = 0; /* use Mac name for ISO/Joliet/RR flag */
+hce_mem *hce; /* libhfs/genisoimage extras */
+char *hfs_boot_file = 0; /* name of HFS boot file */
+int gen_pt = 0; /* generate HFS partition table */
+char *autoname = 0; /* AutoStart filename */
+char *magic_filename = 0; /* name of magic file */
+int probe = 0; /* search files for HFS/Unix type */
+int nomacfiles = 0; /* don't look for Mac/Unix files */
+int hfs_select = 0; /* Mac/Unix types to select */
+int create_dt = 1; /* create the Desktp files */
+int afe_size = 0; /* Apple File Exchange block size */
+int hfs_last = MAG_LAST; /* process magic file after map file */
+char *deftype = APPLE_TYPE_DEFAULT; /* default Apple TYPE */
+char *defcreator = APPLE_CREATOR_DEFAULT; /* default Apple CREATOR */
+char *hfs_volume_id = NULL; /* HFS volume ID */
+int icon_pos = 0; /* Keep icon position */
+char *hfs_icharset = NULL; /* input HFS charset name */
+char *hfs_ocharset = NULL; /* output HFS charset name */
+int hfs_lock = 1; /* lock HFS volume (read-only) */
+char *hfs_bless = NULL; /* name of folder to 'bless' (System Folder) */
+char *hfs_parms = NULL; /* low level HFS parameters */
+
+#ifdef PREP_BOOT
+char *prep_boot_image[4];
+int use_prep_boot = 0;
+int use_chrp_boot = 0;
+#endif /* PREP_BOOT */
+#endif /* APPLE_HYB */
+
+#ifdef UDF
+int use_udf = 0;
+#endif
+
+#ifdef DVD_VIDEO
+int dvd_video = 0;
+#endif
+
+#ifdef SORTING
+int do_sort = 0; /* sort file data */
+#endif /* SORTING */
+
+#ifdef USE_ICONV
+int iconv_possible;
+#endif
+
+struct unls_table *in_nls = NULL; /* input UNICODE conversion table */
+struct unls_table *out_nls = NULL; /* output UNICODE conversion table */
+#ifdef APPLE_HYB
+struct unls_table *hfs_inls = NULL; /* input HFS UNICODE conversion table */
+struct unls_table *hfs_onls = NULL; /* output HFS UNICODE conversion table */
+#endif /* APPLE_HYB */
+
+struct rcopts {
+ char *tag;
+ char **variable;
+};
+
+struct rcopts rcopt[] = {
+ {"PREP", &preparer},
+ {"PUBL", &publisher},
+ {"APPI", &appid},
+ {"COPY", &copyright},
+ {"BIBL", &biblio},
+ {"ABST", &abstract},
+ {"VOLS", &volset_id},
+ {"VOLI", &volume_id},
+ {"SYSI", &system_id},
+#ifdef APPLE_HYB
+ {"HFS_TYPE", &deftype},
+ {"HFS_CREATOR", &defcreator},
+#endif /* APPLE_HYB */
+ {NULL, NULL}
+};
+
+char *merge_warn_msg=0; /* use as pointer and boolean */
+
+/*
+ * In case it isn't obvious, the option handling code was ripped off
+ * from GNU-ld.
+ */
+struct ld_option {
+ /* The long option information. */
+ struct option opt;
+ /* The short option with the same meaning ('\0' if none). */
+ char shortopt;
+ /* The name of the argument (NULL if none). */
+ const char *arg;
+ /*
+ * The documentation string. If this is NULL, this is a synonym for
+ * the previous option.
+ */
+ const char *doc;
+ enum {
+ /* Use one dash before long option name. */
+ ONE_DASH,
+ /* Use two dashes before long option name. */
+ TWO_DASHES,
+ /* Don't mention this option in --help output. */
+ NO_HELP
+ } control;
+};
+
+/*
+ * Codes used for the long options with no short synonyms. Note that all these
+ * values must not be ASCII or EBCDIC.
+ */
+#define OPTION_HELP 1000
+#define OPTION_QUIET 1001
+#define OPTION_NOSPLIT_SL_COMPONENT 1002
+#define OPTION_NOSPLIT_SL_FIELD 1003
+#define OPTION_PRINT_SIZE 1004
+#define OPTION_SPLIT_OUTPUT 1005
+#define OPTION_ABSTRACT 1006
+#define OPTION_BIBLIO 1007
+#define OPTION_COPYRIGHT 1008
+#define OPTION_SYSID 1009
+#define OPTION_VOLSET 1010
+#define OPTION_VOLSET_SIZE 1011
+#define OPTION_VOLSET_SEQ_NUM 1012
+#define OPTION_I_HIDE 1013
+#define OPTION_J_HIDE 1014
+#define OPTION_LOG_FILE 1015
+#define OPTION_PVERSION 1016
+#define OPTION_NOBAK 1017
+#define OPTION_SPARCLABEL 1018
+#define OPTION_HARD_DISK_BOOT 1019
+#define OPTION_NO_EMUL_BOOT 1020
+#define OPTION_NO_BOOT 1021
+#define OPTION_BOOT_LOAD_ADDR 1022
+#define OPTION_BOOT_LOAD_SIZE 1023
+#define OPTION_BOOT_INFO_TABLE 1024
+#define OPTION_HIDE_TRANS_TBL 1025
+#define OPTION_HIDE_RR_MOVED 1026
+#define OPTION_GUI 1027
+#define OPTION_TRANS_TBL 1028
+#define OPTION_P_LIST 1029
+#define OPTION_I_LIST 1030
+#define OPTION_J_LIST 1031
+#define OPTION_X_LIST 1032
+#define OPTION_NO_RR 1033
+#define OPTION_JCHARSET 1034
+#define OPTION_PAD 1035
+#define OPTION_H_HIDE 1036
+#define OPTION_H_LIST 1037
+#define OPTION_CHECK_OLDNAMES 1038
+
+#ifdef SORTING
+#define OPTION_SORT 1039
+#endif /* SORTING */
+#define OPTION_UCS_LEVEL 1040
+#define OPTION_ISO_TRANSLATE 1041
+#define OPTION_ISO_LEVEL 1042
+#define OPTION_RELAXED_FILENAMES 1043
+#define OPTION_ALLOW_LOWERCASE 1044
+#define OPTION_ALLOW_MULTIDOT 1045
+#define OPTION_USE_FILEVERSION 1046
+#define OPTION_MAX_FILENAMES 1047
+#define OPTION_ALT_BOOT 1048
+#define OPTION_USE_GRAFT 1049
+
+#define OPTION_INPUT_CHARSET 1050
+#define OPTION_OUTPUT_CHARSET 1051
+
+#define OPTION_NOPAD 1052
+#define OPTION_UID 1053
+#define OPTION_GID 1054
+#define OPTION_FILEMODE 1055
+#define OPTION_DIRMODE 1056
+#define OPTION_NEW_DIR_MODE 1057
+#define OPTION_CACHE_INODES 1058
+#define OPTION_NOCACHE_INODES 1059
+
+#define OPTION_CHECK_SESSION 1060
+#define OPTION_FORCE_RR 1061
+
+#define OPTION_DEBUG 1062
+
+#define OPTION_JLONG 1063
+
+#define OPTION_STREAM_FILE_NAME 1064
+#define OPTION_STREAM_CD_SIZE 1065
+
+#define OPTION_XA 1066
+#define OPTION_XA_RATIONALIZED 1067
+
+#define OPTION_SUNX86BOOT 1068
+#define OPTION_SUNX86LABEL 1069
+
+#define OPTION_ALLOW_LEADING_DOTS 1070
+#define OPTION_PUBLISHER 1071
+
+#ifdef JIGDO_TEMPLATE
+#define OPTION_JTT_OUTPUT 1101
+#define OPTION_JTJ_OUTPUT 1102
+#define OPTION_JT_MIN_SIZE 1103
+#define OPTION_JT_PATH_MAP 1104
+#define OPTION_JT_MD5_LIST 1105
+#define OPTION_JT_INCLUDE 1106
+#define OPTION_JT_EXCLUDE 1107
+#define OPTION_JT_COMPRESS_ALGO 1108
+
+#define OPTION_JT_CHECKSUM_ALGO_ISO 1120
+#define OPTION_JT_CHECKSUM_ALGO_TMPL 1121
+#endif
+
+#define OPTION_BOOTALPHA 1200
+
+#define OPTION_HPPA_CMDLINE 1210
+#define OPTION_HPPA_KERNEL_32 1211
+#define OPTION_HPPA_KERNEL_64 1212
+#define OPTION_HPPA_BOOTLOADER 1213
+#define OPTION_HPPA_RAMDISK 1214
+
+#define OPTION_BOOTMIPS 1220
+
+#define OPTION_BOOTMIPSEL 1230
+
+#ifdef UDF
+#define OPTION_UDF 1500
+#endif
+#ifdef DVD_VIDEO
+#define OPTION_DVD 1501
+#endif
+
+#ifdef APPLE_HYB
+#define OPTION_CAP 2000
+#define OPTION_NETA 2001
+#define OPTION_DBL 2002
+#define OPTION_ESH 2003
+#define OPTION_FE 2004
+#define OPTION_SGI 2005
+#define OPTION_MBIN 2006
+#define OPTION_SGL 2007
+/* aliases */
+#define OPTION_USH 2008
+#define OPTION_XIN 2009
+
+#define OPTION_DAVE 2010
+#define OPTION_SFM 2011
+#define OPTION_XDBL 2012
+#define OPTION_XHFS 2013
+
+#define OPTION_PROBE 2020
+#define OPTION_MACNAME 2021
+#define OPTION_NOMACFILES 2022
+#define OPTION_BOOT_HFS_FILE 2023
+#define OPTION_MAGIC_FILE 2024
+
+#define OPTION_HFS_LIST 2025
+
+#define OPTION_GEN_PT 2026
+
+#define OPTION_CREATE_DT 2027
+#define OPTION_HFS_HIDE 2028
+
+#define OPTION_AUTOSTART 2029
+#define OPTION_BSIZE 2030
+#define OPTION_HFS_VOLID 2031
+#define OPTION_PREP_BOOT 2032
+#define OPTION_ICON_POS 2033
+
+#define OPTION_HFS_TYPE 2034
+#define OPTION_HFS_CREATOR 2035
+
+#define OPTION_ROOT_INFO 2036
+
+#define OPTION_HFS_INPUT_CHARSET 2037
+#define OPTION_HFS_OUTPUT_CHARSET 2038
+
+#define OPTION_HFS_UNLOCK 2039
+#define OPTION_HFS_BLESS 2040
+#define OPTION_HFS_PARMS 2041
+
+#define OPTION_CHRP_BOOT 2042
+
+#define OPTION_RELOC_ROOT 2043
+#define OPTION_RELOC_OLD_ROOT 2044
+
+#define OPTION_MAP_FILE 2045
+
+#define OPTION_ALLOW_LIMITED_SIZE 2046
+
+#endif /* APPLE_HYB */
+
+static int save_pname = 0;
+
+static const struct ld_option ld_options[] =
+{
+ {{"nobak", no_argument, NULL, OPTION_NOBAK},
+ '\0', NULL, "Do not include backup files", ONE_DASH},
+ {{"no-bak", no_argument, NULL, OPTION_NOBAK},
+ '\0', NULL, "Do not include backup files", ONE_DASH},
+ {{"abstract", required_argument, NULL, OPTION_ABSTRACT},
+ '\0', "FILE", "Set Abstract filename", ONE_DASH},
+ {{"appid", required_argument, NULL, 'A'},
+ 'A', "ID", "Set Application ID", ONE_DASH},
+ {{"biblio", required_argument, NULL, OPTION_BIBLIO},
+ '\0', "FILE", "Set Bibliographic filename", ONE_DASH},
+ {{"cache-inodes", no_argument, NULL, OPTION_CACHE_INODES},
+ '\0', NULL, "Cache inodes (needed to detect hard links)", ONE_DASH},
+ {{"no-cache-inodes", no_argument, NULL, OPTION_NOCACHE_INODES},
+ '\0', NULL, "Do not cache inodes (if filesystem has no unique unides)", ONE_DASH},
+ {{"check-oldnames", no_argument, NULL, OPTION_CHECK_OLDNAMES},
+ '\0', NULL, "Check all imported ISO9660 names from old session", ONE_DASH},
+ {{"check-session", required_argument, NULL, OPTION_CHECK_SESSION},
+ '\0', "FILE", "Check all ISO9660 names from previous session", ONE_DASH},
+ {{"copyright", required_argument, NULL, OPTION_COPYRIGHT},
+ '\0', "FILE", "Set Copyright filename", ONE_DASH},
+ {{"debug", no_argument, NULL, OPTION_DEBUG},
+ '\0', NULL, "Set debug flag", ONE_DASH},
+ {{"eltorito-boot", required_argument, NULL, 'b'},
+ 'b', "FILE", "Set El Torito boot image name", ONE_DASH},
+ {{"eltorito-alt-boot", no_argument, NULL, OPTION_ALT_BOOT},
+ '\0', NULL, "Start specifying alternative El Torito boot parameters", ONE_DASH},
+ {{"sparc-boot", required_argument, NULL, 'B'},
+ 'B', "FILES", "Set sparc boot image names", ONE_DASH},
+ {{"sunx86-boot", required_argument, NULL, OPTION_SUNX86BOOT},
+ '\0', "FILES", "Set sunx86 boot image names", ONE_DASH},
+ {{"generic-boot", required_argument, NULL, 'G'},
+ 'G', "FILE", "Set generic boot image name", ONE_DASH},
+ {{"sparc-label", required_argument, NULL, OPTION_SPARCLABEL},
+ '\0', "label text", "Set sparc boot disk label", ONE_DASH},
+ {{"sunx86-label", required_argument, NULL, OPTION_SUNX86LABEL},
+ '\0', "label text", "Set sunx86 boot disk label", ONE_DASH},
+ {{"eltorito-catalog", required_argument, NULL, 'c'},
+ 'c', "FILE", "Set El Torito boot catalog name", ONE_DASH},
+ {{"cdrecord-params", required_argument, NULL, 'C'},
+ 'C', "PARAMS", "Magic paramters from cdrecord", ONE_DASH},
+ {{"omit-period", no_argument, NULL, 'd'},
+ 'd', NULL, "Omit trailing periods from filenames (violates ISO9660)", ONE_DASH},
+ {{"dir-mode", required_argument, NULL, OPTION_DIRMODE},
+ '\0', "mode", "Make the mode of all directories this mode.", ONE_DASH},
+ {{"disable-deep-relocation", no_argument, NULL, 'D'},
+ 'D', NULL, "Disable deep directory relocation (violates ISO9660)", ONE_DASH},
+ {{"file-mode", required_argument, NULL, OPTION_FILEMODE},
+ '\0', "mode", "Make the mode of all plain files this mode.", ONE_DASH},
+ {{"follow-links", no_argument, NULL, 'f'},
+ 'f', NULL, "Follow symbolic links", ONE_DASH},
+ {{"gid", required_argument, NULL, OPTION_GID},
+ '\0', "gid", "Make the group owner of all files this gid.",
+ ONE_DASH},
+ {{"graft-points", no_argument, NULL, OPTION_USE_GRAFT},
+ '\0', NULL, "Allow to use graft points for filenames", ONE_DASH},
+ {{"root", required_argument, NULL, OPTION_RELOC_ROOT},
+ '\0', "DIR", "Set root directory for all new files and directories", ONE_DASH},
+ {{"old-root", required_argument, NULL, OPTION_RELOC_OLD_ROOT},
+ '\0', "DIR", "Set root directory in previous session that is searched for files", ONE_DASH},
+ {{"help", no_argument, NULL, OPTION_HELP},
+ '\0', NULL, "Print option help", ONE_DASH},
+ {{"hide", required_argument, NULL, OPTION_I_HIDE},
+ '\0', "GLOBFILE", "Hide ISO9660/RR file", ONE_DASH},
+ {{"hide-list", required_argument, NULL, OPTION_I_LIST},
+ '\0', "FILE", "File with list of ISO9660/RR files to hide", ONE_DASH},
+ {{"hidden", required_argument, NULL, OPTION_H_HIDE},
+ '\0', "GLOBFILE", "Set hidden attribute on ISO9660 file", ONE_DASH},
+ {{"hidden-list", required_argument, NULL, OPTION_H_LIST},
+ '\0', "FILE", "File with list of ISO9660 files with hidden attribute", ONE_DASH},
+ {{"hide-joliet", required_argument, NULL, OPTION_J_HIDE},
+ '\0', "GLOBFILE", "Hide Joliet file", ONE_DASH},
+ {{"hide-joliet-list", required_argument, NULL, OPTION_J_LIST},
+ '\0', "FILE", "File with list of Joliet files to hide", ONE_DASH},
+ {{"hide-joliet-trans-tbl", no_argument, NULL, OPTION_HIDE_TRANS_TBL},
+ '\0', NULL, "Hide TRANS.TBL from Joliet tree", ONE_DASH},
+ {{"hide-rr-moved", no_argument, NULL, OPTION_HIDE_RR_MOVED},
+ '\0', NULL, "Rename RR_MOVED to .rr_moved in Rock Ridge tree", ONE_DASH},
+ {{"gui", no_argument, NULL, OPTION_GUI},
+ '\0', NULL, "Switch behaviour for GUI", ONE_DASH},
+ {{NULL, required_argument, NULL, 'i'},
+ 'i', "ADD_FILES", "No longer supported", TWO_DASHES},
+ {{"input-charset", required_argument, NULL, OPTION_INPUT_CHARSET},
+ '\0', "CHARSET", "Local input charset for file name conversion", ONE_DASH},
+ {{"output-charset", required_argument, NULL, OPTION_OUTPUT_CHARSET},
+ '\0', "CHARSET", "Output charset for file name conversion", ONE_DASH},
+ {{"iso-level", required_argument, NULL, OPTION_ISO_LEVEL},
+ '\0', "LEVEL", "Set ISO9660 conformance level (1..3) or 4 for ISO9660 version 2", ONE_DASH},
+ {{"joliet", no_argument, NULL, 'J'},
+ 'J', NULL, "Generate Joliet directory information", ONE_DASH},
+ {{"joliet-long", no_argument, NULL, OPTION_JLONG},
+ '\0', NULL, "Allow Joliet file names to be 103 Unicode characters", ONE_DASH},
+ {{"jcharset", required_argument, NULL, OPTION_JCHARSET},
+ '\0', "CHARSET", "Local charset for Joliet directory information", ONE_DASH},
+ {{"full-iso9660-filenames", no_argument, NULL, 'l'},
+ 'l', NULL, "Allow full 31 character filenames for ISO9660 names", ONE_DASH},
+ {{"max-iso9660-filenames", no_argument, NULL, OPTION_MAX_FILENAMES},
+ '\0', NULL, "Allow 37 character filenames for ISO9660 names (violates ISO9660)", ONE_DASH},
+
+ {{"allow-limited-size", no_argument, NULL, OPTION_ALLOW_LIMITED_SIZE},
+ '\0', NULL, "Allow different file sizes in ISO9660/UDF on large files", ONE_DASH},
+
+ {{"allow-leading-dots", no_argument, NULL, OPTION_ALLOW_LEADING_DOTS},
+ '\0', NULL, "Allow ISO9660 filenames to start with '.' (violates ISO9660)", ONE_DASH},
+ {{"ldots", no_argument, NULL, OPTION_ALLOW_LEADING_DOTS},
+ '\0', NULL, "Allow ISO9660 filenames to start with '.' (violates ISO9660)", ONE_DASH},
+ {{"allow-leading-dots", no_argument, NULL, 'L'},
+ 'L', NULL, "Allow ISO9660 filenames to start with '.' (violates ISO9660)", ONE_DASH},
+
+ {{"log-file", required_argument, NULL, OPTION_LOG_FILE},
+ '\0', "LOG_FILE", "Re-direct messages to LOG_FILE", ONE_DASH},
+ {{"exclude", required_argument, NULL, 'm'},
+ 'm', "GLOBFILE", "Exclude file name", ONE_DASH},
+ {{"exclude-list", required_argument, NULL, OPTION_X_LIST},
+ '\0', "FILE", "File with list of file names to exclude", ONE_DASH},
+ {{"pad", no_argument, NULL, OPTION_PAD},
+ 0, NULL, "Pad output to a multiple of 32k (default)", ONE_DASH},
+ {{"no-pad", no_argument, NULL, OPTION_NOPAD},
+ 0, NULL, "Do not pad output to a multiple of 32k", ONE_DASH},
+ {{"prev-session", required_argument, NULL, 'M'},
+ 'M', "FILE", "Set path to previous session to merge", ONE_DASH},
+ {{"dev", required_argument, NULL, 'M'},
+ '\0', "SCSIdev", "Set path to previous session to merge", ONE_DASH},
+ {{"omit-version-number", no_argument, NULL, 'N'},
+ 'N', NULL, "Omit version number from ISO9660 filename (violates ISO9660)", ONE_DASH},
+ {{"new-dir-mode", required_argument, NULL, OPTION_NEW_DIR_MODE},
+ '\0', "mode", "Mode used when creating new directories.", ONE_DASH},
+ {{"force-rr", no_argument, NULL, OPTION_FORCE_RR},
+ 0, NULL, "Inhibit automatic Rock Ridge detection for previous session", ONE_DASH},
+ {{"no-rr", no_argument, NULL, OPTION_NO_RR},
+ 0, NULL, "Inhibit reading of Rock Ridge attributes from previous session", ONE_DASH},
+ {{"no-split-symlink-components", no_argument, NULL, OPTION_NOSPLIT_SL_COMPONENT},
+ 0, NULL, "Inhibit splitting symlink components", ONE_DASH},
+ {{"no-split-symlink-fields", no_argument, NULL, OPTION_NOSPLIT_SL_FIELD},
+ 0, NULL, "Inhibit splitting symlink fields", ONE_DASH},
+ {{"output", required_argument, NULL, 'o'},
+ 'o', "FILE", "Set output file name", ONE_DASH},
+ {{"path-list", required_argument, NULL, OPTION_P_LIST},
+ '\0', "FILE", "File with list of pathnames to process", ONE_DASH},
+ {{"preparer", required_argument, NULL, 'p'},
+ 'p', "PREP", "Set Volume preparer", ONE_DASH},
+ {{"print-size", no_argument, NULL, OPTION_PRINT_SIZE},
+ '\0', NULL, "Print estimated filesystem size and exit", ONE_DASH},
+ {{"publisher", required_argument, NULL, OPTION_PUBLISHER},
+ '\0', "PUB", "Set Volume publisher", ONE_DASH},
+ {{"publisher", required_argument, NULL, 'P'},
+ 'P', "PUB", "Set Volume publisher", ONE_DASH},
+ {{"quiet", no_argument, NULL, OPTION_QUIET},
+ '\0', NULL, "Run quietly", ONE_DASH},
+ {{"rational-rock", no_argument, NULL, 'r'},
+ 'r', NULL, "Generate rationalized Rock Ridge directory information", ONE_DASH},
+ {{"rock", no_argument, NULL, 'R'},
+ 'R', NULL, "Generate Rock Ridge directory information", ONE_DASH},
+ {{"sectype", required_argument, NULL, 's'},
+ 's', "TYPE", "Set output sector type to e.g. data/xa1/raw", ONE_DASH},
+
+ {{"alpha-boot", required_argument, NULL, OPTION_BOOTALPHA},
+ '\0', "FILE", "Set alpha boot image name (relative to image root)", ONE_DASH},
+
+ {{"hppa-cmdline", required_argument, NULL, OPTION_HPPA_CMDLINE},
+ '\0', "CMDLINE", "Set hppa boot command line (relative to image root)", ONE_DASH},
+ {{"hppa-kernel-32", required_argument, NULL, OPTION_HPPA_KERNEL_32},
+ '\0', "FILE", "Set hppa 32-bit image name (relative to image root)", ONE_DASH},
+ {{"hppa-kernel-64", required_argument, NULL, OPTION_HPPA_KERNEL_64},
+ '\0', "FILE", "Set hppa 64-bit image name (relative to image root)", ONE_DASH},
+ {{"hppa-bootloader", required_argument, NULL, OPTION_HPPA_BOOTLOADER},
+ '\0', "FILE", "Set hppa boot loader file name (relative to image root)", ONE_DASH},
+ {{"hppa-ramdisk", required_argument, NULL, OPTION_HPPA_RAMDISK},
+ '\0', "FILE", "Set hppa ramdisk file name (relative to image root)", ONE_DASH},
+
+ {{"mips-boot", required_argument, NULL, OPTION_BOOTMIPS},
+ '\0', "FILE", "Set mips boot image name (relative to image root)", ONE_DASH},
+
+ {{"mipsel-boot", required_argument, NULL, OPTION_BOOTMIPSEL},
+ '\0', "FILE", "Set mipsel boot image name (relative to image root)", ONE_DASH},
+
+#ifdef JIGDO_TEMPLATE
+ {{"jigdo-jigdo", required_argument, NULL, OPTION_JTJ_OUTPUT},
+ '\0', "FILE", "Produce a jigdo .jigdo file as well as the .iso", ONE_DASH },
+ {{"jigdo-template", required_argument, NULL, OPTION_JTT_OUTPUT},
+ '\0', "FILE", "Produce a jigdo .template file as well as the .iso", ONE_DASH },
+ {{"jigdo-min-file-size", required_argument, NULL, OPTION_JT_MIN_SIZE},
+ '\0', "SIZE", "Minimum size for a file to be listed in the jigdo file", ONE_DASH },
+ {{"jigdo-force-md5", required_argument, NULL, OPTION_JT_INCLUDE},
+ '\0', "PATTERN", "Pattern(s) where files MUST match an externally-supplied MD5sum", ONE_DASH },
+ {{"jigdo-exclude", required_argument, NULL, OPTION_JT_EXCLUDE},
+ '\0', "PATTERN", "Pattern(s) to exclude from the jigdo file", ONE_DASH },
+ {{"jigdo-map", required_argument, NULL, OPTION_JT_PATH_MAP},
+ '\0', "PATTERN1=PATTERN2", "Pattern(s) to map paths (e.g. Debian=/mirror/debian)", ONE_DASH },
+ {{"md5-list", required_argument, NULL, OPTION_JT_MD5_LIST},
+ '\0', "FILE", "File containing MD5 sums of the files that should be checked", ONE_DASH },
+ {{"jigdo-template-compress", required_argument, NULL, OPTION_JT_COMPRESS_ALGO},
+ '\0', "ALGORITHM", "Choose to use gzip or bzip2 compression for template data; default is gzip", ONE_DASH },
+ {{"checksum_algorithm_iso", required_argument, NULL, OPTION_JT_CHECKSUM_ALGO_ISO},
+ '\0', "alg1,alg2,...", "Specify the checksum types desired for the output image", ONE_DASH},
+ {{"checksum_algorithm_template", required_argument, NULL, OPTION_JT_CHECKSUM_ALGO_TMPL},
+ '\0', "alg1,alg2,...", "Specify the checksum types desired for the output jigdo template", ONE_DASH},
+#endif
+
+#ifdef SORTING
+ { {"sort", required_argument, NULL, OPTION_SORT},
+ '\0', "FILE", "Sort file content locations according to rules in FILE", ONE_DASH },
+#endif /* SORTING */
+
+ {{"split-output", no_argument, NULL, OPTION_SPLIT_OUTPUT},
+ '\0', NULL, "Split output into files of approx. 1GB size", ONE_DASH},
+ {{"stream-file-name", required_argument, NULL, OPTION_STREAM_FILE_NAME},
+ '\0', "FILE_NAME", "Set the stream file ISO9660 name (incl. version)", ONE_DASH},
+ {{"stream-media-size", required_argument, NULL, OPTION_STREAM_CD_SIZE},
+ '\0', "#", "Set the size of your CD media in sectors", ONE_DASH},
+ {{"sysid", required_argument, NULL, OPTION_SYSID},
+ '\0', "ID", "Set System ID", ONE_DASH},
+ {{"translation-table", no_argument, NULL, 'T'},
+ 'T', NULL, "Generate translation tables for systems that don't understand long filenames", ONE_DASH},
+ {{"table-name", required_argument, NULL, OPTION_TRANS_TBL},
+ '\0', "TABLE_NAME", "Translation table file name", ONE_DASH},
+ {{"ucs-level", required_argument, NULL, OPTION_UCS_LEVEL},
+ '\0', "LEVEL", "Set Joliet UCS level (1..3)", ONE_DASH},
+
+#ifdef UDF
+ {{"udf", no_argument, NULL, OPTION_UDF},
+ '\0', NULL, "Generate UDF file system", ONE_DASH},
+#endif
+
+#ifdef DVD_VIDEO
+ {{"dvd-video", no_argument, NULL, OPTION_DVD},
+ '\0', NULL, "Generate DVD-Video compliant UDF file system", ONE_DASH},
+#endif
+
+ {{"uid", required_argument, NULL, OPTION_UID},
+ '\0', "uid", "Make the owner of all files this uid.",
+ ONE_DASH},
+ {{"untranslated-filenames", no_argument, NULL, 'U'},
+ /* CSTYLED */
+ 'U', NULL, "Allow Untranslated filenames (for HPUX & AIX - violates ISO9660). Forces -l, -d, -N, -allow-leading-dots, -relaxed-filenames, -allow-lowercase, -allow-multidot", ONE_DASH},
+ {{"relaxed-filenames", no_argument, NULL, OPTION_RELAXED_FILENAMES},
+ '\0', NULL, "Allow 7 bit ASCII except lower case characters (violates ISO9660)", ONE_DASH},
+ {{"no-iso-translate", no_argument, NULL, OPTION_ISO_TRANSLATE},
+ '\0', NULL, "Do not translate illegal ISO characters '~', '-' and '#' (violates ISO9660)", ONE_DASH},
+ {{"allow-lowercase", no_argument, NULL, OPTION_ALLOW_LOWERCASE},
+ '\0', NULL, "Allow lower case characters in addition to the current character set (violates ISO9660)", ONE_DASH},
+ {{"allow-multidot", no_argument, NULL, OPTION_ALLOW_MULTIDOT},
+ '\0', NULL, "Allow more than one dot in filenames (e.g. .tar.gz) (violates ISO9660)", ONE_DASH},
+ {{"use-fileversion", no_argument, NULL, OPTION_USE_FILEVERSION},
+ '\0', "LEVEL", "Use file version # from filesystem", ONE_DASH},
+ {{"verbose", no_argument, NULL, 'v'},
+ 'v', NULL, "Verbose", ONE_DASH},
+ {{"version", no_argument, NULL, OPTION_PVERSION},
+ '\0', NULL, "Print the current version", ONE_DASH},
+ {{"volid", required_argument, NULL, 'V'},
+ 'V', "ID", "Set Volume ID", ONE_DASH},
+ {{"volset", required_argument, NULL, OPTION_VOLSET},
+ '\0', "ID", "Set Volume set ID", ONE_DASH},
+ {{"volset-size", required_argument, NULL, OPTION_VOLSET_SIZE},
+ '\0', "#", "Set Volume set size", ONE_DASH},
+ {{"volset-seqno", required_argument, NULL, OPTION_VOLSET_SEQ_NUM},
+ '\0', "#", "Set Volume set sequence number", ONE_DASH},
+ {{"old-exclude", required_argument, NULL, 'x'},
+ 'x', "FILE", "Exclude file name(depreciated)", ONE_DASH},
+ {{"hard-disk-boot", no_argument, NULL, OPTION_HARD_DISK_BOOT},
+ '\0', NULL, "Boot image is a hard disk image", ONE_DASH},
+ {{"no-emul-boot", no_argument, NULL, OPTION_NO_EMUL_BOOT},
+ '\0', NULL, "Boot image is 'no emulation' image", ONE_DASH},
+ {{"no-boot", no_argument, NULL, OPTION_NO_BOOT},
+ '\0', NULL, "Boot image is not bootable", ONE_DASH},
+ {{"boot-load-seg", required_argument, NULL, OPTION_BOOT_LOAD_ADDR},
+ '\0', "#", "Set load segment for boot image", ONE_DASH},
+ {{"boot-load-size", required_argument, NULL, OPTION_BOOT_LOAD_SIZE},
+ '\0', "#", "Set numbers of load sectors", ONE_DASH},
+ {{"boot-info-table", no_argument, NULL, OPTION_BOOT_INFO_TABLE},
+ '\0', NULL, "Patch boot image with info table", ONE_DASH},
+ {{"XA", no_argument, NULL, OPTION_XA},
+ '\0', NULL, "Generate XA directory attruibutes", ONE_DASH},
+ {{"xa", no_argument, NULL, OPTION_XA_RATIONALIZED},
+ '\0', NULL, "Generate rationalized XA directory attruibutes", ONE_DASH},
+ {{"transparent-compression", no_argument, NULL, 'z'},
+ 'z', NULL, "Enable transparent compression of files", ONE_DASH},
+
+#ifdef APPLE_HYB
+ {{"hfs-type", required_argument, NULL, OPTION_HFS_TYPE},
+ '\0', "TYPE", "Set HFS default TYPE", ONE_DASH},
+ {{"hfs-creator", required_argument, NULL, OPTION_HFS_CREATOR},
+ '\0', "CREATOR", "Set HFS default CREATOR", ONE_DASH},
+ {{"apple", no_argument, NULL, 'g'},
+ 'g', NULL, "Add Apple ISO9660 extensions", ONE_DASH},
+ {{"hfs", no_argument, NULL, 'h'},
+ 'h', NULL, "Create ISO9660/HFS hybrid", ONE_DASH},
+ {{"map", required_argument, NULL, OPTION_MAP_FILE},
+ '\0', "MAPPING_FILE", "Map file extensions to HFS TYPE/CREATOR", ONE_DASH},
+ {{"map", required_argument, NULL, 'H'},
+ 'H', "MAPPING_FILE", "Map file extensions to HFS TYPE/CREATOR", ONE_DASH},
+ {{"magic", required_argument, NULL, OPTION_MAGIC_FILE},
+ '\0', "FILE", "Magic file for HFS TYPE/CREATOR", ONE_DASH},
+ {{"probe", no_argument, NULL, OPTION_PROBE},
+ '\0', NULL, "Probe all files for Apple/Unix file types", ONE_DASH},
+ {{"mac-name", no_argument, NULL, OPTION_MACNAME},
+ '\0', NULL, "Use Macintosh name for ISO9660/Joliet/RockRidge file name",
+ ONE_DASH},
+ {{"no-mac-files", no_argument, NULL, OPTION_NOMACFILES},
+ '\0', NULL, "Do not look for Unix/Mac files (depreciated)", ONE_DASH},
+ {{"boot-hfs-file", required_argument, NULL, OPTION_BOOT_HFS_FILE},
+ '\0', "FILE", "Set HFS boot image name", ONE_DASH},
+ {{"part", no_argument, NULL, OPTION_GEN_PT},
+ '\0', NULL, "Generate HFS partition table", ONE_DASH},
+ {{"cluster-size", required_argument, NULL, OPTION_BSIZE},
+ '\0', "SIZE", "Cluster size for PC Exchange Macintosh files", ONE_DASH},
+ {{"auto", required_argument, NULL, OPTION_AUTOSTART},
+ '\0', "FILE", "Set HFS AutoStart file name", ONE_DASH},
+ {{"no-desktop", no_argument, NULL, OPTION_CREATE_DT},
+ '\0', NULL, "Do not create the HFS (empty) Desktop files", ONE_DASH},
+ {{"hide-hfs", required_argument, NULL, OPTION_HFS_HIDE},
+ '\0', "GLOBFILE", "Hide HFS file", ONE_DASH},
+ {{"hide-hfs-list", required_argument, NULL, OPTION_HFS_LIST},
+ '\0', "FILE", "List of HFS files to hide", ONE_DASH},
+ {{"hfs-volid", required_argument, NULL, OPTION_HFS_VOLID},
+ '\0', "HFS_VOLID", "Volume name for the HFS partition", ONE_DASH},
+ {{"icon-position", no_argument, NULL, OPTION_ICON_POS},
+ '\0', NULL, "Keep HFS icon position", ONE_DASH},
+ {{"root-info", required_argument, NULL, OPTION_ROOT_INFO},
+ '\0', "FILE", "finderinfo for root folder", ONE_DASH},
+ {{"input-hfs-charset", required_argument, NULL, OPTION_HFS_INPUT_CHARSET},
+ '\0', "CHARSET", "Local input charset for HFS file name conversion", ONE_DASH},
+ {{"output-hfs-charset", required_argument, NULL, OPTION_HFS_OUTPUT_CHARSET},
+ '\0', "CHARSET", "Output charset for HFS file name conversion", ONE_DASH},
+ {{"hfs-unlock", no_argument, NULL, OPTION_HFS_UNLOCK},
+ '\0', NULL, "Leave HFS Volume unlocked", ONE_DASH},
+ {{"hfs-bless", required_argument, NULL, OPTION_HFS_BLESS},
+ '\0', "FOLDER_NAME", "Name of Folder to be blessed", ONE_DASH},
+ {{"hfs-parms", required_argument, NULL, OPTION_HFS_PARMS},
+ '\0', "PARAMETERS", "Comma separated list of HFS parameters", ONE_DASH},
+#ifdef PREP_BOOT
+ {{"prep-boot", required_argument, NULL, OPTION_PREP_BOOT},
+ '\0', "FILE", "PReP boot image file -- up to 4 are allowed", ONE_DASH},
+ {{"chrp-boot", no_argument, NULL, OPTION_CHRP_BOOT},
+ '\0', NULL, "Add CHRP boot header", ONE_DASH},
+#endif /* PREP_BOOT */
+ {{"cap", no_argument, NULL, OPTION_CAP},
+ '\0', NULL, "Look for AUFS CAP Macintosh files", TWO_DASHES},
+ {{"netatalk", no_argument, NULL, OPTION_NETA},
+ '\0', NULL, "Look for NETATALK Macintosh files", TWO_DASHES},
+ {{"double", no_argument, NULL, OPTION_DBL},
+ '\0', NULL, "Look for AppleDouble Macintosh files", TWO_DASHES},
+ {{"ethershare", no_argument, NULL, OPTION_ESH},
+ '\0', NULL, "Look for Helios EtherShare Macintosh files", TWO_DASHES},
+ {{"exchange", no_argument, NULL, OPTION_FE},
+ '\0', NULL, "Look for PC Exchange Macintosh files", TWO_DASHES},
+ {{"sgi", no_argument, NULL, OPTION_SGI},
+ '\0', NULL, "Look for SGI Macintosh files", TWO_DASHES},
+ {{"macbin", no_argument, NULL, OPTION_MBIN},
+ '\0', NULL, "Look for MacBinary Macintosh files", TWO_DASHES},
+ {{"single", no_argument, NULL, OPTION_SGL},
+ '\0', NULL, "Look for AppleSingle Macintosh files", TWO_DASHES},
+ {{"ushare", no_argument, NULL, OPTION_USH},
+ '\0', NULL, "Look for IPT UShare Macintosh files", TWO_DASHES},
+ {{"xinet", no_argument, NULL, OPTION_XIN},
+ '\0', NULL, "Look for XINET Macintosh files", TWO_DASHES},
+ {{"dave", no_argument, NULL, OPTION_DAVE},
+ '\0', NULL, "Look for DAVE Macintosh files", TWO_DASHES},
+ {{"sfm", no_argument, NULL, OPTION_SFM},
+ '\0', NULL, "Look for SFM Macintosh files", TWO_DASHES},
+ {{"osx-double", no_argument, NULL, OPTION_XDBL},
+ '\0', NULL, "Look for MacOS X AppleDouble Macintosh files", TWO_DASHES},
+ {{"osx-hfs", no_argument, NULL, OPTION_XHFS},
+ '\0', NULL, "Look for MacOS X HFS Macintosh files", TWO_DASHES},
+#endif /* APPLE_HYB */
+};
+
+#define OPTION_COUNT (sizeof ld_options / sizeof (ld_options[0]))
+
+static void read_rcfile(char *appname);
+static void susage(int excode);
+static void usage(int excode);
+int iso9660_date(char *result, time_t crtime);
+static void hide_reloc_dir(void);
+static char *get_pnames(int argc, char **argv, int opt, char *pname,
+ int pnsize, FILE *fp);
+char *findgequal(char *s);
+static char *escstrcpy(char *to, char *from);
+void *e_malloc(size_t size);
+
+static int
+read_one_rcfile(char *filename)
+{
+ int linum = 0;
+ char linebuffer[256];
+ FILE *fp;
+
+ if (!filename)
+ return 0;
+
+ fp = fopen(filename, "r");
+ if (!fp) {
+ if (errno == ENOENT)
+ return 0;
+#ifdef USE_LIBSCHILY
+ errmsg("Cannot open '%s'.\n", filename);
+#else
+ perror(filename);
+#endif
+ return 0;
+ }
+ if (verbose > 0)
+ fprintf(stderr, "Using \"%s\"\n", filename);
+
+ while (fgets(linebuffer, sizeof(linebuffer), fp)) {
+ char *name, *p, *p1;
+ struct rcopts *rco;
+
+ ++linum;
+ /* skip any leading white space */
+ for (p = linebuffer; *p == ' ' || *p == '\t'; p++)
+ ;
+ /* Skip comments and blank lines */
+ if (!*p || *p == '\n' || *p == '\r' || *p == '#')
+ continue;
+ /*
+ * The name should begin in the left margin. Make sure it is
+ * in upper case. Stop when we see white space or a comment.
+ */
+ name = p;
+ while (*p && (isalpha((unsigned char) *p) || *p == '_'))
+ *p++ = toupper((unsigned char) *p);
+
+ if (name == p) {
+ fprintf(stderr, "%s:%d: name required\n", filename,
+ linum);
+ continue;
+ }
+
+ p1 = p;
+ /* Skip past white space after the name */
+ while (*p == ' ' || *p == '\t')
+ p++;
+ /* silently ignore errors in the rc file. */
+ if (*p != '=') {
+ fprintf(stderr, "%s:%d: equals sign required after '%.*s'\n",
+ filename, linum,
+ (int)(p1-name), name);
+ continue;
+ }
+ *p1 = 0;
+
+ /* Skip pas the = sign, and any white space following it */
+ p++;
+ while (*p == ' ' || *p == '\t')
+ p++;
+
+ /* Get rid of trailing newline */
+ for (p1 = p; *p1 && *p1 != '\n' && *p1 != '\r'; p1++)
+ ;
+ *p1 = 0;
+
+ /* Figure out which option we have */
+ for (rco = rcopt; rco->tag; rco++)
+ if (strcmp(rco->tag, name) == 0) {
+ /* memleak if we ever do this more than once */
+ *rco->variable = strdup(p);
+ break;
+ }
+
+ if (!rco->tag) {
+ fprintf(stderr, "%s:%d: field name '%s' unknown\n",
+ filename, linum,
+ name);
+ }
+ }
+ if (ferror(fp)) {
+#ifdef USE_LIBSCHILY
+ errmsg("Read error on '%s'.\n", filename);
+#else
+ perror(filename);
+#endif
+ fclose(fp);
+ return 0;
+ }
+ fclose(fp);
+ return 1;
+}
+
+#define ETCDIR "/etc"
+#define RCFILENAME "genisoimagerc"
+#define OLD_RCFILENAME "mkisofsrc"
+
+static void
+read_rcfile(char *appname)
+{
+ char *p;
+ char filename[1000];
+
+ if (read_one_rcfile(getenv("GENISOIMAGERC")))
+ return;
+ if (read_one_rcfile(getenv("MKISOFSRC")))
+ return;
+ if (read_one_rcfile("." RCFILENAME))
+ return;
+ if (read_one_rcfile("." OLD_RCFILENAME))
+ return;
+
+ p = getenv("HOME");
+ if (p && strlen(p) + 1 + sizeof(RCFILENAME) < sizeof(filename)) {
+ strcpy(filename, p);
+ p = filename + strlen(filename);
+ *p++ = PATH_SEPARATOR;
+ strcpy(p, "." RCFILENAME);
+ if (read_one_rcfile(filename))
+ return;
+ strcpy(p, "." OLD_RCFILENAME);
+ if (read_one_rcfile(filename))
+ return;
+ }
+
+ if (read_one_rcfile(ETCDIR SPATH_SEPARATOR RCFILENAME))
+ return;
+
+ if (appname &&
+ strlen(appname) + 1 + sizeof(RCFILENAME) < sizeof(filename)) {
+ strcpy(filename, appname);
+ p = strrchr(filename, PATH_SEPARATOR);
+ if (p) {
+ strcpy(p + 1, RCFILENAME);
+ if (read_one_rcfile(filename))
+ return;
+ }
+ }
+}
+
+char *path_table_l = NULL;
+char *path_table_m = NULL;
+
+char *jpath_table_l = NULL;
+char *jpath_table_m = NULL;
+
+int goof = 0;
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+static void
+susage(int excode)
+{
+ const char *program_name = "genisoimage";
+
+ fprintf(stderr, "Usage: %s [options] -o file directory ...\n", program_name);
+ fprintf(stderr, "\nUse %s -help\n", program_name);
+ fprintf(stderr, "to get a list of valid options.\n");
+ fprintf(stderr, "\nReport problems to debburn-devel@lists.alioth.debian.org.\n");
+
+ exit(excode);
+}
+
+static void
+usage(int excode)
+{
+ const char *program_name = "genisoimage";
+
+ int i;
+
+/* const char **targets, **pp;*/
+
+ fprintf(stderr, "Usage: %s [options] file...\n", program_name);
+
+ fprintf(stderr, "Options:\n");
+ for (i = 0; i < (int)OPTION_COUNT; i++) {
+ if (ld_options[i].doc != NULL) {
+ int comma;
+ int len;
+ int j;
+
+ fprintf(stderr, " ");
+
+ comma = FALSE;
+ len = 2;
+
+ j = i;
+ do {
+ if (ld_options[j].shortopt != '\0' &&
+ ld_options[j].control != NO_HELP) {
+ fprintf(stderr, "%s-%c",
+ comma ? ", " : "",
+ ld_options[j].shortopt);
+ len += (comma ? 2 : 0) + 2;
+ if (ld_options[j].arg != NULL) {
+ if (ld_options[j].opt.has_arg != optional_argument) {
+ fprintf(stderr, " ");
+ ++len;
+ }
+ fprintf(stderr, "%s",
+ ld_options[j].arg);
+ len += strlen(ld_options[j].arg);
+ }
+ comma = TRUE;
+ }
+ ++j;
+ }
+ while (j < (int)OPTION_COUNT && ld_options[j].doc == NULL);
+
+ j = i;
+ do {
+ if (ld_options[j].opt.name != NULL &&
+ ld_options[j].control != NO_HELP) {
+ fprintf(stderr, "%s-%s%s",
+ comma ? ", " : "",
+ ld_options[j].control == TWO_DASHES ? "-" : "",
+ ld_options[j].opt.name);
+ len += ((comma ? 2 : 0)
+ + 1
+ + (ld_options[j].control == TWO_DASHES ? 1 : 0)
+ + strlen(ld_options[j].opt.name));
+ if (ld_options[j].arg != NULL) {
+ fprintf(stderr, " %s",
+ ld_options[j].arg);
+ len += 1 +
+ strlen(ld_options[j].arg);
+ }
+ comma = TRUE;
+ }
+ ++j;
+ }
+ while (j < (int)OPTION_COUNT && ld_options[j].doc == NULL);
+
+ if (len >= 30) {
+ fprintf(stderr, "\n");
+ len = 0;
+ }
+ for (; len < 30; len++)
+ fputc(' ', stderr);
+
+ fprintf(stderr, "%s\n", ld_options[i].doc);
+ }
+ }
+ fprintf(stderr,
+ "\nReport problems to debburn-devel@lists.alioth.debian.org.\n");
+ exit(excode);
+}
+
+
+/*
+ * Fill in date in the iso9660 format
+ *
+ * The standards state that the timezone offset is in multiples of 15
+ * minutes, and is what you add to GMT to get the localtime. The U.S.
+ * is always at a negative offset, from -5h to -8h (can vary a little
+ * with DST, I guess). The Linux iso9660 filesystem has had the sign
+ * of this wrong for ages (genisoimage had it wrong too for the longest time).
+ */
+int
+iso9660_date(char *result, time_t crtime)
+{
+ struct tm *local;
+
+ local = localtime(&crtime);
+ result[0] = local->tm_year;
+ result[1] = local->tm_mon + 1;
+ result[2] = local->tm_mday;
+ result[3] = local->tm_hour;
+ result[4] = local->tm_min;
+ result[5] = local->tm_sec;
+
+ /*
+ * Must recalculate proper timezone offset each time, as some files use
+ * daylight savings time and some don't...
+ */
+ result[6] = local->tm_yday; /* save yday 'cause gmtime zaps it */
+ local = gmtime(&crtime);
+ local->tm_year -= result[0];
+ local->tm_yday -= result[6];
+ local->tm_hour -= result[3];
+ local->tm_min -= result[4];
+ if (local->tm_year < 0) {
+ local->tm_yday = -1;
+ } else {
+ if (local->tm_year > 0)
+ local->tm_yday = 1;
+ }
+
+ result[6] = -(local->tm_min + 60 *
+ (local->tm_hour + 24 * local->tm_yday)) / 15;
+
+ return (0);
+}
+
+/* hide "./rr_moved" if all its contents are hidden */
+static void
+hide_reloc_dir()
+{
+ struct directory_entry *s_entry;
+
+ for (s_entry = reloc_dir->contents; s_entry; s_entry = s_entry->next) {
+ if (strcmp(s_entry->name, ".") == 0 ||
+ strcmp(s_entry->name, "..") == 0)
+ continue;
+
+ if ((s_entry->de_flags & INHIBIT_ISO9660_ENTRY) == 0)
+ return;
+ }
+
+ /* all entries are hidden, so hide this directory */
+ reloc_dir->dir_flags |= INHIBIT_ISO9660_ENTRY;
+ reloc_dir->self->de_flags |= INHIBIT_ISO9660_ENTRY;
+}
+
+/*
+ * get pathnames from the command line, and then from given file
+ */
+static char *
+get_pnames(int argc, char **argv, int opt, char *pname, int pnsize, FILE *fp)
+{
+ int len;
+
+ /* we may of already read the first line from the pathnames file */
+ if (save_pname) {
+ save_pname = 0;
+ return (pname);
+ }
+
+ if (opt < argc)
+ return (argv[opt]);
+
+ if (fp == NULL)
+ return ((char *) 0);
+
+ if (fgets(pname, pnsize, fp)) {
+ /* Discard newline */
+ len = strlen(pname);
+ if (pname[len - 1] == '\n') {
+ pname[len - 1] = '\0';
+ }
+ return (pname);
+ }
+ return ((char *) 0);
+}
+
+extern char *cdrecord_data;
+
+int main(int argc, char *argv[])
+{
+ struct directory_entry de;
+
+#ifdef HAVE_SBRK
+ unsigned long mem_start;
+
+#endif
+ struct stat statbuf;
+ char *merge_image = NULL;
+ char *reloc_root = NULL;
+ char *reloc_old_root = NULL;
+ struct iso_directory_record *mrootp = NULL;
+ struct output_fragment *opnt;
+ int longind;
+ char shortopts[OPTION_COUNT * 3 + 2];
+ struct option longopts[OPTION_COUNT + 1];
+ int c;
+ int n;
+ char *log_file = 0;
+ char *node = NULL;
+ char *pathnames = 0;
+ FILE *pfp = NULL;
+ char pname[2*PATH_MAX + 1 + 1]; /* may be too short */
+ char *arg; /* if '\\' present */
+ char nodename[PATH_MAX + 1];
+ int no_path_names = 1;
+ int warn_violate = 0;
+ int have_cmd_line_pathspec = 0;
+ int rationalize_all = 0;
+ char *mkisofs_call = 0; /* use as pointer and boolean */
+
+#ifdef APPLE_HYB
+ char *afpfile = ""; /* mapping file for TYPE/CREATOR */
+ int hfs_ct = 0;
+ char *root_info = 0;
+#endif /* APPLE_HYB */
+
+ /* abusing arg */
+ mkisofs_call=strstr(argv[0], "mkisofs");
+ if(mkisofs_call && '\0' == mkisofs_call[7]) /* lame cheater detected */
+ argv[0]="genisoimage";
+
+#ifdef __EMX__
+ /* This gives wildcard expansion with Non-Posix shells with EMX */
+ _wildcard(&argc, &argv);
+#endif
+ save_args(argc, argv);
+
+ if (argc < 2) {
+#ifdef USE_LIBSCHILY
+ errmsgno(EX_BAD, "Missing pathspec.\n");
+#endif
+ susage(1);
+ }
+ /* Get the defaults from the .genisoimagerc file */
+ read_rcfile(argv[0]);
+
+ outfile = NULL;
+
+ /*
+ * Copy long option initialization from GNU-ld.
+ */
+ /*
+ * Starting the short option string with '-' is for programs that
+ * expect options and other ARGV-elements in any order and that care
+ * about the ordering of the two. We describe each non-option
+ * ARGV-element as if it were the argument of an option with
+ * character code 1.
+ */
+ {
+ int i,
+ is,
+ il;
+
+ shortopts[0] = '-';
+ is = 1;
+ il = 0;
+ for (i = 0; i < (int)OPTION_COUNT; i++) {
+ if (ld_options[i].shortopt != '\0') {
+ shortopts[is] = ld_options[i].shortopt;
+ ++is;
+ if (ld_options[i].opt.has_arg ==
+ required_argument ||
+ ld_options[i].opt.has_arg ==
+ optional_argument) {
+ shortopts[is] = ':';
+ ++is;
+ if (ld_options[i].opt.has_arg ==
+ optional_argument) {
+ shortopts[is] = ':';
+ ++is;
+ }
+ }
+ }
+ if (ld_options[i].opt.name != NULL) {
+ longopts[il] = ld_options[i].opt;
+ ++il;
+ }
+ }
+ shortopts[is] = '\0';
+ longopts[il].name = NULL;
+ }
+
+ while ((c = getopt_long_only(argc, argv, shortopts,
+ longopts, &longind)) != EOF)
+ switch (c) {
+ case 1:
+ /* A filename that we take as input. */
+ optind--;
+ have_cmd_line_pathspec = 1;
+ goto parse_input_files;
+
+ case OPTION_USE_GRAFT:
+ use_graft_ptrs = 1;
+ break;
+ case 'C':
+ /*
+ * This is a temporary hack until cdrecord gets the
+ * proper hooks in it.
+ */
+ cdrecord_data = optarg;
+ break;
+ case OPTION_GUI:
+ gui++;
+ break;
+ case 'i':
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD, "-i option no longer supported.\n");
+#else
+ fprintf(stderr, "-i option no longer supported.\n");
+ exit(1);
+#endif
+ break;
+ case OPTION_ISO_LEVEL:
+ iso9660_level = atoi(optarg);
+
+ switch (iso9660_level) {
+
+ case 1:
+ /*
+ * Only on file section
+ * 8.3 d or d1 characters for files
+ * 8 d or d1 characters for directories
+ */
+ break;
+ case 2:
+ /*
+ * Only on file section
+ */
+ break;
+ case 3:
+ /*
+ * No restrictions
+ */
+ break;
+ case 4:
+ /*
+ * This is ISO-9660:1988 (ISO-9660 version 2)
+ */
+ iso9660_namelen = MAX_ISONAME_V2; /* allow 207 chars */
+ full_iso9660_filenames++; /* 31+ chars */
+ omit_version_number++;
+ RR_relocation_depth = 32767;
+
+ /*
+ * From -U ...
+ */
+ omit_period++; /* trailing dot */
+ allow_leading_dots++;
+ relaxed_filenames++; /* all chars */
+ allow_lowercase++; /* even lowcase */
+ allow_multidot++; /* > 1 dots */
+ break;
+
+ default:
+ comerrno(EX_BAD, "Illegal iso9660 Level %d, use 1..3 or 4.\n",
+ iso9660_level);
+ }
+ break;
+ case 'J':
+ use_Joliet++;
+ break;
+ case OPTION_JLONG:
+ use_Joliet++;
+ jlen = JLONGMAX;
+ break;
+ case OPTION_JCHARSET:
+ use_Joliet++;
+ /* FALLTHROUGH */
+ case OPTION_INPUT_CHARSET:
+ icharset = optarg;
+ break;
+ case OPTION_OUTPUT_CHARSET:
+ ocharset = optarg;
+ break;
+#ifdef JIGDO_TEMPLATE
+ case OPTION_JTT_OUTPUT:
+ jtemplate_out = optarg;
+ break;
+ case OPTION_JTJ_OUTPUT:
+ jjigdo_out = optarg;
+ break;
+ case OPTION_JT_MD5_LIST:
+ jmd5_list = optarg;
+ break;
+ case OPTION_JT_MIN_SIZE:
+ jte_min_size = atoi(optarg);
+ if (jte_min_size < MIN_JIGDO_FILE_SIZE) {
+ fprintf(stderr, "Jigdo min size %d too small; using default %d instead\n", jte_min_size, MIN_JIGDO_FILE_SIZE);
+ jte_min_size = MIN_JIGDO_FILE_SIZE;
+ }
+ break;
+ case OPTION_JT_INCLUDE:
+ if (jte_add_include(optarg)) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "Failed to build jigdo-include list\n");
+#else
+ fprintf(stderr,
+ "Failed to build jigdo-include list\n");
+ exit(1);
+#endif
+ }
+ break;
+ case OPTION_JT_EXCLUDE:
+ if (jte_add_exclude(optarg)) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "Failed to build jigdo-exclude list\n");
+#else
+ fprintf(stderr,
+ "Failed to build jigdo-exclude list\n");
+ exit(1);
+#endif
+ }
+ break;
+ case OPTION_JT_PATH_MAP:
+ if (jte_add_mapping(optarg)) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "Failed to build jigdo mapping list\n");
+#else
+ fprintf(stderr,
+ "Failed to build jigdo mapping list\n");
+ exit(1);
+#endif
+ }
+ break;
+ case OPTION_JT_COMPRESS_ALGO:
+ if (!strcasecmp(optarg, "gzip"))
+ jte_template_compression = JTE_TEMP_GZIP;
+ else if (!strcasecmp(optarg, "bzip2"))
+ jte_template_compression = JTE_TEMP_BZIP2;
+ else
+ {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD, "Compression algorithm %s unknown\n", optarg);
+#else
+ fprintf(stderr, "Compression algorithm %s unknown\n", optarg);
+ exit(1);
+#endif
+ }
+ break;
+
+ case OPTION_JT_CHECKSUM_ALGO_ISO:
+ if (parse_checksum_algo(optarg, &checksum_algo_iso))
+ {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD, "Problem with ISO checksum choices: %s \n", optarg);
+#else
+ fprintf(stderr, "Problem with ISO checksum choices: %s\n", optarg);
+ exit(1);
+#endif
+ }
+
+ break;
+
+ case OPTION_JT_CHECKSUM_ALGO_TMPL:
+ if (parse_checksum_algo(optarg, &checksum_algo_tmpl))
+ {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD, "Problem with template checksum choices: %s \n", optarg);
+#else
+ fprintf(stderr, "Problem with template checksum choices: %s\n", optarg);
+ exit(1);
+#endif
+ }
+ break;
+
+#endif /* JIGDO_TEMPLATE */
+ case OPTION_NOBAK:
+ all_files = 0;
+ break;
+ case 'b':
+ do_sort++; /* We sort bootcat/botimage */
+ use_eltorito++;
+ boot_image = optarg; /* pathname of the boot image */
+ /* on disk */
+ if (boot_image == NULL) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "Required Eltorito boot image pathname missing\n");
+#else
+ fprintf(stderr,
+ "Required Eltorito boot image pathname missing\n");
+ exit(1);
+#endif
+ }
+ get_boot_entry();
+ current_boot_entry->boot_image = boot_image;
+ break;
+ case OPTION_ALT_BOOT:
+ /*
+ * Start new boot entry parameter list.
+ */
+ new_boot_entry();
+ break;
+ case OPTION_BOOTALPHA:
+ use_alphaboot++;
+ /* list of pathnames of boot images */
+ add_boot_alpha_filename(optarg);
+ break;
+ case OPTION_HPPA_CMDLINE:
+ use_hppaboot++;
+ add_boot_hppa_cmdline(optarg);
+ break;
+ case OPTION_HPPA_KERNEL_32:
+ use_hppaboot++;
+ add_boot_hppa_kernel_32(optarg);
+ break;
+ case OPTION_HPPA_KERNEL_64:
+ use_hppaboot++;
+ add_boot_hppa_kernel_64(optarg);
+ break;
+ case OPTION_HPPA_BOOTLOADER:
+ use_hppaboot++;
+ add_boot_hppa_bootloader(optarg);
+ break;
+ case OPTION_HPPA_RAMDISK:
+ use_hppaboot++;
+ /* list of pathnames of boot images */
+ add_boot_hppa_ramdisk(optarg);
+ break;
+ case OPTION_BOOTMIPS:
+ use_mipsboot++;
+ /* list of pathnames of boot images */
+ add_boot_mips_filename(optarg);
+ break;
+ case OPTION_BOOTMIPSEL:
+ use_mipselboot++;
+ add_boot_mipsel_filename(optarg);
+ break;
+ case 'B':
+ if (use_sunx86boot)
+ comerrno(EX_BAD,
+ "-sparc-boot and -sunx86-boot are mutual exclusive.\n");
+ use_sparcboot++;
+ /* list of pathnames of boot images */
+ scan_sparc_boot(optarg);
+ break;
+ case OPTION_SUNX86BOOT:
+ if (use_sparcboot)
+ comerrno(EX_BAD,
+ "-sparc-boot and -sunx86-boot are mutual exclusive.\n");
+ use_sunx86boot++;
+ /* list of pathnames of boot images */
+ scan_sunx86_boot(optarg);
+ break;
+ case 'G':
+ use_genboot++;
+ /* pathname of the boot image on disk */
+ genboot_image = optarg;
+ if (genboot_image == NULL) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "Required generic boot image pathname missing\n");
+#else
+ fprintf(stderr,
+ "Required generic boot image pathname missing\n");
+ exit(1);
+#endif
+ }
+ break;
+ case OPTION_SPARCLABEL:
+ /* Sun disk label string */
+ sparc_boot_label(optarg);
+ break;
+ case OPTION_SUNX86LABEL:
+ /* Sun disk label string */
+ sunx86_boot_label(optarg);
+ break;
+ case 'c':
+ use_eltorito++;
+ /* pathname of the boot image on cd */
+ boot_catalog = optarg;
+ if (boot_catalog == NULL) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "Required boot catalog pathname missing\n");
+#else
+ fprintf(stderr,
+ "Required boot catalog pathname missing\n");
+ exit(1);
+#endif
+ }
+ break;
+ case OPTION_ABSTRACT:
+ abstract = optarg;
+ if (strlen(abstract) > 37) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "Abstract filename string too long\n");
+#else
+ fprintf(stderr,
+ "Abstract filename string too long\n");
+ exit(1);
+#endif
+ }
+ break;
+ case 'A':
+ appid = optarg;
+ if (strlen(appid) > 128) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "Application-id string too long\n");
+#else
+ fprintf(stderr,
+ "Application-id string too long\n");
+ exit(1);
+#endif
+ }
+ break;
+ case OPTION_BIBLIO:
+ biblio = optarg;
+ if (strlen(biblio) > 37) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "Bibliographic filename string too long\n");
+#else
+ fprintf(stderr,
+ "Bibliographic filename string too long\n");
+ exit(1);
+#endif
+ }
+ break;
+ case OPTION_CACHE_INODES:
+ cache_inodes = 1;
+ break;
+ case OPTION_NOCACHE_INODES:
+ cache_inodes = 0;
+ break;
+ case OPTION_CHECK_OLDNAMES:
+ check_oldnames++;
+ break;
+ case OPTION_CHECK_SESSION:
+ check_session++;
+ check_oldnames++;
+ merge_image = optarg;
+ outfile = "/dev/null";
+ /*
+ * cdrecord_data is handled specially in multi.c
+ * as we cannot write to all strings.
+ * If genisoimage is called with -C xx,yy
+ * our default is overwritten.
+ */
+/* cdrecord_data = "0,0";*/
+ break;
+ case OPTION_COPYRIGHT:
+ copyright = optarg;
+ if (strlen(copyright) > 37) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "Copyright filename string too long\n");
+#else
+ fprintf(stderr,
+ "Copyright filename string too long\n");
+ exit(1);
+#endif
+ }
+ break;
+ case OPTION_DEBUG:
+ debug++;
+ break;
+ case 'd':
+ omit_period++;
+ warn_violate++;
+ break;
+ case 'D':
+ RR_relocation_depth = 32767;
+ break;
+ case 'f':
+ follow_links++;
+ break;
+ case 'l':
+ full_iso9660_filenames++;
+ break;
+ case OPTION_MAX_FILENAMES:
+ iso9660_namelen = MAX_ISONAME_V1; /* allow 37 chars */
+ full_iso9660_filenames++;
+ omit_version_number++;
+ warn_violate++;
+ break;
+ case 'L':
+ /* FALLTHRU */
+ case OPTION_ALLOW_LEADING_DOTS:
+ allow_leading_dots++;
+ warn_violate++;
+ break;
+ case OPTION_LOG_FILE:
+ log_file = optarg;
+ break;
+ case 'M':
+ merge_image = optarg;
+ break;
+ case OPTION_RELOC_ROOT:
+ reloc_root = optarg;
+ break;
+ case OPTION_RELOC_OLD_ROOT:
+ reloc_old_root = optarg;
+ break;
+ case 'N':
+ omit_version_number++;
+ warn_violate++;
+ break;
+ case OPTION_FORCE_RR:
+ force_rr++;
+ break;
+ case OPTION_NO_RR:
+ no_rr++;
+ break;
+ case 'o':
+ outfile = optarg;
+ break;
+ case OPTION_PAD:
+ dopad++;
+ break;
+ case OPTION_NOPAD:
+ dopad = 0;
+ break;
+ case OPTION_P_LIST:
+ pathnames = optarg;
+ break;
+ case 'p':
+ preparer = optarg;
+ if (strlen(preparer) > 128) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD, "Preparer string too long\n");
+#else
+ fprintf(stderr, "Preparer string too long\n");
+ exit(1);
+#endif
+ }
+ break;
+ case OPTION_PRINT_SIZE:
+ print_size++;
+ break;
+ case 'P':
+ /* FALLTHRU */
+ case OPTION_PUBLISHER:
+ publisher = optarg;
+ if (strlen(publisher) > 128) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "Publisher string too long\n");
+#else
+ fprintf(stderr, "Publisher string too long\n");
+ exit(1);
+#endif
+ }
+ break;
+ case OPTION_QUIET:
+ verbose = 0;
+ break;
+ case 'R':
+ use_RockRidge++;
+ break;
+ case 'r':
+ rationalize_all++;
+ use_RockRidge++;
+ break;
+ case OPTION_XA:
+ use_XA++;
+ break;
+ case OPTION_XA_RATIONALIZED:
+ rationalize_all++;
+ use_XA++;
+ break;
+
+ case 's':
+ if (strcmp(optarg, "data") == 0)
+ osecsize = 2048;
+ else if (strcmp(optarg, "xa1") == 0)
+ osecsize = 2056;
+ else if (strcmp(optarg, "raw") == 0) {
+ osecsize = 2352;
+ comerrno(EX_BAD,
+ "Unsupported sector type '%s'.\n",
+ optarg);
+ }
+ break;
+ case 'S':
+#ifdef USE_LIBSCHILY
+ errmsgno(EX_BAD, "Option -%c is reserved for future use.\n", c);
+#else
+ fprintf(stderr, "Option -%c is reserved for future use.\n", c);
+#endif
+ susage(1);
+ /* NOTREACHED */
+
+ case OPTION_NEW_DIR_MODE:
+ rationalize++;
+ {
+ char *end = 0;
+
+ new_dir_mode = strtol(optarg, &end, 8);
+ if (!end || *end != 0 ||
+ new_dir_mode < 0 || new_dir_mode > 07777) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD, "Bad mode for -new-dir-mode\n");
+#else
+ fprintf(stderr, "Bad mode for -new-dir-mode\n");
+ exit(1);
+#endif
+ }
+ break;
+ }
+
+ case OPTION_UID:
+ rationalize++;
+ use_RockRidge++;
+ rationalize_uid++;
+ {
+ char *end = 0;
+
+ uid_to_use = strtol(optarg, &end, 0);
+ if (!end || *end != 0) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD, "Bad value for -uid\n");
+#else
+ fprintf(stderr, "Bad value for -uid\n");
+ exit(1);
+#endif
+ }
+ break;
+ }
+
+ case OPTION_GID:
+ rationalize++;
+ use_RockRidge++;
+ rationalize_gid++;
+ {
+ char *end = 0;
+
+ gid_to_use = strtol(optarg, &end, 0);
+ if (!end || *end != 0) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD, "Bad value for -gid\n");
+#else
+ fprintf(stderr, "Bad value for -gid\n");
+ exit(1);
+#endif
+ }
+ break;
+ }
+
+ case OPTION_FILEMODE:
+ rationalize++;
+ use_RockRidge++;
+ rationalize_filemode++;
+ {
+ char *end = 0;
+
+ filemode_to_use = strtol(optarg, &end, 8);
+ if (!end || *end != 0 ||
+ filemode_to_use < 0 || filemode_to_use > 07777) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD, "Bad mode for -file-mode\n");
+#else
+ fprintf(stderr, "Bad mode for -file-mode\n");
+ exit(1);
+#endif
+ }
+ break;
+ }
+
+ case OPTION_DIRMODE:
+ rationalize++;
+ use_RockRidge++;
+ rationalize_dirmode++;
+ {
+ char *end = 0;
+
+ dirmode_to_use = strtol(optarg, &end, 8);
+ if (!end || *end != 0 ||
+ dirmode_to_use < 0 || dirmode_to_use > 07777) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD, "Bad mode for -dir-mode\n");
+#else
+ fprintf(stderr, "Bad mode for -dir-mode\n");
+ exit(1);
+#endif
+ }
+ break;
+ }
+
+#ifdef SORTING
+ case OPTION_SORT:
+ do_sort++;
+ add_sort_list(optarg);
+ break;
+#endif /* SORTING */
+
+ case OPTION_SPLIT_OUTPUT:
+ split_output++;
+ break;
+
+ case OPTION_STREAM_FILE_NAME:
+ stream_filename = optarg;
+ break;
+
+ case OPTION_STREAM_CD_SIZE:
+ stream_media_size = atoi(optarg);
+ break;
+
+ case OPTION_SYSID:
+ system_id = optarg;
+ if (strlen(system_id) > 32) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "System ID string too long\n");
+#else
+ fprintf(stderr, "System ID string too long\n");
+ exit(1);
+#endif
+ }
+ break;
+ case OPTION_TRANS_TBL:
+ trans_tbl = optarg;
+ /* FALLTHRU */
+ case 'T':
+ generate_tables++;
+ break;
+ case OPTION_UCS_LEVEL:
+ ucs_level = atoi(optarg);
+ if (ucs_level < 1 || ucs_level > 3)
+ comerrno(EX_BAD, "Illegal UCS Level %d, use 1..3.\n",
+ ucs_level);
+ break;
+#ifdef UDF
+ case OPTION_UDF:
+ use_udf++;
+ break;
+#endif
+
+#ifdef DVD_VIDEO
+ case OPTION_DVD:
+ use_udf++;
+ dvd_video++;
+ break;
+#endif
+ case OPTION_USE_FILEVERSION:
+ use_fileversion++;
+ break;
+ case 'U':
+ /*
+ * Minimal (only truncation of 31+ characters)
+ * translation of filenames.
+ *
+ * Forces -l, -d, -N, -allow-leading-dots,
+ * -relaxed-filenames,
+ * -allow-lowercase, -allow-multidot
+ *
+ * This is for HP-UX, which does not recognize ANY
+ * extentions (Rock Ridge, Joliet), causing pain when
+ * loading software. pfs_mount can be used to read the
+ * extensions, but the untranslated filenames can be
+ * read by the "native" cdfs mounter. Completely
+ * violates iso9660.
+ */
+ full_iso9660_filenames++; /* 31 chars */
+ omit_period++; /* trailing dot */
+ allow_leading_dots++;
+ omit_version_number++;
+ relaxed_filenames++; /* all chars */
+ allow_lowercase++; /* even lowcase */
+ allow_multidot++; /* > 1 dots */
+ warn_violate++;
+ break;
+
+ case OPTION_RELAXED_FILENAMES:
+ relaxed_filenames++;
+ warn_violate++;
+ break;
+ case OPTION_ALLOW_LOWERCASE:
+ allow_lowercase++;
+ warn_violate++;
+ break;
+ case OPTION_ALLOW_MULTIDOT:
+ allow_multidot++;
+ warn_violate++;
+ break;
+ case OPTION_ISO_TRANSLATE:
+ iso_translate = 0;
+ warn_violate++;
+ break;
+ case 'V':
+ volume_id = optarg;
+ if (strlen(volume_id) > 32) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "Volume ID string too long\n");
+#else
+ fprintf(stderr,
+ "Volume ID string too long\n");
+ exit(1);
+#endif
+ }
+ break;
+ case OPTION_VOLSET:
+ volset_id = optarg;
+ if (strlen(volset_id) > 128) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "Volume set ID string too long\n");
+#else
+ fprintf(stderr,
+ "Volume set ID string too long\n");
+ exit(1);
+#endif
+ }
+ break;
+ case OPTION_VOLSET_SIZE:
+ volume_set_size = atoi(optarg);
+ if (volume_set_size <= 0) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "Illegal Volume Set Size %s\n", optarg);
+#else
+ fprintf(stderr,
+ "Illegal Volume Set Size %s\n", optarg);
+ exit(1);
+#endif
+ }
+ if (volume_set_size > 1) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "Volume Set Size > 1 not yet supported\n");
+#else
+ fprintf(stderr,
+ "Volume Set Size > 1 not yet supported\n");
+ exit(1);
+#endif
+ }
+ break;
+ case OPTION_VOLSET_SEQ_NUM:
+ volume_sequence_number = atoi(optarg);
+ if (volume_sequence_number > volume_set_size) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "Volume set sequence number too big\n");
+#else
+ fprintf(stderr,
+ "Volume set sequence number too big\n");
+ exit(1);
+#endif
+ }
+ break;
+ case 'v':
+ verbose++;
+ break;
+ case 'z':
+#ifdef VMS
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "Transparent compression not supported with VMS\n");
+#else
+ fprintf(stderr,
+ "Transparent compression not supported with VMS\n");
+ exit(1);
+#endif
+#else
+ transparent_compression++;
+#endif
+ break;
+ case 'x':
+ case 'm':
+ /*
+ * Somehow two options to do basically the same thing
+ * got added somewhere along the way. The 'match'
+ * code supports limited globbing, so this is the one
+ * that got selected. Unfortunately the 'x' switch is
+ * probably more intuitive.
+ */
+ add_match(optarg);
+ break;
+ case OPTION_X_LIST:
+ add_list(optarg);
+ break;
+ case OPTION_I_HIDE:
+ i_add_match(optarg);
+ break;
+ case OPTION_I_LIST:
+ i_add_list(optarg);
+ break;
+ case OPTION_H_HIDE:
+ h_add_match(optarg);
+ break;
+ case OPTION_H_LIST:
+ h_add_list(optarg);
+ break;
+ case OPTION_J_HIDE:
+ j_add_match(optarg);
+ break;
+ case OPTION_J_LIST:
+ j_add_list(optarg);
+ break;
+ case OPTION_HIDE_TRANS_TBL:
+ jhide_trans_tbl++;
+ break;
+ case OPTION_HIDE_RR_MOVED:
+ hide_rr_moved++;
+ break;
+ case OPTION_HELP:
+ usage(0);
+ break;
+ case OPTION_PVERSION:
+ if(mkisofs_call)
+ printf("mkisofs 2.01 is not what you see here. This line is only a fake for too clever\n"
+ "GUIs and other frontend applications. In fact, this program is:\n");
+ printf("%s (%s)\n", version_string, HOST_SYSTEM);
+ exit(0);
+ break;
+ case OPTION_NOSPLIT_SL_COMPONENT:
+ split_SL_component = 0;
+ break;
+ case OPTION_NOSPLIT_SL_FIELD:
+ split_SL_field = 0;
+ break;
+ case OPTION_HARD_DISK_BOOT:
+ use_eltorito++;
+ hard_disk_boot++;
+ get_boot_entry();
+ current_boot_entry->hard_disk_boot = 1;
+ break;
+ case OPTION_NO_EMUL_BOOT:
+ use_eltorito++;
+ no_emul_boot++;
+ get_boot_entry();
+ current_boot_entry->no_emul_boot = 1;
+ break;
+ case OPTION_NO_BOOT:
+ use_eltorito++;
+ not_bootable++;
+ get_boot_entry();
+ current_boot_entry->not_bootable = 1;
+ break;
+ case OPTION_BOOT_LOAD_ADDR:
+ use_eltorito++;
+ {
+ long val;
+ char *ptr;
+
+ val = strtol(optarg, &ptr, 0);
+ if (*ptr || val < 0 || val >= 0x10000) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD, "Boot image load address invalid.\n");
+#else
+ fprintf(stderr, "Boot image load address invalid.\n");
+ exit(1);
+#endif
+ }
+ load_addr = val;
+ }
+ get_boot_entry();
+ current_boot_entry->load_addr = load_addr;
+ break;
+ case OPTION_BOOT_LOAD_SIZE:
+ use_eltorito++;
+ {
+ long val;
+ char *ptr;
+
+ val = strtol(optarg, &ptr, 0);
+ if (*ptr || val < 0 || val >= 0x10000) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "Boot image load size invalid.\n");
+#else
+ fprintf(stderr,
+ "Boot image load size invalid.\n");
+ exit(1);
+#endif
+ }
+ load_size = val;
+ }
+ get_boot_entry();
+ current_boot_entry->load_size = load_size;
+ break;
+ case OPTION_BOOT_INFO_TABLE:
+ use_eltorito++;
+ boot_info_table++;
+ get_boot_entry();
+ current_boot_entry->boot_info_table = 1;
+ break;
+#ifdef APPLE_HYB
+ case OPTION_HFS_TYPE:
+ deftype = optarg;
+ hfs_ct++;
+ if (strlen(deftype) != 4) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "HFS default TYPE string has illegal length.\n");
+#else
+ fprintf(stderr,
+ "HFS default TYPE string has illegal length.\n");
+ exit(1);
+#endif
+ }
+ break;
+ case OPTION_HFS_CREATOR:
+ defcreator = optarg;
+ hfs_ct++;
+ if (strlen(defcreator) != 4) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "HFS default CREATOR string has illegal length.\n");
+#else
+ fprintf(stderr,
+ "HFS default CREATOR string has illegal length.\n");
+ exit(1);
+#endif
+ }
+ break;
+ case 'H':
+ /* FALLTHRU */
+ case OPTION_MAP_FILE:
+ afpfile = optarg;
+ hfs_last = MAP_LAST;
+ break;
+ case 'h':
+ apple_hyb = 1;
+ break;
+ case 'g':
+ apple_ext = 1;
+ break;
+ case OPTION_PROBE:
+ probe = 1;
+ break;
+ case OPTION_MACNAME:
+ use_mac_name = 1;
+ break;
+ case OPTION_NOMACFILES:
+#ifdef USE_LIBSCHILY
+ errmsgno(EX_BAD,
+ "Warning: -no-mac-files no longer used ... ignoring\n");
+#else
+ fprintf(stderr,
+ "Warning: -no-mac-files no longer used ... ignoring\n");
+#endif
+ break;
+ case OPTION_BOOT_HFS_FILE:
+ hfs_boot_file = optarg;
+ /* FALLTHRU */
+ case OPTION_GEN_PT:
+ gen_pt = 1;
+ break;
+ case OPTION_MAGIC_FILE:
+#ifndef USE_MAGIC
+ fprintf(stderr, "This program has been compiled without magic library support.\n"
+ "Ignoring the -magic option.\n");
+#endif
+ magic_filename = optarg;
+ hfs_last = MAG_LAST;
+ break;
+ case OPTION_AUTOSTART:
+ autoname = optarg;
+ /* gen_pt = 1; */
+ break;
+ case OPTION_BSIZE:
+ afe_size = atoi(optarg);
+ hfs_select |= DO_FEU;
+ hfs_select |= DO_FEL;
+ break;
+ case OPTION_HFS_VOLID:
+ hfs_volume_id = optarg;
+ break;
+ case OPTION_ROOT_INFO:
+ root_info = optarg;
+ /* FALLTHRU */
+ case OPTION_ICON_POS:
+ icon_pos = 1;
+ break;
+ /* Mac/Unix types to include */
+ case OPTION_CAP:
+ hfs_select |= DO_CAP;
+ break;
+ case OPTION_NETA:
+ hfs_select |= DO_NETA;
+ break;
+ case OPTION_DBL:
+ hfs_select |= DO_DBL;
+ break;
+ case OPTION_ESH:
+ case OPTION_USH:
+ hfs_select |= DO_ESH;
+ break;
+ case OPTION_FE:
+ hfs_select |= DO_FEU;
+ hfs_select |= DO_FEL;
+ break;
+ case OPTION_SGI:
+ case OPTION_XIN:
+ hfs_select |= DO_SGI;
+ break;
+ case OPTION_MBIN:
+ hfs_select |= DO_MBIN;
+ break;
+ case OPTION_SGL:
+ hfs_select |= DO_SGL;
+ break;
+ case OPTION_DAVE:
+ hfs_select |= DO_DAVE;
+ break;
+ case OPTION_SFM:
+ hfs_select |= DO_SFM;
+ break;
+ case OPTION_XDBL:
+ hfs_select |= DO_XDBL;
+ break;
+ case OPTION_XHFS:
+#ifdef IS_MACOS_X
+ hfs_select |= DO_XHFS;
+#else /* IS_MACOS_X */
+#ifdef USE_LIBSCHILY
+ errmsgno(EX_BAD,
+ "Warning: --osx-hfs only works on MacOS X ... ignoring\n");
+#else /* USE_LIBSCHILY */
+ fprintf(stderr,
+ "Warning: --osx-hfs only works on MacOS X ... ignoring\n");
+#endif /* USE_LIBSCHILY */
+#endif /* IS_MACOS_X */
+ break;
+ case OPTION_CREATE_DT:
+ create_dt = 0;
+ break;
+ case OPTION_HFS_HIDE:
+ hfs_add_match(optarg);
+ break;
+ case OPTION_HFS_LIST:
+ hfs_add_list(optarg);
+ break;
+ case OPTION_HFS_INPUT_CHARSET:
+ use_mac_name = 1;
+ hfs_icharset = optarg;
+ break;
+ case OPTION_HFS_OUTPUT_CHARSET:
+ hfs_ocharset = optarg;
+ break;
+ case OPTION_HFS_UNLOCK:
+ hfs_lock = 0;
+ break;
+ case OPTION_HFS_BLESS:
+ hfs_bless = optarg;
+ break;
+ case OPTION_HFS_PARMS:
+ hfs_parms = strdup(optarg);
+ break;
+#ifdef PREP_BOOT
+ case OPTION_PREP_BOOT:
+ use_prep_boot++;
+ if (use_prep_boot > 4 - use_chrp_boot) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "Maximum of 4 PRep+CHRP partition entries are allowed\n");
+#else
+ fprintf(stderr,
+ "Maximum of 4 PRep+CHRP partition entries are allowed\n");
+#endif
+ exit(1);
+ }
+ /* pathname of the boot image on cd */
+ prep_boot_image[use_prep_boot - 1] = optarg;
+ if (prep_boot_image[use_prep_boot - 1] == NULL) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "Required PReP boot image pathname missing\n");
+#else
+ fprintf(stderr,
+ "Required PReP boot image pathname missing\n");
+#endif
+ exit(1);
+ }
+ break;
+ case OPTION_CHRP_BOOT:
+ if (use_chrp_boot)
+ break; /* silently allow duplicates */
+ use_chrp_boot = 1;
+ if (use_prep_boot > 3) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "Maximum of 4 PRep+CHRP partition entries are allowed\n");
+#else
+ fprintf(stderr,
+ "Maximum of 4 PRep+CHRP partition entries are allowed\n");
+#endif
+ exit(1);
+ }
+ break;
+#endif /* PREP_BOOT */
+#endif /* APPLE_HYB */
+ case OPTION_ALLOW_LIMITED_SIZE:
+ allow_limited_size++;
+ use_udf++;
+ break;
+ default:
+ susage(1);
+ }
+ /*
+ * "--" was found, the next argument is a pathspec
+ */
+ if (argc != optind)
+ have_cmd_line_pathspec = 1;
+
+parse_input_files:
+ path_ind = optind;
+
+ /*
+ * XXX This is a hack until we have a decent separate name handling
+ * XXX for UDF filenames.
+ */
+ if (dvd_video && use_Joliet) {
+ use_Joliet = 0;
+ fprintf(stderr, "Warning: Disabling Joliet support for DVD-Video.\n");
+ }
+ if (use_udf && !use_Joliet)
+ jlen = 255;
+
+ if (preparer) {
+ if (strlen(preparer) > 128) {
+ comerrno(EX_BAD, "Preparer string too long\n");
+ }
+ }
+ if (publisher) {
+ if (strlen(publisher) > 128) {
+ comerrno(EX_BAD,
+ "Publisher string too long\n");
+ }
+ }
+ if (stream_filename) {
+ if (strlen(stream_filename) > MAX_ISONAME)
+ comerrno(EX_BAD,
+ "stream-file-name too long (%d), max is %d.\n",
+ (int)strlen(stream_filename), (int)MAX_ISONAME);
+ if (strchr(stream_filename, '/'))
+ comerrno(EX_BAD, "Illegal character '/' in stream-file-name.\n");
+ iso9660_level = 4;
+ } else {
+ stream_filename = "STREAM.IMG;1";
+ }
+ if (system_id) {
+ if (strlen(system_id) > 32) {
+ comerrno(EX_BAD,
+ "System ID string too long\n");
+ }
+ }
+
+
+ if (use_RockRidge && (iso9660_namelen > MAX_ISONAME_V2_RR))
+ iso9660_namelen = MAX_ISONAME_V2_RR;
+
+ if (warn_violate) /* this one is enough for quiet mode, print others warnings only in more verbose modes */
+ fprintf(stderr, "Warning: creating filesystem that does not conform to ISO-9660.\n");
+ if (iso9660_level > 3 && verbose>0)
+ fprintf(stderr, "Warning: Creating ISO-9660:1999 (version 2) filesystem.\n");
+ if (iso9660_namelen > LEN_ISONAME && verbose>0)
+ fprintf(stderr, "Warning: ISO-9660 filenames longer than %d may cause buffer overflows in the OS.\n",
+ LEN_ISONAME);
+ if (use_Joliet && !use_RockRidge && verbose>0) {
+ fprintf(stderr,
+ "Warning: creating filesystem with Joliet extensions but without Rock Ridge\n"
+ " extensions. It is highly recommended to add Rock Ridge.\n");
+ }
+ if (transparent_compression && verbose>0) {
+ fprintf(stderr, "Warning: using transparent compression. This is a nonstandard Rock Ridge\n");
+ fprintf(stderr, " extension. The resulting filesystem can only be transparently\n");
+ fprintf(stderr, " read on Linux. On other operating systems you need to call\n");
+ fprintf(stderr, " mkzftree by hand to decompress the files.\n");
+ }
+ if (transparent_compression && !use_RockRidge && verbose>0) {
+ fprintf(stderr, "Warning: transparent decompression is a Linux Rock Ridge extension, but\n");
+ fprintf(stderr, " creating filesystem without Rock Ridge attributes; files\n");
+ fprintf(stderr, " will not be transparently decompressed.\n");
+ }
+ if(follow_links && verbose>0)
+ fprintf(stderr,
+ "Warning: -follow-links does not always work correctly; be careful.\n");
+
+ init_unls(); /* Initialize UNICODE tables */
+
+ /* initialize code tables from a file - if they exists */
+ init_unls_file(icharset);
+ init_unls_file(ocharset);
+#ifdef APPLE_HYB
+ init_unls_file(hfs_icharset);
+ init_unls_file(hfs_ocharset);
+#endif /* APPLE_HYB */
+
+#ifdef USE_ICONV
+ iconv_possible = !(iso9660_level >= 4 || ((ocharset &&
+ strcmp(ocharset, icharset ? icharset : "")) &&
+ use_RockRidge) || apple_ext || apple_hyb);
+
+ setlocale(LC_CTYPE, "");
+
+ if (icharset == NULL && iconv_possible) {
+ char *charset = nl_langinfo(CODESET);
+ /* set to detected value but only if it is not pure US-ASCII */
+ if(charset) { /* workaround for SunOS, iconv is case-sensitive */
+ char *t;
+ charset = strdup(charset);
+ for(t=charset;*t!='\0';t++)
+ *t=tolower(*t);
+ }
+
+ if(strcmp(charset, "ansi_x3.4-1968") != 0)
+ icharset = charset;
+
+ if(icharset && verbose > 0)
+ fprintf(stderr, "I: -input-charset not specified, using %s (detected in locale settings)\n",
+ icharset);
+ }
+
+ if(iconv_possible) {
+ /*
+ * don't care if initialization fails
+ */
+ init_nls_iconv(icharset);
+ init_nls_iconv(ocharset);
+ }
+#endif
+
+ if (icharset == NULL) {
+#if (defined(__CYGWIN32__) || defined(__CYGWIN__) || defined(__DJGPP__)) && !defined(IS_CYGWIN_1)
+ in_nls = load_unls("cp437");
+#else
+ in_nls = load_unls("iso8859-1");
+#endif
+ } else {
+ if (strcmp(icharset, "default") == 0)
+ in_nls = load_unls_default();
+ else
+ in_nls = load_unls(icharset);
+ }
+ /*
+ * set the output charset to the same as the input or the given output
+ * charset
+ */
+ if (ocharset == NULL) {
+ out_nls = in_nls;
+ } else {
+ if (strcmp(ocharset, "default") == 0)
+ out_nls = load_unls_default();
+ else
+ out_nls = load_unls(ocharset);
+ }
+ if (in_nls == NULL || out_nls == NULL) { /* Unknown charset specified */
+ fprintf(stderr, "Unknown charset\nKnown charsets are:\n");
+ list_unls(); /* List all known charset names */
+#ifdef USE_ICONV
+ fprintf(stderr, "\nAdditional input charsets are available for Joliet through the iconv support."
+ "\nRun \"iconv -l\" to display them. Iconv charsets cannot be used with HFS, Apple"
+ "\nextension, ISO9660 version 2 or Rock Ridge.\n");
+#endif
+ exit(1);
+ }
+
+
+#ifdef APPLE_HYB
+ if (hfs_icharset == NULL || strcmp(hfs_icharset, "mac-roman")) {
+ hfs_inls = load_unls("cp10000");
+ } else {
+ if (strcmp(hfs_icharset, "default") == 0)
+ hfs_inls = load_unls_default();
+ else
+ hfs_inls = load_unls(hfs_icharset);
+ }
+ if (hfs_ocharset == NULL) {
+ hfs_onls = hfs_inls;
+ } else {
+ if (strcmp(hfs_ocharset, "default") == 0)
+ hfs_onls = load_unls_default();
+ else if (strcmp(hfs_ocharset, "mac-roman") == 0)
+ hfs_onls = load_unls("cp10000");
+ else
+ hfs_onls = load_unls(hfs_ocharset);
+ }
+
+ if (hfs_inls == NULL || hfs_onls == NULL) {
+ fprintf(stderr, "Unknown HFS charset\nKnown charsets are:\n");
+ list_unls();
+ exit(1);
+ }
+#endif /* APPLE_HYB */
+
+ if (merge_image != NULL) {
+ if (open_merge_image(merge_image) < 0) {
+ /* Complain and die. */
+#ifdef USE_LIBSCHILY
+ comerr("Unable to open previous session image '%s'.\n",
+ merge_image);
+#else
+ fprintf(stderr,
+ "Unable to open previous session image '%s'.\n",
+ merge_image);
+ exit(1);
+#endif
+ }
+ }
+ /* We don't need root privilleges anymore. */
+#ifdef HAVE_SETREUID
+ if (setreuid(-1, getuid()) < 0)
+#else
+#ifdef HAVE_SETEUID
+ if (seteuid(getuid()) < 0)
+#else
+ if (setuid(getuid()) < 0)
+#endif
+#endif
+#ifdef USE_LIBSCHILY
+ comerr("Panic cannot set back effective uid.\n");
+#else
+ {
+ perror("Panic cannot set back effective uid.");
+ exit(1);
+ }
+#endif
+
+
+#ifdef no_more_needed
+#ifdef __NetBSD__
+ {
+ int resource;
+ struct rlimit rlp;
+
+ if (getrlimit(RLIMIT_DATA, &rlp) == -1)
+ perror("Warning: getrlimit failed");
+ else {
+ rlp.rlim_cur = 33554432;
+ if (setrlimit(RLIMIT_DATA, &rlp) == -1)
+ perror("Warning: setrlimit failed");
+ }
+ }
+#endif
+#endif /* no_more_needed */
+#ifdef HAVE_SBRK
+ mem_start = (unsigned long) sbrk(0);
+#endif
+
+ /*
+ * if the -hide-joliet option has been given, set the Joliet option
+ */
+ if (!use_Joliet && j_ishidden())
+ use_Joliet++;
+
+#ifdef APPLE_HYB
+ if (apple_hyb && apple_ext) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD, "Can't have both -apple and -hfs options");
+#else
+ fprintf(stderr, "Can't have both -apple and -hfs options");
+ exit(1);
+#endif
+ }
+ /*
+ * if -probe, -macname, any hfs selection and/or mapping file is given,
+ * but no HFS option, then select apple_hyb
+ */
+ if (!apple_hyb && !apple_ext) {
+ if (*afpfile || probe || use_mac_name || hfs_select ||
+ hfs_boot_file || magic_filename ||
+ hfs_ishidden() || gen_pt || autoname ||
+ afe_size || icon_pos || hfs_ct ||
+ hfs_icharset || hfs_ocharset) {
+ apple_hyb = 1;
+ }
+ }
+ if (apple_ext && hfs_boot_file) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD, "Can't have -hfs-boot-file with -apple\n");
+#else
+ fprintf(stderr, "Can't have -hfs-boot-file with -apple\n");
+ exit(1);
+#endif
+ }
+ if (apple_ext && autoname) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD, "Can't have -auto with -apple\n");
+#else
+ fprintf(stderr, "Can't have -auto with -apple\n");
+ exit(1);
+#endif
+ }
+ if (apple_hyb && (use_sparcboot || use_sunx86boot)) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD, "Can't have -hfs with -sparc-boot/-sunx86-boot\n");
+#else
+ fprintf(stderr, "Can't have -hfs with -sparc-boot/-sunx86-boot\n");
+ exit(1);
+#endif
+ }
+ if (apple_hyb && use_genboot) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD, "Can't have -hfs with -generic-boot\n");
+#else
+ fprintf(stderr, "Can't have -hfs with -generic-boot\n");
+ exit(1);
+#endif
+ }
+#ifdef PREP_BOOT
+ if (apple_ext && use_prep_boot) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD, "Can't have -prep-boot with -apple\n");
+#else
+ fprintf(stderr, "Can't have -prep-boot with -apple\n");
+ exit(1);
+#endif
+ }
+#endif /* PREP_BOOT */
+
+ if (apple_hyb || apple_ext)
+ apple_both = 1;
+
+ if (probe)
+ /* we need to search for all types of Apple/Unix files */
+ hfs_select = ~0;
+
+ if (apple_both && verbose && !(hfs_select || *afpfile || magic_filename)) {
+#ifdef USE_LIBSCHILY
+ errmsgno(EX_BAD,
+ "Warning: no Apple/Unix files will be decoded/mapped\n");
+#else
+ fprintf(stderr,
+ "Warning: no Apple/Unix files will be decoded/mapped\n");
+#endif
+ }
+ if (apple_both && verbose && !afe_size &&
+ (hfs_select & (DO_FEU | DO_FEL))) {
+#ifdef USE_LIBSCHILY
+ errmsgno(EX_BAD,
+ "Warning: assuming PC Exchange cluster size of 512 bytes\n");
+#else
+ fprintf(stderr,
+ "Warning: assuming PC Exchange cluster size of 512 bytes\n");
+#endif
+ afe_size = 512;
+ }
+ if (apple_both) {
+ /* set up the TYPE/CREATOR mappings */
+ hfs_init(afpfile, 0, hfs_select);
+ }
+ if (apple_ext && !use_RockRidge) {
+#ifdef nonono
+ /* use RockRidge to set the SystemUse field ... */
+ use_RockRidge++;
+ rationalize_all++;
+#else
+ /* EMPTY */
+#endif
+ }
+ if (apple_ext && !(use_XA || use_RockRidge)) {
+ comerrno(EX_BAD, "Need either -XA/-xa or -R/-r for -apple to become active.\n");
+ }
+
+#endif /* APPLE_HYB */
+
+ if (rationalize_all) {
+ rationalize++;
+ rationalize_uid++;
+ rationalize_gid++;
+ rationalize_filemode++;
+ rationalize_dirmode++;
+ }
+
+ if (verbose > 1) {
+ fprintf(stderr, "%s (%s)\n", version_string, HOST_SYSTEM);
+ }
+ if (cdrecord_data == NULL && !check_session && merge_image != NULL) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD,
+ "Multisession usage bug: Must specify -C if -M is used.\n");
+#else
+ fprintf(stderr,
+ "Multisession usage bug: Must specify -C if -M is used.\n");
+ exit(1);
+#endif
+ }
+ if (cdrecord_data != NULL && merge_image == NULL) {
+#ifdef USE_LIBSCHILY
+ errmsgno(EX_BAD,
+ "Warning: -C specified without -M: old session data will not be merged.\n");
+#else
+ fprintf(stderr,
+ "Warning: -C specified without -M: old session data will not be merged.\n");
+#endif
+ }
+#ifdef APPLE_HYB
+ if (merge_image != NULL && apple_hyb) {
+#ifdef USE_LIBSCHILY
+ errmsgno(EX_BAD,
+ "Warning: files from previous sessions will not be included in the HFS volume.\n");
+#else
+ fprintf(stderr,
+ "Warning: files from previous sessions will not be included in the HFS volume.\n");
+#endif
+ }
+#endif /* APPLE_HYB */
+
+ /*
+ * see if we have a list of pathnames to process
+ */
+ if (pathnames) {
+ /* "-" means take list from the standard input */
+ if (strcmp(pathnames, "-")) {
+ if ((pfp = fopen(pathnames, "r")) == NULL) {
+#ifdef USE_LIBSCHILY
+ comerr("Unable to open pathname list %s.\n",
+ pathnames);
+#else
+ fprintf(stderr,
+ "Unable to open pathname list %s.\n",
+ pathnames);
+ exit(1);
+#endif
+ }
+ } else
+ pfp = stdin;
+ }
+
+ /* The first step is to scan the directory tree, and take some notes */
+
+ if ((arg = get_pnames(argc, argv, optind, pname,
+ sizeof (pname), pfp)) == NULL) {
+ if (check_session == 0 && !stream_media_size) {
+#ifdef USE_LIBSCHILY
+ errmsgno(EX_BAD, "Missing pathspec.\n");
+#endif
+ susage(1);
+ }
+ }
+
+ /*
+ * if we don't have a pathspec, then save the pathspec found
+ * in the pathnames file (stored in pname) - we don't want
+ * to skip this pathspec when we read the pathnames file again
+ */
+ if (!have_cmd_line_pathspec && !stream_media_size) {
+ save_pname = 1;
+ }
+ if (stream_media_size) {
+ if (use_XA || use_RockRidge || use_udf || use_Joliet)
+ comerrno(EX_BAD,
+ "Cannot use XA, Rock Ridge, UDF or Joliet with -stream-media-size\n");
+ if (merge_image)
+ comerrno(EX_BAD,
+ "Cannot use multi session with -stream-media-size\n");
+ if (use_eltorito || use_sparcboot || use_sunx86boot ||
+ use_genboot || use_prep_boot || hfs_boot_file)
+ comerrno(EX_BAD,
+ "Cannot use boot options with -stream-media-size\n");
+ if (apple_hyb)
+ comerrno(EX_BAD,
+ "Cannot use Apple hybrid options with -stream-media-size\n");
+ }
+
+ if (use_RockRidge) {
+ /* BEGIN CSTYLED */
+#if 1
+ extension_record = generate_rr_extension_record("RRIP_1991A",
+ "THE ROCK RIDGE INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS",
+ "PLEASE CONTACT DISC PUBLISHER FOR SPECIFICATION SOURCE. SEE PUBLISHER IDENTIFIER IN PRIMARY VOLUME DESCRIPTOR FOR CONTACT INFORMATION.",
+ &extension_record_size);
+#else
+ extension_record = generate_rr_extension_record("IEEE_P1282",
+ "THE IEEE P1282 PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS",
+ "PLEASE CONTACT THE IEEE STANDARDS DEPARTMENT, PISCATAWAY, NJ, USA FOR THE P1282 SPECIFICATION.",
+ &extension_record_size);
+#endif
+ /* END CSTYLED */
+ }
+ if (log_file) {
+ FILE *lfp;
+ int i;
+
+ /* open log file - test that we can open OK */
+ if ((lfp = fopen(log_file, "w")) == NULL) {
+#ifdef USE_LIBSCHILY
+ comerr("Can't open logfile: '%s'.\n", log_file);
+#else
+ fprintf(stderr, "Can't open logfile: '%s'.\n", log_file);
+ exit(1);
+#endif
+ }
+ fclose(lfp);
+
+ /* redirect all stderr message to log_file */
+ fprintf(stderr, "re-directing all messages to %s\n", log_file);
+ fflush(stderr);
+
+ /* associate stderr with the log file */
+ if (freopen(log_file, "w", stderr) == NULL) {
+#ifdef USE_LIBSCHILY
+ comerr("Can't open logfile: '%s'.\n", log_file);
+#else
+ fprintf(stderr, "Can't open logfile: '%s'.\n", log_file);
+ exit(1);
+#endif
+ }
+ if (verbose > 1) {
+ for (i = 0; i < argc; i++)
+ fprintf(stderr, "%s ", argv[i]);
+
+ fprintf(stderr, "\n%s (%s)\n",
+ version_string, HOST_SYSTEM);
+ }
+ }
+ /* Find name of root directory. */
+ if (arg != NULL)
+ node = findgequal(arg);
+ if (!use_graft_ptrs)
+ node = NULL;
+ if (node == NULL) {
+ if (use_graft_ptrs && arg != NULL)
+ node = escstrcpy(nodename, arg);
+ else
+ node = arg;
+ } else {
+ /*
+ * Remove '\\' escape chars which are located
+ * before '\\' and '=' chars
+ */
+ node = escstrcpy(nodename, ++node);
+ }
+
+ /*
+ * See if boot catalog file exists in root directory, if not we will
+ * create it.
+ */
+ if (use_eltorito)
+ init_boot_catalog(node);
+
+ /*
+ * Find the device and inode number of the root directory. Record this
+ * in the hash table so we don't scan it more than once.
+ */
+ stat_filter(node, &statbuf);
+ add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf));
+
+ memset(&de, 0, sizeof (de));
+
+ /*
+ * PO:
+ * Isn't root NULL at this time anyway?
+ * I think it is created by the first call to
+ * find_or_create_directory() below.
+ */
+ de.filedir = root; /* We need this to bootstrap */
+
+ if (cdrecord_data != NULL && merge_image == NULL) {
+ /*
+ * in case we want to add a new session, but don't want to
+ * merge old one
+ */
+ get_session_start(NULL);
+ }
+ if (merge_image != NULL) {
+ char sector[SECTOR_SIZE];
+
+ errno = 0;
+ mrootp = merge_isofs(merge_image);
+ if (mrootp == NULL) {
+ /* Complain and die. */
+#ifdef USE_LIBSCHILY
+ if (errno == 0)
+ errno = -1;
+ comerr("Unable to find previous session PVD '%s'.\n",
+ merge_image);
+#else
+ fprintf(stderr,
+ "Unable to find previous session PVD '%s'.\n",
+ merge_image);
+ exit(1);
+#endif
+ }
+ memcpy(de.isorec.extent, mrootp->extent, 8);
+
+ /*
+ * Look for RR Attributes in '.' entry of root dir.
+ * This is the first ISO directory entry in the root dir.
+ */
+ c = isonum_733((unsigned char *)mrootp->extent);
+#ifdef USE_SCG
+ readsecs(c, sector, 1);
+#else
+ lseek(fileno(in_image), c*2048, SEEK_SET);
+ read(fileno(in_image), sector, sizeof (sector));
+#endif
+ c = rr_flags((struct iso_directory_record *)sector);
+ if (c & RR_FLAG_XA)
+ fprintf(stderr, "XA signatures found\n");
+ if (c & RR_FLAG_AA)
+ fprintf(stderr, "AA signatures found\n");
+ if (c & ~(RR_FLAG_XA|RR_FLAG_AA)) {
+ if (c & RR_FLAG_SP) {
+ fprintf(stderr, "Rock Ridge signatures found\n");
+ } else {
+ fprintf(stderr, "Bad Rock Ridge signatures found (SU record missing)\n");
+ if (!force_rr)
+ no_rr++;
+ }
+ } else {
+ fprintf(stderr, "NO Rock Ridge present\n");
+ if ((c & (RR_FLAG_XA|RR_FLAG_AA)) == 0) {
+ if (!force_rr)
+ no_rr++;
+ }
+ }
+ if (no_rr)
+ fprintf(stderr, "Disabling Rock Ridge / XA / AA\n");
+ }
+ /*
+ * Create an empty root directory. If we ever scan it for real,
+ * we will fill in the contents.
+ */
+ find_or_create_directory(NULL, "", &de, TRUE, NULL);
+
+#ifdef APPLE_HYB
+ /* may need to set window layout of the volume */
+ if (root_info)
+ set_root_info(root_info);
+#endif /* APPLE_HYB */
+
+ if(optind < argc-1)
+ merge_warn_msg="NOTE: multiple source directories have been specified and merged into the root\n"
+ "of the filesystem. Check your program arguments. genisoimage is not tar.\n";
+
+ /*
+ * Scan the actual directory (and any we find below it) for files to
+ * write out to the output image. Note - we take multiple source
+ * directories and keep merging them onto the image.
+ */
+if (check_session == 0)
+ while ((arg = get_pnames(argc, argv, optind, pname,
+ sizeof (pname), pfp)) != NULL) {
+ struct directory *graft_dir;
+ struct stat st;
+ char *short_name;
+ int status;
+ char graft_point[PATH_MAX + 1];
+
+ /*
+ * We would like a syntax like:
+ *
+ * /tmp=/usr/tmp/xxx
+ *
+ * where the user can specify a place to graft each component
+ * of the tree. To do this, we may have to create directories
+ * along the way, of course. Secondly, I would like to allow
+ * the user to do something like:
+ *
+ * /home/baz/RMAIL=/u3/users/baz/RMAIL
+ *
+ * so that normal files could also be injected into the tree
+ * at an arbitrary point.
+ *
+ * The idea is that the last component of whatever is being
+ * entered would take the name from the last component of
+ * whatever the user specifies.
+ *
+ * The default will be that the file is injected at the root of
+ * the image tree.
+ */
+ node = findgequal(arg);
+ if (!use_graft_ptrs)
+ node = NULL;
+ /*
+ * Remove '\\' escape chars which are located
+ * before '\\' and '=' chars ---> below in escstrcpy()
+ */
+
+ short_name = NULL;
+
+ if (node != NULL || reloc_root) {
+ char *pnt;
+ char *xpnt;
+ size_t len;
+ int node_is_dir;
+
+ /* insert -root prefix */
+ if (reloc_root != NULL) {
+ strcpy(graft_point, reloc_root);
+ len = strlen(graft_point);
+ if (graft_point[len] != '/') {
+ graft_point[len++] = '/';
+ graft_point[len] = '\0';
+ }
+ } else {
+ len = 0;
+ }
+
+ if (node) {
+ *node = '\0';
+ escstrcpy(&graft_point[len], arg);
+ *node = '=';
+ }
+
+ /*
+ * Remove unwanted "./" & "/" sequences from start...
+ */
+ do {
+ xpnt = graft_point;
+ while (xpnt[0] == '.' && xpnt[1] == '/')
+ xpnt += 2;
+ while (*xpnt == PATH_SEPARATOR) {
+ xpnt++;
+ }
+ memmove(graft_point, xpnt, strlen(xpnt)+1);
+ } while (xpnt > graft_point);
+
+ if (node) {
+ node = escstrcpy(nodename, ++node);
+ } else {
+ node = arg;
+ }
+
+ graft_dir = root;
+ xpnt = graft_point;
+
+ /*
+ * If "node" points to a directory, then graft_point
+ * needs to point to a directory too.
+ */
+ if (follow_links)
+ status = stat_filter(node, &st);
+ else
+ status = lstat_filter(node, &st);
+
+ node_is_dir = S_ISDIR(st.st_mode);
+ if (status == 0 && node_is_dir) {
+ len = strlen(graft_point);
+
+ if ((len <= (sizeof (graft_point) -1)) &&
+ graft_point[len-1] != '/') {
+ graft_point[len++] = '/';
+ graft_point[len] = '\0';
+ }
+ }
+ if (debug)
+ fprintf(stderr, "GRAFT:'%s'\n", xpnt);
+ /*
+ * Loop down deeper and deeper until we find the
+ * correct insertion spot.
+ * Canonicalize the filename while parsing it.
+ */
+ for (;;) {
+ struct stat* stat_template;
+
+ do {
+ while (xpnt[0] == '.' && xpnt[1] == '/')
+ xpnt += 2;
+ while (xpnt[0] == '/')
+ xpnt += 1;
+ if (xpnt[0] == '.' && xpnt[1] == '.' && xpnt[2] == '/') {
+ if (graft_dir && graft_dir != root) {
+ graft_dir = graft_dir->parent;
+ xpnt += 2;
+ }
+ }
+ } while ((xpnt[0] == '/') || (xpnt[0] == '.' && xpnt[1] == '/'));
+ pnt = strchr(xpnt, PATH_SEPARATOR);
+ if (pnt == NULL) {
+ if (*xpnt != '\0') {
+ short_name = xpnt;
+ }
+ break;
+ }
+ *pnt = '\0';
+ if (debug) {
+ fprintf(stderr, "GRAFT Point:'%s' in '%s : %s' (%s)\n",
+ xpnt,
+ graft_dir->whole_name,
+ graft_dir->de_name,
+ graft_point);
+ }
+ /*
+ * If the node being grafted is a
+ * directory, then we want the last
+ * directory in this graft chain to have
+ * the ownership and permissions of the
+ * source node. Other directories in the
+ * chain get default ownership and
+ * permissions.
+ */
+ stat_template =
+ (pnt[1] == '\0' && node_is_dir) ? &st : 0;
+
+ graft_dir = find_or_create_directory(graft_dir,
+ graft_point, NULL, TRUE,
+ stat_template);
+
+ *pnt = PATH_SEPARATOR;
+ xpnt = pnt + 1;
+ }
+ } else {
+ graft_dir = root;
+ if (use_graft_ptrs)
+ node = escstrcpy(nodename, arg);
+ else
+ node = arg;
+ }
+
+ /*
+ * Get information on the node
+ */
+ if (follow_links)
+ status = stat_filter(node, &st);
+ else
+ status = lstat_filter(node, &st);
+ if (status != 0) {
+ /*
+ * This is a fatal error - the user won't be getting
+ * what they want if we were to proceed.
+ */
+#ifdef USE_LIBSCHILY
+ comerr("Invalid node - '%s'.\n", node);
+#else
+ fprintf(stderr, "Invalid node - '%s'.\n", node);
+ exit(1);
+#endif
+ } else {
+ /*
+ * Now see whether the user wants to add a regular
+ * file or a directory at this point.
+ */
+ if (S_ISDIR(st.st_mode)) {
+ if (debug) {
+ fprintf(stderr, "graft_dir: '%s : %s', node: '%s', (scan)\n",
+ graft_dir->whole_name,
+ graft_dir->de_name, node);
+ }
+ if (!scan_directory_tree(graft_dir,
+ node, &de)) {
+ exit(1);
+ }
+ if (debug) {
+ fprintf(stderr, "scan done\n");
+ }
+ } else {
+ if (short_name == NULL) {
+ short_name = strrchr(node,
+ PATH_SEPARATOR);
+ if (short_name == NULL ||
+ short_name < node) {
+ short_name = node;
+ } else {
+ short_name++;
+ }
+ }
+ if (debug) {
+ fprintf(stderr, "graft_dir: '%s : %s', node: '%s', short_name: '%s'\n",
+ graft_dir->whole_name,
+ graft_dir->de_name, node,
+ short_name);
+ }
+#ifdef APPLE_HYB
+ if (!insert_file_entry(graft_dir, node,
+ short_name, 0))
+#else
+ if (!insert_file_entry(graft_dir, node,
+ short_name))
+#endif /* APPLE_HYB */
+ {
+ /*
+ * Should we ignore this?
+ */
+/* exit(1);*/
+ /* EMPTY */
+ }
+ }
+ }
+
+ optind++;
+ no_path_names = 0;
+ }
+
+ if (pfp && pfp != stdin)
+ fclose(pfp);
+
+ /*
+ * exit if we don't have any pathnames to process
+ * - not going to happen at the moment as we have to have at least one
+ * path on the command line
+ */
+ if (no_path_names && !check_session && !stream_media_size) {
+#ifdef USE_LIBSCHILY
+ errmsgno(EX_BAD, "No pathnames found.\n");
+#endif
+ susage(1);
+ }
+ /*
+ * Now merge in any previous sessions. This is driven on the source
+ * side, since we may need to create some additional directories.
+ */
+ if (merge_image != NULL) {
+ if (merge_previous_session(root, mrootp,
+ reloc_root, reloc_old_root) < 0) {
+#ifdef USE_LIBSCHILY
+ comerrno(EX_BAD, "Cannot merge previous session.\n");
+#else
+ fprintf(stderr, "Cannot merge previous session.\n");
+ exit(1);
+#endif
+ }
+ close_merge_image();
+
+ /*
+ * set up parent_dir and filedir in relocated entries which
+ * were read from previous session so that
+ * finish_cl_pl_entries can do its job
+ */
+ match_cl_re_entries();
+ }
+#ifdef APPLE_HYB
+ /* free up any HFS filename mapping memory */
+ if (apple_both)
+ clean_hfs();
+#endif /* APPLE_HYB */
+
+ /* hide "./rr_moved" if all its contents have been hidden */
+ if (reloc_dir && i_ishidden())
+ hide_reloc_dir();
+
+ /* insert the boot catalog if required */
+ if (use_eltorito)
+ insert_boot_cat();
+
+ /*
+ * Free up any matching memory
+ */
+ for (n = 0; n < MAX_MAT; n++)
+ gen_del_match(n);
+
+#ifdef SORTING
+ del_sort();
+#endif /* SORTING */
+
+ /*
+ * Sort the directories in the required order (by ISO9660). Also,
+ * choose the names for the 8.3 filesystem if required, and do any
+ * other post-scan work.
+ */
+ goof += sort_tree(root);
+
+ if (goof) {
+ fprintf(stderr, "ISO9660/Rock Ridge tree sort failed.\n");
+ if(merge_warn_msg)
+ fprintf(stderr, merge_warn_msg);
+ exit(1);
+ }
+#ifdef UDF
+ if (use_Joliet || use_udf) {
+#else
+ if (use_Joliet) {
+#endif
+ goof += joliet_sort_tree(root);
+ }
+ if (goof) {
+ fprintf(stderr, "Joliet tree sort failed. The -joliet-long switch may help you.\n");
+ if(merge_warn_msg)
+ fprintf(stderr, merge_warn_msg);
+ exit(1);
+ }
+ /*
+ * Fix a couple of things in the root directory so that everything is
+ * self consistent. Fix this up so that the path tables get done right.
+ */
+ root->self = root->contents;
+
+ /* OK, ready to write the file. Open it up, and generate the thing. */
+ if (print_size) {
+ discimage = fopen("/dev/null", "wb");
+ if (!discimage) {
+#ifdef USE_LIBSCHILY
+ comerr("Unable to open /dev/null\n");
+#else
+ fprintf(stderr, "Unable to open /dev/null\n");
+ exit(1);
+#endif
+ }
+ } else if (outfile && (strcmp (outfile, "-")) != 0) {
+ discimage = fopen(outfile, "wb");
+ if (!discimage) {
+#ifdef USE_LIBSCHILY
+ comerr("Unable to open disc image file '%s'.\n", outfile);
+#else
+ fprintf(stderr, "Unable to open disc image file '%s'.\n", outfile);
+ exit(1);
+#endif
+ }
+ if (jtemplate_out || jjigdo_out) {
+ if (!jtemplate_out || !jjigdo_out || !jmd5_list) {
+#ifdef USE_LIBSCHILY
+ comerr("Bad options - need to specify output names for jigdo and template file, and also the md5-list input file!\n");
+#else
+ fprintf(stderr, "Bad options - need to specify output names for jigdo and template file, and also the md5-list input file!\n");
+ exit(1);
+#endif
+ }
+ jtjigdo = fopen(jjigdo_out, "wb");
+ jttemplate = fopen(jtemplate_out, "wb");
+ if (!jtjigdo || !jttemplate) {
+#ifdef USE_LIBSCHILY
+ comerr("Unable to open jigdo template image file\n");
+#else
+ fprintf(stderr, "Unable to open jigdo template image file\n");
+ exit(1);
+#endif
+ }
+ write_jt_header(jttemplate, jtjigdo);
+ }
+ } else if ((outfile == NULL)
+ && isatty (fileno (stdout))) {
+ /* FIXME: a cleaner way to override this check? */
+ fputs (("image not written to a terminal.\n"
+ "Use -o - to force the output.\n"),
+ stderr);
+ exit (1);
+ } else {
+ discimage = stdout;
+
+#ifdef NEED_O_BINARY
+ setmode(fileno(stdout), O_BINARY);
+#endif
+ }
+
+ /* Now assign addresses on the disc for the path table. */
+
+ path_blocks = ISO_BLOCKS(path_table_size);
+ if (path_blocks & 1)
+ path_blocks++;
+
+ jpath_blocks = ISO_BLOCKS(jpath_table_size);
+ if (jpath_blocks & 1)
+ jpath_blocks++;
+
+ /*
+ * Start to set up the linked list that we use to track the contents
+ * of the disc.
+ */
+#ifdef APPLE_HYB
+#ifdef PREP_BOOT
+ if (apple_hyb || use_prep_boot || use_chrp_boot)
+#else /* PREP_BOOT */
+ if (apple_hyb)
+#endif /* PREP_BOOT */
+ outputlist_insert(&hfs_desc);
+#endif /* APPLE_HYB */
+ if (use_sparcboot || use_sunx86boot)
+ outputlist_insert(&sunlabel_desc);
+ if (use_alphaboot)
+ outputlist_insert(&alphaboot_desc);
+ if (use_hppaboot)
+ outputlist_insert(&hppaboot_desc);
+ if (use_alphaboot || use_hppaboot)
+ outputlist_insert(&alpha_hppa_boot_desc);
+ if (use_mipsboot)
+ outputlist_insert(&mipsboot_desc);
+ if (use_mipselboot)
+ outputlist_insert(&mipselboot_desc);
+ if (use_genboot)
+ outputlist_insert(&genboot_desc);
+ outputlist_insert(&startpad_desc);
+
+ /* PVD for disc. */
+ outputlist_insert(&voldesc_desc);
+
+ /* SVD for El Torito. MUST be immediately after the PVD! */
+ if (use_eltorito) {
+ outputlist_insert(&torito_desc);
+ }
+ /* Enhanced PVD for disc. neded if we write ISO-9660:1999 */
+ if (iso9660_level > 3)
+ outputlist_insert(&xvoldesc_desc);
+
+ /* SVD for Joliet. */
+ if (use_Joliet) {
+ outputlist_insert(&joliet_desc);
+ }
+ /* Finally the last volume descriptor. */
+ outputlist_insert(&end_vol);
+
+#ifdef UDF
+ if (use_udf) {
+ outputlist_insert(&udf_vol_recognition_area_frag);
+ }
+#endif
+
+ /* Insert the version descriptor. */
+ outputlist_insert(&version_desc);
+
+#ifdef UDF
+ if (use_udf) {
+ /*
+ * Most of the space before sector 256 is wasted when
+ * UDF is turned on. The waste could be reduced by
+ * putting the ISO9660/Joliet structures before the
+ * pad_to_sector_256; the problem is that they might
+ * overshoot sector 256, so there would have to be some
+ * ugly logic to detect this case and rearrange things
+ * appropriately. I don't know if it's worth it.
+ */
+ outputlist_insert(&udf_pad_to_sector_32_frag);
+ outputlist_insert(&udf_main_seq_frag);
+ outputlist_insert(&udf_main_seq_copy_frag);
+ outputlist_insert(&udf_integ_seq_frag);
+ outputlist_insert(&udf_pad_to_sector_256_frag);
+ outputlist_insert(&udf_anchor_vol_desc_frag);
+ outputlist_insert(&udf_file_set_desc_frag);
+ outputlist_insert(&udf_dirtree_frag);
+ outputlist_insert(&udf_file_entries_frag);
+ }
+#endif
+
+ /* Now start with path tables and directory tree info. */
+ if (!stream_media_size)
+ outputlist_insert(&pathtable_desc);
+ else
+ outputlist_insert(&strpath_desc);
+
+ if (use_Joliet) {
+ outputlist_insert(&jpathtable_desc);
+ }
+
+ if (!stream_media_size)
+ outputlist_insert(&dirtree_desc);
+
+ if (use_Joliet) {
+ outputlist_insert(&jdirtree_desc);
+ }
+ outputlist_insert(&dirtree_clean);
+
+ if (extension_record) {
+ outputlist_insert(&extension_desc);
+ }
+
+ if (!stream_media_size) {
+ outputlist_insert(&files_desc);
+ } else {
+ outputlist_insert(&strfile_desc);
+ outputlist_insert(&strdir_desc);
+ }
+
+ /*
+ * Allow room for the various headers we will be writing.
+ * There will always be a primary and an end volume descriptor.
+ */
+ last_extent = session_start;
+
+ /*
+ * Calculate the size of all of the components of the disc, and assign
+ * extent numbers.
+ */
+ for (opnt = out_list; opnt; opnt = opnt->of_next) {
+ opnt->of_start_extent = last_extent;
+ if (opnt->of_size != NULL) {
+ (*opnt->of_size) (last_extent);
+ }
+ }
+
+ /*
+ * Generate the contents of any of the sections that we want to
+ * generate. Not all of the fragments will do anything here
+ * - most will generate the data on the fly when we get to the write
+ * pass.
+ */
+ for (opnt = out_list; opnt; opnt = opnt->of_next) {
+ if (opnt->of_generate != NULL) {
+ (*opnt->of_generate) ();
+ }
+ }
+
+ /*
+ * Padding just after the ISO-9660 filesystem.
+ *
+ * files_desc does not have an of_size function. For this
+ * reason, we must insert us after the files content has been
+ * generated.
+ */
+#ifdef UDF
+ if (use_udf) {
+ /* Single anchor volume descriptor pointer at end */
+ outputlist_insert(&udf_end_anchor_vol_desc_frag);
+ if (udf_end_anchor_vol_desc_frag.of_size != NULL) {
+ (*udf_end_anchor_vol_desc_frag.of_size) (last_extent);
+ }
+ if (dopad) {
+ /*
+ * Pad with anchor volume descriptor pointer
+ * blocks instead of zeroes.
+ */
+ outputlist_insert(&udf_padend_avdp_frag);
+ if (udf_padend_avdp_frag.of_size != NULL) {
+ (*udf_padend_avdp_frag.of_size) (last_extent);
+ }
+ }
+ } else
+#endif
+ if (dopad && !(use_sparcboot || use_sunx86boot)) {
+ outputlist_insert(&endpad_desc);
+ if (endpad_desc.of_size != NULL) {
+ (*endpad_desc.of_size) (last_extent);
+ }
+ }
+ c = 0;
+ if (use_sparcboot) {
+ if (dopad) {
+ /* Padding before the boot partitions. */
+ outputlist_insert(&interpad_desc);
+ if (interpad_desc.of_size != NULL) {
+ (*interpad_desc.of_size) (last_extent);
+ }
+ }
+ c = make_sun_label();
+ last_extent += c;
+ outputlist_insert(&sunboot_desc);
+ if (dopad) {
+ outputlist_insert(&endpad_desc);
+ if (endpad_desc.of_size != NULL) {
+ (*endpad_desc.of_size) (last_extent);
+ }
+ }
+ } else if (use_sunx86boot) {
+ if (dopad) {
+ /* Padding before the boot partitions. */
+ outputlist_insert(&interpad_desc);
+ if (interpad_desc.of_size != NULL) {
+ (*interpad_desc.of_size) (last_extent);
+ }
+ }
+ c = make_sunx86_label();
+ last_extent += c;
+ outputlist_insert(&sunboot_desc);
+ if (dopad) {
+ outputlist_insert(&endpad_desc);
+ if (endpad_desc.of_size != NULL) {
+ (*endpad_desc.of_size) (last_extent);
+ }
+ }
+ }
+ if (print_size > 0) {
+ if (verbose > 0)
+ fprintf(stderr,
+ "Total extents scheduled to be written = %u\n",
+ (last_extent - session_start));
+ printf("%u\n", (last_extent - session_start));
+ exit(0);
+ }
+ /*
+ * Now go through the list of fragments and write the data that
+ * corresponds to each one.
+ */
+ for (opnt = out_list; opnt; opnt = opnt->of_next) {
+ Uint oext;
+
+ oext = last_extent_written;
+ if (opnt->of_start_extent != 0 &&
+ opnt->of_start_extent != last_extent_written) {
+ /*
+ * Consistency check.
+ * XXX Should make sure that all entries have
+ * XXXX of_start_extent set up correctly.
+ */
+ comerrno(EX_BAD,
+ "Implementation botch: %s should start at %u but starts at %u.\n",
+ opnt->of_name, opnt->of_start_extent, last_extent_written);
+ }
+ if (opnt->of_write != NULL) {
+ if (verbose > 1)
+ fprintf(stderr, "Writing: %-40sStart Block %u\n",
+ opnt->of_name, last_extent_written);
+ (*opnt->of_write) (discimage);
+ if (verbose > 1)
+ fprintf(stderr, "Done with: %-40sBlock(s) %u\n",
+ opnt->of_name, last_extent_written-oext);
+ }
+ }
+ if (last_extent != last_extent_written) {
+ comerrno(EX_BAD,
+ "Implementation botch: FS should end at %u but ends at %u.\n",
+ last_extent, last_extent_written);
+ }
+
+ if (jttemplate) {
+ write_jt_footer();
+ fclose(jttemplate);
+ }
+ if (jtjigdo)
+ fclose(jtjigdo);
+
+ if (verbose > 0) {
+#ifdef HAVE_SBRK
+ fprintf(stderr, "Max brk space used %x\n",
+ (unsigned int)(((unsigned long) sbrk(0)) - mem_start));
+#endif
+ fprintf(stderr, "%u extents written (%u MB)\n",
+ last_extent, last_extent >> 9);
+ }
+#ifdef VMS
+ return (1);
+#else
+ return (0);
+#endif
+}
+
+/*
+ * Find unescaped equal sign in graft pointer string.
+ */
+char *
+findgequal(char *s)
+{
+ char *p = s;
+
+ while ((p = strchr(p, '=')) != NULL) {
+ if (p > s && p[-1] != '\\')
+ return (p);
+ p++;
+ }
+ return (NULL);
+}
+
+/*
+ * Find unescaped equal sign in string.
+ */
+static char *
+escstrcpy(char *to, char *from)
+{
+ char *p = to;
+
+ if (debug)
+ fprintf(stderr, "FROM: '%s'\n", from);
+
+ while ((*p = *from++) != '\0') {
+ if (*p == '\\') {
+ if ((*p = *from++) == '\0')
+ break;
+ if (*p != '\\' && *p != '=') {
+ p[1] = p[0];
+ *p++ = '\\';
+ }
+ }
+ p++;
+ }
+ if (debug)
+ fprintf(stderr, "ESC: '%s'\n", to);
+ return (to);
+}
+
+void *
+e_malloc(size_t size)
+{
+ void *pt = 0;
+
+ if ((size > 0) && ((pt = malloc(size)) == NULL)) {
+#ifdef USE_LIBSCHILY
+ comerr("Not enough memory\n");
+#else
+ fprintf(stderr, "Not enough memory\n");
+ exit(1);
+#endif
+ }
+ /*
+ * Not all code is clean yet.
+ * Filling all allocated data with zeroes will help
+ * to avoid core dumps.
+ */
+ if (size > 0) /* a workaround for gcc bug gcc.gnu.org/PR25639 */
+ memset(pt, 0, size);
+ return (pt);
+}