This commit is contained in:
parent
4b4c4f6400
commit
63eb2d63b1
14 changed files with 4270 additions and 812 deletions
|
@ -20,16 +20,16 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
static char rcsid[] ="$Id: mkisofs.c,v 1.10.1.3 1998/06/02 03:36:16 eric Exp $";
|
||||
|
||||
/* ADD_FILES changes made by Ross Biro biro@yggdrasil.com 2/23/95 */
|
||||
static char rcsid[] ="$Id: mkisofs.c,v 1.29 1998/06/02 03:43:45 eric Exp $";
|
||||
|
||||
#include <errno.h>
|
||||
#include "mkisofs.h"
|
||||
#include "config.h"
|
||||
#include "mkisofs.h"
|
||||
|
||||
#ifdef linux
|
||||
#include <getopt.h>
|
||||
#else
|
||||
#include "getopt.h"
|
||||
#endif
|
||||
|
||||
#include "iso9660.h"
|
||||
|
@ -60,7 +60,7 @@ static char rcsid[] ="$Id: mkisofs.c,v 1.10.1.3 1998/06/02 03:36:16 eric Exp $";
|
|||
|
||||
struct directory * root = NULL;
|
||||
|
||||
static char version_string[] = "mkisofs v1.11.3";
|
||||
static char version_string[] = "mkisofs 1.12b4";
|
||||
|
||||
FILE * discimage;
|
||||
unsigned int next_extent = 0;
|
||||
|
@ -69,19 +69,30 @@ 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;
|
||||
static int extension_record_size = 0;
|
||||
int extension_record_size = 0;
|
||||
|
||||
/* These variables are associated with command line options */
|
||||
int use_eltorito = 0;
|
||||
int use_RockRidge = 0;
|
||||
int verbose = 0;
|
||||
int use_Joliet = 0;
|
||||
int verbose = 1;
|
||||
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;
|
||||
|
@ -101,6 +112,8 @@ 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 */
|
||||
|
||||
struct rcopts{
|
||||
char * tag;
|
||||
|
@ -120,6 +133,110 @@ struct rcopts rcopt[] = {
|
|||
{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
|
||||
|
||||
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 },
|
||||
{ {"appid", required_argument, NULL, 'A'},
|
||||
'A', "ID", "Set Application ID" , 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 cdwrite" , 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 },
|
||||
{ {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 },
|
||||
{ {"exclude", required_argument, NULL, 'm'},
|
||||
'm', "GLOBFILE", "Exclude file name" , ONE_DASH },
|
||||
{ {"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 },
|
||||
{ {"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 },
|
||||
{ {"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 },
|
||||
{ {"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
|
||||
};
|
||||
|
||||
#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;}
|
||||
|
@ -179,7 +296,11 @@ void FDECL1(read_rcfile, char *, appname)
|
|||
}
|
||||
if (!rcfile)
|
||||
return;
|
||||
fprintf(stderr, "Using \"%s\"\n", filename);
|
||||
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))
|
||||
|
@ -260,20 +381,113 @@ void FDECL1(read_rcfile, char *, appname)
|
|||
|
||||
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(){
|
||||
const char * program_name = "mkisofs";
|
||||
#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]"
|
||||
#ifdef ADD_FILES
|
||||
"[-i file] \n"
|
||||
#endif
|
||||
"[-P publisher] [ -A app_id ] [-z] \n \
|
||||
[-b boot_image_name] [-c boot_catalog-name] \
|
||||
[-x path -x path ...] path\n");
|
||||
exit(1);
|
||||
#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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -326,15 +540,18 @@ extern char * cdwrite_data;
|
|||
int FDECL2(main, int, argc, char **, argv){
|
||||
char * outfile;
|
||||
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;
|
||||
#ifdef ADD_FILES
|
||||
char *add_file_file = NULL;
|
||||
#endif
|
||||
|
||||
if (argc < 2)
|
||||
usage();
|
||||
|
@ -343,9 +560,56 @@ int FDECL2(main, int, argc, char **, argv){
|
|||
read_rcfile(argv[0]);
|
||||
|
||||
outfile = NULL;
|
||||
while ((c = getopt(argc, argv, "i:o:V:RrfvaTp:P:b:c:x:dDlLNzA:M:m:C:")) != EOF)
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
@ -353,6 +617,13 @@ int FDECL2(main, int, argc, char **, argv){
|
|||
*/
|
||||
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;
|
||||
|
@ -388,14 +659,6 @@ int FDECL2(main, int, argc, char **, argv){
|
|||
case 'f':
|
||||
follow_links++;
|
||||
break;
|
||||
case 'i':
|
||||
#ifdef ADD_FILES
|
||||
add_file_file = optarg;
|
||||
break;
|
||||
#else
|
||||
usage();
|
||||
exit(1);
|
||||
#endif
|
||||
case 'l':
|
||||
full_iso9660_filenames++;
|
||||
break;
|
||||
|
@ -418,6 +681,9 @@ int FDECL2(main, int, argc, char **, argv){
|
|||
exit(1);
|
||||
};
|
||||
break;
|
||||
case OPTION_PRINT_SIZE:
|
||||
print_size++;
|
||||
break;
|
||||
case 'P':
|
||||
publisher = optarg;
|
||||
if(strlen(publisher) > 128) {
|
||||
|
@ -425,6 +691,9 @@ int FDECL2(main, int, argc, char **, argv){
|
|||
exit(1);
|
||||
};
|
||||
break;
|
||||
case OPTION_QUIET:
|
||||
verbose = 0;
|
||||
break;
|
||||
case 'R':
|
||||
use_RockRidge++;
|
||||
break;
|
||||
|
@ -432,6 +701,9 @@ int FDECL2(main, int, argc, char **, argv){
|
|||
rationalize++;
|
||||
use_RockRidge++;
|
||||
break;
|
||||
case OPTION_SPLIT_OUTPUT:
|
||||
split_output++;
|
||||
break;
|
||||
case 'T':
|
||||
generate_tables++;
|
||||
break;
|
||||
|
@ -449,16 +721,32 @@ int FDECL2(main, int, argc, char **, argv){
|
|||
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 'x':
|
||||
exclude(optarg);
|
||||
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;
|
||||
default:
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
parse_input_files:
|
||||
|
||||
#ifdef __NetBSD__
|
||||
{
|
||||
int resource;
|
||||
|
@ -476,7 +764,7 @@ int FDECL2(main, int, argc, char **, argv){
|
|||
mem_start = (unsigned long) sbrk(0);
|
||||
#endif
|
||||
|
||||
if(verbose) fprintf(stderr,"%s\n", version_string);
|
||||
if(verbose > 1) fprintf(stderr,"%s\n", version_string);
|
||||
|
||||
if( (cdwrite_data != NULL && merge_image == NULL)
|
||||
|| (cdwrite_data == NULL && merge_image != NULL) )
|
||||
|
@ -489,12 +777,6 @@ int FDECL2(main, int, argc, char **, argv){
|
|||
|
||||
scan_tree = argv[optind];
|
||||
|
||||
#ifdef ADD_FILES
|
||||
if (add_file_file) {
|
||||
add_file(add_file_file);
|
||||
}
|
||||
add_file_list (argc, argv, optind+1);
|
||||
#endif
|
||||
|
||||
if(!scan_tree){
|
||||
usage();
|
||||
|
@ -557,28 +839,186 @@ int FDECL2(main, int, argc, char **, argv){
|
|||
}
|
||||
|
||||
/*
|
||||
* Scan the actual directory (and any we find below it)
|
||||
* for files to write out to the output image.
|
||||
* Create an empty root directory. If we ever scan it for real, we will fill in the
|
||||
* contents.
|
||||
*/
|
||||
if (!scan_directory_tree(argv[optind], &de, mrootp))
|
||||
find_or_create_directory(NULL, "", &de, TRUE);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
while(optind < argc)
|
||||
{
|
||||
exit(1);
|
||||
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.
|
||||
*/
|
||||
node = strchr(argv[optind], '=');
|
||||
short_name = NULL;
|
||||
|
||||
if( node != NULL )
|
||||
{
|
||||
char * pnt;
|
||||
char * xpnt;
|
||||
|
||||
*node = '\0';
|
||||
strcpy(graft_point, argv[optind]);
|
||||
*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';
|
||||
graft_dir = find_or_create_directory(graft_dir,
|
||||
graft_point,
|
||||
NULL, TRUE);
|
||||
*pnt = PATH_SEPARATOR;
|
||||
xpnt = pnt + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
graft_dir = root;
|
||||
node = argv[optind];
|
||||
}
|
||||
|
||||
/*
|
||||
* 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++;
|
||||
}
|
||||
}
|
||||
if( !insert_file_entry(graft_dir, node, short_name) )
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
optind++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fix a couple of things in the root directory so that everything
|
||||
* is self consistent.
|
||||
* 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.
|
||||
*/
|
||||
root->self = root->contents; /* Fix this up so that the path tables get done right */
|
||||
goof += sort_tree(root);
|
||||
|
||||
if(reloc_dir) sort_n_finish(reloc_dir);
|
||||
if( use_Joliet )
|
||||
{
|
||||
goof += joliet_sort_tree(root);
|
||||
}
|
||||
|
||||
if (goof) exit(1);
|
||||
|
||||
/*
|
||||
* Fix a couple of things in the root directory so that everything
|
||||
* is self consistent.
|
||||
*/
|
||||
root->self = root->contents; /* Fix this up so that the path
|
||||
tables get done right */
|
||||
|
||||
/*
|
||||
* OK, ready to write the file. Open it up, and generate the thing.
|
||||
*/
|
||||
if (outfile){
|
||||
if (print_size){
|
||||
discimage = fopen("/dev/null", "w");
|
||||
if (!discimage){
|
||||
fprintf(stderr,"Unable to open /dev/null\n");
|
||||
exit(1);
|
||||
}
|
||||
} else if (outfile){
|
||||
discimage = fopen(outfile, "w");
|
||||
if (!discimage){
|
||||
fprintf(stderr,"Unable to open disc image file\n");
|
||||
|
@ -593,54 +1033,120 @@ int FDECL2(main, int, argc, char **, argv){
|
|||
path_blocks = (path_table_size + (SECTOR_SIZE - 1)) >> 11;
|
||||
if (path_blocks & 1) path_blocks++;
|
||||
|
||||
path_table[0] = session_start + 0x10 + 2 + (use_eltorito ? 1 : 0);
|
||||
path_table[1] = 0;
|
||||
path_table[2] = path_table[0] + path_blocks;
|
||||
path_table[3] = 0;
|
||||
jpath_blocks = (jpath_table_size + (SECTOR_SIZE - 1)) >> 11;
|
||||
if (jpath_blocks & 1) jpath_blocks++;
|
||||
|
||||
last_extent += path_table[2] - session_start + path_blocks;
|
||||
/* The next free block */
|
||||
/*
|
||||
* Start to set up the linked list that we use to track the
|
||||
* contents of the disc.
|
||||
*/
|
||||
outputlist_insert(&padblock_desc);
|
||||
|
||||
/* The next step is to go through the directory tree and assign extent
|
||||
numbers for all of the directories */
|
||||
/*
|
||||
* PVD for disc.
|
||||
*/
|
||||
outputlist_insert(&voldesc_desc);
|
||||
|
||||
assign_directory_addresses(root);
|
||||
/*
|
||||
* SVD for El Torito. MUST be immediately after the PVD!
|
||||
*/
|
||||
if( use_eltorito)
|
||||
{
|
||||
outputlist_insert(&torito_desc);
|
||||
}
|
||||
|
||||
if(extension_record) {
|
||||
struct directory_entry * s_entry;
|
||||
extension_record_extent = last_extent++;
|
||||
s_entry = root->contents;
|
||||
set_733((char *) s_entry->rr_attributes + s_entry->rr_attr_size - 24,
|
||||
extension_record_extent);
|
||||
set_733((char *) s_entry->rr_attributes + s_entry->rr_attr_size - 8,
|
||||
extension_record_size);
|
||||
};
|
||||
/*
|
||||
* SVD for Joliet.
|
||||
*/
|
||||
if( use_Joliet)
|
||||
{
|
||||
outputlist_insert(&joliet_desc);
|
||||
}
|
||||
|
||||
if (use_RockRidge && reloc_dir)
|
||||
finish_cl_pl_entries();
|
||||
/*
|
||||
* Finally the last volume desctiptor.
|
||||
*/
|
||||
outputlist_insert(&end_vol);
|
||||
|
||||
/* Now we generate the path tables that are used by DOS to improve directory
|
||||
access times. */
|
||||
generate_path_tables();
|
||||
|
||||
/* Generate root record for volume descriptor. */
|
||||
generate_root_record();
|
||||
outputlist_insert(&pathtable_desc);
|
||||
if( use_Joliet)
|
||||
{
|
||||
outputlist_insert(&jpathtable_desc);
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
dump_tree(root);
|
||||
outputlist_insert(&dirtree_desc);
|
||||
if( use_Joliet)
|
||||
{
|
||||
outputlist_insert(&jdirtree_desc);
|
||||
}
|
||||
|
||||
outputlist_insert(&dirtree_clean);
|
||||
|
||||
if(extension_record)
|
||||
{
|
||||
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;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
iso_write(discimage);
|
||||
/*
|
||||
* 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
|
||||
fprintf(stderr,"Max brk space used %x\n",
|
||||
(unsigned int)(((unsigned long)sbrk(0)) - mem_start));
|
||||
fprintf(stderr,"Max brk space used %x\n",
|
||||
(unsigned int)(((unsigned long)sbrk(0)) - mem_start));
|
||||
#endif
|
||||
fprintf(stderr,"%d extents written (%d Mb)\n", last_extent, last_extent >> 9);
|
||||
fprintf(stderr,"%d extents written (%d Mb)\n", last_extent, last_extent >> 9);
|
||||
}
|
||||
|
||||
#ifdef VMS
|
||||
return 1;
|
||||
#else
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue