From 1a433ecbaca7a0914efe05e00c1aa024cd464646 Mon Sep 17 00:00:00 2001 From: Packit Date: Sep 17 2020 17:27:52 +0000 Subject: Apply patch cdrkit-1.1.9-efi-boot.patch patch_name: cdrkit-1.1.9-efi-boot.patch present_in_specfile: true --- diff --git a/doc/icedax/tracknames.pl b/doc/icedax/tracknames.pl old mode 100755 new mode 100644 index 09f0fcf..801b89e --- a/doc/icedax/tracknames.pl +++ b/doc/icedax/tracknames.pl @@ -1,4 +1,4 @@ -#!/usr/local/bin/perl +#!/usr/bin/perl # A quick perl hack to get rename files pulled in with icedax. # by billo@billo.com # diff --git a/doc/icedax/tracknames.pl.efi b/doc/icedax/tracknames.pl.efi new file mode 100755 index 0000000..09f0fcf --- /dev/null +++ b/doc/icedax/tracknames.pl.efi @@ -0,0 +1,245 @@ +#!/usr/local/bin/perl +# A quick perl hack to get rename files pulled in with icedax. +# by billo@billo.com +# +use Socket; +use IO::Handle; +use Env qw(USER); +use strict; +no strict 'subs'; # can't get it to stop complaining about SOCK + +my $state = "header"; + +my $global_album = "Artist / Title"; +my $global_title = "Title"; +my $global_artist = "Artist"; +my @global_tracks = ("") x 100; +my $global_ntracks = 0; + +my @track_offsets = (); +my $disc_id = 0; +my $disc_time = 0; + + +if ($#ARGV != 1) +{ + print "usage: cddbhack.pl CDDBHOST PORT < audio.cddb\n"; + exit 0; +} + +while () +{ + if ($state eq "header") + { + if (/#\s[\s]*(\d[\d]*)$/) + { + push @track_offsets, $1; + } elsif (/#\s[\s]*Disc length:\s(\d[\d]*)/) { + $disc_time = $1; + $state = "discid"; + } + } elsif ($state eq "discid") + { + if (/DISCID=(\w[\w]*)/) + { + $disc_id = $1; + last; + } + } +} + +my $query_string = "cddb query $disc_id " . ($#track_offsets + 1); +foreach my $offset (@track_offsets) +{ + $query_string .= " $offset"; +} +$query_string .= " $disc_time"; + +print "$query_string\n"; + +my $host = $ARGV[0]; +my $port = $ARGV[1]; + +my $iaddr = inet_aton($host); +my $paddr = sockaddr_in($port, $iaddr); + + +socket(SOCK, AF_INET, SOCK_STREAM, getprotobyname('tcp')) or die "socket: $!"; + +connect(SOCK, $paddr) or die "connect: $!"; + +autoflush SOCK 1; + +print "Connected.\n"; + +my ($status, $result) = &resp(\*SOCK); + +if (int($status) != 201) +{ + print "Unexpected status.\n"; + close(\*SOCK); + exit 0; +} + +$host = `hostname`; + +$host =~ s/\n//g; + +&cmd(\*SOCK, "cddb hello $USER $host billo-scan 0.1"); +($status, $result) = &resp(\*SOCK); +if (int($status) != 200) +{ + print "Unexpected status.\n"; + close(\*SOCK); + exit 0; +} + +&cmd(\*SOCK, "$query_string"); +($status, $result) = &resp(\*SOCK); +if (int($status) != 200) +{ + print "Unexpected status.\n"; + close(\*SOCK); + exit 0; +} + +my ($ignore, $cat, $id, @rest) = split (" ", $result); + + + +my $read_string = "cddb read $cat $id"; + +&cmd(\*SOCK, $read_string); +&resp(\*SOCK); +while () +{ + if (/^\./) + { + # print $_; + # print "last line\n"; + last; + } else { + &process($_); + # print $_; + } +} + +&cmd(\*SOCK, "quit"); +&resp(\*SOCK); + +close(\*SOCK); + +&rename; + +exit 0; + +sub cmd +{ + my ($S, $cmd) = @_; + + print "$cmd\n"; + print $S "$cmd\r\n"; +} + +sub resp +{ + my ($S) = @_; + my ($code, $message); + while (<$S>) + { + if (/^(\d[\d]*)\s.*/) + { + # print "\n$1\n"; + print "$_\n"; + $code = $1; + $message = $_; + last; + } + sleep(1); + } + my @return_array = ($code, $message); + return @return_array; +} + +sub process +{ + my ($line) = @_; + + $_ = $line; + if (/^DTITLE=(.*)$/) + { + $global_album = $1; + $_ = $global_album; + if (m/([^\/][^\/]*)\s\/\s([^\/][^\/\n\r]*)/) + { + $global_artist = $1; + $global_title = $2; + } + print "$global_album\n"; + print "$global_title\n"; + print "$global_artist\n"; + return; + } + if (/^TTITLE(\d[\d]*)=(.*)$/) + { + my $track = $1 + 1; + if ($track > $global_ntracks) + { + $global_ntracks = $track; + } + $global_tracks[$track] = sprintf ("%s-%02d-%s", $global_title, + $track, $2); + $global_tracks[$track] =~ s/\s$//g; + $global_tracks[$track] =~ s/'//g; + $global_tracks[$track] =~ s/\s/_/g; + $global_tracks[$track] =~ s/:/_/g; + $global_tracks[$track] =~ s/\?//g; + $global_tracks[$track] =~ s/\*//g; + $global_tracks[$track] =~ s/\\/_/g; + $global_tracks[$track] =~ s/\s/_/g; + $global_tracks[$track] =~ s/\//_/g; + print "Track match " . $global_tracks[$track] . "\n"; + } +} + +sub rename +{ + my $i = 1; + + for ($i = 1; $i <= $global_ntracks; $i++) + { + my $track_name = $global_tracks[$i]; + if ($track_name ne "") + { + my $file_name = sprintf("audio_%02d.wav", $i); + my $new_file_name = sprintf("$track_name.wav", $i); + + my $mv_cmd = "mv '" . $file_name . "' '" + . $new_file_name . "'"; + print "$mv_cmd\n"; + `echo $mv_cmd >> rename.sh`; + } + } +} + +sub unrename +{ + my $i = 1; + + for ($i = 1; $i <= $global_ntracks; $i++) + { + my $track_name = $global_tracks[$i]; + if ($track_name ne "") + { + my $file_name = sprintf("$track_name.wav", $i); + my $new_file_name = sprintf("audio_%02d.wav", $i); + + my $mv_cmd = "mv '" . $file_name . "' '" + . $new_file_name . "'"; + print "$mv_cmd\n"; + `echo $mv_cmd >> unrename.sh`; + } + } +} + + diff --git a/genisoimage/eltorito.c b/genisoimage/eltorito.c index b97bdf1..475b3c2 100644 --- a/genisoimage/eltorito.c +++ b/genisoimage/eltorito.c @@ -59,7 +59,7 @@ static void get_torito_desc(struct eltorito_boot_descriptor *boot_desc); static void fill_boot_desc(struct eltorito_defaultboot_entry *boot_desc_entry, struct eltorito_boot_entry_info *boot_entry); void get_boot_entry(void); -void new_boot_entry(void); +void new_boot_entry(); static int tvd_write(FILE *outfile); @@ -283,6 +283,7 @@ get_torito_desc(struct eltorito_boot_descriptor *boot_desc) int i; int offset; struct eltorito_defaultboot_entry boot_desc_record; + struct eltorito_sectionheader_entry section_header; memset(boot_desc, 0, sizeof (*boot_desc)); boot_desc->type[0] = 0; @@ -317,7 +318,7 @@ get_torito_desc(struct eltorito_boot_descriptor *boot_desc) */ memset(&valid_desc, 0, sizeof (valid_desc)); valid_desc.headerid[0] = 1; - valid_desc.arch[0] = EL_TORITO_ARCH_x86; + valid_desc.arch[0] = first_boot_entry->arch; /* * we'll shove start of publisher id into id field, @@ -347,10 +348,53 @@ get_torito_desc(struct eltorito_boot_descriptor *boot_desc) /* now write it to the virtual boot catalog */ memcpy(de2->table, &valid_desc, 32); - for (current_boot_entry = first_boot_entry, offset = sizeof (valid_desc); - current_boot_entry != NULL; - current_boot_entry = current_boot_entry->next, - offset += sizeof (boot_desc_record)) { + /* Fill the first entry, since it's special and already has the + * matching header via the validation header... */ + offset = sizeof (valid_desc); + current_boot_entry = first_boot_entry; + + if (offset >= SECTOR_SIZE) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Too many El Torito boot entries\n"); +#else + fprintf(stderr, "Too many El Torito boot entries\n"); + exit(1); +#endif + } + fill_boot_desc(&boot_desc_record, current_boot_entry); + memcpy(de2->table + offset, &boot_desc_record, + sizeof (boot_desc_record)); + + offset += sizeof(boot_desc_record); + + for (current_boot_entry = current_boot_entry->next; + current_boot_entry != NULL; + current_boot_entry = current_boot_entry->next) { + struct eltorito_sectionheader_entry section_header; + + if (offset >= SECTOR_SIZE) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Too many El Torito boot entries\n"); +#else + fprintf(stderr, + "Too many El Torito boot entries\n"); + exit(1); +#endif + } + + memset(§ion_header, '\0', sizeof(section_header)); + if (current_boot_entry->next) + section_header.headerid[0] = EL_TORITO_SECTION_HEADER; + else + section_header.headerid[0] = EL_TORITO_LAST_SECTION_HEADER; + + section_header.arch[0] = current_boot_entry->arch; + set_721(section_header.num_entries, 1); + + memcpy(de2->table + offset, §ion_header, + sizeof(section_header)); + offset += sizeof(section_header); if (offset >= SECTOR_SIZE) { #ifdef USE_LIBSCHILY @@ -365,6 +409,8 @@ get_torito_desc(struct eltorito_boot_descriptor *boot_desc) fill_boot_desc(&boot_desc_record, current_boot_entry); memcpy(de2->table + offset, &boot_desc_record, sizeof (boot_desc_record)); + offset += sizeof (boot_desc_record); + } }/* get_torito_desc(... */ diff --git a/genisoimage/eltorito.c.efi b/genisoimage/eltorito.c.efi new file mode 100644 index 0000000..b97bdf1 --- /dev/null +++ b/genisoimage/eltorito.c.efi @@ -0,0 +1,716 @@ +/* + * 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. + * + */ + +/* @(#)eltorito.c 1.33 05/02/27 joerg */ +/* + * Program eltorito.c - Handle El Torito specific extensions to iso9660. + * + * + * Written by Michael Fulbright (1996). + * + * Copyright 1996 RedHat Software, Incorporated + * Copyright (c) 1999-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. + */ + +#include +#include "genisoimage.h" +#include +#include +#include +#include "match.h" +#include "diskmbr.h" +#include "bootinfo.h" +#include + +#undef MIN +#define MIN(a, b) (((a) < (b))? (a): (b)) + +static struct eltorito_validation_entry valid_desc; +static struct eltorito_boot_descriptor gboot_desc; +static struct disk_master_boot_record disk_mbr; +static unsigned int bcat_de_flags; + +void init_boot_catalog(const char *path); +void insert_boot_cat(void); +static void get_torito_desc(struct eltorito_boot_descriptor *boot_desc); +static void fill_boot_desc(struct eltorito_defaultboot_entry *boot_desc_entry, + struct eltorito_boot_entry_info *boot_entry); +void get_boot_entry(void); +void new_boot_entry(void); +static int tvd_write(FILE *outfile); + + +static char *bootcat_path; /* filename of boot catalog */ +/* + * Make sure any existing boot catalog is excluded + */ +void +init_boot_catalog(const char *path) +{ +#ifdef SORTING + struct eltorito_boot_entry_info * cbe; + + for (cbe = first_boot_entry; + cbe != NULL; + cbe = cbe->next) { + char *p; + + if (cbe->boot_image == NULL) + comerrno(EX_BAD, "Missing boot image name, use -eltorito-boot option.\n"); + p = (char *) e_malloc(strlen(cbe->boot_image) + strlen(path) + 2); + strcpy(p, path); + if (p[strlen(p) - 1] != '/') { + strcat(p, "/"); + } + strcat(p, cbe->boot_image); + add_sort_match(p, sort_matches(p, 1)); + free(p); + } +#endif + bootcat_path = (char *) e_malloc(strlen(boot_catalog) + strlen(path) + 2); + strcpy(bootcat_path, path); + if (bootcat_path[strlen(bootcat_path) - 1] != '/') { + strcat(bootcat_path, "/"); + } + strcat(bootcat_path, boot_catalog); + + /* + * we are going to create a virtual catalog file + * - so make sure any existing is excluded + */ + add_match(bootcat_path); + + /* flag the file as a memory file */ + bcat_de_flags = MEMORY_FILE; + + /* find out if we want to "hide" this file */ + if (i_matches(boot_catalog) || i_matches(bootcat_path)) + bcat_de_flags |= INHIBIT_ISO9660_ENTRY; + + if (j_matches(boot_catalog) || j_matches(bootcat_path)) + bcat_de_flags |= INHIBIT_JOLIET_ENTRY; + +}/* init_boot_catalog(... */ + +/* + * Create a boot catalog file in memory - genisoimage already uses this type of + * file for the TRANS.TBL files. Therefore the boot catalog is set up in + * similar way + */ +void +insert_boot_cat() +{ + struct directory_entry *de; + struct directory_entry *s_entry; + char *p1; + char *p2; + char *p3; + struct directory *this_dir; + struct directory *dir; + char *buffer; + + init_fstatbuf(); + + buffer = (char *) e_malloc(SECTOR_SIZE); + memset(buffer, 0, SECTOR_SIZE); + + /* + * try to find the directory that will contain the boot.cat file + * - not very neat, but I can't think of a better way + */ + p1 = strdup(boot_catalog); + + /* get dirname (p1) and basename (p2) of boot.cat */ + if ((p2 = strrchr(p1, '/')) != NULL) { + *p2 = '\0'; + p2++; + + /* find the dirname directory entry */ + de = search_tree_file(root, p1); + if (!de) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Uh oh, I cant find the boot catalog directory '%s'!\n", + p1); +#else + fprintf(stderr, + "Uh oh, I cant find the boot catalog directory '%s'!\n", + p1); + exit(1); +#endif + } + this_dir = 0; + + /* get the basename (p3) of the directory */ + if ((p3 = strrchr(p1, '/')) != NULL) + p3++; + else + p3 = p1; + + /* find the correct sub-directory entry */ + for (dir = de->filedir->subdir; dir; dir = dir->next) + if (!(strcmp(dir->de_name, p3))) + this_dir = dir; + + if (this_dir == 0) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Uh oh, I cant find the boot catalog directory '%s'!\n", + p3); +#else + fprintf(stderr, + "Uh oh, I cant find the boot catalog directory '%s'!\n", + p3); + exit(1); +#endif + } + } else { + /* boot.cat is in the root directory */ + this_dir = root; + p2 = p1; + } + + /* + * make a directory entry in memory (using the same set up as for table + * entries + */ + s_entry = (struct directory_entry *) + e_malloc(sizeof (struct directory_entry)); + memset(s_entry, 0, sizeof (struct directory_entry)); + s_entry->next = this_dir->contents; + this_dir->contents = s_entry; + +#ifdef SORTING + /* inherit any sort weight from parent directory */ + s_entry->sort = this_dir->sort; + s_entry->sort += 2; + + /* see if this entry should have a new weighting */ + if (do_sort) { + s_entry->sort = sort_matches(bootcat_path, s_entry->sort); + } +#endif /* SORTING */ + + s_entry->isorec.flags[0] = ISO_FILE; + s_entry->priority = 32768; + iso9660_date(s_entry->isorec.date, fstatbuf.st_mtime); + s_entry->inode = TABLE_INODE; + s_entry->dev = (dev_t) UNCACHED_DEVICE; + set_723(s_entry->isorec.volume_sequence_number, + volume_sequence_number); + set_733((char *) s_entry->isorec.size, SECTOR_SIZE); + s_entry->size = SECTOR_SIZE; + s_entry->filedir = this_dir; + s_entry->name = strdup(p2); + iso9660_file_length(p2, s_entry, 0); + + /* flag file as necessary */ + + /* + * If the current directory is hidden, then hide this entry + */ + if (this_dir->dir_flags & INHIBIT_ISO9660_ENTRY) + bcat_de_flags |= INHIBIT_ISO9660_ENTRY; + if (this_dir->dir_flags & INHIBIT_JOLIET_ENTRY) + bcat_de_flags |= INHIBIT_JOLIET_ENTRY; + + s_entry->de_flags = bcat_de_flags; + + if ((use_XA || use_RockRidge) && + !(bcat_de_flags & INHIBIT_ISO9660_ENTRY)) { + fstatbuf.st_mode = 0444 | S_IFREG; + fstatbuf.st_nlink = 1; + generate_xa_rr_attributes("", + p2, s_entry, + &fstatbuf, &fstatbuf, 0); + } + /* + * memory files are stored at s_entry->table + * - but this is also used for each s_entry to generate + * TRANS.TBL entries. So if we are generating tables, + * store the TRANS.TBL data here for the moment + */ + if (generate_tables && !(bcat_de_flags & INHIBIT_ISO9660_ENTRY)) { + sprintf(buffer, "F\t%s\n", s_entry->name); + + /* copy the TRANS.TBL entry info and clear the buffer */ + s_entry->table = strdup(buffer); + memset(buffer, 0, SECTOR_SIZE); + + /* + * store the (empty) file data in the + * unused s_entry->whole_name element for the time being + * - this will be transferred to s_entry->table after any + * TRANS.TBL processing later + */ + s_entry->whole_name = buffer; + } else { + /* store the (empty) file data in the s_entry->table element */ + s_entry->table = buffer; + s_entry->whole_name = NULL; + } +} + +static void +get_torito_desc(struct eltorito_boot_descriptor *boot_desc) +{ + int checksum; + unsigned char *checksum_ptr; + struct directory_entry *de2; /* Boot catalog */ + int i; + int offset; + struct eltorito_defaultboot_entry boot_desc_record; + + memset(boot_desc, 0, sizeof (*boot_desc)); + boot_desc->type[0] = 0; + memcpy(boot_desc->id, ISO_STANDARD_ID, sizeof (ISO_STANDARD_ID)); + boot_desc->version[0] = 1; + + memcpy(boot_desc->system_id, EL_TORITO_ID, sizeof (EL_TORITO_ID)); + + /* + * search from root of iso fs to find boot catalog + * - we already know where the boot catalog is + * - we created it above - but lets search for it anyway + * - good sanity check! + */ + de2 = search_tree_file(root, boot_catalog); + if (!de2 || !(de2->de_flags & MEMORY_FILE)) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Uh oh, I cant find the boot catalog '%s'!\n", + boot_catalog); +#else + fprintf(stderr, "Uh oh, I cant find the boot catalog '%s'!\n", + boot_catalog); + exit(1); +#endif + } + set_731(boot_desc->bootcat_ptr, + (unsigned int) get_733(de2->isorec.extent)); + + /* + * we have the boot image, so write boot catalog information + * Next we write out the primary descriptor for the disc + */ + memset(&valid_desc, 0, sizeof (valid_desc)); + valid_desc.headerid[0] = 1; + valid_desc.arch[0] = EL_TORITO_ARCH_x86; + + /* + * we'll shove start of publisher id into id field, + * may get truncated but who really reads this stuff! + */ + if (publisher) + memcpy_max(valid_desc.id, publisher, + MIN(23, strlen(publisher))); + + valid_desc.key1[0] = (char) 0x55; + valid_desc.key2[0] = (char) 0xAA; + + /* compute the checksum */ + checksum = 0; + checksum_ptr = (unsigned char *) &valid_desc; + /* Set checksum to 0 before computing checksum */ + set_721(valid_desc.cksum, 0); + for (i = 0; i < (int)sizeof (valid_desc); i += 2) { + checksum += (unsigned int) checksum_ptr[i]; + checksum += ((unsigned int) checksum_ptr[i + 1]) * 256; + } + + /* now find out the real checksum */ + checksum = -checksum; + set_721(valid_desc.cksum, (unsigned int) checksum); + + /* now write it to the virtual boot catalog */ + memcpy(de2->table, &valid_desc, 32); + + for (current_boot_entry = first_boot_entry, offset = sizeof (valid_desc); + current_boot_entry != NULL; + current_boot_entry = current_boot_entry->next, + offset += sizeof (boot_desc_record)) { + + if (offset >= SECTOR_SIZE) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Too many El Torito boot entries\n"); +#else + fprintf(stderr, + "Too many El Torito boot entries\n"); + exit(1); +#endif + } + fill_boot_desc(&boot_desc_record, current_boot_entry); + memcpy(de2->table + offset, &boot_desc_record, + sizeof (boot_desc_record)); + } +}/* get_torito_desc(... */ + +static void +fill_boot_desc(struct eltorito_defaultboot_entry *boot_desc_entry, + struct eltorito_boot_entry_info *boot_entry) +{ + struct directory_entry *de; /* Boot file */ + int bootmbr; + int i; + int nsectors; + int geosec; + + if (!boot_desc_entry || !boot_entry) + return; + + /* now adjust boot catalog lets find boot image first */ + de = search_tree_file(root, boot_entry->boot_image); + if (!de) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Uh oh, I cant find the boot image '%s' !\n", + boot_entry->boot_image); +#else + fprintf(stderr, "Uh oh, I cant find the boot image '%s' !\n", + boot_entry->boot_image); + exit(1); +#endif + } + /* now make the initial/default entry for boot catalog */ + memset(boot_desc_entry, 0, sizeof (*boot_desc_entry)); + boot_desc_entry->boot_id[0] = (char) boot_entry->not_bootable ? + EL_TORITO_NOT_BOOTABLE : EL_TORITO_BOOTABLE; + + /* use default BIOS loadpnt */ + set_721(boot_desc_entry->loadseg, boot_entry->load_addr); + + /* + * figure out size of boot image in 512-byte sectors. + * However, round up to the nearest integral CD (2048-byte) sector. + * This is only used for no-emulation booting. + */ + nsectors = boot_entry->load_size ? boot_entry->load_size : + ISO_BLOCKS(de->size) * (SECTOR_SIZE/512); + + if (verbose > 0) { + fprintf(stderr, + "Size of boot image is %d sectors -> ", nsectors); + } + + if (boot_entry->hard_disk_boot) { + /* sanity test hard disk boot image */ + boot_desc_entry->boot_media[0] = EL_TORITO_MEDIA_HD; + if (verbose > 0) + fprintf(stderr, "Emulating a hard disk\n"); + + /* read MBR */ + bootmbr = open(de->whole_name, O_RDONLY | O_BINARY); + if (bootmbr == -1) { +#ifdef USE_LIBSCHILY + comerr("Error opening boot image '%s' for read.\n", + de->whole_name); +#else + fprintf(stderr, + "Error opening boot image '%s' for read.\n", + de->whole_name); + perror(""); + exit(1); +#endif + } + if (read(bootmbr, &disk_mbr, sizeof (disk_mbr)) != + sizeof (disk_mbr)) { +#ifdef USE_LIBSCHILY + comerr("Error reading MBR from boot image '%s'.\n", + de->whole_name); +#else + fprintf(stderr, + "Error reading MBR from boot image '%s'.\n", + de->whole_name); + exit(1); +#endif + } + close(bootmbr); + if (la_to_u_2_byte(disk_mbr.magic) != MBR_MAGIC) { +#ifdef USE_LIBSCHILY + errmsgno(EX_BAD, + "Warning: boot image '%s' MBR is not a boot sector.\n", + de->whole_name); +#else + fprintf(stderr, + "Warning: boot image '%s' MBR is not a boot sector.\n", + de->whole_name); +#endif + } + /* find partition type */ + boot_desc_entry->sys_type[0] = PARTITION_UNUSED; + for (i = 0; i < PARTITION_COUNT; ++i) { + int s_cyl_sec; + int e_cyl_sec; + + s_cyl_sec = + la_to_u_2_byte(disk_mbr.partition[i].s_cyl_sec); + e_cyl_sec = + la_to_u_2_byte(disk_mbr.partition[i].e_cyl_sec); + + if (disk_mbr.partition[i].type != PARTITION_UNUSED) { + if (boot_desc_entry->sys_type[0] != + PARTITION_UNUSED) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Boot image '%s' has multiple partitions.\n", + de->whole_name); +#else + fprintf(stderr, + "Boot image '%s' has multiple partitions.\n", + de->whole_name); + exit(1); +#endif + } + boot_desc_entry->sys_type[0] = + disk_mbr.partition[i].type; + + /* a few simple sanity warnings */ + if (!boot_entry->not_bootable && + disk_mbr.partition[i].status != + PARTITION_ACTIVE) { + fprintf(stderr, + "Warning: partition not marked active.\n"); + } + if (MBR_CYLINDER(s_cyl_sec) != 0 || + disk_mbr.partition[i].s_head != 1 || + MBR_SECTOR(s_cyl_sec != 1)) { + fprintf(stderr, + "Warning: partition does not start at 0/1/1.\n"); + } + geosec = (MBR_CYLINDER(e_cyl_sec) + 1) * + (disk_mbr.partition[i].e_head + 1) * + MBR_SECTOR(e_cyl_sec); + if (geosec != nsectors) { + fprintf(stderr, + "Warning: image size does not match geometry (%d)\n", + geosec); + } +#ifdef DEBUG_TORITO + fprintf(stderr, "Partition start %u/%u/%u\n", + MBR_CYLINDER(s_cyl_sec), + disk_mbr.partition[i].s_head, + MBR_SECTOR(s_cyl_sec)); + fprintf(stderr, "Partition end %u/%u/%u\n", + MBR_CYLINDER(e_cyl_sec), + disk_mbr.partition[i].e_head, + MBR_SECTOR(e_cyl_sec)); +#endif + } + } + if (boot_desc_entry->sys_type[0] == PARTITION_UNUSED) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Boot image '%s' has no partitions.\n", + de->whole_name); +#else + fprintf(stderr, + "Boot image '%s' has no partitions.\n", + de->whole_name); + exit(1); +#endif + } +#ifdef DEBUG_TORITO + fprintf(stderr, "Partition type %u\n", + boot_desc_entry->sys_type[0]); +#endif + /* load single boot sector, in this case the MBR */ + nsectors = 1; + + } else if (boot_entry->no_emul_boot) { + /* + * no emulation is a simple image boot of all the sectors + * in the boot image + */ + boot_desc_entry->boot_media[0] = EL_TORITO_MEDIA_NOEMUL; + if (verbose > 0) + fprintf(stderr, "No emulation\n"); + + } else { + /* choose size of emulated floppy based on boot image size */ + if (nsectors == 2880) { + boot_desc_entry->boot_media[0] = EL_TORITO_MEDIA_144FLOP; + if (verbose > 0) + fprintf(stderr, "Emulating a 1440 kB floppy\n"); + + } else if (nsectors == 5760) { + boot_desc_entry->boot_media[0] = EL_TORITO_MEDIA_288FLOP; + if (verbose > 0) + fprintf(stderr, "Emulating a 2880 kB floppy\n"); + + } else if (nsectors == 2400) { + boot_desc_entry->boot_media[0] = EL_TORITO_MEDIA_12FLOP; + if (verbose > 0) + fprintf(stderr, "Emulating a 1200 kB floppy\n"); + + } else { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Error - boot image '%s' has not an allowable size.\n", + de->whole_name); +#else + fprintf(stderr, + "Error - boot image '%s' has not an allowable size.\n", + de->whole_name); + exit(1); +#endif + } + + /* load single boot sector for floppies */ + nsectors = 1; + } + + /* fill in boot image details */ +#ifdef DEBUG_TORITO + fprintf(stderr, "Boot %u sectors\n", nsectors); + fprintf(stderr, "Extent of boot images is %d\n", + get_733(de->isorec.extent)); +#endif + set_721(boot_desc_entry->nsect, (unsigned int) nsectors); + set_731(boot_desc_entry->bootoff, + (unsigned int) get_733(de->isorec.extent)); + + + /* If the user has asked for it, patch the boot image */ + if (boot_entry->boot_info_table) { + int bootimage; + unsigned int bi_checksum; + unsigned int total_len; + static char csum_buffer[SECTOR_SIZE]; + int len; + struct genisoimage_boot_info bi_table; + bootimage = open(de->whole_name, O_RDWR | O_BINARY); + if (bootimage == -1) { +#ifdef USE_LIBSCHILY + comerr( + "Error opening boot image file '%s' for update.\n", + de->whole_name); +#else + fprintf(stderr, + "Error opening boot image file '%s' for update.\n", + de->whole_name); + perror(""); + exit(1); +#endif + } + /* Compute checksum of boot image, sans 64 bytes */ + total_len = 0; + bi_checksum = 0; + while ((len = read(bootimage, csum_buffer, SECTOR_SIZE)) > 0) { + if (total_len & 3) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Odd alignment at non-end-of-file in boot image '%s'.\n", + de->whole_name); +#else + fprintf(stderr, + "Odd alignment at non-end-of-file in boot image '%s'.\n", + de->whole_name); + exit(1); +#endif + } + if (total_len < 64) + memset(csum_buffer, 0, 64 - total_len); + if (len < SECTOR_SIZE) + memset(csum_buffer + len, 0, SECTOR_SIZE-len); + for (i = 0; i < SECTOR_SIZE; i += 4) + bi_checksum += get_731(&csum_buffer[i]); + total_len += len; + } + + if (total_len != de->size) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, + "Boot image file '%s' changed underneath us!\n", + de->whole_name); +#else + fprintf(stderr, + "Boot image file '%s' changed underneath us!\n", + de->whole_name); + exit(1); +#endif + } + /* End of file, set position to byte 8 */ + lseek(bootimage, (off_t)8, SEEK_SET); + memset(&bi_table, 0, sizeof (bi_table)); + /* Is it always safe to assume PVD is at session_start+16? */ + set_731(bi_table.bi_pvd, session_start + 16); + set_731(bi_table.bi_file, de->starting_block); + set_731(bi_table.bi_length, de->size); + set_731(bi_table.bi_csum, bi_checksum); + + do{int ret;ret=write(bootimage, &bi_table, sizeof (bi_table));}while(0); /* FIXME: check return value */ + close(bootimage); + } +}/* fill_boot_desc(... */ + +void +get_boot_entry() +{ + if (current_boot_entry) + return; + + current_boot_entry = (struct eltorito_boot_entry_info *) + e_malloc(sizeof (struct eltorito_boot_entry_info)); + memset(current_boot_entry, 0, sizeof (*current_boot_entry)); + + if (!first_boot_entry) { + first_boot_entry = current_boot_entry; + last_boot_entry = current_boot_entry; + } else { + last_boot_entry->next = current_boot_entry; + last_boot_entry = current_boot_entry; + } +} + +void +new_boot_entry() +{ + current_boot_entry = NULL; +} + +/* + * Function to write the EVD for the disc. + */ +static int +tvd_write(FILE *outfile) +{ + /* check the boot image is not NULL */ + if (!boot_image) { +#ifdef USE_LIBSCHILY + comerrno(EX_BAD, "No boot image specified.\n"); +#else + fprintf(stderr, "No boot image specified.\n"); + exit(1); +#endif + } + /* Next we write out the boot volume descriptor for the disc */ + get_torito_desc(&gboot_desc); + jtwrite(&gboot_desc, SECTOR_SIZE, 1, 0, FALSE); + xfwrite(&gboot_desc, SECTOR_SIZE, 1, outfile, 0, FALSE); + last_extent_written++; + return (0); +} + +struct output_fragment torito_desc = {NULL, oneblock_size, NULL, tvd_write, "Eltorito Volume Descriptor"}; diff --git a/genisoimage/genisoimage.c b/genisoimage/genisoimage.c index 46f0cb7..56ce303 100644 --- a/genisoimage/genisoimage.c +++ b/genisoimage/genisoimage.c @@ -47,6 +47,7 @@ #include #include "genisoimage.h" +#include "iso9660.h" #include #include #include @@ -526,6 +527,8 @@ static const struct ld_option ld_options[] = '\0', NULL, "Set debug flag", ONE_DASH}, {{"eltorito-boot", required_argument, NULL, 'b'}, 'b', "FILE", "Set El Torito boot image name", ONE_DASH}, + {{"efi-boot", required_argument, NULL, 'e'}, + 'e', "FILE", "Set EFI 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'}, @@ -1535,6 +1538,7 @@ int main(int argc, char *argv[]) all_files = 0; break; case 'b': + case 'e': do_sort++; /* We sort bootcat/botimage */ use_eltorito++; boot_image = optarg; /* pathname of the boot image */ @@ -1550,6 +1554,10 @@ int main(int argc, char *argv[]) #endif } get_boot_entry(); + if (c == 'e') + current_boot_entry->arch = EL_TORITO_ARCH_EFI; + else + current_boot_entry->arch = EL_TORITO_ARCH_x86; current_boot_entry->boot_image = boot_image; break; case OPTION_ALT_BOOT: diff --git a/genisoimage/genisoimage.c.efi b/genisoimage/genisoimage.c.efi new file mode 100644 index 0000000..46f0cb7 --- /dev/null +++ b/genisoimage/genisoimage.c.efi @@ -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 +*/ +/* @(#)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 +#include "genisoimage.h" +#include +#include +#include +#include +#include "match.h" +#include "exclude.h" +#include /* For UNICODE translation */ +#include +#ifdef UDF +#include "udf.h" +#endif + +#ifdef NEED_O_BINARY +#include /* for setmode() prototype */ +#endif + +#ifdef HAVE_GETOPT_H +#include +#else +#include "getopt.h" +extern int optind; +extern char *optarg; +#endif + +#ifdef VMS +#include "vms.h" +#endif + +#ifdef no_more_needed +#ifdef __NetBSD__ +#include +#endif +#endif /* no_more_needed */ + +#ifdef USE_ICONV +#include +#include +#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", ©right}, + {"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); +} diff --git a/genisoimage/genisoimage.h b/genisoimage/genisoimage.h index bbedfb0..76e5e21 100644 --- a/genisoimage/genisoimage.h +++ b/genisoimage/genisoimage.h @@ -293,6 +293,7 @@ struct deferred_write { struct eltorito_boot_entry_info { struct eltorito_boot_entry_info *next; char *boot_image; + char arch; int not_bootable; int no_emul_boot; int hard_disk_boot; diff --git a/genisoimage/genisoimage.h.efi b/genisoimage/genisoimage.h.efi new file mode 100644 index 0000000..bbedfb0 --- /dev/null +++ b/genisoimage/genisoimage.h.efi @@ -0,0 +1,802 @@ +/* + * 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. + * + */ + +/* @(#)genisoimage.h 1.95 05/05/01 joerg */ +/* + * Header file genisoimage.h - assorted structure definitions and typecasts. + * + * Written by Eric Youngdale (1993). + * + * Copyright 1993 Yggdrasil Computing, Incorporated + * Copyright (c) 1999,2000-2003 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 23/2/2000 */ + +#define APPID_DEFAULT "GENISOIMAGE ISO 9660/HFS FILESYSTEM CREATOR (C) 1993 E.YOUNGDALE (C) 1997-2006 J.PEARSON/J.SCHILLING (C) 2006-2007 CDRKIT TEAM" + + +#include /* Must be before stdio.h for LARGEFILE support */ +#include +#include +#include +#include /* Needed for for LARGEFILE support */ +#include +#include +#include +#include +#include +#include "scsi.h" +#ifdef JIGDO_TEMPLATE +#include "jte.h" +#endif + +#ifdef DVD_VIDEO +#ifndef UDF +#define UDF +#endif +#endif + +/*#if _LFS_LARGEFILE*/ +#ifdef HAVE_LARGEFILES +/* + * XXX Hack until fseeko()/ftello() are available everywhere or until + * XXX we know a secure way to let autoconf ckeck for fseeko()/ftello() + * XXX without defining FILE_OFFSETBITS to 64 in confdefs.h + */ +# define fseek fseeko +# define ftell ftello +#endif + +#ifndef HAVE_LSTAT +#ifndef VMS +#define lstat stat +#endif +#endif + +#include "iso9660.h" +#include "defaults.h" +#include + +extern struct unls_table *in_nls; /* input UNICODE conversion table */ +extern struct unls_table *out_nls; /* output UNICODE conversion table */ +extern struct unls_table *hfs_inls; /* input HFS UNICODE conversion table */ +extern struct unls_table *hfs_onls; /* output HFS UNICODE conversion table */ + +#ifdef APPLE_HYB +#include "mactypes.h" +#include "hfs.h" + +struct hfs_info { + unsigned char finderinfo[32]; + char name[HFS_MAX_FLEN + 1]; + /* should have fields for dates here as well */ + char *keyname; + struct hfs_info *next; +}; + +#endif /* APPLE_HYB */ + +struct directory_entry { + struct directory_entry *next; + struct directory_entry *jnext; + struct iso_directory_record isorec; + unsigned int starting_block; + off_t size; + unsigned short priority; + unsigned char jreclen; /* Joliet record len */ + char *name; + char *table; + char *whole_name; + struct directory *filedir; + struct directory_entry *parent_rec; + unsigned int de_flags; + ino_t inode; /* Used in the hash table */ + dev_t dev; /* Used in the hash table */ + unsigned char *rr_attributes; + unsigned int rr_attr_size; + unsigned int total_rr_attr_size; + unsigned int got_rr_name; +#ifdef APPLE_HYB + struct directory_entry *assoc; /* entry has a resource fork */ + hfsdirent *hfs_ent; /* HFS parameters */ + off_t hfs_off; /* offset to real start of fork */ + int hfs_type; /* type of HFS Unix file */ +#endif /* APPLE_HYB */ +#ifdef SORTING + int sort; /* sort weight for entry */ +#endif /* SORTING */ +#ifdef UDF + int udf_file_entry_sector; /* also used as UDF unique ID */ +#endif + uint64_t realsize; +}; + +struct file_hash { + struct file_hash *next; + ino_t inode; /* Used in the hash table */ + dev_t dev; /* Used in the hash table */ + nlink_t nlink; /* Used to compute new link count */ + unsigned int starting_block; + off_t size; +#ifdef SORTING + struct directory_entry *de; +#endif /* SORTING */ +}; + + +/* + * This structure is used to control the output of fragments to the cdrom + * image. Everything that will be written to the output image will eventually + * go through this structure. There are two pieces - first is the sizing where + * we establish extent numbers for everything, and the second is when we actually + * generate the contents and write it to the output image. + * + * This makes it trivial to extend genisoimage to write special things in the image. + * All you need to do is hook an additional structure in the list, and the rest + * works like magic. + * + * The three passes each do the following: + * + * The 'size' pass determines the size of each component and assigns the extent number + * for that component. + * + * The 'generate' pass will adjust the contents and pointers as required now that extent + * numbers are assigned. In some cases, the contents of the record are also generated. + * + * The 'write' pass actually writes the data to the disc. + */ +struct output_fragment { + struct output_fragment *of_next; + int (*of_size)(int); + int (*of_generate)(void); + int (*of_write)(FILE *); + char *of_name; /* Textual description */ + unsigned int of_start_extent; /* For consist check */ +}; + +extern struct output_fragment *out_list; +extern struct output_fragment *out_tail; + +extern struct output_fragment startpad_desc; +extern struct output_fragment voldesc_desc; +extern struct output_fragment xvoldesc_desc; +extern struct output_fragment joliet_desc; +extern struct output_fragment torito_desc; +extern struct output_fragment end_vol; +extern struct output_fragment version_desc; +extern struct output_fragment pathtable_desc; +extern struct output_fragment jpathtable_desc; +extern struct output_fragment dirtree_desc; +extern struct output_fragment dirtree_clean; +extern struct output_fragment jdirtree_desc; +extern struct output_fragment extension_desc; +extern struct output_fragment files_desc; +extern struct output_fragment interpad_desc; +extern struct output_fragment endpad_desc; +extern struct output_fragment sunboot_desc; +extern struct output_fragment sunlabel_desc; +extern struct output_fragment genboot_desc; +extern struct output_fragment strfile_desc; +extern struct output_fragment strdir_desc; +extern struct output_fragment strpath_desc; +extern struct output_fragment alphaboot_desc; +extern struct output_fragment hppaboot_desc; +extern struct output_fragment alpha_hppa_boot_desc; +extern struct output_fragment mipsboot_desc; +extern struct output_fragment mipselboot_desc; + +#ifdef APPLE_HYB +extern struct output_fragment hfs_desc; + +#endif /* APPLE_HYB */ +#ifdef DVD_VIDEO +/* + * This structure holds the information necessary to create a valid + * DVD-Video image. Basically it's how much to pad the files so the + * file offsets described in the video_ts.ifo and vts_xx_0.ifo are + * the correct one in the image that we create. + */ +typedef struct { + int realsize_ifo; + int realsize_menu; + int realsize_bup; + int size_ifo; + int size_menu; + int size_title; + int size_bup; + int pad_ifo; + int pad_menu; + int pad_title; + int pad_bup; + int number_of_vob_files; + int realsize_vob[10]; +} title_set_t; + +typedef struct { + int num_titles; + title_set_t *title_set; +} title_set_info_t; +#endif /* DVD_VIDEO */ + +/* + * This structure describes one complete directory. It has pointers + * to other directories in the overall tree so that it is clear where + * this directory lives in the tree, and it also must contain pointers + * to the contents of the directory. Note that subdirectories of this + * directory exist twice in this stucture. Once in the subdir chain, + * and again in the contents chain. + */ +struct directory { + struct directory *next; /* Next directory at same level as this one */ + struct directory *subdir; /* First subdirectory in this directory */ + struct directory *parent; + struct directory_entry *contents; + struct directory_entry *jcontents; + struct directory_entry *self; + char *whole_name; /* Entire path */ + char *de_name; /* Entire path */ + unsigned int ce_bytes; /* Number of bytes of CE entries read */ + /* for this dir */ + unsigned int depth; + unsigned int size; + unsigned int extent; + unsigned int jsize; + unsigned int jextent; + unsigned int path_index; + unsigned int jpath_index; + unsigned short dir_flags; + unsigned short dir_nlink; +#ifdef APPLE_HYB + hfsdirent *hfs_ent; /* HFS parameters */ + struct hfs_info *hfs_info; /* list of info for all entries in dir */ +#endif /* APPLE_HYB */ +#ifdef SORTING + int sort; /* sort weight for child files */ +#endif /* SORTING */ +}; + +struct deferred_write { + struct deferred_write *next; + char *table; + unsigned int extent; + off_t size; + char *name; + struct directory_entry *s_entry; + unsigned int pad; + off_t off; +}; + +struct eltorito_boot_entry_info { + struct eltorito_boot_entry_info *next; + char *boot_image; + int not_bootable; + int no_emul_boot; + int hard_disk_boot; + int boot_info_table; + int load_size; + int load_addr; +}; + +extern int goof; +extern struct directory *root; +extern struct directory *reloc_dir; +extern unsigned int next_extent; +extern unsigned int last_extent; +extern unsigned int last_extent_written; +extern unsigned int session_start; + +extern unsigned int path_table_size; +extern unsigned int path_table[4]; +extern unsigned int path_blocks; +extern char *path_table_l; +extern char *path_table_m; + +extern unsigned int jpath_table_size; +extern unsigned int jpath_table[4]; +extern unsigned int jpath_blocks; +extern char *jpath_table_l; +extern char *jpath_table_m; + +extern struct iso_directory_record root_record; +extern struct iso_directory_record jroot_record; + +extern int check_oldnames; +extern int check_session; +extern int use_eltorito; +extern int hard_disk_boot; +extern int not_bootable; +extern int no_emul_boot; +extern int load_addr; +extern int load_size; +extern int boot_info_table; +extern int use_RockRidge; +extern int osecsize; +extern int use_XA; +extern int use_Joliet; +extern int rationalize; +extern int rationalize_uid; +extern int rationalize_gid; +extern int rationalize_filemode; +extern int rationalize_dirmode; +extern uid_t uid_to_use; +extern gid_t gid_to_use; +extern int filemode_to_use; +extern int dirmode_to_use; +extern int new_dir_mode; +extern int follow_links; +extern int cache_inodes; +extern int verbose; +extern int debug; +extern int gui; +extern int all_files; +extern int generate_tables; +extern int print_size; +extern int split_output; +extern int use_graft_ptrs; +extern int jhide_trans_tbl; +extern int hide_rr_moved; +extern int omit_period; +extern int omit_version_number; +extern int no_rr; +extern int transparent_compression; +extern Uint RR_relocation_depth; +extern int iso9660_level; +extern int iso9660_namelen; +extern int full_iso9660_filenames; +extern int relaxed_filenames; +extern int allow_lowercase; +extern int allow_multidot; +extern int iso_translate; +extern int allow_leading_dots; +extern int use_fileversion; +extern int split_SL_component; +extern int split_SL_field; +extern char *trans_tbl; +char *outfile; + +#define JMAX 64 /* maximum Joliet file name length (spec) */ +#define JLONGMAX 103 /* out of spec Joliet file name length */ +extern int jlen; /* selected maximum Joliet file name length */ + +#ifdef DVD_VIDEO +extern int dvd_video; +#endif /* DVD_VIDEO */ + + +#ifdef APPLE_HYB +extern int apple_hyb; /* create HFS hybrid */ +extern int apple_ext; /* use Apple extensions */ +extern int apple_both; /* common flag (for above) */ +extern int hfs_extra; /* extra ISO extents (hfs_ce_size) */ +extern hce_mem *hce; /* libhfs/genisoimage extras */ +extern int use_mac_name; /* use Mac name for ISO9660/Joliet/RR */ +extern int create_dt; /* create the Desktp files */ +extern char *hfs_boot_file; /* name of HFS boot file */ +extern char *magic_filename; /* magic file for CREATOR/TYPE matching */ +extern int hfs_last; /* order in which to process map/magic files */ +extern char *deftype; /* default Apple TYPE */ +extern char *defcreator; /* default Apple CREATOR */ +extern int gen_pt; /* generate HFS partition table */ +extern char *autoname; /* Autostart filename */ +extern int afe_size; /* Apple File Exchange block size */ +extern char *hfs_volume_id; /* HFS volume ID */ +extern int icon_pos; /* Keep Icon position */ +extern int hfs_lock; /* lock HFS volume (read-only) */ +extern char *hfs_bless; /* name of folder to 'bless' (System Folder) */ +extern char *hfs_parms; /* low level HFS parameters */ + +#define MAP_LAST 1 /* process magic then map file */ +#define MAG_LAST 2 /* process map then magic file */ + +#ifndef PREP_BOOT +#define PREP_BOOT +#endif /* PREP_BOOT */ + +#ifdef PREP_BOOT +extern char *prep_boot_image[4]; +extern int use_prep_boot; +extern int use_chrp_boot; + +#endif /* PREP_BOOT */ +#endif /* APPLE_HYB */ + +#ifdef SORTING +extern int do_sort; +#endif /* SORTING */ + +/* tree.c */ +extern int stat_filter(char *, struct stat *); +extern int lstat_filter(char *, struct stat *); +extern int sort_tree(struct directory *); +extern struct directory * +find_or_create_directory(struct directory *, const char *, + struct directory_entry *self, + int, + struct stat *stat_template); +extern void finish_cl_pl_entries(void); +extern int scan_directory_tree(struct directory *this_dir, char *path, + struct directory_entry *self); + +#ifdef APPLE_HYB +extern int insert_file_entry(struct directory *, char *, char *, int); +#else +extern int insert_file_entry(struct directory *, char *, char *); +#endif /* APPLE_HYB */ + +extern void generate_iso9660_directories(struct directory *, FILE *); +extern void dump_tree(struct directory * node); +extern struct directory_entry * +search_tree_file(struct directory * node, char *filename); +extern void update_nlink_field(struct directory * node); +extern void init_fstatbuf(void); +extern struct stat root_statbuf; +extern struct stat fstatbuf; + +/* eltorito.c */ +extern void init_boot_catalog(const char *path); +extern void insert_boot_cat(void); +extern void get_boot_entry(void); +extern void new_boot_entry(void); + +/* boot.c */ +extern void sparc_boot_label(char *label); +extern void sunx86_boot_label(char *label); +extern void scan_sparc_boot(char *files); +extern void scan_sunx86_boot(char *files); +extern int make_sun_label(void); +extern int make_sunx86_label(void); + +/* boot-alpha.c */ +extern int add_boot_alpha_filename(char *filename); + +/* boot-hppa.c */ +extern int add_boot_hppa_cmdline(char *cmdline); +extern int add_boot_hppa_kernel_32(char *filename); +extern int add_boot_hppa_kernel_64(char *filename); +extern int add_boot_hppa_bootloader(char *filename); +extern int add_boot_hppa_ramdisk(char *filename); + +/* boot-mips.c */ +extern int add_boot_mips_filename(char *filename); + +/* boot-mipsel.c */ +extern int add_boot_mipsel_filename(char *filename); + +/* rsync.c */ +extern unsigned long long rsync64(unsigned char *mem, size_t size); + +/* write.c */ +extern int get_731(char *); +extern int get_732(char *); +extern int get_733(char *); +extern int isonum_733(unsigned char *); +extern void set_723(char *, unsigned int); +extern void set_731(char *, unsigned int); +extern void set_721(char *, unsigned int); +extern void set_733(char *, unsigned int); +extern int sort_directory(struct directory_entry **, int); +extern void generate_one_directory(struct directory *, FILE *); +extern void memcpy_max(char *, char *, int); +extern int oneblock_size(int starting_extent); +extern struct iso_primary_descriptor vol_desc; +extern void xfwrite(void *buffer, int size, int count, FILE *file, int submode, + BOOL islast); +extern void set_732(char *pnt, unsigned int i); +extern void set_722(char *pnt, unsigned int i); +extern void outputlist_insert(struct output_fragment * frag); + +#ifdef APPLE_HYB +extern Ulong get_adj_size(int Csize); +extern int adj_size(int Csize, int start_extent, int extra); +extern void adj_size_other(struct directory * dpnt); +extern int insert_padding_file(int size); +extern int gen_mac_label(struct deferred_write *); + +#ifdef PREP_BOOT +extern void gen_prepboot_label(unsigned char *); + +#endif /* PREP_BOOT */ +#endif /* APPLE_HYB */ + +/* multi.c */ + +extern FILE *in_image; +extern int open_merge_image(char *path); +extern int close_merge_image(void); +extern struct iso_directory_record * +merge_isofs(char *path); +extern unsigned char *parse_xa(unsigned char *pnt, int *lenp, + struct directory_entry *dpnt); +extern int rr_flags(struct iso_directory_record *idr); +extern int merge_previous_session(struct directory *, + struct iso_directory_record *, + char *, char *); +extern int get_session_start(int *); + +/* joliet.c */ +#ifdef UDF +# ifdef USE_ICONV +extern size_t convert_to_unicode (unsigned char *buffer, + int size, char *source, struct unls_table *inls); +# else +extern void convert_to_unicode (unsigned char *buffer, + int size, char *source, struct unls_table *inls); +# endif +extern int joliet_strlen (const char *string, struct unls_table *inls); +#endif +extern unsigned char conv_charset(unsigned char, struct unls_table *, + struct unls_table *); +extern int joliet_sort_tree(struct directory * node); + +/* match.c */ +extern int matches(char *); +extern int add_match(char *); + +/* files.c */ +struct dirent *readdir_add_files(char **, char *, DIR *); + +/* name.c */ + +extern void iso9660_check(struct iso_directory_record *idr, + struct directory_entry *ndr); +extern int iso9660_file_length(const char *name, + struct directory_entry *sresult, int flag); + +/* various */ +extern int iso9660_date(char *, time_t); +extern void add_hash(struct directory_entry *); +extern struct file_hash *find_hash(dev_t, ino_t); + +extern void flush_hash(void); +extern void add_directory_hash(dev_t, ino_t); +extern struct file_hash *find_directory_hash(dev_t, ino_t); +extern void flush_file_hash(void); +extern int delete_file_hash(struct directory_entry *); +extern struct directory_entry *find_file_hash(char *); +extern void add_file_hash(struct directory_entry *); + +extern int generate_xa_rr_attributes(char *, char *, struct directory_entry *, + struct stat *, struct stat *, + int deep_flag); +extern char *generate_rr_extension_record(char *id, char *descriptor, + char *source, int *size); + +extern int check_prev_session(struct directory_entry **, int len, + struct directory_entry *, struct stat *, + struct stat *, struct directory_entry **); + +extern void match_cl_re_entries(void); +extern void finish_cl_pl_for_prev_session(void); +extern char *find_rr_attribute(unsigned char *pnt, int len, char *attr_type); + +#ifdef APPLE_HYB +/* volume.c */ +extern int make_mac_volume(struct directory * dpnt, int start_extent); +extern int write_fork(hfsfile * hfp, long tot); + +/* apple.c */ + +extern void del_hfs_info(struct hfs_info *); +extern int get_hfs_dir(char *, char *, struct directory_entry *); +extern int get_hfs_info(char *, char *, struct directory_entry *); +extern int get_hfs_rname(char *, char *, char *); +extern int hfs_exclude(char *); +extern void print_hfs_info(struct directory_entry *); +extern void hfs_init(char *, unsigned short, unsigned int); +extern void delete_rsrc_ent(struct directory_entry *); +extern void clean_hfs(void); +extern void perr(char *); +extern void set_root_info(char *); + +/* desktop.c */ + +extern int make_desktop(hfsvol *, int); + +/* mac_label.c */ + +#ifdef _MAC_LABEL_H +#ifdef PREP_BOOT +extern void gen_prepboot_label(MacLabel * mac_label); +#endif +extern int gen_mac_label(defer *); +#endif +extern int autostart(void); + +/* libfile */ + +extern char *get_magic_match(const char *); +extern void clean_magic(void); + +#endif /* APPLE_HYB */ + +extern char *extension_record; +extern int extension_record_extent; +extern int n_data_extents; + +/* + * These are a few goodies that can be specified on the command line, and are + * filled into the root record + */ +extern char *preparer; +extern char *publisher; +extern char *copyright; +extern char *biblio; +extern char *abstract; +extern char *appid; +extern char *volset_id; +extern char *system_id; +extern char *volume_id; +extern char *boot_catalog; +extern char *boot_image; +extern char *genboot_image; +extern int ucs_level; +extern int volume_set_size; +extern int volume_sequence_number; + +extern struct eltorito_boot_entry_info *first_boot_entry; +extern struct eltorito_boot_entry_info *last_boot_entry; +extern struct eltorito_boot_entry_info *current_boot_entry; + +extern char *findgequal(char *); +extern void *e_malloc(size_t); + +/* + * Note: always use these macros to avoid problems. + * + * ISO_ROUND_UP(X) may cause an integer overflow and thus give + * incorrect results. So avoid it if possible. + * + * ISO_BLOCKS(X) is overflow safe. Prefer this when ever it is possible. + */ +#define SECTOR_SIZE (2048) +#define ISO_ROUND_UP(X) (((X) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) +#define ISO_BLOCKS(X) (((X) / SECTOR_SIZE) + (((X)%SECTOR_SIZE)?1:0)) + +#define ROUND_UP(X, Y) (((X + (Y - 1)) / Y) * Y) + +#ifdef APPLE_HYB +/* + * ISO blocks == 2048, HFS blocks == 512 + */ +#define HFS_BLK_CONV (SECTOR_SIZE/HFS_BLOCKSZ) + +#define HFS_ROUND_UP(X) ISO_ROUND_UP(((X)*HFS_BLOCKSZ)) /* XXX ??? */ +#define HFS_BLOCKS(X) (ISO_BLOCKS(X) * HFS_BLK_CONV) + +#define USE_MAC_NAME(E) (use_mac_name && ((E)->hfs_ent != NULL) && (E)->hfs_type) +#endif /* APPLE_HYB */ + +/* + * Rock Ridge defines + */ +#define NEED_RE 1 /* Need Relocated Direcotry */ +#define NEED_PL 2 /* Need Parent link */ +#define NEED_CL 4 /* Need Child link */ +#define NEED_CE 8 /* Need Continuation Area */ +#define NEED_SP 16 /* Need SUSP record */ + +#define RR_FLAG_PX 1 /* POSIX attributes */ +#define RR_FLAG_PN 2 /* POSIX device number */ +#define RR_FLAG_SL 4 /* Symlink */ +#define RR_FLAG_NM 8 /* Alternate Name */ +#define RR_FLAG_CL 16 /* Child link */ +#define RR_FLAG_PL 32 /* Parent link */ +#define RR_FLAG_RE 64 /* Relocated Direcotry */ +#define RR_FLAG_TF 128 /* Time stamp */ + +#define RR_FLAG_SP 1024 /* SUSP record */ +#define RR_FLAG_AA 2048 /* Apple Signature record */ +#define RR_FLAG_XA 4096 /* XA signature record */ + +#define RR_FLAG_CE 8192 /* SUSP Continuation aerea */ +#define RR_FLAG_ER 16384 /* Extension record for RR signature */ +#define RR_FLAG_RR 32768 /* RR Signature in every file */ +#define RR_FLAG_ZF 65535 /* Linux compression extension */ + + +#define PREV_SESS_DEV (sizeof (dev_t) >= 4 ? 0x7ffffffd : 0x7ffd) +#define TABLE_INODE (sizeof (ino_t) >= 4 ? 0x7ffffffe : 0x7ffe) +#define UNCACHED_INODE (sizeof (ino_t) >= 4 ? 0x7fffffff : 0x7fff) +#define UNCACHED_DEVICE (sizeof (dev_t) >= 4 ? 0x7fffffff : 0x7fff) + +#ifdef VMS +#define STAT_INODE(X) (X.st_ino[0]) +#define PATH_SEPARATOR ']' +#define SPATH_SEPARATOR "" +#else +#define STAT_INODE(X) (X.st_ino) +#define PATH_SEPARATOR '/' +#define SPATH_SEPARATOR "/" +#endif + +/* + * When using multi-session, indicates that we can reuse the + * TRANS.TBL information for this directory entry. If this flag + * is set for all entries in a directory, it means we can just + * reuse the TRANS.TBL and not generate a new one. + */ +#define SAFE_TO_REUSE_TABLE_ENTRY 0x01 /* de_flags only */ +#define DIR_HAS_DOT 0x02 /* dir_flags only */ +#define DIR_HAS_DOTDOT 0x04 /* dir_flags only */ +#define INHIBIT_JOLIET_ENTRY 0x08 +#define INHIBIT_RR_ENTRY 0x10 /* not used */ +#define RELOCATED_DIRECTORY 0x20 /* de_flags only */ +#define INHIBIT_ISO9660_ENTRY 0x40 +#define MEMORY_FILE 0x80 /* de_flags only */ +#define HIDDEN_FILE 0x100 /* de_flags only */ +#define DIR_WAS_SCANNED 0x200 /* dir_flags only */ + +/* + * Volume sequence number to use in all of the iso directory records. + */ +#define DEF_VSN 1 + +/* + * Make sure we have a definition for this. If not, take a very conservative + * guess. + * POSIX requires the max pathname component lenght to be defined in limits.h + * If variable, it may be undefined. If undefined, there should be + * a definition for _POSIX_NAME_MAX in limits.h or in unistd.h + * As _POSIX_NAME_MAX is defined to 14, we cannot use it. + * XXX Eric's wrong comment: + * XXX From what I can tell SunOS is the only one with this trouble. + */ +#ifdef HAVE_LIMITS_H +#include +#endif +#ifndef NAME_MAX +#ifdef FILENAME_MAX +#define NAME_MAX FILENAME_MAX +#else +#define NAME_MAX 256 +#endif +#endif + +#ifndef PATH_MAX +#ifdef FILENAME_MAX +#define PATH_MAX FILENAME_MAX +#else +#define PATH_MAX 1024 +#endif +#endif + +/* + * XXX JS: Some structures have odd lengths! + * Some compilers (e.g. on Sun3/mc68020) padd the structures to even length. + * For this reason, we cannot use sizeof (struct iso_path_table) or + * sizeof (struct iso_directory_record) to compute on disk sizes. + * Instead, we use offsetof(..., name) and add the name size. + * See iso9660.h + */ +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif + +/* + * EB: various shared stuff + */ +extern char *merge_warn_msg; diff --git a/genisoimage/iso9660.h b/genisoimage/iso9660.h index c74c2a9..bbc5492 100644 --- a/genisoimage/iso9660.h +++ b/genisoimage/iso9660.h @@ -62,10 +62,14 @@ struct iso_volume_descriptor { #define EL_TORITO_ARCH_x86 0 #define EL_TORITO_ARCH_PPC 1 #define EL_TORITO_ARCH_MAC 2 +#define EL_TORITO_ARCH_EFI 0xef #define EL_TORITO_BOOTABLE 0x88 #define EL_TORITO_NOT_BOOTABLE 0 +#define EL_TORITO_SECTION_HEADER 0x90 +#define EL_TORITO_LAST_SECTION_HEADER 0x91 + #define EL_TORITO_MEDIA_NOEMUL 0 #define EL_TORITO_MEDIA_12FLOP 1 #define EL_TORITO_MEDIA_144FLOP 2 @@ -173,7 +177,7 @@ struct eltorito_validation_entry { struct eltorito_defaultboot_entry { char boot_id [ISODCL(1, 1)]; /* 711 */ char boot_media [ISODCL(2, 2)]; - char loadseg [ISODCL(3, 4)]; /* 711 */ + char loadseg [ISODCL(3, 4)]; /* 712 */ char sys_type [ISODCL(5, 5)]; char pad1 [ISODCL(6, 6)]; char nsect [ISODCL(7, 8)]; @@ -181,6 +185,14 @@ struct eltorito_defaultboot_entry { char pad2 [ISODCL(13, 32)]; }; +/* El Torito Section Header Entry in boot catalog */ +struct eltorito_sectionheader_entry { + char headerid [ISODCL(1, 1)]; /* 711 */ + char arch [ISODCL(2, 2)]; + char num_entries [ISODCL(3, 4)]; /* 711 */ + char id [ISODCL(5, 32)]; +}; + /* * XXX JS: The next two structures have odd lengths! * Some compilers (e.g. on Sun3/mc68020) padd the structures to even length. diff --git a/genisoimage/iso9660.h.efi b/genisoimage/iso9660.h.efi new file mode 100644 index 0000000..c74c2a9 --- /dev/null +++ b/genisoimage/iso9660.h.efi @@ -0,0 +1,359 @@ +/* + * 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. + * + */ + +/* @(#)iso9660.h 1.19 04/03/02 joerg */ +/* + * Header file iso9660.h - assorted structure definitions and typecasts. + * specific to iso9660 filesystem. + * + * 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. + */ +#ifndef _ISOFS_FS_H +#define _ISOFS_FS_H + +/* + * The isofs filesystem constants/structures + */ + +/* This part borrowed from the bsd386 isofs */ +#define ISODCL(from, to) (to - from + 1) + +struct iso_volume_descriptor { + char type [ISODCL(1, 1)]; /* 711 */ + char id [ISODCL(2, 6)]; + char version [ISODCL(7, 7)]; + char data [ISODCL(8, 2048)]; +}; + +/* volume descriptor types */ +#define ISO_VD_PRIMARY 1 +#define ISO_VD_SUPPLEMENTARY 2 /* Used by Joliet */ +#define ISO_VD_END 255 + +#define ISO_STANDARD_ID "CD001" + +#define EL_TORITO_ID "EL TORITO SPECIFICATION" +#define EL_TORITO_ARCH_x86 0 +#define EL_TORITO_ARCH_PPC 1 +#define EL_TORITO_ARCH_MAC 2 + +#define EL_TORITO_BOOTABLE 0x88 +#define EL_TORITO_NOT_BOOTABLE 0 + +#define EL_TORITO_MEDIA_NOEMUL 0 +#define EL_TORITO_MEDIA_12FLOP 1 +#define EL_TORITO_MEDIA_144FLOP 2 +#define EL_TORITO_MEDIA_288FLOP 3 +#define EL_TORITO_MEDIA_HD 4 + +struct iso_primary_descriptor { + char type [ISODCL(1, 1)]; /* 711 */ + char id [ISODCL(2, 6)]; + char version [ISODCL(7, 7)]; /* 711 */ + char unused1 [ISODCL(8, 8)]; + char system_id [ISODCL(9, 40)]; /* achars */ + char volume_id [ISODCL(41, 72)]; /* dchars */ + char unused2 [ISODCL(73, 80)]; + char volume_space_size [ISODCL(81, 88)]; /* 733 */ + char escape_sequences [ISODCL(89, 120)]; + char volume_set_size [ISODCL(121, 124)]; /* 723 */ + char volume_sequence_number [ISODCL(125, 128)]; /* 723 */ + char logical_block_size [ISODCL(129, 132)]; /* 723 */ + char path_table_size [ISODCL(133, 140)]; /* 733 */ + char type_l_path_table [ISODCL(141, 144)]; /* 731 */ + char opt_type_l_path_table [ISODCL(145, 148)]; /* 731 */ + char type_m_path_table [ISODCL(149, 152)]; /* 732 */ + char opt_type_m_path_table [ISODCL(153, 156)]; /* 732 */ + char root_directory_record [ISODCL(157, 190)]; /* 9.1 */ + char volume_set_id [ISODCL(191, 318)]; /* dchars */ + char publisher_id [ISODCL(319, 446)]; /* achars */ + char preparer_id [ISODCL(447, 574)]; /* achars */ + char application_id [ISODCL(575, 702)]; /* achars */ + char copyright_file_id [ISODCL(703, 739)]; /* 7.5 dchars */ + char abstract_file_id [ISODCL(740, 776)]; /* 7.5 dchars */ + char bibliographic_file_id [ISODCL(777, 813)]; /* 7.5 dchars */ + char creation_date [ISODCL(814, 830)]; /* 8.4.26.1 */ + char modification_date [ISODCL(831, 847)]; /* 8.4.26.1 */ + char expiration_date [ISODCL(848, 864)]; /* 8.4.26.1 */ + char effective_date [ISODCL(865, 881)]; /* 8.4.26.1 */ + char file_structure_version [ISODCL(882, 882)]; /* 711 */ + char unused4 [ISODCL(883, 883)]; + char application_data [ISODCL(884, 1395)]; + char unused5 [ISODCL(1396, 2048)]; +}; + +/* + * Supplementary or enhanced volume descriptor + */ +struct iso_enhanced_descriptor { + char type [ISODCL(1, 1)]; /* 711 */ + char id [ISODCL(2, 6)]; + char version [ISODCL(7, 7)]; /* 711 */ + char flags [ISODCL(8, 8)]; + char system_id [ISODCL(9, 40)]; /* achars */ + char volume_id [ISODCL(41, 72)]; /* dchars */ + char unused2 [ISODCL(73, 80)]; + char volume_space_size [ISODCL(81, 88)]; /* 733 */ + char escape_sequences [ISODCL(89, 120)]; + char volume_set_size [ISODCL(121, 124)]; /* 723 */ + char volume_sequence_number [ISODCL(125, 128)]; /* 723 */ + char logical_block_size [ISODCL(129, 132)]; /* 723 */ + char path_table_size [ISODCL(133, 140)]; /* 733 */ + char type_l_path_table [ISODCL(141, 144)]; /* 731 */ + char opt_type_l_path_table [ISODCL(145, 148)]; /* 731 */ + char type_m_path_table [ISODCL(149, 152)]; /* 732 */ + char opt_type_m_path_table [ISODCL(153, 156)]; /* 732 */ + char root_directory_record [ISODCL(157, 190)]; /* 9.1 */ + char volume_set_id [ISODCL(191, 318)]; /* dchars */ + char publisher_id [ISODCL(319, 446)]; /* achars */ + char preparer_id [ISODCL(447, 574)]; /* achars */ + char application_id [ISODCL(575, 702)]; /* achars */ + char copyright_file_id [ISODCL(703, 739)]; /* 7.5 dchars */ + char abstract_file_id [ISODCL(740, 776)]; /* 7.5 dchars */ + char bibliographic_file_id [ISODCL(777, 813)]; /* 7.5 dchars */ + char creation_date [ISODCL(814, 830)]; /* 8.4.26.1 */ + char modification_date [ISODCL(831, 847)]; /* 8.4.26.1 */ + char expiration_date [ISODCL(848, 864)]; /* 8.4.26.1 */ + char effective_date [ISODCL(865, 881)]; /* 8.4.26.1 */ + char file_structure_version [ISODCL(882, 882)]; /* 711 */ + char unused4 [ISODCL(883, 883)]; + char application_data [ISODCL(884, 1395)]; + char unused5 [ISODCL(1396, 2048)]; +}; + +/* El Torito Boot Record Volume Descriptor */ +struct eltorito_boot_descriptor { + char type [ISODCL(1, 1)]; /* 711 */ + char id [ISODCL(2, 6)]; + char version [ISODCL(7, 7)]; /* 711 */ + char system_id [ISODCL(8, 39)]; + char unused2 [ISODCL(40, 71)]; + char bootcat_ptr [ISODCL(72, 75)]; + char unused5 [ISODCL(76, 2048)]; +}; + +/* Validation entry for El Torito */ +struct eltorito_validation_entry { + char headerid [ISODCL(1, 1)]; /* 711 */ + char arch [ISODCL(2, 2)]; + char pad1 [ISODCL(3, 4)]; /* 711 */ + char id [ISODCL(5, 28)]; /* CD devel/man*/ + char cksum [ISODCL(29, 30)]; + char key1 [ISODCL(31, 31)]; + char key2 [ISODCL(32, 32)]; +}; + +/* El Torito initial/default entry in boot catalog */ +struct eltorito_defaultboot_entry { + char boot_id [ISODCL(1, 1)]; /* 711 */ + char boot_media [ISODCL(2, 2)]; + char loadseg [ISODCL(3, 4)]; /* 711 */ + char sys_type [ISODCL(5, 5)]; + char pad1 [ISODCL(6, 6)]; + char nsect [ISODCL(7, 8)]; + char bootoff [ISODCL(9, 12)]; + char pad2 [ISODCL(13, 32)]; +}; + +/* + * XXX JS: The next two structures have odd lengths! + * Some compilers (e.g. on Sun3/mc68020) padd the structures to even length. + * For this reason, we cannot use sizeof (struct iso_path_table) or + * sizeof (struct iso_directory_record) to compute on disk sizes. + * Instead, we use offsetof(..., name) and add the name size. + * See genisoimage.h + */ + +/* We use this to help us look up the parent inode numbers. */ + +struct iso_path_table { + unsigned char name_len[2]; /* 721 */ + char extent[4]; /* 731 */ + char parent[2]; /* 721 */ + char name[1]; +}; + +/* + * A ISO filename is: "abcde.eee;1" -> '.' ';' + * + * The maximum needed string length is: + * 30 chars (filename + ext) + * + 2 chars ('.' + ';') + * + strlen("32767") + * + null byte + * ================================ + * = 38 chars + * + * We currently do not support CD-ROM-XA entension records, but we must honor + * the needed space for ISO-9660:1999 (Version 2). + * + * XXX If we ever will start to support XA records, we will need to take care + * XXX that the the maximum ISO-9660 name length will be reduced by another + * XXX 14 bytes resulting in a new total of 179 Bytes. + */ +#define LEN_ISONAME 31 +#define MAX_ISONAME_V1 37 +#define MAX_ISONAME_V2 207 /* 254 - 33 - 14 (XA Record) */ +#define MAX_ISONAME_V2_RR 193 /* 254 - 33 - 28 (CE Record) */ +#define MAX_ISONAME_V2_RR_XA 179 /* 254 - 33 - 14 - 28 */ +#define MAX_ISONAME MAX_ISONAME_V2 /* Used for array space defs */ +#define MAX_ISODIR 254 /* Must be even and <= 255 */ + +struct iso_directory_record { + unsigned char length [ISODCL(1, 1)]; /* 711 */ + char ext_attr_length [ISODCL(2, 2)]; /* 711 */ + char extent [ISODCL(3, 10)]; /* 733 */ + char size [ISODCL(11, 18)]; /* 733 */ + char date [ISODCL(19, 25)]; /* 7 by 711 */ + char flags [ISODCL(26, 26)]; + char file_unit_size [ISODCL(27, 27)]; /* 711 */ + char interleave [ISODCL(28, 28)]; /* 711 */ + char volume_sequence_number [ISODCL(29, 32)]; /* 723 */ + unsigned char name_len [ISODCL(33, 33)]; /* 711 */ + char name [MAX_ISONAME+1]; /* Not really, but we need something here */ +}; + + +/* + * Iso directory flags. + */ +#define ISO_FILE 0 /* Not really a flag... */ +#define ISO_EXISTENCE 1 /* Do not make existence known (hidden) */ +#define ISO_DIRECTORY 2 /* This file is a directory */ +#define ISO_ASSOCIATED 4 /* This file is an assiciated file */ +#define ISO_RECORD 8 /* Record format in extended attr. != 0 */ +#define ISO_PROTECTION 16 /* No read/execute perm. in ext. attr. */ +#define ISO_DRESERVED1 32 /* Reserved bit 5 */ +#define ISO_DRESERVED2 64 /* Reserved bit 6 */ +#define ISO_MULTIEXTENT 128 /* Not final entry of a mult. ext. file */ + + +struct iso_ext_attr_record { + char owner [ISODCL(1, 4)]; /* 723 */ + char group [ISODCL(5, 8)]; /* 723 */ + char permissions [ISODCL(9, 10)]; /* 16 bits */ + char creation_date [ISODCL(11, 27)]; /* 8.4.26.1 */ + char modification_date [ISODCL(28, 44)]; /* 8.4.26.1 */ + char expiration_date [ISODCL(45, 61)]; /* 8.4.26.1 */ + char effective_date [ISODCL(62, 78)]; /* 8.4.26.1 */ + char record_format [ISODCL(79, 79)]; /* 711 */ + char record_attributes [ISODCL(80, 80)]; /* 711 */ + char record_length [ISODCL(81, 84)]; /* 723 */ + char system_id [ISODCL(85, 116)]; /* achars */ + char system_use [ISODCL(117, 180)]; + char ext_attr_version [ISODCL(181, 181)]; /* 711 */ + char esc_seq_len [ISODCL(182, 182)]; /* 711 */ + char reserved [ISODCL(183, 246)]; /* for future use */ + char appl_use_len [ISODCL(247, 250)]; /* 723 */ + char appl_use[1]; /* really more */ +/* char esc_seq[]; escape sequences recorded after appl_use */ +}; + +/* + * Iso extended attribute permissions. + */ +#define ISO_GS_READ 0x0001 /* System Group Read */ +#define ISO_BIT_1 0x0002 +#define ISO_GS_EXEC 0x0004 /* System Group Execute */ +#define ISO_BIT_3 0x0008 + +#define ISO_O_READ 0x0010 /* Owner Read */ +#define ISO_BIT_5 0x0020 +#define ISO_O_EXEC 0x0040 /* Owner Exexute */ +#define ISO_BIT_7 0x0080 + +#define ISO_G_READ 0x0100 /* Group Read */ +#define ISO_BIT_9 0x0200 +#define ISO_G_EXEC 0x0400 /* Group Execute */ +#define ISO_BIT_11 0x0800 + +#define ISO_W_READ 0x1000 /* World (other) Read */ +#define ISO_BIT_13 0x2000 +#define ISO_W_EXEC 0x4000 /* World (other) Execute */ +#define ISO_BIT_15 0x8000 + +#define ISO_MB_ONE (ISO_BIT_1|ISO_BIT_3|ISO_BIT_5|ISO_BIT_7| \ + ISO_BIT_9|ISO_BIT_11|ISO_BIT_13|ISO_BIT_15) + +/* + * Extended Attributes record according to Yellow Book. + */ +struct iso_xa_dir_record { + char group_id [ISODCL(1, 2)]; + char user_id [ISODCL(3, 4)]; + char attributes [ISODCL(5, 6)]; + char signature [ISODCL(7, 8)]; + char file_number [ISODCL(9, 9)]; + char reserved [ISODCL(10, 14)]; +}; + +/* + * Definitions for XA attributes + */ +#define XA_O_READ 0x0001 /* Owner Read */ +#define XA_O_RES 0x0002 /* Owner Reserved (write ?) */ +#define XA_O_EXEC 0x0004 /* Owner Execute */ +#define XA_O_RES2 0x0008 /* Owner Reserved */ +#define XA_G_READ 0x0010 /* Group Read */ +#define XA_G_RES 0x0020 /* Group Reserved (write ?) */ +#define XA_G_EXEC 0x0040 /* Group Execute */ +#define XA_G_RES2 0x0080 /* Group Reserved */ +#define XA_W_READ 0x0100 /* World Read */ +#define XA_W_RES 0x0200 /* World Reserved (write ?) */ +#define XA_W_EXEC 0x0400 /* World Execute */ + +#define XA_FORM1 0x0800 /* File contains Form 1 sector */ +#define XA_FORM2 0x1000 /* File contains Form 2 sector */ +#define XA_INTERLEAVED 0x2000 /* File contains interleaved sectors */ +#define XA_CDDA 0x4000 /* File contains audio data */ +#define XA_DIR 0x8000 /* This is a directory */ + +/* + * Definitions for CD-ROM XA-Mode-2-form-1/2 sector sub-headers + */ +struct xa_subhdr { + Uchar file_number; /* Identifies file for block */ + Uchar channel_number; /* Playback channel selection */ + Uchar sub_mode; /* See bit definitions below */ + Uchar coding; /* Coding information */ +}; + +/* + * Sub mode bit definitions + */ +#define XA_SUBH_EOR 0x01 /* End-Of-Record */ +#define XA_SUBH_VIDEO 0x02 /* Video Block */ +#define XA_SUBH_AUDIO 0x04 /* Audio Block (not CD-DA) */ +#define XA_SUBH_DATA 0x08 /* Data Block */ +#define XA_SUBH_TRIGGER 0x10 /* Trigger Block */ +#define XA_SUBH_FORM2 0x20 /* 0 == Form1, 1 == Form2 */ +#define XA_SUBH_REALTIME 0x40 /* Real Time Block */ +#define XA_SUBH_EOF 0x80 /* End-Of-File */ + +#endif /* _ISOFS_FS_H */