2023-04-30 03:15:27 +02:00
/*
* Program mkisofs . c - generate iso9660 filesystem based upon directory
* tree on hard disk .
Written by Eric Youngdale ( 1993 ) .
Copyright 1993 Yggdrasil Computing , Incorporated
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 0213 9 , USA . */
/* APPLE_HYB James Pearson j.pearson@ge.ucl.ac.uk 12/3/99 */
# include <errno.h>
# include "config.h"
# include "mkisofs.h"
# include "match.h"
# include "apple_proto.h"
# ifdef linux
# include <getopt.h>
# else
# include "getopt.h"
# endif
# include "iso9660.h"
# include <ctype.h>
# ifndef VMS
# include <time.h>
# else
# include <sys/time.h>
# include "vms.h"
# endif
# include <stdlib.h>
# include <sys/stat.h>
# ifndef VMS
# ifdef HAVE_UNISTD_H
# include <unistd.h>
# endif
# endif
# include <fctldefs.h>
2023-11-11 02:29:48 +01:00
# if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__SecBSD__)
2023-04-30 03:15:27 +02:00
# include <sys/time.h>
# include <sys/resource.h>
# endif
struct directory * root = NULL ;
# ifdef APPLE_HYB
static char version_string [ ] = " mkhybrid 1.12b5.1 " ;
# else
static char version_string [ ] = " mkisofs 1.12b5 " ;
# endif /* APPLE_HYB */
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 use_eltorito = 0 ;
int use_RockRidge = 0 ;
int use_Joliet = 0 ;
int verbose = 0 ;
int all_files = 0 ;
int follow_links = 0 ;
int rationalize = 0 ;
int generate_tables = 0 ;
int print_size = 0 ;
int split_output = 0 ;
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 ;
int volume_set_size = 1 ;
int volume_sequence_number = 1 ;
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 RR_relocation_depth = 6 ; /* Violates iso9660, but most systems work */
int full_iso9660_filenames = 0 ; /* Used with Amiga. Disc will not work with
DOS */
int allow_leading_dots = 0 ; /* DOS cannot read names with leading dots */
int split_SL_component = 1 ; /* circumvent a bug in the SunOS driver */
int split_SL_field = 1 ; /* circumvent a bug in the SunOS */
# 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 mac_name = 0 ; /* use Mac name for ISO/Joliet/RR flag */
hce_mem * hce ; /* libhfs/mkisofs 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_file = 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 bsize = 0 ; /* Apple File Exchange block size */
int hfs_last = MAG_LAST ; /* process magic file after map file */
char * deftype = DEFTYPE ; /* default Apple TYPE */
char * defcreator = DEFCREATOR ; /* default Apple CREATOR */
char * trans_tbl = " TRANS.TBL " ; /* default name for translation table */
char * hfs_volume_id = NULL ; /* HFS volume ID */
char * hfs_bless = NULL ; /* name of folder to 'bless' (System Folder) */
# 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
{ " TYPE " , & deftype } ,
{ " CREATOR " , & defcreator } ,
# endif /* APPLE_HYB */
{ NULL , NULL }
} ;
/*
* 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. 150 isn't
special ; it ' s just an arbitrary non - ASCII char value . */
# define OPTION_HELP 150
# define OPTION_QUIET 151
# define OPTION_NOSPLIT_SL_COMPONENT 152
# define OPTION_NOSPLIT_SL_FIELD 153
# define OPTION_PRINT_SIZE 154
# define OPTION_SPLIT_OUTPUT 155
# define OPTION_ABSTRACT 156
# define OPTION_BIBLIO 157
# define OPTION_COPYRIGHT 158
# define OPTION_SYSID 159
# define OPTION_VOLSET 160
# define OPTION_VOLSET_SIZE 161
# define OPTION_VOLSET_SEQ_NUM 162
# define OPTION_I_HIDE 163
# define OPTION_J_HIDE 164
# define OPTION_LOG_FILE 165
# ifdef APPLE_HYB
# define OPTION_CAP 200
# define OPTION_NETA 201
# define OPTION_DBL 202
# define OPTION_ESH 203
# define OPTION_FE 204
# define OPTION_SGI 205
# define OPTION_MBIN 206
# define OPTION_SGL 207
/* aliases */
# define OPTION_USH 208
# define OPTION_XIN 209
# define OPTION_PROBE 220
# define OPTION_MACNAME 221
# define OPTION_NOMACFILES 222
# define OPTION_BOOT_HFS_FILE 223
# define OPTION_MAGIC_FILE 224
# define OPTION_TRANS_TBL 225
# define OPTION_GEN_PT 226
# define OPTION_CREATE_DT 227
# define OPTION_HFS_HIDE 228
# define OPTION_AUTOSTART 229
# define OPTION_BSIZE 230
# define OPTION_HFS_VOLID 231
# define OPTION_H_LIST 240
# define OPTION_P_LIST 241
# define OPTION_I_LIST 242
# define OPTION_J_LIST 243
# define OPTION_X_LIST 244
# define OPTION_HFS_BLESS 245
# endif /* APPLE_HYB */
static const struct ld_option ld_options [ ] =
{
{ { " all-files " , no_argument , NULL , ' a ' } ,
' a ' , NULL , " Process all files (don't skip 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 } ,
{ { " copyright " , required_argument , NULL , OPTION_COPYRIGHT } ,
' \0 ' , " FILE " , " Set Copyright filename " , ONE_DASH } ,
{ { " eltorito-boot " , required_argument , NULL , ' b ' } ,
' b ' , " FILE " , " Set El Torito boot image name " , ONE_DASH } ,
{ { " eltorito-catalog " , required_argument , NULL , ' c ' } ,
' c ' , " FILE " , " Set El Torito boot catalog name " , ONE_DASH } ,
{ { " cdwrite-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 " , ONE_DASH } ,
{ { " disable-deep-relocation " , no_argument , NULL , ' D ' } ,
' D ' , NULL , " Disable deep directory relocation " , ONE_DASH } ,
{ { " follow-links " , no_argument , NULL , ' f ' } ,
' f ' , NULL , " Follow symbolic links " , 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 } ,
# ifdef APPLE_HYB
/* NON-HFS change */
{ { " hide-list " , required_argument , NULL , OPTION_I_LIST } ,
' \0 ' , " FILE " , " list of ISO9660/RR files to hide " , ONE_DASH } ,
# endif /* APPLE_HYB */
{ { " hide-joliet " , required_argument , NULL , OPTION_J_HIDE } ,
' \0 ' , " GLOBFILE " , " Hide Joliet file " , ONE_DASH } ,
# ifdef APPLE_HYB
/* NON-HFS change */
{ { " hide-joliet-list " , required_argument , NULL , OPTION_J_LIST } ,
' \0 ' , " FILE " , " List of Joliet files to hide " , ONE_DASH } ,
# endif /* APPLE_HYB */
{ { NULL , required_argument , NULL , ' i ' } ,
' i ' , " ADD_FILES " , " No longer supported " , TWO_DASHES } ,
{ { " joliet " , no_argument , NULL , ' J ' } ,
' J ' , NULL , " Generate Joliet directory information " , ONE_DASH } ,
{ { " full-iso9660-filenames " , no_argument , NULL , ' l ' } ,
' l ' , NULL , " Allow full 32 character filenames for iso9660 names " , ONE_DASH } ,
{ { " allow-leading-dots " , no_argument , NULL , ' L ' } ,
' L ' , NULL , " Allow iso9660 filenames to start with '.' " , 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 } ,
# ifdef APPLE_HYB
{ { " exclude-list " , required_argument , NULL , OPTION_X_LIST } ,
' m ' , " FILE " , " List of file names to exclude " , ONE_DASH } ,
# endif /* APPLE_HYB */
{ { " prev-session " , required_argument , NULL , ' M ' } ,
' M ' , " FILE " , " Set path to previous session to merge " , ONE_DASH } ,
{ { " omit-version-number " , no_argument , NULL , ' N ' } ,
' N ' , NULL , " Omit version number from iso9660 filename " , ONE_DASH } ,
{ { " no-split-symlink-components " , no_argument , NULL , 0 } ,
0 , NULL , " Inhibit splitting symlink components " , ONE_DASH } ,
{ { " no-split-symlink-fields " , no_argument , NULL , 0 } ,
0 , NULL , " Inhibit splitting symlink fields " , ONE_DASH } ,
{ { " output " , required_argument , NULL , ' o ' } ,
' o ' , " FILE " , " Set output file name " , ONE_DASH } ,
# ifdef APPLE_HYB
{ { " path-list " , required_argument , NULL , OPTION_P_LIST } ,
' \0 ' , " FILE " , " list of pathnames to process " , ONE_DASH } ,
# endif /* APPLE_HYB */
{ { " 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 , ' 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 } ,
{ { " split-output " , no_argument , NULL , OPTION_SPLIT_OUTPUT } ,
' \0 ' , NULL , " Split output into files of approx. 1GB size " , 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 } ,
{ { " verbose " , no_argument , NULL , ' v ' } ,
' v ' , NULL , " Verbose " , 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 } ,
# ifdef ERIC_neverdef
{ { " transparent-compression " , no_argument , NULL , ' z ' } ,
' z ' , NULL , " Enable transparent compression of files " , ONE_DASH } ,
# endif
# ifdef APPLE_HYB
{ { " 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 , ' 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 Unix/HFS file type " , 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 " , 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_H_LIST } ,
' \0 ' , " GLOBFILE " , " List of HFS files to hide " , ONE_DASH } ,
{ { " table-name " , required_argument , NULL , OPTION_TRANS_TBL } ,
' \0 ' , " TABLE_NAME " , " translation table file name " , ONE_DASH } ,
{ { " hfs-volid " , required_argument , NULL , OPTION_HFS_VOLID } ,
' \0 ' , " HFS_VOLID " , " Volume name for the HFS partition " , ONE_DASH } ,
{ { " hfs-bless " , required_argument , NULL , OPTION_HFS_BLESS } ,
' \0 ' , " FOLDER_NAME " , " Name of Folder to be blessed " , ONE_DASH } ,
{ { " 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 } ,
# endif /* APPLE_HYB */
} ;
# define OPTION_COUNT (sizeof ld_options / sizeof ld_options[0])
# if defined(ultrix) || defined(_AUX_SOURCE)
char * strdup ( s )
char * s ; { char * c ; if ( c = ( char * ) malloc ( strlen ( s ) + 1 ) ) strcpy ( c , s ) ; return c ; }
# endif
void read_rcfile __PR ( ( char * appname ) ) ;
void usage __PR ( ( void ) ) ;
static void hide_reloc_dir __PR ( ( void ) ) ;
void FDECL1 ( read_rcfile , char * , appname )
{
FILE * rcfile ;
struct rcopts * rco ;
char * pnt , * pnt1 ;
char linebuffer [ 256 ] ;
static char rcfn [ ] = " .mkisofsrc " ;
char filename [ 1000 ] ;
int linum ;
strcpy ( filename , rcfn ) ;
rcfile = fopen ( filename , " r " ) ;
if ( ! rcfile & & errno ! = ENOENT )
perror ( filename ) ;
if ( ! rcfile )
{
pnt = getenv ( " MKISOFSRC " ) ;
if ( pnt & & strlen ( pnt ) < = sizeof ( filename ) )
{
strcpy ( filename , pnt ) ;
rcfile = fopen ( filename , " r " ) ;
if ( ! rcfile & & errno ! = ENOENT )
perror ( filename ) ;
}
}
if ( ! rcfile )
{
pnt = getenv ( " HOME " ) ;
if ( pnt & & strlen ( pnt ) + strlen ( rcfn ) + 2 < = sizeof ( filename ) )
{
strcpy ( filename , pnt ) ;
strcat ( filename , " / " ) ;
strcat ( filename , rcfn ) ;
rcfile = fopen ( filename , " r " ) ;
if ( ! rcfile & & errno ! = ENOENT )
perror ( filename ) ;
}
}
if ( ! rcfile & & strlen ( appname ) + sizeof ( rcfn ) + 2 < = sizeof ( filename ) )
{
strcpy ( filename , appname ) ;
pnt = strrchr ( filename , ' / ' ) ;
if ( pnt )
{
strcpy ( pnt + 1 , rcfn ) ;
rcfile = fopen ( filename , " r " ) ;
if ( ! rcfile & & errno ! = ENOENT )
perror ( filename ) ;
}
}
if ( ! rcfile )
return ;
if ( verbose > 0 )
{
fprintf ( stderr , " Using \" %s \" \n " , filename ) ;
}
/* OK, we got it. Now read in the lines and parse them */
linum = 0 ;
while ( fgets ( linebuffer , sizeof ( linebuffer ) , rcfile ) )
{
char * name ;
char * name_end ;
+ + linum ;
/* skip any leading white space */
pnt = linebuffer ;
while ( * pnt = = ' ' | | * pnt = = ' \t ' )
+ + pnt ;
/* If we are looking at a # character, this line is a comment. */
if ( * pnt = = ' # ' )
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 = pnt ;
while ( * pnt & & isalpha ( ( unsigned char ) * pnt ) )
{
if ( islower ( ( unsigned char ) * pnt ) )
* pnt = toupper ( ( unsigned char ) * pnt ) ;
pnt + + ;
}
if ( name = = pnt )
{
fprintf ( stderr , " %s:%d: name required \n " , filename , linum ) ;
continue ;
}
name_end = pnt ;
/* Skip past white space after the name */
while ( * pnt = = ' ' | | * pnt = = ' \t ' )
pnt + + ;
/* silently ignore errors in the rc file. */
if ( * pnt ! = ' = ' )
{
fprintf ( stderr , " %s:%d: equals sign required \n " , filename , linum ) ;
continue ;
}
/* Skip pas the = sign, and any white space following it */
pnt + + ; /* Skip past '=' sign */
while ( * pnt = = ' ' | | * pnt = = ' \t ' )
pnt + + ;
/* now it is safe to NUL terminate the name */
* name_end = 0 ;
/* Now get rid of trailing newline */
pnt1 = pnt ;
while ( * pnt1 )
{
if ( * pnt1 = = ' \n ' )
{
* pnt1 = 0 ;
break ;
}
pnt1 + + ;
} ;
/* OK, now figure out which option we have */
for ( rco = rcopt ; rco - > tag ; rco + + ) {
if ( strcmp ( rco - > tag , name ) = = 0 )
{
* rco - > variable = strdup ( pnt ) ;
break ;
} ;
}
if ( rco - > tag = = NULL )
{
fprintf ( stderr , " %s:%d: field name \" %s \" unknown \n " , filename , linum ,
name ) ;
}
}
if ( ferror ( rcfile ) )
perror ( filename ) ;
fclose ( rcfile ) ;
}
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
void usage ( ) {
# ifdef APPLE_HYB
const char * program_name = " mkhybrid " ;
# else
const char * program_name = " mkisofs " ;
# endif /* APPLE_HYB */
#if 0
fprintf ( stderr , " Usage: \n " ) ;
fprintf ( stderr ,
" mkisofs [-o outfile] [-R] [-V volid] [-v] [-a] \
[ - T ] \ n [ - l ] [ - d ] [ - V ] [ - D ] [ - L ] [ - p preparer ] "
" [-P publisher] [ -A app_id ] [-z] \n \
[ - b boot_image_name ] [ - c boot_catalog - name ] \
[ - x path - x path . . . ] path \ n " );
# endif
int i ;
/* const char **targets, **pp;*/
fprintf ( stderr , " Usage: %s [options] file... \n " , program_name ) ;
fprintf ( stderr , " Options: \n " ) ;
for ( i = 0 ; i < 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 < 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 < 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 ) ;
}
}
exit ( 1 ) ;
}
2023-11-11 02:29:48 +01:00
/*
* Fill in date in the iso9660 format
2023-04-30 03:15:27 +02:00
*
* 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 - 5 h to - 8 h ( can vary a little
* with DST , I guess ) . The Linux iso9660 filesystem has had the sign
* of this wrong for ages ( mkisofs had it wrong too for the longest time ) .
*/
int FDECL2 ( 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 ;
2023-11-11 02:29:48 +01:00
/*
2023-04-30 03:15:27 +02:00
* Must recalculate proper timezone offset each time ,
2023-11-11 02:29:48 +01:00
* as some files use daylight savings time and some don ' t . . .
2023-04-30 03:15:27 +02:00
*/
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 ] ;
2023-11-11 02:29:48 +01:00
if ( local - > tm_year < 0 )
2023-04-30 03:15:27 +02:00
{
local - > tm_yday = - 1 ;
}
2023-11-11 02:29:48 +01:00
else
2023-04-30 03:15:27 +02:00
{
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 *
FDECL5 ( get_pnames , int , argc , char * * , argv , int , opt , char * , pname , FILE * , fp )
{
if ( opt < argc )
return ( argv [ opt ] ) ;
if ( fp = = NULL )
return ( ( char * ) 0 ) ;
if ( fscanf ( fp , " %s " , pname ) ! = EOF )
return ( pname ) ;
return ( ( char * ) 0 ) ;
}
extern char * cdwrite_data ;
int FDECL2 ( main , int , argc , char * * , argv ) {
struct directory_entry de ;
# ifdef HAVE_SBRK
unsigned long mem_start ;
# endif
struct stat statbuf ;
char * scan_tree ;
char * merge_image = 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 ;
char * log_file = 0 ;
# ifdef APPLE_HYB
char * afpfile = " " ; /* mapping file for TYPE/CREATOR */
char * pathnames = 0 ;
FILE * pfp = NULL ;
char pname [ 1024 ] , * arg ;
int no_path_names = 0 ;
# endif /* APPLE_HYB */
if ( argc < 2 )
usage ( ) ;
/* Get the defaults from the .mkisofsrc 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 < 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 - - ;
goto parse_input_files ;
case ' C ' :
/*
* This is a temporary hack until cdwrite gets the proper hooks in
* it .
*/
cdwrite_data = optarg ;
break ;
case ' i ' :
fprintf ( stderr , " -i option no longer supported. \n " ) ;
exit ( 1 ) ;
break ;
case ' J ' :
use_Joliet + + ;
break ;
case ' a ' :
all_files + + ;
break ;
case ' b ' :
use_eltorito + + ;
boot_image = optarg ; /* pathname of the boot image on cd */
if ( boot_image = = NULL ) {
fprintf ( stderr , " Required boot image pathname missing \n " ) ;
exit ( 1 ) ;
}
break ;
case ' c ' :
use_eltorito + + ;
boot_catalog = optarg ; /* pathname of the boot image on cd */
if ( boot_catalog = = NULL ) {
fprintf ( stderr , " Required boot catalog pathname missing \n " ) ;
exit ( 1 ) ;
}
break ;
case OPTION_ABSTRACT :
abstract = optarg ;
if ( strlen ( abstract ) > 37 ) {
fprintf ( stderr , " Abstract filename string too long \n " ) ;
exit ( 1 ) ;
} ;
break ;
case ' A ' :
appid = optarg ;
if ( strlen ( appid ) > 128 ) {
fprintf ( stderr , " Application-id string too long \n " ) ;
exit ( 1 ) ;
} ;
break ;
case OPTION_BIBLIO :
biblio = optarg ;
if ( strlen ( biblio ) > 37 ) {
fprintf ( stderr , " Bibliographic filename string too long \n " ) ;
exit ( 1 ) ;
} ;
break ;
case OPTION_COPYRIGHT :
copyright = optarg ;
if ( strlen ( copyright ) > 37 ) {
fprintf ( stderr , " Copyright filename string too long \n " ) ;
exit ( 1 ) ;
} ;
break ;
case ' d ' :
omit_period + + ;
break ;
case ' D ' :
RR_relocation_depth = 32767 ;
break ;
case ' f ' :
follow_links + + ;
break ;
case ' l ' :
full_iso9660_filenames + + ;
break ;
case ' L ' :
allow_leading_dots + + ;
break ;
case OPTION_LOG_FILE :
log_file = optarg ;
break ;
case ' M ' :
merge_image = optarg ;
break ;
case ' N ' :
omit_version_number + + ;
break ;
case ' o ' :
outfile = optarg ;
break ;
case ' p ' :
preparer = optarg ;
if ( strlen ( preparer ) > 128 ) {
fprintf ( stderr , " Preparer string too long \n " ) ;
exit ( 1 ) ;
} ;
break ;
case OPTION_PRINT_SIZE :
print_size + + ;
break ;
case ' P ' :
publisher = optarg ;
if ( strlen ( publisher ) > 128 ) {
fprintf ( stderr , " Publisher string too long \n " ) ;
exit ( 1 ) ;
} ;
break ;
case OPTION_QUIET :
verbose = 0 ;
break ;
case ' R ' :
use_RockRidge + + ;
break ;
case ' r ' :
rationalize + + ;
use_RockRidge + + ;
break ;
case OPTION_SPLIT_OUTPUT :
split_output + + ;
break ;
case OPTION_SYSID :
system_id = optarg ;
if ( strlen ( system_id ) > 32 ) {
fprintf ( stderr , " System ID string too long \n " ) ;
exit ( 1 ) ;
} ;
break ;
# ifdef APPLE_HYB
case OPTION_TRANS_TBL :
trans_tbl = optarg ;
/* fall through */
# endif /* APPLE_HYB */
case ' T ' :
generate_tables + + ;
break ;
case ' V ' :
volume_id = optarg ;
if ( strlen ( volume_id ) > 32 ) {
fprintf ( stderr , " Volume ID string too long \n " ) ;
exit ( 1 ) ;
} ;
break ;
case OPTION_VOLSET :
volset_id = optarg ;
if ( strlen ( volset_id ) > 128 ) {
fprintf ( stderr , " Volume set ID string too long \n " ) ;
exit ( 1 ) ;
} ;
break ;
case OPTION_VOLSET_SIZE :
volume_set_size = atoi ( optarg ) ;
break ;
case OPTION_VOLSET_SEQ_NUM :
volume_sequence_number = atoi ( optarg ) ;
if ( volume_sequence_number > volume_set_size ) {
fprintf ( stderr , " Volume set sequence number too big \n " ) ;
exit ( 1 ) ;
}
break ;
case ' v ' :
verbose + + ;
break ;
case ' z ' :
# ifdef VMS
fprintf ( stderr , " Transparent compression not supported with VMS \n " ) ;
exit ( 1 ) ;
# 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_I_HIDE :
i_add_match ( optarg ) ;
break ;
case OPTION_J_HIDE :
j_add_match ( optarg ) ;
break ;
case OPTION_HELP :
usage ( ) ;
exit ( 0 ) ;
break ;
case OPTION_NOSPLIT_SL_COMPONENT :
split_SL_component = 0 ;
break ;
case OPTION_NOSPLIT_SL_FIELD :
split_SL_field = 0 ;
break ;
# ifdef APPLE_HYB
case ' H ' :
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 :
mac_name = 1 ;
break ;
case OPTION_NOMACFILES :
nomacfiles = 1 ;
break ;
case OPTION_BOOT_HFS_FILE :
hfs_boot_file = optarg ;
/* fall through */
case OPTION_GEN_PT :
gen_pt = 1 ;
break ;
case OPTION_MAGIC_FILE :
magic_file = optarg ;
hfs_last = MAG_LAST ;
break ;
case OPTION_AUTOSTART :
autoname = optarg ;
/* gen_pt = 1; */
break ;
case OPTION_BSIZE :
bsize = atoi ( optarg ) ;
break ;
case OPTION_HFS_VOLID :
hfs_volume_id = optarg ;
break ;
case OPTION_HFS_BLESS :
hfs_bless = optarg ;
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_CREATE_DT :
create_dt = 0 ;
break ;
case OPTION_HFS_HIDE :
hfs_add_match ( optarg ) ;
break ;
case OPTION_H_LIST :
hfs_add_list ( optarg ) ;
break ;
2023-11-11 02:29:48 +01:00
/* NON-HFS change
2023-04-30 03:15:27 +02:00
The next options will probably appear in mkisofs in the future */
case OPTION_P_LIST :
pathnames = optarg ;
break ;
case OPTION_X_LIST :
add_list ( optarg ) ;
break ;
case OPTION_I_LIST :
i_add_list ( optarg ) ;
break ;
case OPTION_J_LIST :
j_add_list ( optarg ) ;
break ;
# endif /* APPLE_HYB */
default :
usage ( ) ;
exit ( 1 ) ;
}
parse_input_files :
2023-11-11 02:29:48 +01:00
# if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__SecBSD__)
2023-04-30 03:15:27 +02:00
{
struct rlimit rlp ;
2023-11-11 02:29:48 +01:00
if ( getrlimit ( RLIMIT_DATA , & rlp ) = = - 1 )
2023-04-30 03:15:27 +02:00
perror ( " Warning: getrlimit " ) ;
else {
rlp . rlim_cur = 33554432 ;
if ( setrlimit ( RLIMIT_DATA , & rlp ) = = - 1 )
perror ( " Warning: setrlimit " ) ;
}
}
# endif
# 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 ) {
fprintf ( stderr , " can't have both -apple and -hfs options " ) ;
exit ( 1 ) ;
}
/* 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 | | mac_name | | nomacfiles | | hfs_select | | hfs_boot_file | | magic_file | | hfs_ishidden ( ) | | gen_pt | | autoname | | bsize )
apple_hyb = 1 ;
}
if ( apple_ext & & hfs_boot_file ) {
fprintf ( stderr , " can't have -hfs-boot-file with -apple \n " ) ;
exit ( 1 ) ;
}
if ( hfs_select )
/* if we have selected certain types of Mac/Unix files, then turn off
probe and nomacfiles */
probe = nomacfiles = 0 ;
if ( apple_hyb | | apple_ext )
apple_both = 1 ;
if ( apple_both ) {
/* set up the TYPE/CREATOR mappings */
hfs_init ( afpfile , 0 , probe , nomacfiles , hfs_select ) ;
}
if ( apple_ext & & ! use_RockRidge ) {
/* use RockRidge to set the SystemUse field ... */
use_RockRidge + + ;
rationalize + + ;
}
# endif /* APPLE_HYB */
if ( verbose > 1 ) fprintf ( stderr , " %s \n " , version_string ) ;
if ( cdwrite_data = = NULL & & merge_image ! = NULL )
{
fprintf ( stderr , " Multisession usage bug: Must specify -C if -M is used. \n " ) ;
exit ( 0 ) ;
}
if ( cdwrite_data ! = NULL & & merge_image = = NULL )
{
fprintf ( stderr , " Warning: -C specified without -M: old session data will not be merged. \n " ) ;
}
/* The first step is to scan the directory tree, and take some notes */
scan_tree = argv [ optind ] ;
if ( ! scan_tree ) {
usage ( ) ;
exit ( 1 ) ;
} ;
# ifndef VMS
if ( scan_tree [ strlen ( scan_tree ) - 1 ] ! = ' / ' ) {
scan_tree = ( char * ) e_malloc ( strlen ( argv [ optind ] ) + 2 ) ;
strcpy ( scan_tree , argv [ optind ] ) ;
strcat ( scan_tree , " / " ) ;
} ;
# endif
if ( use_RockRidge ) {
# 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
}
if ( log_file ) {
FILE * lfp ;
int i ;
/* open log file - test that we can open OK */
if ( ( lfp = fopen ( log_file , " w " ) ) = = NULL ) {
fprintf ( stderr , " can't open logfile: %s \n " , log_file ) ;
exit ( 1 ) ;
}
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 ) {
fprintf ( stderr , " can't open logfile: %s \n " , log_file ) ;
exit ( 1 ) ;
}
if ( verbose > 1 ) {
for ( i = 0 ; i < argc ; i + + )
fprintf ( stderr , " %s " , argv [ i ] ) ;
fprintf ( stderr , " \n %s \n " , version_string ) ;
}
}
/*
* See if boot catalog file exists in root directory , if not
* we will create it .
*/
if ( use_eltorito )
init_boot_catalog ( argv [ optind ] ) ;
/*
* 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 ( argv [ optind ] , & statbuf ) ;
add_directory_hash ( statbuf . st_dev , STAT_INODE ( statbuf ) ) ;
memset ( & de , 0 , sizeof ( de ) ) ;
de . filedir = root ; /* We need this to bootstrap */
if ( cdwrite_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 )
{
mrootp = merge_isofs ( merge_image ) ;
if ( mrootp = = NULL )
{
/*
* Complain and die .
*/
fprintf ( stderr , " Unable to open previous session image %s \n " ,
merge_image ) ;
exit ( 1 ) ;
}
2023-11-11 02:29:48 +01:00
memcpy ( & de . isorec . extent , mrootp - > extent , 8 ) ;
2023-04-30 03:15:27 +02:00
}
/*
* 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 ) ;
# ifdef APPLE_HYB
/* NON-HFS change: 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 ) {
fprintf ( stderr , " unable to open pathname list %s \n " , pathnames ) ;
exit ( 1 ) ;
}
}
else
pfp = stdin ;
}
# endif /* APPLE_HYB */
/*
* 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 APPLE_HYB
/* NON-HFS change */
while ( ( arg = get_pnames ( argc , argv , optind , pname , pfp ) ) ! = NULL )
# else
while ( optind < argc )
# endif /* APPLE_HYB */
{
char * node ;
struct directory * graft_dir ;
struct stat st ;
char * short_name ;
int status ;
char graft_point [ 1024 ] ;
/*
* 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 .
*/
# ifdef APPLE_HYB
/* NON-HFS change */
node = strchr ( arg , ' = ' ) ;
# else
node = strchr ( argv [ optind ] , ' = ' ) ;
# endif /* APPLE_HYB */
short_name = NULL ;
if ( node ! = NULL )
{
char * pnt ;
char * xpnt ;
* node = ' \0 ' ;
# ifdef APPLE_HYB
/* NON-HFS change */
strcpy ( graft_point , arg ) ;
# else
strcpy ( graft_point , argv [ optind ] ) ;
# endif /* APPLE_HYB */
* node = ' = ' ;
node + + ;
graft_dir = root ;
xpnt = graft_point ;
if ( * xpnt = = PATH_SEPARATOR )
{
xpnt + + ;
}
/*
* Loop down deeper and deeper until we
* find the correct insertion spot .
*/
while ( 1 = = 1 )
{
pnt = strchr ( xpnt , PATH_SEPARATOR ) ;
if ( pnt = = NULL )
{
if ( * xpnt ! = ' \0 ' )
{
short_name = xpnt ;
}
break ;
}
* pnt = ' \0 ' ;
2023-11-11 02:29:48 +01:00
graft_dir = find_or_create_directory ( graft_dir ,
graft_point ,
2023-04-30 03:15:27 +02:00
NULL , TRUE ) ;
* pnt = PATH_SEPARATOR ;
xpnt = pnt + 1 ;
}
}
else
{
graft_dir = root ;
# ifdef APPLE_HYB
/* NON-HFS change */
node = arg ;
# else
node = argv [ optind ] ;
# endif /* APPLE_HYB */
}
/*
* Now see whether the user wants to add a regular file ,
* or a directory at this point .
*/
status = stat_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 .
*/
fprintf ( stderr , " Invalid node - %s \n " , node ) ;
exit ( 1 ) ;
}
else
{
if ( S_ISDIR ( st . st_mode ) )
{
if ( ! scan_directory_tree ( graft_dir , node , & de ) )
{
exit ( 1 ) ;
}
}
else
{
if ( short_name = = NULL )
{
short_name = strrchr ( node , PATH_SEPARATOR ) ;
if ( short_name = = NULL | | short_name < node )
{
short_name = node ;
}
else
{
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 */
{
exit ( 1 ) ;
}
}
}
optind + + ;
# ifdef APPLE_HYB
/* NON-HFS change */
no_path_names = 0 ;
# endif /* APPLE_HYB */
}
# ifdef APPLE_HYB
/* NON-HFS change */
if ( pfp & & pfp ! = stdin )
fclose ( pfp ) ;
2023-11-11 02:29:48 +01:00
/* exit if we don't have any pathnames to process - not going to happen
2023-04-30 03:15:27 +02:00
at the moment as we have to have at least one path on the command line */
if ( no_path_names ) {
usage ( ) ;
exit ( 1 ) ;
} ;
# endif /* APPLE_HYB */
/*
* 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 )
{
merge_previous_session ( root , mrootp ) ;
}
# 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 ( ) ;
/*
* 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 ( use_Joliet )
{
goof + = joliet_sort_tree ( root ) ;
}
if ( goof )
{
fprintf ( stderr , " Joliet tree sort failed. \n " ) ;
exit ( 1 ) ;
}
2023-11-11 02:29:48 +01:00
2023-04-30 03:15:27 +02:00
/*
* Fix a couple of things in the root directory so that everything
* is self consistent .
*/
2023-11-11 02:29:48 +01:00
root - > self = root - > contents ; /* Fix this up so that the path
2023-04-30 03:15:27 +02:00
tables get done right */
/*
* OK , ready to write the file . Open it up , and generate the thing .
*/
if ( print_size ) {
discimage = fopen ( " /dev/null " , " wb " ) ;
if ( ! discimage ) {
fprintf ( stderr , " Unable to open /dev/null \n " ) ;
exit ( 1 ) ;
}
} else if ( outfile ) {
discimage = fopen ( outfile , " wb " ) ;
if ( ! discimage ) {
fprintf ( stderr , " Unable to open disc image file \n " ) ;
exit ( 1 ) ;
} ;
} else {
discimage = stdout ;
# if defined(__CYGWIN32__)
setmode ( fileno ( stdout ) , O_BINARY ) ;
# endif
}
/* Now assign addresses on the disc for the path table. */
path_blocks = ( path_table_size + ( SECTOR_SIZE - 1 ) ) > > 11 ;
if ( path_blocks & 1 ) path_blocks + + ;
jpath_blocks = ( jpath_table_size + ( SECTOR_SIZE - 1 ) ) > > 11 ;
if ( jpath_blocks & 1 ) jpath_blocks + + ;
/*
* Start to set up the linked list that we use to track the
* contents of the disc .
*/
outputlist_insert ( & padblock_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 ) ;
}
/*
* SVD for Joliet .
*/
if ( use_Joliet )
{
outputlist_insert ( & joliet_desc ) ;
}
/*
* Finally the last volume desctiptor .
*/
outputlist_insert ( & end_vol ) ;
outputlist_insert ( & pathtable_desc ) ;
if ( use_Joliet )
{
outputlist_insert ( & jpathtable_desc ) ;
}
outputlist_insert ( & dirtree_desc ) ;
if ( use_Joliet )
{
outputlist_insert ( & jdirtree_desc ) ;
}
outputlist_insert ( & dirtree_clean ) ;
2023-11-11 02:29:48 +01:00
if ( extension_record )
{
2023-04-30 03:15:27 +02:00
outputlist_insert ( & extension_desc ) ;
}
outputlist_insert ( & files_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 ;
2023-11-11 02:29:48 +01:00
2023-04-30 03:15:27 +02:00
/*
* Calculate the size of all of the components of the disc , and assign
* extent numbers .
*/
for ( opnt = out_list ; opnt ; opnt = opnt - > of_next )
{
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 ) ( ) ;
}
}
if ( in_image ! = NULL )
{
fclose ( in_image ) ;
}
/*
* 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 )
{
if ( opnt - > of_write ! = NULL )
{
( * opnt - > of_write ) ( discimage ) ;
}
}
if ( verbose > 0 )
{
# ifdef HAVE_SBRK
2023-11-11 02:29:48 +01:00
fprintf ( stderr , " Max brk space used %x \n " ,
2023-04-30 03:15:27 +02:00
( unsigned int ) ( ( ( unsigned long ) sbrk ( 0 ) ) - mem_start ) ) ;
# endif
fprintf ( stderr , " %d extents written (%d Mb) \n " , last_extent , last_extent > > 9 ) ;
}
# ifdef APPLE_HYB
last_extent + = hfs_extra ;
# endif /* APPLE_HYB */
# ifdef VMS
return 1 ;
# else
return 0 ;
# endif
}
void *
FDECL1 ( e_malloc , size_t , size )
{
void * pt = 0 ;
if ( ( size > 0 ) & & ( ( pt = malloc ( size ) ) = = NULL ) ) {
fprintf ( stderr , " Not enough memory \n " ) ;
exit ( 1 ) ;
}
return pt ;
}