* conf/common.rmk (bin_UTILITIES): Remove grub-mkisofs.
(grub_mkisofs_SOURCES): Removed.
(grub_mkisofs_CFLAGS): Removed.
* util/mkisofs/defaults.h: Removed.
* util/mkisofs/eltorito.c: Likewise.
* util/mkisofs/exclude.h: Likewise.
* util/mkisofs/hash.c: Likewise.
* util/mkisofs/include/: Likewise.
* util/mkisofs/include/fctldefs.h: Likewise.
* util/mkisofs/include/mconfig.h: Likewise.
* util/mkisofs/include/prototyp.h: Likewise.
* util/mkisofs/include/statdefs.h: Likewise.
* util/mkisofs/iso9660.h: Likewise.
* util/mkisofs/joliet.c: Likewise.
* util/mkisofs/match.c: Likewise.
* util/mkisofs/match.h: Likewise.
* util/mkisofs/mkisofs.c: Likewise.
* util/mkisofs/mkisofs.h: Likewise.
* util/mkisofs/msdos_partition.h: Likewise.
* util/mkisofs/multi.c: Likewise.
* util/mkisofs/name.c: Likewise.
* util/mkisofs/rock.c: Likewise.
* util/mkisofs/tree.c: Likewise.
* util/mkisofs/write.c: Likewise.
+2010-05-17 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Remove grub-mkisofs.
+
+ * conf/common.rmk (bin_UTILITIES): Remove grub-mkisofs.
+ (grub_mkisofs_SOURCES): Removed.
+ (grub_mkisofs_CFLAGS): Removed.
+ * util/mkisofs/defaults.h: Removed.
+ * util/mkisofs/eltorito.c: Likewise.
+ * util/mkisofs/exclude.h: Likewise.
+ * util/mkisofs/hash.c: Likewise.
+ * util/mkisofs/include/: Likewise.
+ * util/mkisofs/include/fctldefs.h: Likewise.
+ * util/mkisofs/include/mconfig.h: Likewise.
+ * util/mkisofs/include/prototyp.h: Likewise.
+ * util/mkisofs/include/statdefs.h: Likewise.
+ * util/mkisofs/iso9660.h: Likewise.
+ * util/mkisofs/joliet.c: Likewise.
+ * util/mkisofs/match.c: Likewise.
+ * util/mkisofs/match.h: Likewise.
+ * util/mkisofs/mkisofs.c: Likewise.
+ * util/mkisofs/mkisofs.h: Likewise.
+ * util/mkisofs/msdos_partition.h: Likewise.
+ * util/mkisofs/multi.c: Likewise.
+ * util/mkisofs/name.c: Likewise.
+ * util/mkisofs/rock.c: Likewise.
+ * util/mkisofs/tree.c: Likewise.
+ * util/mkisofs/write.c: Likewise.
+
2010-05-17 Vladimir Serbinenko <phcoder@gmail.com>
Unify grub-mkimage accross platforms.
bin_UTILITIES += grub-fstest
endif
-bin_UTILITIES += grub-mkisofs
-grub_mkisofs_SOURCES = util/mkisofs/eltorito.c \
- util/mkisofs/hash.c util/mkisofs/joliet.c \
- util/mkisofs/match.c util/mkisofs/mkisofs.c \
- util/mkisofs/multi.c util/mkisofs/name.c \
- util/mkisofs/rock.c util/mkisofs/tree.c \
- util/mkisofs/write.c \
- \
- gnulib/fnmatch.c gnulib/getopt1.c gnulib/getopt.c \
- gnulib/error.c gnulib/progname.c
-grub_mkisofs_CFLAGS = -D_FILE_OFFSET_BITS=64 \
- -I$(srcdir)/util/mkisofs/include \
- -Wno-all -Werror $(GNULIB_UTIL_CFLAGS)
-
# For grub-fstest.
util/grub-fstest.c_DEPENDENCIES = grub_fstest_init.h
grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c kern/emu/hostfs.c \
+++ /dev/null
-/*
- * Header file defaults.h - assorted default values for character strings in
- * the volume descriptor.
- *
- * $Id: defaults.h,v 1.8 1999/03/02 03:41:25 eric Exp $
- */
-
-#define PREPARER_DEFAULT NULL
-#define PUBLISHER_DEFAULT NULL
-#ifndef APPID_DEFAULT
-#define APPID_DEFAULT PACKAGE_NAME " ISO 9660 filesystem builder"
-#endif
-#define COPYRIGHT_DEFAULT NULL
-#define BIBLIO_DEFAULT NULL
-#define ABSTRACT_DEFAULT NULL
-#define VOLSET_ID_DEFAULT NULL
-#define VOLUME_ID_DEFAULT "CDROM"
-#define BOOT_CATALOG_DEFAULT "boot.catalog"
-#define BOOT_IMAGE_DEFAULT NULL
-#define SYSTEM_ID_DEFAULT "GNU"
+++ /dev/null
-/*
- * Program eltorito.c - Handle El Torito specific extensions to iso9660.
- *
-
- Written by Michael Fulbright <msf@redhat.com> (1996).
-
- Copyright 1996 RedHat Software, Incorporated
-
- Copyright (C) 2009 Free Software Foundation, Inc.
-
- Boot Info Table generation based on code from genisoimage.c
- (from cdrkit 1.1.9), which was originally licensed under GPLv2+.
-
- 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 3, 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, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#include "config.h"
-#include "mkisofs.h"
-#include "iso9660.h"
-
-/* used by Win32 for opening binary file - not used by Unix */
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif /* O_BINARY */
-
-#undef MIN
-#define MIN(a, b) (((a) < (b))? (a): (b))
-
-static struct eltorito_validation_entry valid_desc;
-static struct eltorito_defaultboot_entry default_desc;
-static struct eltorito_boot_descriptor gboot_desc;
-
-static int tvd_write __PR((FILE * outfile));
-
-/*
- * Check for presence of boot catalog. If it does not exist then make it
- */
-void FDECL1(init_boot_catalog, const char *, path)
-{
- FILE *bcat;
- char * bootpath; /* filename of boot catalog */
- char * buf;
- struct stat statbuf;
-
- bootpath = (char *) e_malloc(strlen(boot_catalog)+strlen(path)+2);
- strcpy(bootpath, path);
- if (bootpath[strlen(bootpath)-1] != '/')
- {
- strcat(bootpath,"/");
- }
-
- strcat(bootpath, boot_catalog);
-
- /*
- * check for the file existing
- */
-#ifdef DEBUG_TORITO
- fprintf(stderr,"Looking for boot catalog file %s\n",bootpath);
-#endif
-
- if (!stat_filter(bootpath, &statbuf))
- {
- /*
- * make sure its big enough to hold what we want
- */
- if (statbuf.st_size == 2048)
- {
- /*
- * printf("Boot catalog exists, so we do nothing\n");
- */
- free(bootpath);
- return;
- }
- else
- {
- fprintf (stderr, _("A boot catalog exists and appears corrupted.\n"));
- fprintf (stderr, _("Please check the following file: %s.\n"), bootpath);
- fprintf (stderr, _("This file must be removed before a bootable CD can be done.\n"));
- free (bootpath);
- exit (1);
- }
- }
-
- /*
- * file does not exist, so we create it
- * make it one CD sector long
- */
- bcat = fopen (bootpath, "wb");
- if (bcat == NULL)
- error (1, errno, _("Error creating boot catalog (%s)"), bootpath);
-
- buf = (char *) e_malloc( 2048 );
- if (fwrite (buf, 1, 2048, bcat) != 2048)
- error (1, errno, _("Error writing to boot catalog (%s)"), bootpath);
- fclose (bcat);
- chmod (bootpath, S_IROTH | S_IRGRP | S_IRWXU);
-
- free(bootpath);
-} /* init_boot_catalog(... */
-
-void FDECL1(get_torito_desc, struct eltorito_boot_descriptor *, boot_desc)
-{
- FILE *bootcat;
- int checksum;
- unsigned char * checksum_ptr;
- struct directory_entry * de;
- struct directory_entry * de2;
- unsigned int i;
- int nsectors;
-
- memset(boot_desc, 0, sizeof(*boot_desc));
- boot_desc->id[0] = 0;
- memcpy(boot_desc->id2, 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
- */
- de2 = search_tree_file(root, boot_catalog);
- if (!de2)
- {
- fprintf (stderr, _("Boot catalog cannot be found!\n"));
- exit (1);
- }
-
- set_731(boot_desc->bootcat_ptr,
- (unsigned int) get_733(de2->isorec.extent));
-
- /*
- * now adjust boot catalog
- * lets find boot image first
- */
- de=search_tree_file(root, boot_image);
- if (!de)
- {
- fprintf (stderr, _("Boot image cannot be found!\n"));
- exit (1);
- }
-
- /*
- * 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] = 0x55;
- valid_desc.key2[0] = 0xAA;
-
- /*
- * compute the checksum
- */
- checksum=0;
- checksum_ptr = (unsigned char *) &valid_desc;
- for (i=0; i<sizeof(valid_desc); i+=2)
- {
- /*
- * skip adding in ckecksum word, since we dont have it yet!
- */
- if (i == 28)
- {
- continue;
- }
- 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 make the initial/default entry for boot catalog
- */
- memset(&default_desc, 0, sizeof(default_desc));
- default_desc.boot_id[0] = EL_TORITO_BOOTABLE;
-
- /*
- * use default BIOS loadpnt
- */
- set_721(default_desc.loadseg, 0);
- default_desc.arch[0] = EL_TORITO_ARCH_x86;
-
- /*
- * figure out size of boot image in sectors, for now hard code to
- * assume 512 bytes/sector on a bootable floppy
- */
- nsectors = ((de->size + 511) & ~(511))/512;
- fprintf (stderr, _("\nSize of boot image is %d sectors"), nsectors);
- fprintf (stderr, " -> ");
-
- if (! use_eltorito_emul_floppy)
- {
- default_desc.boot_media[0] = EL_TORITO_MEDIA_NOEMUL;
- fprintf (stderr, _("No emulation\n"));
- }
- else if (nsectors == 2880 )
- /*
- * choose size of emulated floppy based on boot image size
- */
- {
- default_desc.boot_media[0] = EL_TORITO_MEDIA_144FLOP;
- fprintf (stderr, _("Emulating a 1.44 meg floppy\n"));
- }
- else if (nsectors == 5760 )
- {
- default_desc.boot_media[0] = EL_TORITO_MEDIA_288FLOP;
- fprintf (stderr, _("Emulating a 2.88 meg floppy\n"));
- }
- else if (nsectors == 2400 )
- {
- default_desc.boot_media[0] = EL_TORITO_MEDIA_12FLOP;
- fprintf (stderr, _("Emulating a 1.2 meg floppy\n"));
- }
- else
- {
- fprintf (stderr, _("\nError - boot image is not the an allowable size.\n"));
- exit (1);
- }
-
- /*
- * FOR NOW LOAD 1 SECTOR, JUST LIKE FLOPPY BOOT!!!
- */
- nsectors = 1;
- set_721(default_desc.nsect, (unsigned int) nsectors );
-#ifdef DEBUG_TORITO
- fprintf(stderr,"Extent of boot images is %d\n",get_733(de->isorec.extent));
-#endif
- set_731(default_desc.bootoff,
- (unsigned int) get_733(de->isorec.extent));
-
- /*
- * now write it to disk
- */
- bootcat = fopen (de2->whole_name, "r+b");
- if (bootcat == NULL)
- error (1, errno, _("Error opening boot catalog for update"));
-
- /*
- * write out
- */
- if (fwrite (&valid_desc, 1, 32, bootcat) != 32)
- error (1, errno, _("Error writing to boot catalog"));
- if (fwrite (&default_desc, 1, 32, bootcat) != 32)
- error (1, errno, _("Error writing to boot catalog"));
- fclose (bootcat);
-
- /* If the user has asked for it, patch the boot image */
- if (use_boot_info_table)
- {
- FILE *bootimage;
- uint32_t bi_checksum;
- unsigned int total_len;
- static char csum_buffer[SECTOR_SIZE];
- int len;
- struct eltorito_boot_info bi_table;
- bootimage = fopen (de->whole_name, "r+b");
- if (bootimage == NULL)
- error (1, errno, _("Error opening boot image file `%s' for update"),
- de->whole_name);
- /* Compute checksum of boot image, sans 64 bytes */
- total_len = 0;
- bi_checksum = 0;
- while ((len = fread (csum_buffer, 1, SECTOR_SIZE, bootimage)) > 0)
- {
- if (total_len & 3)
- error (1, 0, _("Odd alignment at non-end-of-file in boot image `%s'"),
- de->whole_name);
- 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)
- error (1, 0, _("Boot image file `%s' changed unexpectedly"),
- de->whole_name);
- /* End of file, set position to byte 8 */
- fseeko (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.pvd_addr, session_start + 16);
- set_731 (bi_table.file_addr, de->starting_block);
- set_731 (bi_table.file_length, de->size);
- set_731 (bi_table.file_checksum, bi_checksum);
-
- if (fwrite (&bi_table, 1, sizeof (bi_table), bootimage) != sizeof (bi_table))
- error (1, errno, _("Error writing to boot image (%s)"), bootimage);
- fclose (bootimage);
- }
-
-} /* get_torito_desc(... */
-
-/*
- * Function to write the EVD for the disc.
- */
-static int FDECL1(tvd_write, FILE *, outfile)
-{
- /*
- * Next we write out the boot volume descriptor for the disc
- */
- get_torito_desc(&gboot_desc);
- xfwrite(&gboot_desc, 1, 2048, outfile);
- last_extent_written ++;
- return 0;
-}
-
-struct output_fragment torito_desc = {NULL, oneblock_size, NULL, tvd_write};
+++ /dev/null
-/*
- * 9-Dec-93 R.-D. Marzusch, marzusch@odiehh.hanse.de:
- * added 'exclude' option (-x) to specify pathnames NOT to be included in
- * CD image.
- *
- * $Id: exclude.h,v 1.2 1999/03/02 03:41:25 eric Exp $
- */
-
-void exclude __PR((char * fn));
-int is_excluded __PR((char * fn));
+++ /dev/null
-/*
- * File hash.c - generate hash tables for iso9660 filesystem.
-
- Written by Eric Youngdale (1993).
-
- Copyright 1993 Yggdrasil Computing, Incorporated
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include <stdlib.h>
-#include "config.h"
-#include "mkisofs.h"
-
-#define NR_HASH 1024
-
-#define HASH_FN(DEV, INO) ((DEV + INO + (INO >> 2) + (INO << 8)) % NR_HASH)
-
-static struct file_hash * hash_table[NR_HASH] = {0,};
-
-void FDECL1(add_hash, struct directory_entry *, spnt){
- struct file_hash * s_hash;
- unsigned int hash_number;
-
- if(spnt->size == 0 || spnt->starting_block == 0)
- if(spnt->size != 0 || spnt->starting_block != 0) {
- fprintf(stderr,"Non zero-length file assigned zero extent.\n");
- exit(1);
- };
-
- if (spnt->dev == (dev_t) UNCACHED_DEVICE || spnt->inode == UNCACHED_INODE) return;
- hash_number = HASH_FN((unsigned int) spnt->dev, (unsigned int) spnt->inode);
-
-#if 0
- if (verbose > 1) fprintf(stderr,"%s ",spnt->name);
-#endif
- s_hash = (struct file_hash *) e_malloc(sizeof(struct file_hash));
- s_hash->next = hash_table[hash_number];
- s_hash->inode = spnt->inode;
- s_hash->dev = spnt->dev;
- s_hash->starting_block = spnt->starting_block;
- s_hash->size = spnt->size;
- hash_table[hash_number] = s_hash;
-}
-
-struct file_hash * FDECL2(find_hash, dev_t, dev, ino_t, inode){
- unsigned int hash_number;
- struct file_hash * spnt;
- hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode);
- if (dev == (dev_t) UNCACHED_DEVICE || inode == UNCACHED_INODE) return NULL;
-
- spnt = hash_table[hash_number];
- while(spnt){
- if(spnt->inode == inode && spnt->dev == dev) return spnt;
- spnt = spnt->next;
- };
- return NULL;
-}
-
-
-static struct file_hash * directory_hash_table[NR_HASH] = {0,};
-
-void FDECL2(add_directory_hash, dev_t, dev, ino_t, inode){
- struct file_hash * s_hash;
- unsigned int hash_number;
-
- if (dev == (dev_t) UNCACHED_DEVICE || inode == UNCACHED_INODE) return;
- hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode);
-
- s_hash = (struct file_hash *) e_malloc(sizeof(struct file_hash));
- s_hash->next = directory_hash_table[hash_number];
- s_hash->inode = inode;
- s_hash->dev = dev;
- directory_hash_table[hash_number] = s_hash;
-}
-
-struct file_hash * FDECL2(find_directory_hash, dev_t, dev, ino_t, inode){
- unsigned int hash_number;
- struct file_hash * spnt;
- hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode);
- if (dev == (dev_t) UNCACHED_DEVICE || inode == UNCACHED_INODE) return NULL;
-
- spnt = directory_hash_table[hash_number];
- while(spnt){
- if(spnt->inode == inode && spnt->dev == dev) return spnt;
- spnt = spnt->next;
- };
- return NULL;
-}
-
-struct name_hash
-{
- struct name_hash * next;
- struct directory_entry * de;
-};
-
-#define NR_NAME_HASH 128
-
-static struct name_hash * name_hash_table[NR_NAME_HASH] = {0,};
-
-/*
- * Find the hash bucket for this name.
- */
-static unsigned int FDECL1(name_hash, const char *, name)
-{
- unsigned int hash = 0;
- const char * p;
-
- p = name;
-
- while (*p)
- {
- /*
- * Don't hash the iso9660 version number. This way
- * we can detect duplicates in cases where we have
- * directories (i.e. foo) and non-directories
- * (i.e. foo;1).
- */
- if( *p == ';' )
- {
- break;
- }
- hash = (hash << 15) + (hash << 3) + (hash >> 3) + *p++;
- }
- return hash % NR_NAME_HASH;
-}
-
-void FDECL1(add_file_hash, struct directory_entry *, de){
- struct name_hash * new;
- int hash;
-
- new = (struct name_hash *) e_malloc(sizeof(struct name_hash));
- new->de = de;
- new->next = NULL;
- hash = name_hash(de->isorec.name);
-
- /* Now insert into the hash table */
- new->next = name_hash_table[hash];
- name_hash_table[hash] = new;
-}
-
-struct directory_entry * FDECL1(find_file_hash, char *, name)
-{
- struct name_hash * nh;
- char * p1;
- char * p2;
-
- for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
- {
- p1 = name;
- p2 = nh->de->isorec.name;
-
- /*
- * Look for end of string, or a mismatch.
- */
- while(1==1)
- {
- if( (*p1 == '\0' || *p1 == ';')
- || (*p2 == '\0' || *p2 == ';')
- || (*p1 != *p2) )
- {
- break;
- }
- p1++;
- p2++;
- }
-
- /*
- * If we are at the end of both strings, then
- * we have a match.
- */
- if( (*p1 == '\0' || *p1 == ';')
- && (*p2 == '\0' || *p2 == ';') )
- {
- return nh->de;
- }
- }
- return NULL;
-}
-
-int FDECL1(delete_file_hash, struct directory_entry *, de){
- struct name_hash * nh, *prev;
- int hash;
-
- prev = NULL;
- hash = name_hash(de->isorec.name);
- for(nh = name_hash_table[hash]; nh; nh = nh->next) {
- if(nh->de == de) break;
- prev = nh;
- }
- if(!nh) return 1;
- if(!prev)
- name_hash_table[hash] = nh->next;
- else
- prev->next = nh->next;
- free(nh);
- return 0;
-}
-
-void flush_file_hash(){
- struct name_hash * nh, *nh1;
- int i;
-
- for(i=0; i<NR_NAME_HASH; i++) {
- nh = name_hash_table[i];
- while(nh) {
- nh1 = nh->next;
- free(nh);
- nh = nh1;
- }
- name_hash_table[i] = NULL;
-
- }
-}
+++ /dev/null
-/* @(#)fctldefs.h 1.2 98/10/08 Copyright 1996 J. Schilling */
-/*
- * Generic header for users of open(), creat() and chmod()
- *
- * Copyright (c) 1996 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; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _FCTLDEFS_H
-#define _FCTLDEFS_H
-
-#ifndef _MCONFIG_H
-#include <mconfig.h>
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#ifdef HAVE_FCNTL_H
-
-# include <fcntl.h>
-
-#else /* HAVE_FCNTL_H */
-
-# include <sys/file.h>
-
-#endif /* HAVE_FCNTL_H */
-
-/*
- * Do not define more than O_RDONLY / O_WRONLY / O_RDWR
- * The values may differ.
- */
-#ifndef O_RDONLY
-#define O_RDONLY 0
-#endif
-#ifndef O_WRONLY
-#define O_WRONLY 1
-#endif
-#ifndef O_RDWR
-#define O_RDWR 2
-#endif
-
-#endif /* _FCTLDEFS_H */
+++ /dev/null
-/* @(#)mconfig.h 1.24 98/12/14 Copyright 1995 J. Schilling */
-/*
- * definitions for machine configuration
- *
- * Copyright (c) 1995 J. Schilling
- *
- * This file must be included before any other file.
- * Use only cpp instructions.
- *
- * NOTE: SING: (Schily Is Not Gnu)
- */
-/*
- * 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; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _MCONFIG_H
-#define _MCONFIG_H
-
-#include <config.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined(unix) || defined(__unix) || defined(__unix__)
-# define IS_UNIX
-#endif
-
-#ifdef __MSDOS__
-# define IS_MSDOS
-#endif
-
-#if defined(tos) || defined(__tos)
-# define IS_TOS
-#endif
-
-#ifdef THINK_C
-# define IS_MAC
-#endif
-
-#if defined(sun) || defined(__sun) || defined(__sun__)
-# define IS_SUN
-#endif
-
-#if defined(__CYGWIN32__)
-# define IS_GCC_WIN32
-#endif
-
-/*--------------------------------------------------------------------------*/
-/*
- * Some magic that cannot (yet) be figured out with autoconf.
- */
-
-#ifdef sparc
-# ifndef HAVE_LDSTUB
-# define HAVE_LDSTUB
-# endif
-# ifndef HAVE_SCANSTACK
-# define HAVE_SCANSTACK
-# endif
-#endif
-#if defined(__i386_) || defined(i386)
-# ifndef HAVE_XCHG
-# define HAVE_XCHG
-# endif
-# ifndef HAVE_SCANSTACK
-# define HAVE_SCANSTACK
-# endif
-#endif
-
-#if defined(SOL2) || defined(SOL2) || defined(S5R4) || defined(__S5R4) \
- || defined(SVR4)
-# ifndef __SVR4
-# define __SVR4
-# endif
-#endif
-
-#ifdef __SVR4
-# ifndef SVR4
-# define SVR4
-# endif
-#endif
-
-/*
- * SunOS 4.x / SunOS 5.x
- */
-#if defined(IS_SUN)
-# define HAVE_GETAV0
-#endif
-
-/*
- * AIX
- */
-#if defined(_IBMR2) || defined(_AIX)
-# define IS_UNIX /* ??? really ??? */
-#endif
-
-/*
- * Silicon Graphics (must be before SVR4)
- */
-#if defined(sgi) || defined(__sgi)
-# define __NOT_SVR4__ /* Not a real SVR4 implementation */
-#endif
-
-/*
- * Data General
- */
-#if defined(__DGUX__)
-#ifdef XXXXXXX
-# undef HAVE_MTGET_DSREG
-# undef HAVE_MTGET_RESID
-# undef HAVE_MTGET_FILENO
-# undef HAVE_MTGET_BLKNO
-#endif
-# define mt_type mt_model
-# define mt_dsreg mt_status1
-# define mt_erreg mt_status2
- /*
- * DGUX hides its flock as dg_flock.
- */
-# define HAVE_FLOCK
-# define flock dg_flock
- /*
- * Use the BSD style wait on DGUX to get the resource usages of child
- * processes.
- */
-# define _BSD_WAIT_FLAVOR
-#endif
-
-/*
- * Apple Rhapsody
- */
-#if defined(__NeXT__) && defined(__TARGET_OSNAME) && __TARGET_OSNAME == rhapsody
-# define HAVE_OSDEF /* prevent later definitions to overwrite current */
-#endif
-
-/*
- * NextStep
- */
-#if defined(__NeXT__) && !defined(HAVE_OSDEF)
-#define NO_PRINT_OVR
-#undef HAVE_USG_STDIO /*
- * NeXT Step 3.x uses __flsbuf(unsigned char , FILE *)
- * instead of __flsbuf(int, FILE *)
- */
-#endif
-
-/*
- * NextStep 3.x has a broken linker that does not allow us to override
- * these functions.
- */
-#ifndef __OPRINTF__
-
-#ifdef NO_PRINT_OVR
-# define printf Xprintf
-# define fprintf Xfprintf
-# define sprintf Xsprintf
-#endif
-
-#endif /* __OPRINTF__ */
-
-/*--------------------------------------------------------------------------*/
-/*
- * If there is no flock defined by the system, use emulation
- * through fcntl record locking.
- */
-#ifndef HAVE_FLOCK
-#define LOCK_SH 1 /* shared lock */
-#define LOCK_EX 2 /* exclusive lock */
-#define LOCK_NB 4 /* don't block when locking */
-#define LOCK_UN 8 /* unlock */
-#endif
-
-#include <prototyp.h>
-
-/*
- * gcc 2.x generally implements the long long type.
- */
-#ifdef __GNUC__
-# if __GNUC__ > 1
-# ifndef HAVE_LONGLONG
-# define HAVE_LONGLONG
-# endif
-# endif
-#endif
-
-/*
- * Convert to GNU name
- */
-#ifdef HAVE_STDC_HEADERS
-# ifndef STDC_HEADERS
-# define STDC_HEADERS
-# endif
-#endif
-/*
- * Convert to SCHILY name
- */
-#ifdef STDC_HEADERS
-# ifndef HAVE_STDC_HEADERS
-# define HAVE_STDC_HEADERS
-# endif
-#endif
-
-#ifdef IS_UNIX
-# define PATH_DELIM '/'
-# define PATH_DELIM_STR "/"
-# define far
-# define near
-#endif
-
-#ifdef IS_GCC_WIN32
-# define PATH_DELIM '/'
-# define PATH_DELIM_STR "/"
-# define far
-# define near
-#endif
-
-#ifdef IS_MSDOS
-# define PATH_DELIM '\\'
-# define PATH_DELIM_STR "\\"
-#endif
-
-#ifdef IS_TOS
-# define PATH_DELIM '\\'
-# define PATH_DELIM_STR "\\"
-# define far
-# define near
-#endif
-
-#ifdef IS_MAC
-# define PATH_DELIM ':'
-# define PATH_DELIM_STR ":"
-# define far
-# define near
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _MCONFIG_H */
+++ /dev/null
-/* @(#)prototyp.h 1.7 98/10/08 Copyright 1995 J. Schilling */
-/*
- * Definitions for dealing with ANSI / KR C-Compilers
- *
- * Copyright (c) 1995 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; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _PROTOTYP_H
-#define _PROTOTYP_H
-
-#ifndef PROTOTYPES
- /*
- * If this has already been defined,
- * someone else knows better than us...
- */
-# ifdef __STDC__
-# if __STDC__ /* ANSI C */
-# define PROTOTYPES
-# endif
-# if defined(sun) && __STDC__ - 0 == 0 /* Sun C */
-# define PROTOTYPES
-# endif
-# endif
-#endif /* PROTOTYPES */
-
-/*
- * If we have prototypes, we should have stdlib.h string.h stdarg.h
- */
-#ifdef PROTOTYPES
-#if !(defined(SABER) && defined(sun))
-# ifndef HAVE_STDARG_H
-# define HAVE_STDARG_H
-# endif
-#endif
-# ifndef HAVE_STDLIB_H
-# define HAVE_STDLIB_H
-# endif
-# ifndef HAVE_STRING_H
-# define HAVE_STRING_H
-# endif
-# ifndef HAVE_STDC_HEADERS
-# define HAVE_STDC_HEADERS
-# endif
-# ifndef STDC_HEADERS
-# define STDC_HEADERS /* GNU name */
-# endif
-#endif
-
-#ifdef NO_PROTOTYPES /* Force not to use prototypes */
-# undef PROTOTYPES
-#endif
-
-#ifdef PROTOTYPES
-# define __PR(a) a
-#else
-# define __PR(a) ()
-#endif
-
-#endif /* _PROTOTYP_H */
+++ /dev/null
-/* @(#)statdefs.h 1.1 98/11/22 Copyright 1998 J. Schilling */
-/*
- * Definitions for stat() file mode
- *
- * Copyright (c) 1998 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; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _STATDEFS_H
-#define _STATDEFS_H
-
-#ifndef _MCONFIG_H
-#include <mconfig.h>
-#endif
-
-#ifdef STAT_MACROS_BROKEN
-#undef S_ISFIFO /* Named pipe */
-#undef S_ISCHR /* Character special */
-#undef S_ISMPC /* UNUSED multiplexed c */
-#undef S_ISDIR /* Directory */
-#undef S_ISNAM /* Named file (XENIX) */
-#undef S_ISBLK /* Block special */
-#undef S_ISMPB /* UNUSED multiplexed b */
-#undef S_ISREG /* Regular file */
-#undef S_ISCNT /* Contiguous file */
-#undef S_ISLNK /* Symbolic link */
-#undef S_ISSHAD /* Solaris shadow inode */
-#undef S_ISSOCK /* UNIX domain socket */
-#undef S_ISDOOR /* Solaris DOOR */
-#endif
-
-#ifndef S_ISFIFO /* Named pipe */
-# ifdef S_IFIFO
-# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
-# else
-# define S_ISFIFO(m) (0)
-# endif
-#endif
-#ifndef S_ISCHR /* Character special */
-# ifdef S_IFCHR
-# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
-# else
-# define S_ISCHR(m) (0)
-# endif
-#endif
-#ifndef S_ISMPC /* UNUSED multiplexed c */
-# ifdef S_IFMPC
-# define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
-# else
-# define S_ISMPC(m) (0)
-# endif
-#endif
-#ifndef S_ISDIR /* Directory */
-# ifdef S_IFDIR
-# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-# else
-# define S_ISDIR(m) (0)
-# endif
-#endif
-#ifndef S_ISNAM /* Named file (XENIX) */
-# ifdef S_IFNAM
-# define S_ISNAM(m) (((m) & S_IFMT) == S_IFNAM)
-# else
-# define S_ISNAM(m) (0)
-# endif
-#endif
-#ifndef S_ISBLK /* Block special */
-# ifdef S_IFBLK
-# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
-# else
-# define S_ISBLK(m) (0)
-# endif
-#endif
-#ifndef S_ISMPB /* UNUSED multiplexed b */
-# ifdef S_IFMPB
-# define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
-# else
-# define S_ISMPB(m) (0)
-# endif
-#endif
-#ifndef S_ISREG /* Regular file */
-# ifdef S_IFREG
-# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
-# else
-# define S_ISREG(m) (0)
-# endif
-#endif
-#ifndef S_ISCNT /* Contiguous file */
-# ifdef S_IFCNT
-# define S_ISCNT(m) (((m) & S_IFMT) == S_IFCNT)
-# else
-# define S_ISCNT(m) (0)
-# endif
-#endif
-#ifndef S_ISLNK /* Symbolic link */
-# ifdef S_IFLNK
-# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
-# else
-# define S_ISLNK(m) (0)
-# endif
-#endif
-#ifndef S_ISSHAD /* Solaris shadow inode */
-# ifdef S_IFSHAD
-# define S_ISSHAD(m) (((m) & S_IFMT) == S_IFSHAD)
-# else
-# define S_ISSHAD(m) (0)
-# endif
-#endif
-#ifndef S_ISSOCK /* UNIX domain socket */
-# ifdef S_IFSOCK
-# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
-# else
-# define S_ISSOCK(m) (0)
-# endif
-#endif
-#ifndef S_ISDOOR /* Solaris DOOR */
-# ifdef S_IFDOOR
-# define S_ISDOOR(m) (((m) & S_IFMT) == S_IFDOOR)
-# else
-# define S_ISDOOR(m) (0)
-# endif
-#endif
-
-#endif /* _STATDEFS_H */
-
+++ /dev/null
-/*
- * 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) 2009 Free Software Foundation, Inc.
-
- 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 3, 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, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * $Id: iso9660.h,v 1.2 1997/05/17 15:46:44 eric Exp $
- */
-
-#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_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)];
-};
-
-/* El Torito Boot Record Volume Descriptor */
-struct eltorito_boot_descriptor {
- char id [ISODCL ( 1, 1)]; /* 711 */
- char id2 [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)];
- 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 arch [ISODCL ( 5, 5)];
- char pad1 [ISODCL ( 6, 6)];
- char nsect [ISODCL ( 7, 8)];
- char bootoff [ISODCL ( 9, 12)];
- char pad2 [ISODCL ( 13, 32)];
-};
-
-/* El Torito boot information table */
-struct eltorito_boot_info
-{
- /* Address of Primary Volume Descriptor. */
- char pvd_addr[ISODCL (1, 4)];
- /* Boot file address. */
- char file_addr[ISODCL (5, 8)];
- /* Boot file length. */
- char file_length[ISODCL (9, 12)];
- /* Boot file checksum. */
- char file_checksum[ISODCL (13, 16)];
- char dummy[ISODCL (17, 56)];
-};
-
-
-/* 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];
-};
-
-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 [34]; /* Not really, but we need something here */
-};
-#endif
-
-
-
+++ /dev/null
-/*
- * File joliet.c - handle Win95/WinNT long file/unicode extensions for iso9660.
-
- Copyright 1997 Eric Youngdale.
-
- Copyright (C) 2009 Free Software Foundation, Inc.
-
- 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 3, 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, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * Joliet extensions for ISO9660. These are spottily documented by
- * Microsoft. In their infinite stupidity, they completely ignored
- * the possibility of using an SUSP record with the long filename
- * in it, and instead wrote out a duplicate directory tree with the
- * long filenames in it.
- *
- * I am not sure why they did this. One reason is that they get the path
- * tables with the long filenames in them.
- *
- * There are two basic principles to Joliet, and the non-Unicode variant
- * known as Romeo. Long filenames seem to be the main one, and the second
- * is that the character set and a few other things is substantially relaxed.
- *
- * The SVD is identical to the PVD, except:
- *
- * Id is 2, not 1 (indicates SVD).
- * escape_sequences contains UCS-2 indicator (levels 1, 2 or 3).
- * The root directory record points to a different extent (with different
- * size).
- * There are different path tables for the two sets of directory trees.
- *
- * The following fields are recorded in Unicode:
- * system_id
- * volume_id
- * volume_set_id
- * publisher_id
- * preparer_id
- * application_id
- * copyright_file_id
- * abstract_file_id
- * bibliographic_file_id
- *
- * Unicode strings are always encoded in big-endian format.
- *
- * In a directory record, everything is the same as with iso9660, except
- * that the name is recorded in unicode. The name length is specified in
- * total bytes, not in number of unicode characters.
- *
- * The character set used for the names is different with UCS - the
- * restrictions are that the following are not allowed:
- *
- * Characters (00)(00) through (00)(1f) (control chars)
- * (00)(2a) '*'
- * (00)(2f) '/'
- * (00)(3a) ':'
- * (00)(3b) ';'
- * (00)(3f) '?'
- * (00)(5c) '\'
- */
-#include "config.h"
-#include "mkisofs.h"
-#include "iso9660.h"
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <time.h>
-
-static unsigned int jpath_table_index;
-static struct directory ** jpathlist;
-static int next_jpath_index = 1;
-static int sort_goof;
-
-static int generate_joliet_path_tables __PR((void));
-static int DECL(joliet_sort_directory, (struct directory_entry ** sort_dir));
-static void DECL(assign_joliet_directory_addresses, (struct directory * node));
-static int jroot_gen __PR((void));
-
-/*
- * Function: convert_to_unicode
- *
- * Purpose: Perform a 1/2 assed unicode conversion on a text
- * string.
- *
- * Notes:
- */
-static void FDECL3(convert_to_unicode, unsigned char *, buffer, int, size, char *, source )
-{
- unsigned char * tmpbuf;
- int i;
- int j;
-
- /*
- * If we get a NULL pointer for the source, it means we have an inplace
- * copy, and we need to make a temporary working copy first.
- */
- if( source == NULL )
- {
- tmpbuf = (uint8_t *) e_malloc(size);
- memcpy( tmpbuf, buffer, size);
- }
- else
- {
- tmpbuf = (uint8_t *)source;
- }
-
- /*
- * Now start copying characters. If the size was specified to be 0, then
- * assume the input was 0 terminated.
- */
- j = 0;
- for(i=0; i < size ; i += 2, j++)
- {
- buffer[i] = 0;
- /*
- * JS integrated from: Achim_Kaiser@t-online.de
- *
- * Let all valid unicode characters pass through (assuming ISO-8859-1).
- * Others are set to '_' .
- */
- if( tmpbuf[j] != 0 &&
- (tmpbuf[j] <= 0x1f || (tmpbuf[j] >= 0x7F && tmpbuf[j] <= 0xA0)) )
- {
- buffer[i+1] = '_';
- }
- else
- {
- switch(tmpbuf[j])
- {
- case '*':
- case '/':
- case ':':
- case ';':
- case '?':
- case '\\':
- /*
- * Even Joliet has some standards as to what is allowed in a pathname.
- * Pretty tame in comparison to what DOS restricts you to.
- */
- buffer[i+1] = '_';
- break;
- default:
- buffer[i+1] = tmpbuf[j];
- break;
- }
- }
- }
-
- if( source == NULL )
- {
- free(tmpbuf);
- }
-}
-
-/*
- * Function: joliet_strlen
- *
- * Purpose: Return length in bytes of string after conversion to unicode.
- *
- * Notes: This is provided mainly as a convenience so that when more intelligent
- * Unicode conversion for either Multibyte or 8-bit codes is available that
- * we can easily adapt.
- */
-static int FDECL1(joliet_strlen, const char *, string)
-{
- int rtn;
-
- rtn = strlen(string) << 1;
-
- /*
- * We do clamp the maximum length of a Joliet string to be the
- * maximum path size. This helps to ensure that we don't completely
- * bolix things up with very long paths. The Joliet specs say
- * that the maximum length is 128 bytes, or 64 unicode characters.
- */
- if( rtn > 0x80)
- {
- rtn = 0x80;
- }
- return rtn;
-}
-
-/*
- * Function: get_joliet_vol_desc
- *
- * Purpose: generate a Joliet compatible volume desc.
- *
- * Notes: Assume that we have the non-joliet vol desc
- * already present in the buffer. Just modifiy the
- * appropriate fields.
- */
-static void FDECL1(get_joliet_vol_desc, struct iso_primary_descriptor *, jvol_desc)
-{
- jvol_desc->type[0] = ISO_VD_SUPPLEMENTARY;
-
- /*
- * For now, always do Unicode level 3. I don't really know what 1 and 2
- * are - perhaps a more limited Unicode set.
- *
- * FIXME(eric) - how does Romeo fit in here? As mkisofs just
- * "expands" 8 bit character codes to 16 bits and does nothing
- * special with the Unicode characters, therefore shouldn't mkisofs
- * really be stating that it's using UCS-2 Level 1, not Level 3 for
- * the Joliet directory tree.
- */
- strcpy(jvol_desc->escape_sequences, "%/@");
-
- /*
- * Until we have Unicode path tables, leave these unset.
- */
- set_733((char *) jvol_desc->path_table_size, jpath_table_size);
- set_731(jvol_desc->type_l_path_table, jpath_table[0]);
- set_731(jvol_desc->opt_type_l_path_table, jpath_table[1]);
- set_732(jvol_desc->type_m_path_table, jpath_table[2]);
- set_732(jvol_desc->opt_type_m_path_table, jpath_table[3]);
-
- /*
- * Set this one up.
- */
- memcpy(jvol_desc->root_directory_record, &jroot_record,
- sizeof(struct iso_directory_record));
-
- /*
- * Finally, we have a bunch of strings to convert to Unicode.
- * FIXME(eric) - I don't know how to do this in general, so we will
- * just be really lazy and do a char -> short conversion. We probably
- * will want to filter any characters >= 0x80.
- */
- convert_to_unicode((uint8_t *)jvol_desc->system_id, sizeof(jvol_desc->system_id), NULL);
- convert_to_unicode((uint8_t *)jvol_desc->volume_id, sizeof(jvol_desc->volume_id), NULL);
- convert_to_unicode((uint8_t *)jvol_desc->volume_set_id, sizeof(jvol_desc->volume_set_id), NULL);
- convert_to_unicode((uint8_t *)jvol_desc->publisher_id, sizeof(jvol_desc->publisher_id), NULL);
- convert_to_unicode((uint8_t *)jvol_desc->preparer_id, sizeof(jvol_desc->preparer_id), NULL);
- convert_to_unicode((uint8_t *)jvol_desc->application_id, sizeof(jvol_desc->application_id), NULL);
- convert_to_unicode((uint8_t *)jvol_desc->copyright_file_id, sizeof(jvol_desc->copyright_file_id), NULL);
- convert_to_unicode((uint8_t *)jvol_desc->abstract_file_id, sizeof(jvol_desc->abstract_file_id), NULL);
- convert_to_unicode((uint8_t *)jvol_desc->bibliographic_file_id, sizeof(jvol_desc->bibliographic_file_id), NULL);
-
-
-}
-
-static void FDECL1(assign_joliet_directory_addresses, struct directory *, node)
-{
- int dir_size;
- struct directory * dpnt;
-
- dpnt = node;
-
- while (dpnt)
- {
- if( (dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) == 0 )
- {
- /*
- * If we already have an extent for this (i.e. it came from
- * a multisession disc), then don't reassign a new extent.
- */
- dpnt->jpath_index = next_jpath_index++;
- if( dpnt->jextent == 0 )
- {
- dpnt->jextent = last_extent;
- dir_size = (dpnt->jsize + (SECTOR_SIZE - 1)) >> 11;
- last_extent += dir_size;
- }
- }
-
- /* skip if hidden - but not for the rr_moved dir */
- if(dpnt->subdir && (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir))
- {
- assign_joliet_directory_addresses(dpnt->subdir);
- }
- dpnt = dpnt->next;
- }
-}
-
-static
-void FDECL1(build_jpathlist, struct directory *, node)
-{
- struct directory * dpnt;
-
- dpnt = node;
-
- while (dpnt)
-
- {
- if( (dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) == 0 )
- {
- jpathlist[dpnt->jpath_index] = dpnt;
- }
- if(dpnt->subdir) build_jpathlist(dpnt->subdir);
- dpnt = dpnt->next;
- }
-} /* build_jpathlist(... */
-
-static int FDECL2(joliet_compare_paths, void const *, r, void const *, l)
-{
- struct directory const *ll = *(struct directory * const *)l;
- struct directory const *rr = *(struct directory * const *)r;
- int rparent, lparent;
-
- rparent = rr->parent->jpath_index;
- lparent = ll->parent->jpath_index;
- if( rr->parent == reloc_dir )
- {
- rparent = rr->self->parent_rec->filedir->jpath_index;
- }
-
- if( ll->parent == reloc_dir )
- {
- lparent = ll->self->parent_rec->filedir->jpath_index;
- }
-
- if (rparent < lparent)
- {
- return -1;
- }
-
- if (rparent > lparent)
- {
- return 1;
- }
-
- return strcmp(rr->self->name, ll->self->name);
-
-} /* compare_paths(... */
-
-static int generate_joliet_path_tables()
-{
- struct directory_entry * de;
- struct directory * dpnt;
- int fix;
- int j;
- int namelen;
- char * npnt;
- char * npnt1;
- int tablesize;
-
- /*
- * First allocate memory for the tables and initialize the memory
- */
- tablesize = jpath_blocks << 11;
- jpath_table_m = (char *) e_malloc(tablesize);
- jpath_table_l = (char *) e_malloc(tablesize);
- memset(jpath_table_l, 0, tablesize);
- memset(jpath_table_m, 0, tablesize);
-
- if( next_jpath_index > 0xffff )
- {
- fprintf (stderr, _("Unable to generate sane path tables - too many directories (%d)\n"),
- next_jpath_index);
- exit (1);
- }
- /*
- * Now start filling in the path tables. Start with root directory
- */
- jpath_table_index = 0;
- jpathlist = (struct directory **) e_malloc(sizeof(struct directory *)
- * next_jpath_index);
- memset(jpathlist, 0, sizeof(struct directory *) * next_jpath_index);
- build_jpathlist(root);
-
- do
- {
- fix = 0;
-#ifdef __STDC__
- qsort(&jpathlist[1], next_jpath_index-1, sizeof(struct directory *),
- (int (*)(const void *, const void *))joliet_compare_paths);
-#else
- qsort(&jpathlist[1], next_jpath_index-1, sizeof(struct directory *),
- joliet_compare_paths);
-#endif
-
- for(j=1; j<next_jpath_index; j++)
- {
- if(jpathlist[j]->jpath_index != j)
- {
- jpathlist[j]->jpath_index = j;
- fix++;
- }
- }
- } while(fix);
-
- for(j=1; j<next_jpath_index; j++)
- {
- dpnt = jpathlist[j];
- if(!dpnt)
- {
- fprintf (stderr, _("Entry %d not in path tables\n"), j);
- exit (1);
- }
- npnt = dpnt->de_name;
-
- npnt1 = strrchr(npnt, PATH_SEPARATOR);
- if(npnt1)
- {
- npnt = npnt1 + 1;
- }
-
- de = dpnt->self;
- if(!de)
- {
- fprintf (stderr, _("Fatal goof - directory has amnesia\n"));
- exit (1);
- }
-
- namelen = joliet_strlen(de->name);
-
- if( dpnt == root )
- {
- jpath_table_l[jpath_table_index] = 1;
- jpath_table_m[jpath_table_index] = 1;
- }
- else
- {
- jpath_table_l[jpath_table_index] = namelen;
- jpath_table_m[jpath_table_index] = namelen;
- }
- jpath_table_index += 2;
-
- set_731(jpath_table_l + jpath_table_index, dpnt->jextent);
- set_732(jpath_table_m + jpath_table_index, dpnt->jextent);
- jpath_table_index += 4;
-
- if( dpnt->parent != reloc_dir )
- {
- set_721(jpath_table_l + jpath_table_index,
- dpnt->parent->jpath_index);
- set_722(jpath_table_m + jpath_table_index,
- dpnt->parent->jpath_index);
- }
- else
- {
- set_721(jpath_table_l + jpath_table_index,
- dpnt->self->parent_rec->filedir->jpath_index);
- set_722(jpath_table_m + jpath_table_index,
- dpnt->self->parent_rec->filedir->jpath_index);
- }
-
- jpath_table_index += 2;
-
- /*
- * The root directory is still represented in non-unicode fashion.
- */
- if( dpnt == root )
- {
- jpath_table_l[jpath_table_index] = 0;
- jpath_table_m[jpath_table_index] = 0;
- jpath_table_index ++;
- }
- else
- {
- convert_to_unicode((uint8_t *)jpath_table_l + jpath_table_index,
- namelen, de->name);
- convert_to_unicode((uint8_t *)jpath_table_m + jpath_table_index,
- namelen, de->name);
- jpath_table_index += namelen;
- }
-
- if(jpath_table_index & 1)
- {
- jpath_table_index++; /* For odd lengths we pad */
- }
- }
-
- free(jpathlist);
- if(jpath_table_index != jpath_table_size)
- {
- fprintf(stderr, _("Joliet path table lengths do not match %d %d\n"),
- jpath_table_index,
- jpath_table_size);
- }
- return 0;
-} /* generate_path_tables(... */
-
-static void FDECL2(generate_one_joliet_directory, struct directory *, dpnt, FILE *, outfile)
-{
- unsigned int dir_index;
- char * directory_buffer;
- int new_reclen;
- struct directory_entry * s_entry;
- struct directory_entry * s_entry1;
- struct iso_directory_record jrec;
- unsigned int total_size;
- int cvt_len;
- struct directory * finddir;
-
- total_size = (dpnt->jsize + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1);
- directory_buffer = (char *) e_malloc(total_size);
- memset(directory_buffer, 0, total_size);
- dir_index = 0;
-
- s_entry = dpnt->jcontents;
- while(s_entry)
- {
- if(s_entry->de_flags & INHIBIT_JOLIET_ENTRY) {
- s_entry = s_entry->jnext;
- continue;
- }
-
- /*
- * If this entry was a directory that was relocated, we have a bit
- * of trouble here. We need to dig out the real thing and put it
- * back here. In the Joliet tree, there is no relocated rock
- * ridge, as there are no depth limits to a directory tree.
- */
- if( (s_entry->de_flags & RELOCATED_DIRECTORY) != 0 )
- {
- for(s_entry1 = reloc_dir->contents; s_entry1; s_entry1 = s_entry1->next)
- {
- if( s_entry1->parent_rec == s_entry )
- {
- break;
- }
- }
- if( s_entry1 == NULL )
- {
- /*
- * We got trouble.
- */
- fprintf (stderr, _("Unable to locate relocated directory\n"));
- exit (1);
- }
- }
- else
- {
- s_entry1 = s_entry;
- }
-
- /*
- * We do not allow directory entries to cross sector boundaries.
- * Simply pad, and then start the next entry at the next sector
- */
- new_reclen = s_entry1->jreclen;
- if( (dir_index & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE )
- {
- dir_index = (dir_index + (SECTOR_SIZE - 1)) &
- ~(SECTOR_SIZE - 1);
- }
-
- memcpy(&jrec, &s_entry1->isorec, sizeof(struct iso_directory_record) -
- sizeof(s_entry1->isorec.name));
-
- cvt_len = joliet_strlen(s_entry1->name);
-
- /*
- * Fix the record length - this was the non-Joliet version we
- * were seeing.
- */
- jrec.name_len[0] = cvt_len;
- jrec.length[0] = s_entry1->jreclen;
-
- /*
- * If this is a directory, fix the correct size and extent
- * number.
- */
- if( (jrec.flags[0] & 2) != 0 )
- {
- if(strcmp(s_entry1->name,".") == 0)
- {
- jrec.name_len[0] = 1;
- set_733((char *) jrec.extent, dpnt->jextent);
- set_733((char *) jrec.size, ROUND_UP(dpnt->jsize));
- }
- else if(strcmp(s_entry1->name,"..") == 0)
- {
- jrec.name_len[0] = 1;
- if( dpnt->parent == reloc_dir )
- {
- set_733((char *) jrec.extent, dpnt->self->parent_rec->filedir->jextent);
- set_733((char *) jrec.size, ROUND_UP(dpnt->self->parent_rec->filedir->jsize));
- }
- else
-
- {
- set_733((char *) jrec.extent, dpnt->parent->jextent);
- set_733((char *) jrec.size, ROUND_UP(dpnt->parent->jsize));
- }
- }
- else
- {
- if( (s_entry->de_flags & RELOCATED_DIRECTORY) != 0 )
- {
- finddir = reloc_dir->subdir;
- }
- else
- {
- finddir = dpnt->subdir;
- }
- while(1==1)
- {
- if(finddir->self == s_entry1) break;
- finddir = finddir->next;
- if(!finddir)
- {
- fprintf (stderr, _("Fatal goof - unable to find directory location\n"));
- exit (1);
- }
- }
- set_733((char *) jrec.extent, finddir->jextent);
- set_733((char *) jrec.size, ROUND_UP(finddir->jsize));
- }
- }
-
- memcpy(directory_buffer + dir_index, &jrec,
- sizeof(struct iso_directory_record) -
- sizeof(s_entry1->isorec.name));
-
-
- dir_index += sizeof(struct iso_directory_record) -
- sizeof (s_entry1->isorec.name);
-
- /*
- * Finally dump the Unicode version of the filename.
- * Note - . and .. are the same as with non-Joliet discs.
- */
- if( (jrec.flags[0] & 2) != 0
- && strcmp(s_entry1->name, ".") == 0 )
- {
- directory_buffer[dir_index++] = 0;
- }
- else if( (jrec.flags[0] & 2) != 0
- && strcmp(s_entry1->name, "..") == 0 )
- {
- directory_buffer[dir_index++] = 1;
- }
- else
- {
- convert_to_unicode((uint8_t *)directory_buffer + dir_index,
- cvt_len,
- s_entry1->name);
- dir_index += cvt_len;
- }
-
- if(dir_index & 1)
- {
- directory_buffer[dir_index++] = 0;
- }
-
- s_entry = s_entry->jnext;
- }
-
- if(dpnt->jsize != dir_index)
- {
- fprintf (stderr, _("Unexpected joliet directory length %d %d %s\n"),
- dpnt->jsize, dir_index, dpnt->de_name);
- }
-
- xfwrite(directory_buffer, 1, total_size, outfile);
- last_extent_written += total_size >> 11;
- free(directory_buffer);
-} /* generate_one_joliet_directory(... */
-
-static int FDECL1(joliet_sort_n_finish, struct directory *, this_dir)
-{
- struct directory_entry * s_entry;
- int status = 0;
-
- /* don't want to skip this directory if it's the reloc_dir at the moment */
- if(this_dir != reloc_dir && this_dir->dir_flags & INHIBIT_JOLIET_ENTRY)
- {
- return 0;
- }
-
- for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next)
- {
- /* skip hidden entries */
- if( (s_entry->de_flags & INHIBIT_JOLIET_ENTRY) != 0 )
- {
- continue;
- }
-
- /*
- * First update the path table sizes for directories.
- *
- * Finally, set the length of the directory entry if Joliet is used.
- * The name is longer, but no Rock Ridge is ever used here, so
- * depending upon the options the entry size might turn out to be about
- * the same. The Unicode name is always a multiple of 2 bytes, so
- * we always add 1 to make it an even number.
- */
- if(s_entry->isorec.flags[0] == 2)
- {
- if (strcmp(s_entry->name,".") && strcmp(s_entry->name,".."))
- {
- jpath_table_size += joliet_strlen(s_entry->name) + sizeof(struct iso_path_table) - 1;
- if (jpath_table_size & 1)
- {
- jpath_table_size++;
- }
- }
- else
- {
- if (this_dir == root && strlen(s_entry->name) == 1)
- {
- jpath_table_size += sizeof(struct iso_path_table);
- if (jpath_table_size & 1) jpath_table_size++;
- }
- }
- }
-
- if (strcmp(s_entry->name,".") && strcmp(s_entry->name,".."))
- {
- s_entry->jreclen = sizeof(struct iso_directory_record)
- - sizeof(s_entry->isorec.name)
- + joliet_strlen(s_entry->name)
- + 1;
- }
- else
- {
- /*
- * Special - for '.' and '..' we generate the same records we
- * did for non-Joliet discs.
- */
- s_entry->jreclen = sizeof(struct iso_directory_record)
- - sizeof(s_entry->isorec.name)
- + 1;
- }
-
-
- }
-
- if( (this_dir->dir_flags & INHIBIT_JOLIET_ENTRY) != 0 )
- {
- return 0;
- }
-
- this_dir->jcontents = this_dir->contents;
- status = joliet_sort_directory(&this_dir->jcontents);
-
- /*
- * Now go through the directory and figure out how large this one will be.
- * Do not split a directory entry across a sector boundary
- */
- s_entry = this_dir->jcontents;
-/*
- * XXX Is it ok to comment this out?
- */
-/*XXX JS this_dir->ce_bytes = 0;*/
- for(s_entry = this_dir->jcontents; s_entry; s_entry = s_entry->jnext)
- {
- int jreclen;
-
- if( (s_entry->de_flags & INHIBIT_JOLIET_ENTRY) != 0 )
- {
- continue;
- }
-
- jreclen = s_entry->jreclen;
-
- if ((this_dir->jsize & (SECTOR_SIZE - 1)) + jreclen >= SECTOR_SIZE)
- {
- this_dir->jsize = (this_dir->jsize + (SECTOR_SIZE - 1)) &
- ~(SECTOR_SIZE - 1);
- }
- this_dir->jsize += jreclen;
- }
- return status;
-}
-
-/*
- * Similar to the iso9660 case, except here we perform a full sort based upon the
- * regular name of the file, not the 8.3 version.
- */
-static int FDECL2(joliet_compare_dirs, const void *, rr, const void *, ll)
-{
- char * rpnt, *lpnt;
- struct directory_entry ** r, **l;
-
- r = (struct directory_entry **) rr;
- l = (struct directory_entry **) ll;
- rpnt = (*r)->name;
- lpnt = (*l)->name;
-
- /*
- * If the entries are the same, this is an error.
- */
- if( strcmp(rpnt, lpnt) == 0 )
- {
- sort_goof++;
- }
-
- /*
- * Put the '.' and '..' entries on the head of the sorted list.
- * For normal ASCII, this always happens to be the case, but out of
- * band characters cause this not to be the case sometimes.
- */
- if( strcmp(rpnt, ".") == 0 ) return -1;
- if( strcmp(lpnt, ".") == 0 ) return 1;
-
- if( strcmp(rpnt, "..") == 0 ) return -1;
- if( strcmp(lpnt, "..") == 0 ) return 1;
-
- while(*rpnt && *lpnt)
- {
- if(*rpnt == ';' && *lpnt != ';') return -1;
- if(*rpnt != ';' && *lpnt == ';') return 1;
-
- if(*rpnt == ';' && *lpnt == ';') return 0;
-
- /*
- * Extensions are not special here. Don't treat the dot as something that
- * must be bumped to the start of the list.
- */
-#if 0
- if(*rpnt == '.' && *lpnt != '.') return -1;
- if(*rpnt != '.' && *lpnt == '.') return 1;
-#endif
-
- if(*rpnt < *lpnt) return -1;
- if(*rpnt > *lpnt) return 1;
- rpnt++; lpnt++;
- }
- if(*rpnt) return 1;
- if(*lpnt) return -1;
- return 0;
-}
-
-
-/*
- * Function: sort_directory
- *
- * Purpose: Sort the directory in the appropriate ISO9660
- * order.
- *
- * Notes: Returns 0 if OK, returns > 0 if an error occurred.
- */
-static int FDECL1(joliet_sort_directory, struct directory_entry **, sort_dir)
-{
- int dcount = 0;
- int i;
- struct directory_entry * s_entry;
- struct directory_entry ** sortlist;
-
- s_entry = *sort_dir;
- while(s_entry)
- {
- /* skip hidden entries */
- if (!(s_entry->de_flags & INHIBIT_JOLIET_ENTRY))
- dcount++;
- s_entry = s_entry->next;
- }
-
- /*
- * OK, now we know how many there are. Build a vector for sorting.
- */
- sortlist = (struct directory_entry **)
- e_malloc(sizeof(struct directory_entry *) * dcount);
-
- dcount = 0;
- s_entry = *sort_dir;
- while(s_entry)
- {
- /* skip hidden entries */
- if (!(s_entry->de_flags & INHIBIT_JOLIET_ENTRY)) {
- sortlist[dcount] = s_entry;
- dcount++;
- }
- s_entry = s_entry->next;
- }
-
- sort_goof = 0;
-#ifdef __STDC__
- qsort(sortlist, dcount, sizeof(struct directory_entry *),
- (int (*)(const void *, const void *))joliet_compare_dirs);
-#else
- qsort(sortlist, dcount, sizeof(struct directory_entry *),
- joliet_compare_dirs);
-#endif
-
- /*
- * Now reassemble the linked list in the proper sorted order
- */
- for(i=0; i<dcount-1; i++)
- {
- sortlist[i]->jnext = sortlist[i+1];
- }
-
- sortlist[dcount-1]->jnext = NULL;
- *sort_dir = sortlist[0];
-
- free(sortlist);
- return sort_goof;
-}
-
-int FDECL1(joliet_sort_tree, struct directory *, node)
-{
- struct directory * dpnt;
- int ret = 0;
-
- dpnt = node;
-
- while (dpnt){
- ret = joliet_sort_n_finish(dpnt);
- if( ret )
- {
- break;
- }
- if(dpnt->subdir) ret = joliet_sort_tree(dpnt->subdir);
- if( ret )
- {
- break;
- }
- dpnt = dpnt->next;
- }
- return ret;
-}
-
-static void FDECL2(generate_joliet_directories, struct directory *, node, FILE*, outfile){
- struct directory * dpnt;
-
- dpnt = node;
-
- while (dpnt)
- {
- if( (dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) == 0 )
- {
- /*
- * In theory we should never reuse a directory, so this doesn't
- * make much sense.
- */
- if( dpnt->jextent > session_start )
- {
- generate_one_joliet_directory(dpnt, outfile);
- }
- }
- /* skip if hidden - but not for the rr_moved dir */
- if(dpnt->subdir && (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir))
- generate_joliet_directories(dpnt->subdir, outfile);
- dpnt = dpnt->next;
- }
-}
-
-
-/*
- * Function to write the EVD for the disc.
- */
-static int FDECL1(jpathtab_write, FILE *, outfile)
-{
- /*
- * Next we write the path tables
- */
- xfwrite(jpath_table_l, 1, jpath_blocks << 11, outfile);
- xfwrite(jpath_table_m, 1, jpath_blocks << 11, outfile);
- last_extent_written += 2*jpath_blocks;
- free(jpath_table_l);
- free(jpath_table_m);
- jpath_table_l = NULL;
- jpath_table_m = NULL;
- return 0;
-}
-
-static int FDECL1(jdirtree_size, int, starting_extent)
-{
- assign_joliet_directory_addresses(root);
- return 0;
-}
-
-static int jroot_gen()
-{
- jroot_record.length[0] = 1 + sizeof(struct iso_directory_record)
- - sizeof(jroot_record.name);
- jroot_record.ext_attr_length[0] = 0;
- set_733((char *) jroot_record.extent, root->jextent);
- set_733((char *) jroot_record.size, ROUND_UP(root->jsize));
- iso9660_date(jroot_record.date, root_statbuf.st_mtime);
- jroot_record.flags[0] = 2;
- jroot_record.file_unit_size[0] = 0;
- jroot_record.interleave[0] = 0;
- set_723(jroot_record.volume_sequence_number, volume_sequence_number);
- jroot_record.name_len[0] = 1;
- return 0;
-}
-
-static int FDECL1(jdirtree_write, FILE *, outfile)
-{
- generate_joliet_directories(root, outfile);
- return 0;
-}
-
-/*
- * Function to write the EVD for the disc.
- */
-static int FDECL1(jvd_write, FILE *, outfile)
-{
- struct iso_primary_descriptor jvol_desc;
-
- /*
- * Next we write out the boot volume descriptor for the disc
- */
- jvol_desc = vol_desc;
- get_joliet_vol_desc(&jvol_desc);
- xfwrite(&jvol_desc, 1, 2048, outfile);
- last_extent_written ++;
- return 0;
-}
-
-/*
- * Functions to describe padding block at the start of the disc.
- */
-static int FDECL1(jpathtab_size, int, starting_extent)
-{
- jpath_table[0] = starting_extent;
- jpath_table[1] = 0;
- jpath_table[2] = jpath_table[0] + jpath_blocks;
- jpath_table[3] = 0;
-
- last_extent += 2*jpath_blocks;
- return 0;
-}
-
-struct output_fragment joliet_desc = {NULL, oneblock_size, jroot_gen,jvd_write};
-struct output_fragment jpathtable_desc= {NULL, jpathtab_size, generate_joliet_path_tables, jpathtab_write};
-struct output_fragment jdirtree_desc = {NULL, jdirtree_size, NULL, jdirtree_write};
+++ /dev/null
-/*
- * Copyright (C) 2009 Free Software Foundation, Inc.
- *
- * 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include "fnmatch.h"
-
-#include "match.h"
-
-struct pattern
-{
- char *str;
- struct pattern *next;
-};
-
-static struct pattern *patlist = NULL;
-static struct pattern *i_patlist = NULL; /* ISO9660/RR */
-static struct pattern *j_patlist = NULL; /* Joliet */
-
-#define DECL_ADD_MATCH(function, list) \
-void \
-function (char *pattern) \
-{ \
- struct pattern *new; \
- new = malloc (sizeof (*new)); \
- new->str = strdup (pattern); \
- new->next = list; \
- list = new; \
-}
-
-DECL_ADD_MATCH (add_match, patlist)
-DECL_ADD_MATCH (i_add_match, i_patlist)
-DECL_ADD_MATCH (j_add_match, j_patlist)
-
-#define DECL_MATCHES(function, list) \
-int \
-function (char *str) \
-{ \
- struct pattern *i; \
- for (i = list; i != NULL; i = i->next) \
- if (fnmatch (i->str, str, FNM_FILE_NAME) != FNM_NOMATCH) \
- return 1; \
- return 0; \
-}
-
-DECL_MATCHES (matches, patlist)
-DECL_MATCHES (i_matches, i_patlist)
-DECL_MATCHES (j_matches, j_patlist)
-
-int
-i_ishidden()
-{
- return (i_patlist != NULL);
-}
-
-
-int j_ishidden()
-{
- return (j_patlist != NULL);
-}
+++ /dev/null
-/*
- * Copyright (C) 2009 Free Software Foundation, Inc.
- *
- * 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-extern void add_match (char *);
-extern void i_add_match (char *);
-extern void j_add_match (char *);
-
-extern int matches (char *);
-extern int i_matches (char *);
-extern int j_matches (char *);
-
-extern int i_ishidden ();
-extern int j_ishidden ();
+++ /dev/null
-/*
- * Program mkisofs.c - generate iso9660 filesystem based upon directory
- * tree on hard disk.
-
- Written by Eric Youngdale (1993).
-
- Copyright 1993 Yggdrasil Computing, Incorporated
-
- Copyright (C) 2009,2010 Free Software Foundation, Inc.
-
- 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 3, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <errno.h>
-#include "config.h"
-#include "mkisofs.h"
-#include "match.h"
-#include "getopt.h"
-
-#include "iso9660.h"
-#include <ctype.h>
-
-#ifndef VMS
-#include <time.h>
-#else
-#include <sys/time.h>
-#include "vms.h"
-#endif
-
-#include <stdlib.h>
-#include <sys/stat.h>
-
-#ifndef VMS
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#endif
-#include <fctldefs.h>
-
-#include "exclude.h"
-
-#ifdef __NetBSD__
-#include <sys/time.h>
-#include <sys/resource.h>
-#endif
-
-struct directory * root = NULL;
-
-static char version_string[] = "mkisofs 1.12b5";
-
-#include "progname.h"
-
-char * outfile;
-FILE * discimage;
-uint64_t next_extent = 0;
-uint64_t last_extent = 0;
-uint64_t session_start = 0;
-unsigned int path_table_size = 0;
-unsigned int path_table[4] = {0,};
-unsigned int path_blocks = 0;
-
-
-unsigned int jpath_table_size = 0;
-unsigned int jpath_table[4] = {0,};
-unsigned int jpath_blocks = 0;
-
-struct iso_directory_record root_record;
-struct iso_directory_record jroot_record;
-
-char * extension_record = NULL;
-int extension_record_extent = 0;
-int extension_record_size = 0;
-
-/* These variables are associated with command line options */
-int use_eltorito = 0;
-int use_eltorito_emul_floppy = 0;
-int use_embedded_boot = 0;
-int use_protective_msdos_label = 0;
-int use_boot_info_table = 0;
-int use_RockRidge = 0;
-int use_Joliet = 0;
-int verbose = 1;
-int all_files = 0;
-int follow_links = 0;
-int rationalize = 0;
-int generate_tables = 0;
-int print_size = 0;
-int split_output = 0;
-char *preparer = PREPARER_DEFAULT;
-char *publisher = PUBLISHER_DEFAULT;
-char *appid = APPID_DEFAULT;
-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 *boot_image_embed = NULL;
-int volume_set_size = 1;
-int volume_sequence_number = 1;
-
-int omit_period = 0; /* Violates iso9660, but these are a pain */
-int transparent_compression = 0; /* So far only works with linux */
-int omit_version_number = 0; /* May violate iso9660, but noone uses vers*/
-unsigned int RR_relocation_depth = 6; /* Violates iso9660, but most systems work */
-int full_iso9660_filenames = 0; /* Used with Amiga. Disc will not work with
- DOS */
-int allow_leading_dots = 0; /* DOS cannot read names with leading dots */
-int split_SL_component = 1; /* circumvent a bug in the SunOS driver */
-int split_SL_field = 1; /* circumvent a bug in the SunOS */
-
-struct rcopts{
- char * tag;
- 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},
- {NULL, NULL}
-};
-
-/*
- * In case it isn't obvious, the option handling code was ripped off from GNU-ld.
- */
-struct ld_option
-{
- /* The long option information. */
- struct option opt;
- /* The short option with the same meaning ('\0' if none). */
- char shortopt;
- /* The name of the argument (NULL if none). */
- const char *arg;
- /* The documentation string. If this is NULL, this is a synonym for
- the previous option. */
- const char *doc;
- enum
- {
- /* Use one dash before long option name. */
- ONE_DASH,
- /* Use two dashes before long option name. */
- TWO_DASHES,
- /* Don't mention this option in --help output. */
- NO_HELP
- } control;
-};
-
-/* Codes used for the long options with no short synonyms. 150 isn't
- special; it's just an arbitrary non-ASCII char value. */
-#define OPTION_HELP 150
-#define OPTION_QUIET 151
-#define OPTION_NOSPLIT_SL_COMPONENT 152
-#define OPTION_NOSPLIT_SL_FIELD 153
-#define OPTION_PRINT_SIZE 154
-#define OPTION_SPLIT_OUTPUT 155
-#define OPTION_ABSTRACT 156
-#define OPTION_BIBLIO 157
-#define OPTION_COPYRIGHT 158
-#define OPTION_SYSID 159
-#define OPTION_VOLSET 160
-#define OPTION_VOLSET_SIZE 161
-#define OPTION_VOLSET_SEQ_NUM 162
-#define OPTION_I_HIDE 163
-#define OPTION_J_HIDE 164
-#define OPTION_LOG_FILE 165
-
-#define OPTION_CREAT_DATE 166
-#define OPTION_MODIF_DATE 167
-#define OPTION_EXPIR_DATE 168
-#define OPTION_EFFEC_DATE 169
-
-#define OPTION_BOOT_INFO_TABLE 170
-#define OPTION_NO_EMUL_BOOT 171
-#define OPTION_ELTORITO_EMUL_FLOPPY 172
-
-#define OPTION_VERSION 173
-
-#define OPTION_PROTECTIVE_MSDOS_LABEL 174
-
-static const struct ld_option ld_options[] =
-{
- { {"all-files", no_argument, NULL, 'a'},
- 'a', NULL, N_("Process all files (don't skip backup files)"), ONE_DASH },
- { {"abstract", required_argument, NULL, OPTION_ABSTRACT},
- '\0', N_("FILE"), N_("Set Abstract filename"), ONE_DASH },
- { {"appid", required_argument, NULL, 'A'},
- 'A', N_("ID"), N_("Set Application ID"), ONE_DASH },
- { {"biblio", required_argument, NULL, OPTION_BIBLIO},
- '\0', N_("FILE"), N_("Set Bibliographic filename"), ONE_DASH },
- { {"copyright", required_argument, NULL, OPTION_COPYRIGHT},
- '\0', N_("FILE"), N_("Set Copyright filename"), ONE_DASH },
- { {"embedded-boot", required_argument, NULL, 'G'},
- 'G', N_("FILE"), N_("Set embedded boot image name"), TWO_DASHES },
- { {"protective-msdos-label", no_argument, NULL, OPTION_PROTECTIVE_MSDOS_LABEL },
- '\0', NULL, N_("Patch a protective DOS-style label in the image"), TWO_DASHES },
- { {"eltorito-boot", required_argument, NULL, 'b'},
- 'b', N_("FILE"), N_("Set El Torito boot image name"), ONE_DASH },
- { {"eltorito-catalog", required_argument, NULL, 'c'},
- 'c', N_("FILE"), N_("Set El Torito boot catalog name"), ONE_DASH },
- { {"boot-info-table", no_argument, NULL, OPTION_BOOT_INFO_TABLE },
- '\0', NULL, N_("Patch Boot Info Table in El Torito boot image"), ONE_DASH },
- { {"no-emul-boot", no_argument, NULL, OPTION_NO_EMUL_BOOT },
- '\0', NULL, N_("Dummy option for backward compatibility"), ONE_DASH },
- { {"eltorito-emul-floppy", no_argument, NULL, OPTION_ELTORITO_EMUL_FLOPPY },
- '\0', NULL, N_("Enable floppy drive emulation for El Torito"), TWO_DASHES },
- { {"cdwrite-params", required_argument, NULL, 'C'},
- 'C', N_("PARAMS"), N_("Magic parameters from cdrecord"), ONE_DASH },
- { {"omit-period", no_argument, NULL, 'd'},
- 'd', NULL, N_("Omit trailing periods from filenames"), ONE_DASH },
- { {"disable-deep-relocation", no_argument, NULL, 'D'},
- 'D', NULL, N_("Disable deep directory relocation"), ONE_DASH },
- { {"follow-links", no_argument, NULL, 'f'},
- 'f', NULL, N_("Follow symbolic links"), ONE_DASH },
- { {"help", no_argument, NULL, OPTION_HELP},
- '\0', NULL, N_("Print option help"), ONE_DASH },
- { {"help", no_argument, NULL, OPTION_HELP},
- '\0', NULL, N_("Print option help"), TWO_DASHES },
- { {"version", no_argument, NULL, OPTION_VERSION},
- '\0', NULL, N_("Print version information and exit"), TWO_DASHES },
- { {"hide", required_argument, NULL, OPTION_I_HIDE},
- '\0', N_("GLOBFILE"), N_("Hide ISO9660/RR file"), ONE_DASH },
- { {"hide-joliet", required_argument, NULL, OPTION_J_HIDE},
- '\0', N_("GLOBFILE"), N_("Hide Joliet file"), ONE_DASH },
- { {NULL, required_argument, NULL, 'i'},
- 'i', N_("ADD_FILES"), N_("No longer supported"), TWO_DASHES },
- { {"joliet", no_argument, NULL, 'J'},
- 'J', NULL, N_("Generate Joliet directory information"), ONE_DASH },
- { {"full-iso9660-filenames", no_argument, NULL, 'l'},
- 'l', NULL, N_("Allow full 32 character filenames for iso9660 names"), ONE_DASH },
- { {"allow-leading-dots", no_argument, NULL, 'L'},
- 'L', NULL, N_("Allow iso9660 filenames to start with '.'"), ONE_DASH },
- { {"log-file", required_argument, NULL, OPTION_LOG_FILE},
- '\0', N_("LOG_FILE"), N_("Re-direct messages to LOG_FILE"), ONE_DASH },
- { {"exclude", required_argument, NULL, 'm'},
- 'm', N_("GLOBFILE"), N_("Exclude file name"), ONE_DASH },
- { {"prev-session", required_argument, NULL, 'M'},
- 'M', N_("FILE"), N_("Set path to previous session to merge"), ONE_DASH },
- { {"omit-version-number", no_argument, NULL, 'N'},
- 'N', NULL, N_("Omit version number from iso9660 filename"), ONE_DASH },
- { {"no-split-symlink-components", no_argument, NULL, 0},
- 0, NULL, N_("Inhibit splitting symlink components"), ONE_DASH },
- { {"no-split-symlink-fields", no_argument, NULL, 0},
- 0, NULL, N_("Inhibit splitting symlink fields"), ONE_DASH },
- { {"output", required_argument, NULL, 'o'},
- 'o', N_("FILE"), N_("Set output file name"), ONE_DASH },
- { {"preparer", required_argument, NULL, 'p'},
- 'p', N_("PREP"), N_("Set Volume preparer"), ONE_DASH },
- { {"print-size", no_argument, NULL, OPTION_PRINT_SIZE},
- '\0', NULL, N_("Print estimated filesystem size and exit"), ONE_DASH },
- { {"publisher", required_argument, NULL, 'P'},
- 'P', N_("PUB"), N_("Set Volume publisher"), ONE_DASH },
- { {"quiet", no_argument, NULL, OPTION_QUIET},
- '\0', NULL, N_("Run quietly"), ONE_DASH },
- { {"rational-rock", no_argument, NULL, 'r'},
- 'r', NULL, N_("Generate rationalized Rock Ridge directory information"), ONE_DASH },
- { {"rock", no_argument, NULL, 'R'},
- 'R', NULL, N_("Generate Rock Ridge directory information"), ONE_DASH },
- { {"split-output", no_argument, NULL, OPTION_SPLIT_OUTPUT},
- '\0', NULL, N_("Split output into files of approx. 1GB size"), ONE_DASH },
- { {"sysid", required_argument, NULL, OPTION_SYSID},
- '\0', N_("ID"), N_("Set System ID"), ONE_DASH },
- { {"translation-table", no_argument, NULL, 'T'},
- 'T', NULL, N_("Generate translation tables for systems that don't understand long filenames"), ONE_DASH },
- { {"verbose", no_argument, NULL, 'v'},
- 'v', NULL, N_("Verbose"), ONE_DASH },
- { {"volid", required_argument, NULL, 'V'},
- 'V', N_("ID"), N_("Set Volume ID"), ONE_DASH },
- { {"volset", required_argument, NULL, OPTION_VOLSET},
- '\0', N_("ID"), N_("Set Volume set ID"), ONE_DASH },
- { {"volset-size", required_argument, NULL, OPTION_VOLSET_SIZE},
- '\0', "#", N_("Set Volume set size"), ONE_DASH },
- { {"volset-seqno", required_argument, NULL, OPTION_VOLSET_SEQ_NUM},
- '\0', "#", N_("Set Volume set sequence number"), ONE_DASH },
- { {"old-exclude", required_argument, NULL, 'x'},
- 'x', N_("FILE"), N_("Exclude file name (deprecated)"), ONE_DASH },
-#ifdef ERIC_neverdef
- { {"transparent-compression", no_argument, NULL, 'z'},
- 'z', NULL, "Enable transparent compression of files", ONE_DASH },
-#endif
- { {"creation-date", required_argument, NULL, OPTION_CREAT_DATE },
- '\0', NULL, N_("Override creation date"), TWO_DASHES },
- { {"modification-date", required_argument, NULL, OPTION_MODIF_DATE },
- '\0', NULL, N_("Override modification date"), TWO_DASHES },
- { {"expiration-date", required_argument, NULL, OPTION_EXPIR_DATE },
- '\0', NULL, N_("Override expiration date"), TWO_DASHES },
- { {"effective-date", required_argument, NULL, OPTION_EFFEC_DATE },
- '\0', NULL, N_("Override effective date"), TWO_DASHES },
-};
-
-#define OPTION_COUNT (sizeof ld_options / sizeof ld_options[0])
-
-#if defined(ultrix) || defined(_AUX_SOURCE)
-char *strdup(s)
-char *s;{char *c;if(c=(char *)malloc(strlen(s)+1))strcpy(c,s);return c;}
-#endif
-
- void read_rcfile __PR((char * appname));
- void usage __PR((void));
-static void hide_reloc_dir __PR((void));
-
-void FDECL1(read_rcfile, char *, appname)
-{
- FILE * rcfile;
- struct rcopts * rco;
- char * pnt, *pnt1;
- char linebuffer[256];
- static char rcfn[] = ".mkisofsrc";
- char filename[1000];
- int linum;
-
- strcpy(filename, rcfn);
- rcfile = fopen(filename, "r");
- if (!rcfile && errno != ENOENT)
- perror(filename);
-
- if (!rcfile)
- {
- pnt = getenv("MKISOFSRC");
- if (pnt && strlen(pnt) <= sizeof(filename))
- {
- strcpy(filename, pnt);
- rcfile = fopen(filename, "r");
- if (!rcfile && errno != ENOENT)
- perror(filename);
- }
- }
-
- if (!rcfile)
- {
- pnt = getenv("HOME");
- if (pnt && strlen(pnt) + strlen(rcfn) + 2 <= sizeof(filename))
- {
- strcpy(filename, pnt);
- strcat(filename, "/");
- strcat(filename, rcfn);
- rcfile = fopen(filename, "r");
- if (!rcfile && errno != ENOENT)
- perror(filename);
- }
- }
- if (!rcfile && strlen(appname)+sizeof(rcfn)+2 <= sizeof(filename))
- {
- strcpy(filename, appname);
- pnt = strrchr(filename, '/');
- if (pnt)
- {
- strcpy(pnt + 1, rcfn);
- rcfile = fopen(filename, "r");
- if (!rcfile && errno != ENOENT)
- perror(filename);
- }
- }
- if (!rcfile)
- return;
- if ( verbose > 0 )
- {
- fprintf (stderr, _("Using \"%s\"\n"), filename);
- }
-
- /* OK, we got it. Now read in the lines and parse them */
- linum = 0;
- while (fgets(linebuffer, sizeof(linebuffer), rcfile))
- {
- char *name;
- char *name_end;
- ++linum;
- /* skip any leading white space */
- pnt = linebuffer;
- while (*pnt == ' ' || *pnt == '\t')
- ++pnt;
- /* If we are looking at a # character, this line is a comment. */
- if (*pnt == '#')
- continue;
- /* The name should begin in the left margin. Make sure it is in
- upper case. Stop when we see white space or a comment. */
- name = pnt;
- while (*pnt && isalpha((unsigned char)*pnt))
- {
- if(islower((unsigned char)*pnt))
- *pnt = toupper((unsigned char)*pnt);
- pnt++;
- }
- if (name == pnt)
- {
- fprintf(stderr, _("%s:%d: name required\n"), filename, linum);
- continue;
- }
- name_end = pnt;
- /* Skip past white space after the name */
- while (*pnt == ' ' || *pnt == '\t')
- pnt++;
- /* silently ignore errors in the rc file. */
- if (*pnt != '=')
- {
- fprintf (stderr, _("%s:%d: equals sign required\n"), filename, linum);
- continue;
- }
- /* Skip pas the = sign, and any white space following it */
- pnt++; /* Skip past '=' sign */
- while (*pnt == ' ' || *pnt == '\t')
- pnt++;
-
- /* now it is safe to NUL terminate the name */
-
- *name_end = 0;
-
- /* Now get rid of trailing newline */
-
- pnt1 = pnt;
- while (*pnt1)
- {
- if (*pnt1 == '\n')
- {
- *pnt1 = 0;
- break;
- }
- pnt1++;
- };
- /* OK, now figure out which option we have */
- for(rco = rcopt; rco->tag; rco++) {
- if(strcmp(rco->tag, name) == 0)
- {
- *rco->variable = strdup(pnt);
- break;
- };
- }
- if (rco->tag == NULL)
- {
- fprintf (stderr, _("%s:%d: field name \"%s\" unknown\n"), filename, linum,
- name);
- }
- }
- if (ferror(rcfile))
- perror(filename);
- fclose(rcfile);
-}
-
-char * path_table_l = NULL;
-char * path_table_m = NULL;
-
-char * jpath_table_l = NULL;
-char * jpath_table_m = NULL;
-
-int goof = 0;
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-void usage(){
- unsigned int i;
-/* const char **targets, **pp;*/
-
- printf (_("Usage: %s [options] file...\n"), program_name);
-
- printf (_("Options:\n"));
- for (i = 0; i < OPTION_COUNT; i++)
- {
- if (ld_options[i].doc != NULL)
- {
- int comma;
- int len;
- unsigned int j;
- const char *arg;
-
- printf (" ");
-
- comma = FALSE;
- len = 2;
-
- j = i;
- do
- {
- if (ld_options[j].shortopt != '\0'
- && ld_options[j].control != NO_HELP)
- {
- printf ("%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)
- {
- putchar (' ');
- ++len;
- }
- arg = gettext (ld_options[j].arg);
- printf ("%s", arg);
- len += strlen (arg);
- }
- comma = TRUE;
- }
- ++j;
- }
- while (j < OPTION_COUNT && ld_options[j].doc == NULL);
-
- j = i;
- do
- {
- if (ld_options[j].opt.name != NULL
- && ld_options[j].control != NO_HELP)
- {
- printf ("%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)
- {
- arg = gettext (ld_options[j].arg);
- printf (" %s", arg);
- len += 1 + strlen (arg);
- }
- comma = TRUE;
- }
- ++j;
- }
- while (j < OPTION_COUNT && ld_options[j].doc == NULL);
-
- if (len >= 30)
- {
- printf ("\n");
- len = 0;
- }
-
- for (; len < 30; len++)
- putchar (' ');
-
- printf ("%s\n", gettext (ld_options[i].doc));
- }
- }
- exit(1);
-}
-
-
-/*
- * 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 (mkisofs had it wrong too for the longest time).
- */
-int FDECL2(iso9660_date,char *, result, time_t, crtime){
- struct tm *local;
- local = localtime(&crtime);
- result[0] = local->tm_year;
- result[1] = local->tm_mon + 1;
- result[2] = local->tm_mday;
- result[3] = local->tm_hour;
- result[4] = local->tm_min;
- result[5] = local->tm_sec;
-
- /*
- * 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;
-}
-
-extern char * cdwrite_data;
-
-int FDECL2(main, int, argc, char **, argv){
- struct directory_entry de;
-#ifdef HAVE_SBRK
- unsigned long mem_start;
-#endif
- struct stat statbuf;
- char * scan_tree;
- char * merge_image = NULL;
- struct iso_directory_record * mrootp = NULL;
- struct output_fragment * opnt;
- int longind;
- char shortopts[OPTION_COUNT * 3 + 2];
- struct option longopts[OPTION_COUNT + 1];
- int c;
- char *log_file = 0;
-
- set_program_name (argv[0]);
-#if (defined(ENABLE_NLS) && ENABLE_NLS)
- setlocale (LC_ALL, "");
- bindtextdomain (PACKAGE, LOCALEDIR);
- textdomain (PACKAGE);
-#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */
-
- if (argc < 2)
- usage();
-
- /* Get the defaults from the .mkisofsrc file */
- read_rcfile(argv[0]);
-
- outfile = NULL;
-
- /*
- * Copy long option initialization from GNU-ld.
- */
- /* Starting the short option string with '-' is for programs that
- expect options and other ARGV-elements in any order and that care about
- the ordering of the two. We describe each non-option ARGV-element
- as if it were the argument of an option with character code 1. */
- {
- unsigned int i;
- int is, il;
- shortopts[0] = '-';
- is = 1;
- il = 0;
- for (i = 0; i < OPTION_COUNT; i++)
- {
- if (ld_options[i].shortopt != '\0')
- {
- shortopts[is] = ld_options[i].shortopt;
- ++is;
- if (ld_options[i].opt.has_arg == required_argument
- || ld_options[i].opt.has_arg == optional_argument)
- {
- shortopts[is] = ':';
- ++is;
- if (ld_options[i].opt.has_arg == optional_argument)
- {
- shortopts[is] = ':';
- ++is;
- }
- }
- }
- if (ld_options[i].opt.name != NULL)
- {
- longopts[il] = ld_options[i].opt;
- ++il;
- }
- }
- shortopts[is] = '\0';
- longopts[il].name = NULL;
- }
-
- while ((c = getopt_long_only (argc, argv, shortopts, longopts, &longind)) != EOF)
- switch (c)
- {
- case 1:
- /*
- * A filename that we take as input.
- */
- optind--;
- goto parse_input_files;
- case 'C':
- /*
- * This is a temporary hack until cdwrite gets the proper hooks in
- * it.
- */
- cdwrite_data = optarg;
- break;
- case 'i':
- fprintf (stderr, _("-i option no longer supported.\n"));
- exit(1);
- break;
- case 'J':
- use_Joliet++;
- break;
- case 'a':
- all_files++;
- break;
- case 'b':
- use_eltorito++;
- boot_image = optarg; /* pathname of the boot image on cd */
- if (boot_image == NULL)
- error (1, 0, _("Required boot image pathname missing"));
- break;
- case 'G':
- use_embedded_boot = 1;
- boot_image_embed = optarg; /* pathname of the boot image on host filesystem */
- if (boot_image_embed == NULL)
- error (1, 0, _("Required boot image pathname missing"));
- break;
- case OPTION_PROTECTIVE_MSDOS_LABEL:
- use_protective_msdos_label = 1;
- break;
- case 'c':
- use_eltorito++;
- boot_catalog = optarg; /* pathname of the boot image on cd */
- if (boot_catalog == NULL)
- {
- fprintf (stderr, _("Required boot catalog pathname missing\n"));
- exit (1);
- }
- break;
- case OPTION_BOOT_INFO_TABLE:
- use_boot_info_table = 1;
- break;
- case OPTION_NO_EMUL_BOOT:
- fprintf (stderr, _("Ignoring -no-emul-boot (no-emulation is the default behaviour)\n"));
- break;
- case OPTION_ELTORITO_EMUL_FLOPPY:
- use_eltorito_emul_floppy = 1;
- break;
- case OPTION_ABSTRACT:
- abstract = optarg;
- if(strlen(abstract) > 37)
- {
- fprintf (stderr, _("Abstract filename string too long\n"));
- exit (1);
- };
- break;
- case 'A':
- appid = optarg;
- if(strlen(appid) > 128)
- {
- fprintf (stderr, _("Application-id string too long\n"));
- exit (1);
- };
- break;
- case OPTION_BIBLIO:
- biblio = optarg;
- if(strlen(biblio) > 37)
- {
- fprintf (stderr, _("Bibliographic filename string too long\n"));
- exit (1);
- };
- break;
- case OPTION_COPYRIGHT:
- copyright = optarg;
- if(strlen(copyright) > 37)
- {
- fprintf (stderr, _("Copyright filename string too long\n"));
- exit (1);
- };
- break;
- case 'd':
- omit_period++;
- break;
- case 'D':
- RR_relocation_depth = 32767;
- break;
- case 'f':
- follow_links++;
- break;
- case 'l':
- full_iso9660_filenames++;
- break;
- case 'L':
- allow_leading_dots++;
- break;
- case OPTION_LOG_FILE:
- log_file = optarg;
- break;
- case 'M':
- merge_image = optarg;
- break;
- case 'N':
- omit_version_number++;
- break;
- case 'o':
- outfile = optarg;
- break;
- case 'p':
- preparer = optarg;
- if(strlen(preparer) > 128)
- {
- fprintf (stderr, _("Preparer string too long\n"));
- exit (1);
- };
- break;
- case OPTION_PRINT_SIZE:
- print_size++;
- break;
- case 'P':
- publisher = optarg;
- if(strlen(publisher) > 128)
- {
- fprintf (stderr, _("Publisher string too long\n"));
- exit (1);
- };
- break;
- case OPTION_QUIET:
- verbose = 0;
- break;
- case 'R':
- use_RockRidge++;
- break;
- case 'r':
- rationalize++;
- use_RockRidge++;
- break;
- case OPTION_SPLIT_OUTPUT:
- split_output++;
- break;
- case OPTION_SYSID:
- system_id = optarg;
- if(strlen(system_id) > 32)
- {
- fprintf (stderr, _("System ID string too long\n"));
- exit (1);
- };
- break;
- case 'T':
- generate_tables++;
- break;
- case 'V':
- volume_id = optarg;
- if(strlen(volume_id) > 32)
- {
- fprintf (stderr, _("Volume ID string too long\n"));
- exit (1);
- };
- break;
- case OPTION_VOLSET:
- volset_id = optarg;
- if(strlen(volset_id) > 128)
- {
- fprintf (stderr, _("Volume set ID string too long\n"));
- exit (1);
- };
- break;
- case OPTION_VOLSET_SIZE:
- volume_set_size = atoi(optarg);
- break;
- case OPTION_VOLSET_SEQ_NUM:
- volume_sequence_number = atoi(optarg);
- if (volume_sequence_number > volume_set_size)
- {
- fprintf (stderr, _("Volume set sequence number too big\n"));
- exit (1);
- }
- break;
- case 'v':
- verbose++;
- break;
- case 'z':
- transparent_compression++;
- break;
- case 'x':
- case 'm':
- /*
- * Somehow two options to do basically the same thing got added somewhere along
- * the way. The 'match' code supports limited globbing, so this is the one
- * that got selected. Unfortunately the 'x' switch is probably more intuitive.
- */
- add_match(optarg);
- break;
- case OPTION_I_HIDE:
- i_add_match(optarg);
- break;
- case OPTION_J_HIDE:
- j_add_match(optarg);
- break;
- case OPTION_HELP:
- usage ();
- exit (0);
- break;
- case OPTION_VERSION:
- printf ("%s version %s\n", PACKAGE_NAME, PACKAGE_VERSION);
- 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_CREAT_DATE:
- if (strlen (optarg) != 16)
- {
- fprintf (stderr, _("date string must be 16 characters.\n"));
- exit (1);
- }
- if (creation_date)
- free(creation_date);
- creation_date = strdup(optarg);
- break;
- case OPTION_MODIF_DATE:
- if (strlen (optarg) != 16)
- {
- fprintf (stderr, _("date string must be 16 characters.\n"));
- exit (1);
- }
- if (modification_date)
- free(modification_date);
- modification_date = strdup(optarg);
- break;
- case OPTION_EXPIR_DATE:
- if (strlen (optarg) != 16)
- {
- fprintf (stderr, _("date string must be 16 characters.\n"));
- exit (1);
- }
- if (expiration_date)
- free(expiration_date);
- expiration_date = strdup(optarg);
- break;
- case OPTION_EFFEC_DATE:
- if (strlen (optarg) != 16)
- {
- fprintf (stderr, _("date string must be 16 characters.\n"));
- exit (1);
- }
- if (effective_date)
- free(effective_date);
- effective_date = strdup(optarg);
- break;
- default:
- usage();
- exit(1);
- }
-
-parse_input_files:
-
-#ifdef __NetBSD__
- {
- int resource;
- struct rlimit rlp;
- if (getrlimit(RLIMIT_DATA,&rlp) == -1)
- perror (_("Warning: getrlimit"));
- else {
- rlp.rlim_cur=33554432;
- if (setrlimit(RLIMIT_DATA,&rlp) == -1)
- perror (_("Warning: setrlimit"));
- }
- }
-#endif
-#ifdef HAVE_SBRK
- mem_start = (unsigned long) sbrk(0);
-#endif
-
- /* if the -hide-joliet option has been given, set the Joliet option */
- if (!use_Joliet && j_ishidden())
- use_Joliet++;
-
- if(verbose > 1) fprintf(stderr,"%s\n", version_string);
-
- if(cdwrite_data == NULL && merge_image != NULL)
- {
- fprintf (stderr, _("Multisession usage bug: Must specify -C if -M is used.\n"));
- exit (0);
- }
-
- if(cdwrite_data != NULL && merge_image == NULL)
- {
- fprintf (stderr, _("Warning: -C specified without -M: old session data will not be merged.\n"));
- }
-
- /* The first step is to scan the directory tree, and take some notes */
-
- scan_tree = argv[optind];
-
-
- if(!scan_tree){
- usage();
- exit(1);
- };
-
-#ifndef VMS
- if(scan_tree[strlen(scan_tree)-1] != '/') {
- scan_tree = (char *) e_malloc(strlen(argv[optind])+2);
- strcpy(scan_tree, argv[optind]);
- strcat(scan_tree, "/");
- };
-#endif
-
- if(use_RockRidge){
-#if 1
- extension_record = generate_rr_extension_record("RRIP_1991A",
- "THE ROCK RIDGE INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS",
- "PLEASE CONTACT DISC PUBLISHER FOR SPECIFICATION SOURCE. SEE PUBLISHER IDENTIFIER IN PRIMARY VOLUME DESCRIPTOR FOR CONTACT INFORMATION.", &extension_record_size);
-#else
- extension_record = generate_rr_extension_record("IEEE_P1282",
- "THE IEEE P1282 PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS",
- "PLEASE CONTACT THE IEEE STANDARDS DEPARTMENT, PISCATAWAY, NJ, USA FOR THE P1282 SPECIFICATION.", &extension_record_size);
-#endif
- }
-
- if (log_file) {
- FILE *lfp;
- int i;
-
- /* open log file - test that we can open OK */
- if ((lfp = fopen(log_file, "w")) == NULL)
- error (1, errno, _("can't open logfile: %s"), log_file);
- 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)
- error (1, errno, _("can't open logfile: %s\n"), log_file);
- if(verbose > 1) {
- for (i=0;i<argc;i++)
- fprintf(stderr,"%s ", argv[i]);
-
- fprintf(stderr,"\n%s\n", version_string);
- }
- }
-
- /*
- * See if boot catalog file exists in root directory, if not
- * we will create it.
- */
- if (use_eltorito)
- init_boot_catalog(argv[optind]);
-
- /*
- * Find the device and inode number of the root directory.
- * Record this in the hash table so we don't scan it more than
- * once.
- */
- stat_filter(argv[optind], &statbuf);
- add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf));
-
- memset(&de, 0, sizeof(de));
-
- de.filedir = root; /* We need this to bootstrap */
-
- if (cdwrite_data != NULL && merge_image == NULL) {
- /* in case we want to add a new session, but don't want to merge old one */
- get_session_start(NULL);
- }
-
- if( merge_image != NULL )
- {
- mrootp = merge_isofs(merge_image);
- if( mrootp == NULL )
- {
- /*
- * Complain and die.
- */
- error (1, 0, _("Unable to open previous session image %s\n"),
- merge_image);
- }
-
- memcpy(&de.isorec.extent, mrootp->extent, 8);
- }
-
- /*
- * 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);
-
- /*
- * Scan the actual directory (and any we find below it)
- * for files to write out to the output image. Note - we
- * take multiple source directories and keep merging them
- * onto the image.
- */
- while(optind < argc)
- {
- char * node;
- struct directory * graft_dir;
- struct stat st;
- char * short_name;
- int status;
- char graft_point[1024];
-
- /*
- * We would like a syntax like:
- *
- * /tmp=/usr/tmp/xxx
- *
- * where the user can specify a place to graft each
- * component of the tree. To do this, we may have to create
- * directories along the way, of course.
- * Secondly, I would like to allow the user to do something
- * like:
- *
- * /home/baz/RMAIL=/u3/users/baz/RMAIL
- *
- * so that normal files could also be injected into the tree
- * at an arbitrary point.
- *
- * The idea is that the last component of whatever is being
- * entered would take the name from the last component of
- * whatever the user specifies.
- *
- * The default will be that the file is injected at the
- * root of the image tree.
- */
- node = strchr(argv[optind], '=');
- short_name = NULL;
-
- if( node != NULL )
- {
- char * pnt;
- char * xpnt;
-
- *node = '\0';
- strcpy(graft_point, argv[optind]);
- *node = '=';
- node++;
-
- graft_dir = root;
- xpnt = graft_point;
- if( *xpnt == PATH_SEPARATOR )
- {
- xpnt++;
- }
-
- /*
- * Loop down deeper and deeper until we
- * find the correct insertion spot.
- */
- while(1==1)
- {
- pnt = strchr(xpnt, PATH_SEPARATOR);
- if( pnt == NULL )
- {
- if( *xpnt != '\0' )
- {
- short_name = xpnt;
- }
- break;
- }
- *pnt = '\0';
- graft_dir = find_or_create_directory(graft_dir,
- graft_point,
- NULL, TRUE);
- *pnt = PATH_SEPARATOR;
- xpnt = pnt + 1;
- }
- }
- else
- {
- graft_dir = root;
- node = argv[optind];
- }
-
- /*
- * Now see whether the user wants to add a regular file,
- * or a directory at this point.
- */
- status = stat_filter(node, &st);
- if( status != 0 )
- {
- /*
- * This is a fatal error - the user won't be getting what
- * they want if we were to proceed.
- */
- error (1, 0, _("Invalid node - %s\n"), node);
- }
- else
- {
- if( S_ISDIR(st.st_mode) )
- {
- if (!scan_directory_tree(graft_dir, node, &de))
- {
- exit(1);
- }
- }
- else
- {
- if( short_name == NULL )
- {
- short_name = strrchr(node, PATH_SEPARATOR);
- if( short_name == NULL || short_name < node )
- {
- short_name = node;
- }
- else
- {
- short_name++;
- }
- }
- if( !insert_file_entry(graft_dir, node, short_name) )
- {
- exit(1);
- }
- }
- }
-
- optind++;
- }
-
-
- /*
- * Now merge in any previous sessions. This is driven on the source
- * side, since we may need to create some additional directories.
- */
- if( merge_image != NULL )
- {
- merge_previous_session(root, mrootp);
- }
-
- /* hide "./rr_moved" if all its contents have been hidden */
- if (reloc_dir && i_ishidden())
- hide_reloc_dir();
-
- /*
- * Sort the directories in the required order (by ISO9660). Also,
- * choose the names for the 8.3 filesystem if required, and do
- * any other post-scan work.
- */
- goof += sort_tree(root);
-
- if( use_Joliet )
- {
- goof += joliet_sort_tree(root);
- }
-
- if (goof)
- error (1, 0, _("Joliet tree sort failed.\n"));
-
- /*
- * Fix a couple of things in the root directory so that everything
- * is self consistent.
- */
- root->self = root->contents; /* Fix this up so that the path
- tables get done right */
-
- /*
- * OK, ready to write the file. Open it up, and generate the thing.
- */
- if (print_size){
- discimage = fopen("/dev/null", "wb");
- if (!discimage)
- error (1, errno, _("Unable to open /dev/null\n"));
- } else if (outfile){
- discimage = fopen(outfile, "wb");
- if (!discimage)
- error (1, errno, _("Unable to open disc image file\n"));
- } else {
- discimage = stdout;
-
-#if defined(__CYGWIN32__)
- setmode(fileno(stdout), O_BINARY);
-#endif
- }
-
- /* Now assign addresses on the disc for the path table. */
-
- path_blocks = (path_table_size + (SECTOR_SIZE - 1)) >> 11;
- if (path_blocks & 1) path_blocks++;
-
- jpath_blocks = (jpath_table_size + (SECTOR_SIZE - 1)) >> 11;
- if (jpath_blocks & 1) jpath_blocks++;
-
- /*
- * Start to set up the linked list that we use to track the
- * contents of the disc.
- */
- outputlist_insert(&padblock_desc);
-
- /*
- * PVD for disc.
- */
- outputlist_insert(&voldesc_desc);
-
- /*
- * SVD for El Torito. MUST be immediately after the PVD!
- */
- if( use_eltorito)
- {
- outputlist_insert(&torito_desc);
- }
-
- /*
- * SVD for Joliet.
- */
- if( use_Joliet)
- {
- outputlist_insert(&joliet_desc);
- }
-
- /*
- * Finally the last volume desctiptor.
- */
- outputlist_insert(&end_vol);
-
-
- outputlist_insert(&pathtable_desc);
- if( use_Joliet)
- {
- outputlist_insert(&jpathtable_desc);
- }
-
- outputlist_insert(&dirtree_desc);
- if( use_Joliet)
- {
- outputlist_insert(&jdirtree_desc);
- }
-
- outputlist_insert(&dirtree_clean);
-
- if(extension_record)
- {
- outputlist_insert(&extension_desc);
- }
-
- outputlist_insert(&files_desc);
-
- /*
- * Allow room for the various headers we will be writing. There
- * will always be a primary and an end volume descriptor.
- */
- last_extent = session_start;
-
- /*
- * Calculate the size of all of the components of the disc, and assign
- * extent numbers.
- */
- for(opnt = out_list; opnt; opnt = opnt->of_next )
- {
- if( opnt->of_size != NULL )
- {
- (*opnt->of_size)(last_extent);
- }
- }
-
- /*
- * Generate the contents of any of the sections that we want to generate.
- * Not all of the fragments will do anything here - most will generate the
- * data on the fly when we get to the write pass.
- */
- for(opnt = out_list; opnt; opnt = opnt->of_next )
- {
- if( opnt->of_generate != NULL )
- {
- (*opnt->of_generate)();
- }
- }
-
- if( in_image != NULL )
- {
- fclose(in_image);
- }
-
- /*
- * Now go through the list of fragments and write the data that corresponds to
- * each one.
- */
- for(opnt = out_list; opnt; opnt = opnt->of_next )
- {
- if( opnt->of_write != NULL )
- {
- (*opnt->of_write)(discimage);
- }
- }
-
- if( verbose > 0 )
- {
-#ifdef HAVE_SBRK
- fprintf (stderr, _("Max brk space used %x\n"),
- (unsigned int)(((unsigned long)sbrk(0)) - mem_start));
-#endif
- fprintf (stderr, _("%llu extents written (%llu MiB)\n"), last_extent, last_extent >> 9);
- }
-
-#ifdef VMS
- return 1;
-#else
- return 0;
-#endif
-}
-
-void *
-FDECL1(e_malloc, size_t, size)
-{
- void* pt = 0;
- if( (size > 0) && ((pt = malloc (size)) == NULL))
- error (1, errno, "malloc");
-return pt;
-}
+++ /dev/null
-/*
- * Header file mkisofs.h - assorted structure definitions and typecasts.
-
- Written by Eric Youngdale (1993).
-
- Copyright 1993 Yggdrasil Computing, Incorporated
-
- Copyright (C) 2009,2010 Free Software Foundation, Inc.
-
- 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 3, 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, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * $Id: mkisofs.h,v 1.20 1999/03/02 04:16:41 eric Exp $
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <prototyp.h>
-#include <sys/stat.h>
-
-#if (defined(ENABLE_NLS) && ENABLE_NLS)
-
-# include <locale.h>
-# include <libintl.h>
-
-#else /* ! (defined(ENABLE_NLS) && ENABLE_NLS) */
-
-/* Disabled NLS.
- The casts to 'const char *' serve the purpose of producing warnings
- for invalid uses of the value returned from these functions.
- On pre-ANSI systems without 'const', the config.h file is supposed to
- contain "#define const". */
-# define gettext(Msgid) ((const char *) (Msgid))
-#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */
-
-#define _(str) gettext(str)
-#define N_(str) str
-
-/* This symbol is used to indicate that we do not have things like
- symlinks, devices, and so forth available. Just files and dirs */
-
-#ifdef VMS
-#define NON_UNIXFS
-#endif
-
-#ifdef DJGPP
-#define NON_UNIXFS
-#endif
-
-#ifdef VMS
-#include <sys/dir.h>
-#define dirent direct
-#endif
-
-#ifdef _WIN32
-#define NON_UNIXFS
-#endif /* _WIN32 */
-
-#ifndef S_IROTH
-#define S_IROTH 0
-#endif
-
-#ifndef S_IRGRP
-#define S_IRGRP 0
-#endif
-
-#ifndef HAVE_GETUID
-static inline int
-getuid ()
-{
- return 0;
-}
-#endif
-
-#ifndef HAVE_GETGID
-static inline int
-getgid ()
-{
- return 0;
-}
-#endif
-
-#ifndef HAVE_LSTAT
-static inline int
-lstat (const char *filename, struct stat *buf)
-{
- return stat (filename, buf);
-}
-#endif
-
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#if defined(HAVE_DIRENT_H)
-# include <dirent.h>
-# define NAMLEN(dirent) strlen((dirent)->d_name)
-#else
-# define dirent direct
-# define NAMLEN(dirent) (dirent)->d_namlen
-# if defined(HAVE_SYS_NDIR_H)
-# include <sys/ndir.h>
-# endif
-# if defined(HAVE_SYS_DIR_H)
-# include <sys/dir.h>
-# endif
-# if defined(HAVE_NDIR_H)
-# include <ndir.h>
-# endif
-#endif
-
-#if defined(HAVE_STRING_H)
-#include <string.h>
-#else
-#if defined(HAVE_STRINGS_H)
-#include <strings.h>
-#endif
-#endif
-
-#ifdef ultrix
-extern char *strdup();
-#endif
-
-#ifdef __STDC__
-#define DECL(NAME,ARGS) NAME ARGS
-#define FDECL1(NAME,TYPE0, ARG0) \
- NAME(TYPE0 ARG0)
-#define FDECL2(NAME,TYPE0, ARG0,TYPE1, ARG1) \
- NAME(TYPE0 ARG0, TYPE1 ARG1)
-#define FDECL3(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2) \
- NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2)
-#define FDECL4(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3) \
- NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2, TYPE3 ARG3)
-#define FDECL5(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4) \
- NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2, TYPE3 ARG3, TYPE4 ARG4)
-#define FDECL6(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4, TYPE5, ARG5) \
- NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2, TYPE3 ARG3, TYPE4 ARG4, TYPE5 ARG5)
-#else
-#define DECL(NAME,ARGS) NAME()
-#define FDECL1(NAME,TYPE0, ARG0) NAME(ARG0) TYPE0 ARG0;
-#define FDECL2(NAME,TYPE0, ARG0,TYPE1, ARG1) NAME(ARG0, ARG1) TYPE0 ARG0; TYPE1 ARG1;
-#define FDECL3(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2) \
- NAME(ARG0, ARG1, ARG2) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2;
-#define FDECL4(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3) \
- NAME(ARG0, ARG1, ARG2, ARG3, ARG4) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2; TYPE3 ARG3;
-#define FDECL5(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4) \
- NAME(ARG0, ARG1, ARG2, ARG3, ARG4) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2; TYPE3 ARG3; TYPE4 ARG4;
-#define FDECL6(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4, TYPE5, ARG5) \
- NAME(ARG0, ARG1, ARG2, ARG3, ARG4, ARG5) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2; TYPE3 ARG3; TYPE4 ARG4; TYPE5 ARG5;
-#define const
-#endif
-
-
-#ifdef __SVR4
-#include <stdlib.h>
-#else
-extern int optind;
-extern char *optarg;
-/* extern int getopt (int __argc, char **__argv, char *__optstring); */
-#endif
-
-#include "iso9660.h"
-#include "defaults.h"
-
-struct directory_entry{
- struct directory_entry * next;
- struct directory_entry * jnext;
- struct iso_directory_record isorec;
- uint64_t starting_block;
- uint64_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;
-};
-
-struct file_hash{
- struct file_hash * next;
- ino_t inode; /* Used in the hash table */
- dev_t dev; /* Used in the hash table */
- unsigned int starting_block;
- unsigned int size;
-};
-
-
-/*
- * 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 mkisofs 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;
-#ifdef __STDC__
- int (*of_size)(int);
- int (*of_generate)(void);
- int (*of_write)(FILE *);
-#else
- int (*of_size)();
- int (*of_generate)();
- int (*of_write)();
-#endif
-};
-
-extern struct output_fragment * out_list;
-extern struct output_fragment * out_tail;
-
-extern struct output_fragment padblock_desc;
-extern struct output_fragment voldesc_desc;
-extern struct output_fragment joliet_desc;
-extern struct output_fragment torito_desc;
-extern struct output_fragment end_vol;
-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;
-
-/*
- * 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 reqd for this dir */
- unsigned int depth;
- unsigned int size;
- unsigned int extent;
- unsigned int jsize;
- unsigned int jextent;
- unsigned short path_index;
- unsigned short jpath_index;
- unsigned short dir_flags;
- unsigned short dir_nlink;
-};
-
-extern int goof;
-extern struct directory * root;
-extern struct directory * reloc_dir;
-extern uint64_t next_extent;
-extern uint64_t last_extent;
-extern uint64_t last_extent_written;
-extern uint64_t 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 use_eltorito;
-extern int use_embedded_boot;
-extern int use_protective_msdos_label;
-extern int use_eltorito_emul_floppy;
-extern int use_boot_info_table;
-extern int use_RockRidge;
-extern int use_Joliet;
-extern int rationalize;
-extern int follow_links;
-extern int verbose;
-extern int all_files;
-extern int generate_tables;
-extern int print_size;
-extern int split_output;
-extern int omit_period;
-extern int omit_version_number;
-extern int transparent_compression;
-extern unsigned int RR_relocation_depth;
-extern int full_iso9660_filenames;
-extern int split_SL_component;
-extern int split_SL_field;
-
-/* tree.c */
-extern int DECL(stat_filter, (char *, struct stat *));
-extern int DECL(lstat_filter, (char *, struct stat *));
-extern int DECL(sort_tree,(struct directory *));
-extern struct directory *
- DECL(find_or_create_directory,(struct directory *, const char *,
- struct directory_entry * self, int));
-extern void DECL (finish_cl_pl_entries, (void));
-extern int DECL(scan_directory_tree,(struct directory * this_dir,
- char * path,
- struct directory_entry * self));
-extern int DECL(insert_file_entry,(struct directory *, char *,
- char *));
-
-extern void DECL(generate_iso9660_directories,(struct directory *, FILE*));
-extern void DECL(dump_tree,(struct directory * node));
-extern struct directory_entry * DECL(search_tree_file, (struct
- directory * node,char * filename));
-extern void DECL(update_nlink_field,(struct directory * node));
-extern void DECL (init_fstatbuf, (void));
-extern struct stat root_statbuf;
-
-/* eltorito.c */
-extern void DECL(init_boot_catalog, (const char * path ));
-extern void DECL(get_torito_desc, (struct eltorito_boot_descriptor * path ));
-
-/* write.c */
-extern int DECL(get_731,(char *));
-extern int DECL(get_733,(char *));
-extern int DECL(isonum_733,(unsigned char *));
-extern void DECL(set_723,(char *, unsigned int));
-extern void DECL(set_731,(char *, unsigned int));
-extern void DECL(set_721,(char *, unsigned int));
-extern void DECL(set_733,(char *, unsigned int));
-extern int DECL(sort_directory,(struct directory_entry **));
-extern void DECL(generate_one_directory,(struct directory *, FILE*));
-extern void DECL(memcpy_max, (char *, char *, int));
-extern int DECL(oneblock_size, (int starting_extent));
-extern struct iso_primary_descriptor vol_desc;
-extern void DECL(xfwrite, (void * buffer, uint64_t count, uint64_t size, FILE * file));
-extern void DECL(set_732, (char * pnt, unsigned int i));
-extern void DECL(set_722, (char * pnt, unsigned int i));
-extern void DECL(outputlist_insert, (struct output_fragment * frag));
-
-/*
- * Set by user command-line to override default date values
- */
-
-extern char *creation_date;
-extern char *modification_date;
-extern char *expiration_date;
-extern char *effective_date;
-
-/* multi.c */
-
-extern FILE * in_image;
-extern struct iso_directory_record *
- DECL(merge_isofs,(char * path));
-
-extern int DECL(free_mdinfo, (struct directory_entry **, int len));
-
-extern struct directory_entry **
- DECL(read_merging_directory,(struct iso_directory_record *, int*));
-extern void
- DECL(merge_remaining_entries, (struct directory *,
- struct directory_entry **, int));
-extern int
- DECL(merge_previous_session, (struct directory *,
- struct iso_directory_record *));
-
-extern int DECL(get_session_start, (int *));
-
-/* joliet.c */
-int DECL(joliet_sort_tree, (struct directory * node));
-
-/* match.c */
-extern int DECL(matches, (char *));
-extern void DECL(add_match, (char *));
-
-/* files.c */
-struct dirent * DECL(readdir_add_files, (char **, char *, DIR *));
-
-/* */
-
-extern int DECL(iso9660_file_length,(const char* name,
- struct directory_entry * sresult, int flag));
-extern int DECL(iso9660_date,(char *, time_t));
-extern void DECL(add_hash,(struct directory_entry *));
-extern struct file_hash * DECL(find_hash,(dev_t, ino_t));
-extern void DECL(add_directory_hash,(dev_t, ino_t));
-extern struct file_hash * DECL(find_directory_hash,(dev_t, ino_t));
-extern void DECL (flush_file_hash, (void));
-extern int DECL(delete_file_hash,(struct directory_entry *));
-extern struct directory_entry * DECL(find_file_hash,(char *));
-extern void DECL(add_file_hash,(struct directory_entry *));
-extern int DECL(generate_rock_ridge_attributes,(char *, char *,
- struct directory_entry *,
- struct stat *, struct stat *,
- int deep_flag));
-extern char * DECL(generate_rr_extension_record,(char * id, char * descriptor,
- char * source, int * size));
-
-extern int DECL(check_prev_session, (struct directory_entry **, int len,
- struct directory_entry *,
- struct stat *,
- struct stat *,
- struct directory_entry **));
-
-#ifdef USE_SCG
-/* scsi.c */
-#ifdef __STDC__
-extern int readsecs(int startsecno, void *buffer, int sectorcount);
-extern int scsidev_open(char *path);
-#else
-extern int readsecs();
-extern int scsidev_open();
-#endif
-#endif
-
-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 *boot_image_embed;
-extern int volume_set_size;
-extern int volume_sequence_number;
-
-extern void * DECL(e_malloc,(size_t));
-
-
-#define SECTOR_SIZE (2048)
-#define ROUND_UP(X) ((X + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1))
-
-#define NEED_RE 1
-#define NEED_PL 2
-#define NEED_CL 4
-#define NEED_CE 8
-#define NEED_SP 16
-
-#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
-#define DIR_HAS_DOT 0x02
-#define DIR_HAS_DOTDOT 0x04
-#define INHIBIT_JOLIET_ENTRY 0x08
-#define INHIBIT_RR_ENTRY 0x10
-#define RELOCATED_DIRECTORY 0x20
-#define INHIBIT_ISO9660_ENTRY 0x40
-
-/*
- * 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. From what I can tell SunOS is the only one with this trouble.
- */
-#ifndef NAME_MAX
-#ifdef FILENAME_MAX
-#define NAME_MAX FILENAME_MAX
-#else
-#define NAME_MAX 128
-#endif
-#endif
+++ /dev/null
-/*
- * GRUB -- GRand Unified Bootloader
- * Copyright (C) 1999,2000,2001,2002,2004,2007 Free Software Foundation, Inc.
- *
- * GRUB 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 3 of the License, or
- * (at your option) any later version.
- *
- * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef MSDOS_PARTITION_H
-#define MSDOS_PARTITION_H 1
-
-#include <stdint.h>
-
-/* The signature. */
-#define MSDOS_PARTITION_SIGNATURE ((0xaa << 8) | 0x55)
-
-/* This is not a flag actually, but used as if it were a flag. */
-#define MSDOS_PARTITION_TYPE_HIDDEN_FLAG 0x10
-
-/* The partition entry. */
-struct msdos_partition_entry
-{
- /* If active, 0x80, otherwise, 0x00. */
- uint8_t flag;
-
- /* The head of the start. */
- uint8_t start_head;
-
- /* (S | ((C >> 2) & 0xC0)) where S is the sector of the start and C
- is the cylinder of the start. Note that S is counted from one. */
- uint8_t start_sector;
-
- /* (C & 0xFF) where C is the cylinder of the start. */
- uint8_t start_cylinder;
-
- /* The partition type. */
- uint8_t type;
-
- /* The end versions of start_head, start_sector and start_cylinder,
- respectively. */
- uint8_t end_head;
- uint8_t end_sector;
- uint8_t end_cylinder;
-
- /* The start sector. Note that this is counted from zero. */
- uint32_t start;
-
- /* The length in sector units. */
- uint32_t length;
-} __attribute__ ((packed));
-
-/* The structure of MBR. */
-struct msdos_partition_mbr
-{
- /* The code area (actually, including BPB). */
- uint8_t code[446];
-
- /* Four partition entries. */
- struct msdos_partition_entry entries[4];
-
- /* The signature 0xaa55. */
- uint16_t signature;
-} __attribute__ ((packed));
-
-#endif
+++ /dev/null
-/*
- * File multi.c - scan existing iso9660 image and merge into
- * iso9660 filesystem. Used for multisession support.
- *
- * Written by Eric Youngdale (1996).
- *
- * Copyright (C) 2009 Free Software Foundation, Inc.
- *
- * 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 3, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "config.h"
-
-#ifndef VMS
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#else
-#include <sys/file.h>
-#include <vms/fabdef.h>
-#include "vms.h"
-extern char * strdup(const char *);
-#endif
-
-#include "mkisofs.h"
-#include "iso9660.h"
-
-#define TF_CREATE 1
-#define TF_MODIFY 2
-#define TF_ACCESS 4
-#define TF_ATTRIBUTES 8
-
-static int isonum_711 __PR((unsigned char * p));
-static int isonum_721 __PR((unsigned char * p));
-static int isonum_723 __PR((unsigned char * p));
-static int isonum_731 __PR((unsigned char * p));
-
-static int DECL(merge_old_directory_into_tree, (struct directory_entry *,
- struct directory *));
-
-#ifdef __STDC__
-static int
-isonum_711 (unsigned char * p)
-#else
-static int
-isonum_711 (p)
- unsigned char * p;
-#endif
-{
- return (*p & 0xff);
-}
-
-#ifdef __STDC__
-static int
-isonum_721 (unsigned char * p)
-#else
-static int
-isonum_721 (p)
- unsigned char * p;
-#endif
-{
- return ((p[0] & 0xff) | ((p[1] & 0xff) << 8));
-}
-
-#ifdef __STDC__
-static int
-isonum_723 (unsigned char * p)
-#else
-static int
-isonum_723 (p)
- unsigned char * p;
-#endif
-{
-#if 0
- if (p[0] != p[3] || p[1] != p[2]) {
- fprintf (stderr, "invalid format 7.2.3 number\n");
- exit (1);
- }
-#endif
- return (isonum_721 (p));
-}
-
-#ifdef __STDC__
-static int
-isonum_731 (unsigned char * p)
-#else
-static int
-isonum_731 (p)
- unsigned char * p;
-#endif
-{
- return ((p[0] & 0xff)
- | ((p[1] & 0xff) << 8)
- | ((p[2] & 0xff) << 16)
- | ((p[3] & 0xff) << 24));
-}
-
-#ifdef __STDC__
-int
-isonum_733 (unsigned char * p)
-#else
-int
-isonum_733 (p)
- unsigned char * p;
-#endif
-{
- return (isonum_731 (p));
-}
-
-FILE * in_image = NULL;
-
-#ifndef USE_SCG
-/*
- * Don't define readsecs if mkisofs is linked with
- * the SCSI library.
- * readsecs() will be implemented as SCSI command in this case.
- *
- * Use global var in_image directly in readsecs()
- * the SCSI equivalent will not use a FILE* for I/O.
- *
- * The main point of this pointless abstraction is that Solaris won't let
- * you read 2K sectors from the cdrom driver. The fact that 99.9% of the
- * discs out there have a 2K sectorsize doesn't seem to matter that much.
- * Anyways, this allows the use of a scsi-generics type of interface on
- * Solaris.
- */
-#ifdef __STDC__
-static int
-readsecs(int startsecno, void *buffer, int sectorcount)
-#else
-static int
-readsecs(startsecno, buffer, sectorcount)
- int startsecno;
- void *buffer;
- int sectorcount;
-#endif
-{
- int f = fileno(in_image);
-
- if (lseek(f, (off_t)startsecno * SECTOR_SIZE, 0) == (off_t)-1)
- error (10, errno, _("Seek error on old image\n"));
- return (read(f, buffer, sectorcount * SECTOR_SIZE));
-}
-#endif
-
-/*
- * Parse the RR attributes so we can find the file name.
- */
-static int
-FDECL3(parse_rr, unsigned char *, pnt, int, len, struct directory_entry *,dpnt)
-{
- int cont_extent, cont_offset, cont_size;
- char name_buf[256];
-
- cont_extent = cont_offset = cont_size = 0;
-
- while(len >= 4){
- if(pnt[3] != 1) {
- fprintf (stderr, _("**Bad RR version attribute"));
- return -1;
- };
- if(strncmp((char *) pnt, "NM", 2) == 0) {
- strncpy(name_buf, (char *) pnt+5, pnt[2] - 5);
- name_buf[pnt[2] - 5] = 0;
- dpnt->name = strdup(name_buf);
- dpnt->got_rr_name = 1;
- return 0;
- }
-
- if(strncmp((char *) pnt, "CE", 2) == 0) {
- cont_extent = isonum_733(pnt+4);
- cont_offset = isonum_733(pnt+12);
- cont_size = isonum_733(pnt+20);
- };
-
- len -= pnt[2];
- pnt += pnt[2];
- if(len <= 3 && cont_extent) {
- unsigned char sector[SECTOR_SIZE];
- readsecs(cont_extent, sector, 1);
- parse_rr(§or[cont_offset], cont_size, dpnt);
- };
- };
-
- /* Fall back to the iso name if no RR name found */
- if (dpnt->name == NULL) {
- char *cp;
-
- strcpy(name_buf, dpnt->isorec.name);
- cp = strchr(name_buf, ';');
- if (cp != NULL) {
- *cp = '\0';
- }
-
- dpnt->name = strdup(name_buf);
- }
-
- return 0;
-} /* parse_rr */
-
-
-static int
-FDECL4(check_rr_dates, struct directory_entry *, dpnt,
- struct directory_entry *, current,
- struct stat *, statbuf,
- struct stat *,lstatbuf)
-{
- int cont_extent, cont_offset, cont_size;
- int offset;
- unsigned char * pnt;
- int len;
- int same_file;
- int same_file_type;
- mode_t mode;
- char time_buf[7];
-
-
- cont_extent = cont_offset = cont_size = 0;
- same_file = 1;
- same_file_type = 1;
-
- pnt = dpnt->rr_attributes;
- len = dpnt->rr_attr_size;
- /*
- * We basically need to parse the rr attributes again, and
- * dig out the dates and file types.
- */
- while(len >= 4){
- if(pnt[3] != 1) {
- fprintf (stderr, _("**Bad RR version attribute"));
- return -1;
- };
-
- /*
- * If we have POSIX file modes, make sure that the file type
- * is the same. If it isn't, then we must always
- * write the new file.
- */
- if(strncmp((char *) pnt, "PX", 2) == 0) {
- mode = isonum_733(pnt + 4);
- if( (lstatbuf->st_mode & S_IFMT) != (mode & S_IFMT) )
- {
- same_file_type = 0;
- same_file = 0;
- }
- }
-
- if(strncmp((char *) pnt, "TF", 2) == 0) {
- offset = 5;
- if( pnt[4] & TF_CREATE )
- {
- iso9660_date((char *) time_buf, lstatbuf->st_ctime);
- if(memcmp(time_buf, pnt+offset, 7) == 0)
- same_file = 0;
- offset += 7;
- }
- if( pnt[4] & TF_MODIFY )
- {
- iso9660_date((char *) time_buf, lstatbuf->st_mtime);
- if(memcmp(time_buf, pnt+offset, 7) == 0)
- same_file = 0;
- offset += 7;
- }
- }
-
- if(strncmp((char *) pnt, "CE", 2) == 0) {
- cont_extent = isonum_733(pnt+4);
- cont_offset = isonum_733(pnt+12);
- cont_size = isonum_733(pnt+20);
- };
-
- len -= pnt[2];
- pnt += pnt[2];
- if(len <= 3 && cont_extent) {
- unsigned char sector[SECTOR_SIZE];
-
- readsecs(cont_extent, sector, 1);
- parse_rr(§or[cont_offset], cont_size, dpnt);
- };
- };
-
- /*
- * If we have the same fundamental file type, then it is clearly
- * safe to reuse the TRANS.TBL entry.
- */
- if( same_file_type )
- {
- current->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY;
- }
-
- return same_file;
-}
-
-struct directory_entry **
-FDECL2(read_merging_directory, struct iso_directory_record *, mrootp,
- int *, nent)
-{
- unsigned char * cpnt;
- unsigned char * cpnt1;
- char * dirbuff;
- int i;
- struct iso_directory_record * idr;
- int len;
- struct directory_entry **pnt;
- int rlen;
- struct directory_entry **rtn;
- int seen_rockridge;
- unsigned char * tt_buf;
- int tt_extent;
- int tt_size;
-
- static int warning_given = 0;
-
- /*
- * First, allocate a buffer large enough to read in the entire
- * directory.
- */
- dirbuff = (char *) e_malloc(isonum_733((unsigned char *)mrootp->size));
-
- readsecs(isonum_733((unsigned char *)mrootp->extent), dirbuff,
- isonum_733((unsigned char *)mrootp->size)/SECTOR_SIZE);
-
- /*
- * Next look over the directory, and count up how many entries we
- * have.
- */
- len = isonum_733((unsigned char *)mrootp->size);
- i = 0;
- *nent = 0;
- while(i < len )
- {
- idr = (struct iso_directory_record *) &dirbuff[i];
- if(idr->length[0] == 0)
- {
- i = (i + SECTOR_SIZE - 1) & ~(SECTOR_SIZE - 1);
- continue;
- }
- (*nent)++;
- i += idr->length[0];
- }
-
- /*
- * Now allocate the buffer which will hold the array we are
- * about to return.
- */
- rtn = (struct directory_entry **) e_malloc(*nent * sizeof(*rtn));
-
- /*
- * Finally, scan the directory one last time, and pick out the
- * relevant bits of information, and store it in the relevant
- * bits of the structure.
- */
- i = 0;
- pnt = rtn;
- tt_extent = 0;
- seen_rockridge = 0;
- tt_size = 0;
- while(i < len )
- {
- idr = (struct iso_directory_record *) &dirbuff[i];
- if(idr->length[0] == 0)
- {
- i = (i + SECTOR_SIZE - 1) & ~(SECTOR_SIZE - 1);
- continue;
- }
- *pnt = (struct directory_entry *) e_malloc(sizeof(**rtn));
- (*pnt)->next = NULL;
- (*pnt)->isorec = *idr;
- (*pnt)->starting_block = isonum_733((unsigned char *)idr->extent);
- (*pnt)->size = isonum_733((unsigned char *)idr->size);
- (*pnt)->priority = 0;
- (*pnt)->name = NULL;
- (*pnt)->got_rr_name = 0;
- (*pnt)->table = NULL;
- (*pnt)->whole_name = NULL;
- (*pnt)->filedir = NULL;
- (*pnt)->parent_rec = NULL;
- /*
- * Set this information so that we correctly cache previous
- * session bits of information.
- */
- (*pnt)->inode = (*pnt)->starting_block;
- (*pnt)->dev = PREV_SESS_DEV;
- (*pnt)->rr_attributes = NULL;
- (*pnt)->rr_attr_size = 0;
- (*pnt)->total_rr_attr_size = 0;
- (*pnt)->de_flags = SAFE_TO_REUSE_TABLE_ENTRY;
-
- /*
- * Check for and parse any RR attributes for the file.
- * All we are really looking for here is the original name
- * of the file.
- */
- rlen = idr->length[0] & 0xff;
- cpnt = (unsigned char *) idr;
-
- rlen -= sizeof(struct iso_directory_record);
- cpnt += sizeof(struct iso_directory_record);
-
- rlen += sizeof(idr->name);
- cpnt -= sizeof(idr->name);
-
- rlen -= idr->name_len[0];
- cpnt += idr->name_len[0];
-
- if((idr->name_len[0] & 1) == 0){
- cpnt++;
- rlen--;
- };
-
- if( rlen != 0 )
- {
- (*pnt)->total_rr_attr_size = (*pnt)->rr_attr_size = rlen;
- (*pnt)->rr_attributes = e_malloc(rlen);
- memcpy((*pnt)->rr_attributes, cpnt, rlen);
- seen_rockridge = 1;
- }
-
- /*
- * Now zero out the remainder of the name field.
- */
- cpnt = (unsigned char *) &(*pnt)->isorec.name;
- cpnt += idr->name_len[0];
- memset(cpnt, 0, sizeof((*pnt)->isorec.name) - idr->name_len[0]);
-
- parse_rr((*pnt)->rr_attributes, rlen, *pnt);
-
- if( ((*pnt)->isorec.name_len[0] == 1)
- && ( ((*pnt)->isorec.name[0] == 0)
- || ((*pnt)->isorec.name[0] == 1)) )
- {
- if( (*pnt)->name != NULL )
- {
- free((*pnt)->name);
- }
- if( (*pnt)->whole_name != NULL )
- {
- free((*pnt)->whole_name);
- }
- if( (*pnt)->isorec.name[0] == 0 )
- {
- (*pnt)->name = strdup(".");
- }
- else
- {
- (*pnt)->name = strdup("..");
- }
- }
-
-#ifdef DEBUG
- fprintf(stderr, "got DE name: %s\n", (*pnt)->name);
-#endif
-
- if( strncmp(idr->name, "TRANS.TBL", 9) == 0)
- {
- if( (*pnt)->name != NULL )
- {
- free((*pnt)->name);
- }
- if( (*pnt)->whole_name != NULL )
- {
- free((*pnt)->whole_name);
- }
- (*pnt)->name = strdup("<translation table>");
- tt_extent = isonum_733((unsigned char *)idr->extent);
- tt_size = isonum_733((unsigned char *)idr->size);
- }
-
- pnt++;
- i += idr->length[0];
- }
-
- /*
- * If there was a TRANS.TBL;1 entry, then grab it, read it, and use it
- * to get the filenames of the files. Also, save the table info, just
- * in case we need to use it.
- */
- if( tt_extent != 0 && tt_size != 0 )
- {
- tt_buf = (unsigned char *) e_malloc(tt_size);
- readsecs(tt_extent, tt_buf, tt_size/SECTOR_SIZE);
-
- /*
- * Loop through the file, examine each entry, and attempt to
- * attach it to the correct entry.
- */
- cpnt = tt_buf;
- cpnt1 = tt_buf;
- while( cpnt - tt_buf < tt_size )
- {
- while(*cpnt1 != '\n' && *cpnt1 != '\0') cpnt1++;
- *cpnt1 = '\0';
-
- for(pnt = rtn, i = 0; i <*nent; i++, pnt++)
- {
- rlen = isonum_711((*pnt)->isorec.name_len);
- if( strncmp((char *) cpnt + 2, (*pnt)->isorec.name,
- rlen) == 0
- && cpnt[2+rlen] == ' ')
- {
- (*pnt)->table = e_malloc(strlen((char*)cpnt) - 33);
- sprintf((*pnt)->table, "%c\t%s\n",
- *cpnt, cpnt+37);
- if( !(*pnt)->got_rr_name )
- {
- if ((*pnt)->name != NULL) {
- free((*pnt)->name);
- }
- (*pnt)->name = strdup((char *) cpnt+37);
- }
- break;
- }
- }
- cpnt = cpnt1 + 1;
- cpnt1 = cpnt;
- }
-
- free(tt_buf);
- }
- else if( !seen_rockridge && !warning_given )
- {
- /*
- * Warn the user that iso (8.3) names were used because neither
- * Rock Ridge (-R) nor TRANS.TBL (-T) name translations were found.
- */
- fprintf (stderr, _("Warning: Neither Rock Ridge (-R) nor TRANS.TBL (-T) "
- "name translations were found on previous session. "
- "ISO (8.3) file names have been used instead.\n"));
- warning_given = 1;
- }
-
- if( dirbuff != NULL )
- {
- free(dirbuff);
- }
-
- return rtn;
-} /* read_merging_directory */
-
-/*
- * Free any associated data related to the structures.
- */
-int
-FDECL2(free_mdinfo, struct directory_entry ** , ptr, int, len )
-{
- int i;
- struct directory_entry **p;
-
- p = ptr;
- for(i=0; i<len; i++, p++)
- {
- /*
- * If the tree-handling code decided that it needed an entry,
- * it will have removed it from the list. Thus we must allow
- * for null pointers here.
- */
- if( *p == NULL )
- {
- continue;
- }
-
- if( (*p)->name != NULL )
- {
- free((*p)->name);
- }
-
- if( (*p)->whole_name != NULL )
- {
- free((*p)->whole_name);
- }
-
- if( (*p)->rr_attributes != NULL )
- {
- free((*p)->rr_attributes);
- }
-
- if( (*p)->table != NULL )
- {
- free((*p)->table);
- }
-
- free(*p);
-
- }
-
- free(ptr);
- return 0;
-}
-
-/*
- * Search the list to see if we have any entries from the previous
- * session that match this entry. If so, copy the extent number
- * over so we don't bother to write it out to the new session.
- */
-
-int
-FDECL6(check_prev_session, struct directory_entry ** , ptr, int, len,
- struct directory_entry *, curr_entry,
- struct stat *, statbuf, struct stat *, lstatbuf,
- struct directory_entry **, odpnt)
-{
- int i;
-
- for( i=0; i < len; i++ )
- {
- if( ptr[i] == NULL )
- {
- continue;
- }
-
-#if 0
- if( ptr[i]->name != NULL && ptr[i]->isorec.name_len[0] == 1
- && ptr[i]->name[0] == '\0' )
- {
- continue;
- }
- if( ptr[i]->name != NULL && ptr[i]->isorec.name_len[0] == 1
- && ptr[i]->name[0] == 1)
- {
- continue;
- }
-#else
- if( ptr[i]->name != NULL && strcmp(ptr[i]->name, ".") == 0 )
- {
- continue;
- }
- if( ptr[i]->name != NULL && strcmp(ptr[i]->name, "..") == 0 )
- {
- continue;
- }
-#endif
-
- if( ptr[i]->name != NULL
- && strcmp(ptr[i]->name, curr_entry->name) != 0 )
- {
- continue;
- }
-
- /*
- * We know that the files have the same name. If they also have
- * the same file type (i.e. file, dir, block, etc), then we
- * can safely reuse the TRANS.TBL entry for this file.
- * The check_rr_dates function will do this for us.
- *
- * Verify that the file type and dates are consistent.
- * If not, we probably have a different file, and we need
- * to write it out again.
- */
- if( (ptr[i]->rr_attributes != NULL)
- && (check_rr_dates(ptr[i], curr_entry, statbuf, lstatbuf)) )
- {
- goto found_it;
- }
-
-
- /*
- * Verify size and timestamp. If rock ridge is in use, we need
- * to compare dates from RR too. Directories are special, we
- * calculate their size later.
- */
- if( (curr_entry->isorec.flags[0] & 2) == 0
- && ptr[i]->size != curr_entry->size )
- {
- goto found_it;
- }
-
- if( memcmp(ptr[i]->isorec.date, curr_entry->isorec.date,7) != 0 )
- {
- goto found_it;
- }
-
- /*
- * Never ever reuse directory extents. See comments in
- * tree.c for an explaination of why this must be the case.
- */
- if( (curr_entry->isorec.flags[0] & 2) != 0 )
- {
- goto found_it;
- }
-
- memcpy(curr_entry->isorec.extent, ptr[i]->isorec.extent, 8);
- curr_entry->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY;
- goto found_it;
- }
- return 0;
-
-found_it:
- if( odpnt != NULL )
- {
- *odpnt = ptr[i];
- }
- else
- {
- free(ptr[i]);
- }
- ptr[i] = NULL;
- return 0;
-}
-
-/*
- * merge_isofs: Scan an existing image, and return a pointer
- * to the root directory for this image.
- */
-struct iso_directory_record * FDECL1(merge_isofs, char *, path)
-{
- char buffer[SECTOR_SIZE];
- int file_addr;
- int i;
- struct iso_primary_descriptor * pri = NULL;
- struct iso_directory_record * rootp;
- struct iso_volume_descriptor * vdp;
-
- /*
- * Start by opening up the image and searching for the volume header.
- * Ultimately, we need to search for volume headers in multiple places
- * because we might be starting with a multisession image.
- * FIXME(eric).
- */
-
-#ifndef USE_SCG
- in_image = fopen(path, "rb");
- if( in_image == NULL )
- {
- return NULL;
- }
-#else
- if (strchr(path, '/')) {
- in_image = fopen(path, "rb");
- if( in_image == NULL ) {
- return NULL;
- }
- } else {
- if (scsidev_open(path) < 0)
- return NULL;
- }
-#endif
-
- get_session_start(&file_addr);
-
- for(i = 0; i< 100; i++)
- {
- if (readsecs(file_addr/SECTOR_SIZE, &buffer,
- sizeof(buffer)/SECTOR_SIZE) != sizeof(buffer))
- error (10, errno, _("Read error on old image %s\n"), path);
-
- vdp = (struct iso_volume_descriptor *)buffer;
-
- if( (strncmp(vdp->id, ISO_STANDARD_ID, sizeof vdp->id) == 0)
- && (isonum_711((unsigned char *) vdp->type) == ISO_VD_PRIMARY) )
- {
- break;
- }
- file_addr += SECTOR_SIZE;
- }
-
- if( i == 100 )
- {
- return NULL;
- }
-
- pri = (struct iso_primary_descriptor *)vdp;
-
- /*
- * Check the blocksize of the image to make sure it is compatible.
- */
- if( (isonum_723 ((unsigned char *) pri->logical_block_size) != SECTOR_SIZE)
- || (isonum_723 ((unsigned char *) pri->volume_set_size) != 1) )
- {
- return NULL;
- }
-
- /*
- * Get the location and size of the root directory.
- */
- rootp = (struct iso_directory_record *)
- malloc(sizeof(struct iso_directory_record));
-
- memcpy(rootp, pri->root_directory_record, sizeof(*rootp));
-
- return rootp;
-}
-
-void FDECL3(merge_remaining_entries, struct directory *, this_dir,
- struct directory_entry **, pnt,
- int, n_orig)
-{
- int i;
- struct directory_entry * s_entry;
- unsigned int ttbl_extent = 0;
- unsigned int ttbl_index = 0;
- char whole_path[1024];
-
- /*
- * Whatever is leftover in the list needs to get merged back
- * into the directory.
- */
- for( i=0; i < n_orig; i++ )
- {
- if( pnt[i] == NULL )
- {
- continue;
- }
-
- if( pnt[i]->name != NULL && pnt[i]->whole_name == NULL)
- {
- /*
- * Set the name for this directory.
- */
- strcpy(whole_path, this_dir->de_name);
- strcat(whole_path, SPATH_SEPARATOR);
- strcat(whole_path, pnt[i]->name);
-
- pnt[i]->whole_name = strdup(whole_path);
- }
-
- if( pnt[i]->name != NULL
- && strcmp(pnt[i]->name, "<translation table>") == 0 )
- {
- ttbl_extent = isonum_733((unsigned char *) pnt[i]->isorec.extent);
- ttbl_index = i;
- continue;
- }
- /*
- * Skip directories for now - these need to be treated
- * differently.
- */
- if( (pnt[i]->isorec.flags[0] & 2) != 0 )
- {
- /*
- * FIXME - we need to insert this directory into the
- * tree, so that the path tables we generate will
- * be correct.
- */
- if( (strcmp(pnt[i]->name, ".") == 0)
- || (strcmp(pnt[i]->name, "..") == 0) )
- {
- free(pnt[i]);
- pnt[i] = NULL;
- continue;
- }
- else
- {
- merge_old_directory_into_tree(pnt[i], this_dir);
- }
- }
- pnt[i]->next = this_dir->contents;
- pnt[i]->filedir = this_dir;
- this_dir->contents = pnt[i];
- pnt[i] = NULL;
- }
-
-
- /*
- * If we don't have an entry for the translation table, then
- * don't bother trying to copy the starting extent over.
- * Note that it is possible that if we are copying the entire
- * directory, the entry for the translation table will have already
- * been inserted into the linked list and removed from the old
- * entries list, in which case we want to leave the extent number
- * as it was before.
- */
- if( ttbl_extent == 0 )
- {
- return;
- }
-
- /*
- * Finally, check the directory we are creating to see whether
- * there are any new entries in it. If there are not, we can
- * reuse the same translation table.
- */
- for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next)
- {
- /*
- * Don't care about '.' or '..'. They are never in the table
- * anyways.
- */
- if( s_entry->name != NULL && strcmp(s_entry->name, ".") == 0 )
- {
- continue;
- }
- if( s_entry->name != NULL && strcmp(s_entry->name, "..") == 0 )
- {
- continue;
- }
- if( strcmp(s_entry->name, "<translation table>") == 0)
- {
- continue;
- }
- if( (s_entry->de_flags & SAFE_TO_REUSE_TABLE_ENTRY) == 0 )
- {
- return;
- }
- }
-
- /*
- * Locate the translation table, and re-use the same extent.
- * It isn't clear that there should ever be one in there already
- * so for now we try and muddle through the best we can.
- */
- for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next)
- {
- if( strcmp(s_entry->name, "<translation table>") == 0)
- {
- fprintf (stderr, "Should never get here\n");
- set_733(s_entry->isorec.extent, ttbl_extent);
- return;
- }
- }
-
- pnt[ttbl_index]->next = this_dir->contents;
- pnt[ttbl_index]->filedir = this_dir;
- this_dir->contents = pnt[ttbl_index];
- pnt[ttbl_index] = NULL;
-}
-
-
-/*
- * Here we have a case of a directory that has completely disappeared from
- * the face of the earth on the tree we are mastering from. Go through and
- * merge it into the tree, as well as everything beneath it.
- *
- * Note that if a directory has been moved for some reason, this will
- * incorrectly pick it up and attempt to merge it back into the old
- * location. FIXME(eric).
- */
-static int
-FDECL2(merge_old_directory_into_tree, struct directory_entry *, dpnt,
- struct directory *, parent)
-{
- struct directory_entry **contents = NULL;
- int i;
- int n_orig;
- struct directory * this_dir, *next_brother;
- char whole_path[1024];
-
- this_dir = (struct directory *) e_malloc(sizeof(struct directory));
- memset(this_dir, 0, sizeof(struct directory));
- this_dir->next = NULL;
- this_dir->subdir = NULL;
- this_dir->self = dpnt;
- this_dir->contents = NULL;
- this_dir->size = 0;
- this_dir->extent = 0;
- this_dir->depth = parent->depth + 1;
- this_dir->parent = parent;
- if(!parent->subdir)
- parent->subdir = this_dir;
- else {
- next_brother = parent->subdir;
- while(next_brother->next) next_brother = next_brother->next;
- next_brother->next = this_dir;
- }
-
- /*
- * Set the name for this directory.
- */
- strcpy(whole_path, parent->de_name);
- strcat(whole_path, SPATH_SEPARATOR);
- strcat(whole_path, dpnt->name);
- this_dir->de_name = strdup(whole_path);
- this_dir->whole_name = strdup(whole_path);
-
- /*
- * Now fill this directory using information from the previous
- * session.
- */
- contents = read_merging_directory(&dpnt->isorec, &n_orig);
- /*
- * Start by simply copying the '.', '..' and non-directory
- * entries to this directory. Technically we could let
- * merge_remaining_entries handle this, but it gets rather confused
- * by the '.' and '..' entries.
- */
- for(i=0; i < n_orig; i ++ )
- {
- /*
- * We can always reuse the TRANS.TBL in this particular case.
- */
- contents[i]->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY;
-
- if( ((contents[i]->isorec.flags[0] & 2) != 0)
- && (i >= 2) )
- {
- continue;
- }
-
- /*
- * If we have a directory, don't reuse the extent number.
- */
- if( (contents[i]->isorec.flags[0] & 2) != 0 )
- {
- memset(contents[i]->isorec.extent, 0, 8);
-
- if( strcmp(contents[i]->name, ".") == 0 )
- this_dir->dir_flags |= DIR_HAS_DOT;
-
- if( strcmp(contents[i]->name, "..") == 0 )
- this_dir->dir_flags |= DIR_HAS_DOTDOT;
- }
-
- /*
- * Set the whole name for this file.
- */
- strcpy(whole_path, this_dir->whole_name);
- strcat(whole_path, SPATH_SEPARATOR);
- strcat(whole_path, contents[i]->name);
-
- contents[i]->whole_name = strdup(whole_path);
-
- contents[i]->next = this_dir->contents;
- contents[i]->filedir = this_dir;
- this_dir->contents = contents[i];
- contents[i] = NULL;
- }
-
- /*
- * Zero the extent number for ourselves.
- */
- memset(dpnt->isorec.extent, 0, 8);
-
- /*
- * Anything that is left are other subdirectories that need to be merged.
- */
- merge_remaining_entries(this_dir, contents, n_orig);
- free_mdinfo(contents, n_orig);
-#if 0
- /*
- * This is no longer required. The post-scan sort will handle
- * all of this for us.
- */
- sort_n_finish(this_dir);
-#endif
-
- return 0;
-}
-
-
-char * cdwrite_data = NULL;
-
-int
-FDECL1(get_session_start, int *, file_addr)
-{
- char * pnt;
-
-#ifdef CDWRITE_DETERMINES_FIRST_WRITABLE_ADDRESS
- /*
- * FIXME(eric). We need to coordinate with cdwrite to obtain
- * the parameters. For now, we assume we are writing the 2nd session,
- * so we start from the session that starts at 0.
- */
-
- *file_addr = (16 << 11);
-
- /*
- * We need to coordinate with cdwrite to get the next writable address
- * from the device. Here is where we use it.
- */
- session_start = last_extent = last_extent_written = cdwrite_result();
-
-#else
-
- if( cdwrite_data == NULL )
- error (1, 0, _("Special parameters for cdwrite not specified with -C\n"));
-
- /*
- * Next try and find the ',' in there which delimits the two numbers.
- */
- pnt = strchr(cdwrite_data, ',');
- if( pnt == NULL )
- error (1, 0, _("Malformed cdwrite parameters\n"));
-
- *pnt = '\0';
- if (file_addr != NULL) {
- *file_addr = atol(cdwrite_data) * SECTOR_SIZE;
- }
- pnt++;
-
- session_start = last_extent = last_extent_written = atol(pnt);
-
- pnt--;
- *pnt = ',';
-
-#endif
- return 0;
-}
-
-/*
- * This function scans the directory tree, looking for files, and it makes
- * note of everything that is found. We also begin to construct the ISO9660
- * directory entries, so that we can determine how large each directory is.
- */
-
-int
-FDECL2(merge_previous_session,struct directory *, this_dir,
- struct iso_directory_record *, mrootp)
-{
- struct directory_entry **orig_contents = NULL;
- struct directory_entry * odpnt = NULL;
- int n_orig;
- struct directory_entry * s_entry;
- int status, lstatus;
- struct stat statbuf, lstatbuf;
-
- /*
- * Parse the same directory in the image that we are merging
- * for multisession stuff.
- */
- orig_contents = read_merging_directory(mrootp, &n_orig);
- if( orig_contents == NULL )
- {
- return 0;
- }
-
-
-/* Now we scan the directory itself, and look at what is inside of it. */
-
- for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next)
- {
- status = stat_filter(s_entry->whole_name, &statbuf);
- lstatus = lstat_filter(s_entry->whole_name, &lstatbuf);
-
- /*
- * We always should create an entirely new directory tree whenever
- * we generate a new session, unless there were *no* changes whatsoever
- * to any of the directories, in which case it would be kind of pointless
- * to generate a new session.
- *
- * I believe it is possible to rigorously prove that any change anywhere
- * in the filesystem will force the entire tree to be regenerated
- * because the modified directory will get a new extent number. Since
- * each subdirectory of the changed directory has a '..' entry, all of
- * them will need to be rewritten too, and since the parent directory
- * of the modified directory will have an extent pointer to the directory
- * it too will need to be rewritten. Thus we will never be able to reuse
- * any directory information when writing new sessions.
- *
- * We still check the previous session so we can mark off the equivalent
- * entry in the list we got from the original disc, however.
- */
-
- /*
- * The check_prev_session function looks for an identical entry in
- * the previous session. If we see it, then we copy the extent
- * number to s_entry, and cross it off the list.
- */
- check_prev_session(orig_contents, n_orig, s_entry,
- &statbuf, &lstatbuf, &odpnt);
-
- if(S_ISDIR(statbuf.st_mode) && odpnt != NULL)
- {
- int dflag;
-
- if (strcmp(s_entry->name,".") && strcmp(s_entry->name,".."))
- {
- struct directory * child;
-
- child = find_or_create_directory(this_dir,
- s_entry->whole_name,
- s_entry, 1);
- dflag = merge_previous_session(child,
- &odpnt->isorec);
- /* If unable to scan directory, mark this as a non-directory */
- if(!dflag)
- lstatbuf.st_mode = (lstatbuf.st_mode & ~S_IFMT) | S_IFREG;
- free(odpnt);
- odpnt = NULL;
- }
- }
- }
-
- /*
- * Whatever is left over, are things which are no longer in the tree
- * on disk. We need to also merge these into the tree.
- */
- merge_remaining_entries(this_dir, orig_contents, n_orig);
- free_mdinfo(orig_contents, n_orig);
-
- return 1;
-}
-
+++ /dev/null
-/*
- * File name.c - map full Unix file names to unique 8.3 names that
- * would be valid on DOS.
- *
-
- Written by Eric Youngdale (1993).
-
- Copyright 1993 Yggdrasil Computing, Incorporated
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include "config.h"
-#include "mkisofs.h"
-
-#include <ctype.h>
-
-extern int allow_leading_dots;
-
-/*
- * Function: iso9660_file_length
- *
- * Purpose: Map file name to 8.3 format, return length
- * of result.
- *
- * Arguments: name file name we need to map.
- * sresult directory entry structure to contain mapped name.
- * dirflag flag indicating whether this is a directory or not.
- *
- * Notes: This procedure probably needs to be rationalized somehow.
- * New options to affect the behavior of this function
- * would also be nice to have.
- */
-int FDECL3(iso9660_file_length,
- const char*, name,
- struct directory_entry *, sresult,
- int, dirflag)
-{
- char * c;
- int chars_after_dot = 0;
- int chars_before_dot = 0;
- int current_length = 0;
- int extra = 0;
- int ignore = 0;
- char * last_dot;
- const char * pnt;
- int priority = 32767;
- char * result;
- int seen_dot = 0;
- int seen_semic = 0;
- int tildes = 0;
-
- result = sresult->isorec.name;
-
- /*
- * For the '.' entry, generate the correct record, and return
- * 1 for the length.
- */
- if(strcmp(name,".") == 0)
- {
- if(result)
- {
- *result = 0;
- }
- return 1;
- }
-
- /*
- * For the '..' entry, generate the correct record, and return
- * 1 for the length.
- */
- if(strcmp(name,"..") == 0)
- {
- if(result)
- {
- *result++ = 1;
- *result++ = 0;
- }
- return 1;
- }
-
- /*
- * Now scan the directory one character at a time, and figure out
- * what to do.
- */
- pnt = name;
-
- /*
- * Find the '.' that we intend to use for the extension. Usually this
- * is the last dot, but if we have . followed by nothing or a ~, we
- * would consider this to be unsatisfactory, and we keep searching.
- */
- last_dot = strrchr (pnt,'.');
- if( (last_dot != NULL)
- && ( (last_dot[1] == '~')
- || (last_dot[1] == '\0')) )
- {
- c = last_dot;
- *c = '\0';
- last_dot = strrchr (pnt,'.');
- *c = '.';
- }
-
- while(*pnt)
- {
-#ifdef VMS
- if( strcmp(pnt,".DIR;1") == 0 )
- {
- break;
- }
-#endif
-
- /*
- * This character indicates a Unix style of backup file
- * generated by some editors. Lower the priority of
- * the file.
- */
- if(*pnt == '#')
- {
- priority = 1;
- pnt++;
- continue;
- }
-
- /*
- * This character indicates a Unix style of backup file
- * generated by some editors. Lower the priority of
- * the file.
- */
- if(*pnt == '~')
- {
- priority = 1;
- tildes++;
- pnt++;
- continue;
- }
-
- /*
- * This might come up if we had some joker already try and put
- * iso9660 version numbers into the file names. This would be
- * a silly thing to do on a Unix box, but we check for it
- * anyways. If we see this, then we don't have to add our
- * own version number at the end.
- * UNLESS the ';' is part of the filename and no version
- * number is following. [VK]
- */
- if(*pnt == ';')
- {
- /* [VK] */
- if (pnt[1] != '\0' && (pnt[1] < '0' || pnt[1] > '9'))
- {
- pnt++;
- ignore++;
- continue;
- }
- }
-
- /*
- * If we have a name with multiple '.' characters, we ignore everything
- * after we have gotten the extension.
- */
- if(ignore)
- {
- pnt++;
- continue;
- }
-
- /*
- * Spin past any iso9660 version number we might have.
- */
- if(seen_semic)
- {
- if(*pnt >= '0' && *pnt <= '9')
- {
- *result++ = *pnt;
- }
- extra++;
- pnt++;
- continue;
- }
-
- /*
- * If we have full names, the names we generate will not
- * work on a DOS machine, since they are not guaranteed
- * to be 8.3. Nonetheless, in many cases this is a useful
- * option. We still only allow one '.' character in the
- * name, however.
- */
- if(full_iso9660_filenames)
- {
- /* Here we allow a more relaxed syntax. */
- if(*pnt == '.')
- {
- if (seen_dot)
- {
- ignore++;
- continue;
- }
- seen_dot++;
- }
- if(current_length < 30)
- {
- if( !isascii (*pnt))
- {
- *result++ = '_';
- }
- else
- {
- *result++ = (islower((unsigned char)*pnt) ? toupper((unsigned char)*pnt) : *pnt);
- }
- }
- }
- else
- {
- /*
- * Dos style filenames. We really restrict the
- * names here.
- */
- /* It would be nice to have .tar.gz transform to .tgz,
- * .ps.gz to .psz, ...
- */
- if(*pnt == '.')
- {
- if (!chars_before_dot && !allow_leading_dots)
- {
- /* DOS can't read files with dot first */
- chars_before_dot++;
- if (result)
- {
- *result++ = '_'; /* Substitute underscore */
- }
- }
- else if( pnt != last_dot )
- {
- /*
- * If this isn't the dot that we use for the extension,
- * then change the character into a '_' instead.
- */
- if(chars_before_dot < 8)
- {
- chars_before_dot++;
- if(result)
- {
- *result++ = '_';
- }
- }
- }
- else
- {
- if (seen_dot)
- {
- ignore++; continue;
- }
- if(result)
- {
- *result++ = '.';
- }
- seen_dot++;
- }
- }
- else
- {
- if( (seen_dot && (chars_after_dot < 3) && ++chars_after_dot)
- || (!seen_dot && (chars_before_dot < 8) && ++chars_before_dot) )
- {
- if(result)
- {
- switch (*pnt)
- {
- default:
- if( !isascii (*pnt) )
- {
- *result++ = '_';
- }
- else
- {
- *result++ = islower((unsigned char)*pnt) ? toupper((unsigned char)*pnt) : *pnt;
- }
- break;
-
- /*
- * Descriptions of DOS's 'Parse Filename'
- * (function 29H) describes V1 and V2.0+
- * separator and terminator characters.
- * These characters in a DOS name make
- * the file visible but un-manipulable
- * (all useful operations error off.
- */
- /* separators */
- case '+':
- case '=':
- case '%': /* not legal DOS filename */
- case ':':
- case ';': /* already handled */
- case '.': /* already handled */
- case ',': /* already handled */
- case '\t':
- case ' ':
- /* V1 only separators */
- case '/':
- case '"':
- case '[':
- case ']':
- /* terminators */
- case '>':
- case '<':
- case '|':
- /* Hmm - what to do here? Skip?
- * Win95 looks like it substitutes '_'
- */
- *result++ = '_';
- break;
- } /* switch (*pnt) */
- } /* if (result) */
- } /* if (chars_{after,before}_dot) ... */
- } /* else *pnt == '.' */
- } /* else DOS file names */
- current_length++;
- pnt++;
- } /* while (*pnt) */
-
- /*
- * OK, that wraps up the scan of the name. Now tidy up a few other
- * things.
- */
-
- /*
- * Look for emacs style of numbered backups, like foo.c.~3~. If
- * we see this, convert the version number into the priority
- * number. In case of name conflicts, this is what would end
- * up being used as the 'extension'.
- */
- if(tildes == 2)
- {
- int prio1 = 0;
- pnt = name;
- while (*pnt && *pnt != '~')
- {
- pnt++;
- }
- if (*pnt)
- {
- pnt++;
- }
- while(*pnt && *pnt != '~')
- {
- prio1 = 10*prio1 + *pnt - '0';
- pnt++;
- }
- priority = prio1;
- }
-
- /*
- * If this is not a directory, force a '.' in case we haven't
- * seen one, and add a version number if we haven't seen one
- * of those either.
- */
- if (!dirflag)
- {
- if (!seen_dot && !omit_period)
- {
- if (result) *result++ = '.';
- extra++;
- }
- if(!omit_version_number && !seen_semic)
- {
- if(result)
- {
- *result++ = ';';
- *result++ = '1';
- };
- extra += 2;
- }
- }
-
- if(result)
- {
- *result++ = 0;
- }
- sresult->priority = priority;
-
- return (chars_before_dot + chars_after_dot + seen_dot + extra);
-}
+++ /dev/null
-/*
- * File rock.c - generate RRIP records for iso9660 filesystems.
-
- Written by Eric Youngdale (1993).
-
- Copyright 1993 Yggdrasil Computing, Incorporated
-
- Copyright (C) 2009,2010 Free Software Foundation, Inc.
-
- 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 3, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-
-#include "config.h"
-
-#ifndef VMS
-#if defined(MAJOR_IN_SYSMACROS)
-#include <sys/sysmacros.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#endif
-#if defined(MAJOR_IN_MKDEV)
-#include <sys/types.h>
-#include <sys/mkdev.h>
-#endif
-
-#include "mkisofs.h"
-#include "iso9660.h"
-#include <string.h>
-#include <errno.h>
-
-#ifdef DOESNT_WORK
-
-#ifdef NON_UNIXFS
-#define S_ISLNK(m) (0)
-#else
-#ifndef S_ISLNK
-#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
-#endif
-#endif
-
-#else
-#include <statdefs.h>
-#endif
-
-#define SU_VERSION 1
-
-#define SL_ROOT 8
-#define SL_PARENT 4
-#define SL_CURRENT 2
-#define SL_CONTINUE 1
-
-#define CE_SIZE 28
-#define CL_SIZE 12
-#define ER_SIZE 8
-#define NM_SIZE 5
-#define PL_SIZE 12
-#define PN_SIZE 20
-#define PX_SIZE 36
-#define RE_SIZE 4
-#define SL_SIZE 20
-#define ZZ_SIZE 15
-#ifdef __QNX__
-#define TF_SIZE (5 + 4 * 7)
-#else
-#define TF_SIZE (5 + 3 * 7)
-#endif
-
-/* If we need to store this number of bytes, make sure we
- do not box ourselves in so that we do not have room for
- a CE entry for the continuation record */
-
-#define MAYBE_ADD_CE_ENTRY(BYTES) \
- ((unsigned) ((BYTES) + CE_SIZE + currlen + ipnt) > (unsigned) (recstart + reclimit) ? 1 : 0)
-
-/*
- * Buffer to build RR attributes
- */
-
-static unsigned char Rock[16384];
-static unsigned char symlink_buff[256];
-static int ipnt = 0;
-static int recstart = 0;
-static int currlen = 0;
-static int mainrec = 0;
-static int reclimit;
-
-static void add_CE_entry __PR((void));
-
-static void add_CE_entry(){
- if(recstart)
- set_733((char*)Rock + recstart - 8, ipnt + 28 - recstart);
- Rock[ipnt++] ='C';
- Rock[ipnt++] ='E';
- Rock[ipnt++] = CE_SIZE;
- Rock[ipnt++] = SU_VERSION;
- set_733((char*)Rock + ipnt, 0);
- ipnt += 8;
- set_733((char*)Rock + ipnt, 0);
- ipnt += 8;
- set_733((char*)Rock + ipnt, 0);
- ipnt += 8;
- recstart = ipnt;
- currlen = 0;
- if(!mainrec) mainrec = ipnt;
- reclimit = SECTOR_SIZE - 8; /* Limit to one sector */
-}
-
-#ifdef __STDC__
-int generate_rock_ridge_attributes (char * whole_name, char * name,
- struct directory_entry * s_entry,
- struct stat * statbuf,
- struct stat * lstatbuf,
- int deep_opt)
-#else
-int generate_rock_ridge_attributes (whole_name, name,
- s_entry,
- statbuf,
- lstatbuf,
- deep_opt)
-char * whole_name; char * name; struct directory_entry * s_entry;
-struct stat * statbuf, *lstatbuf;
-int deep_opt;
-#endif
-{
- int flagpos, flagval;
- int need_ce;
-
- statbuf = statbuf; /* this shuts up unreferenced compiler warnings */
- mainrec = recstart = ipnt = 0;
- reclimit = 0xf8;
-
- /* no need to fill in the RR stuff if we won't see the file */
- if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY)
- return 0;
-
- /* Obtain the amount of space that is currently used for the directory
- record. Assume max for name, since name conflicts may cause us
- to rename the file later on */
- currlen = sizeof(s_entry->isorec);
-
- /* Identify that we are using the SUSP protocol */
- if(deep_opt & NEED_SP){
- Rock[ipnt++] ='S';
- Rock[ipnt++] ='P';
- Rock[ipnt++] = 7;
- Rock[ipnt++] = SU_VERSION;
- Rock[ipnt++] = 0xbe;
- Rock[ipnt++] = 0xef;
- Rock[ipnt++] = 0;
- };
-
- /* First build the posix name field */
- Rock[ipnt++] ='R';
- Rock[ipnt++] ='R';
- Rock[ipnt++] = 5;
- Rock[ipnt++] = SU_VERSION;
- flagpos = ipnt;
- flagval = 0;
- Rock[ipnt++] = 0; /* We go back and fix this later */
-
- if(strcmp(name,".") && strcmp(name,"..")){
- char * npnt;
- int remain, use;
-
- remain = strlen(name);
- npnt = name;
-
- while(remain){
- use = remain;
- need_ce = 0;
- /* Can we fit this SUSP and a CE entry? */
- if(use + currlen + CE_SIZE + (ipnt - recstart) > reclimit) {
- use = reclimit - currlen - CE_SIZE - (ipnt - recstart);
- need_ce++;
- }
-
- /* Only room for 256 per SUSP field */
- if(use > 0xf8) use = 0xf8;
-
- /* First build the posix name field */
- Rock[ipnt++] ='N';
- Rock[ipnt++] ='M';
- Rock[ipnt++] = NM_SIZE + use;
- Rock[ipnt++] = SU_VERSION;
- Rock[ipnt++] = (remain != use ? 1 : 0);
- flagval |= (1<<3);
- strncpy((char *)&Rock[ipnt], npnt, use);
- npnt += use;
- ipnt += use;
- remain -= use;
- if(remain && need_ce) add_CE_entry();
- };
- };
-
- /*
- * Add the posix modes
- */
- if(MAYBE_ADD_CE_ENTRY(PX_SIZE)) add_CE_entry();
- Rock[ipnt++] ='P';
- Rock[ipnt++] ='X';
- Rock[ipnt++] = PX_SIZE;
- Rock[ipnt++] = SU_VERSION;
- flagval |= (1<<0);
- set_733((char*)Rock + ipnt, lstatbuf->st_mode);
- ipnt += 8;
- set_733((char*)Rock + ipnt, lstatbuf->st_nlink);
- ipnt += 8;
- set_733((char*)Rock + ipnt, lstatbuf->st_uid);
- ipnt += 8;
- set_733((char*)Rock + ipnt, lstatbuf->st_gid);
- ipnt += 8;
-
- /*
- * Check for special devices
- */
-#ifndef NON_UNIXFS
- if (S_ISCHR(lstatbuf->st_mode) || S_ISBLK(lstatbuf->st_mode)) {
- if(MAYBE_ADD_CE_ENTRY(PN_SIZE)) add_CE_entry();
- Rock[ipnt++] ='P';
- Rock[ipnt++] ='N';
- Rock[ipnt++] = PN_SIZE;
- Rock[ipnt++] = SU_VERSION;
- flagval |= (1<<1);
-#if defined(MAJOR_IN_SYSMACROS) || defined(MAJOR_IN_MKDEV)
- set_733((char*)Rock + ipnt, major(lstatbuf->st_rdev ));
- ipnt += 8;
- set_733((char*)Rock + ipnt, minor(lstatbuf->st_rdev));
- ipnt += 8;
-#else
- /*
- * If we don't have sysmacros.h, then we have to guess as to how
- * best to pick apart the device number for major/minor.
- * Note: this may very well be wrong for many systems, so
- * it is always best to use the major/minor macros if the
- * system supports it.
- */
- if(sizeof(dev_t) <= 2) {
- set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 8));
- ipnt += 8;
- set_733((char*)Rock + ipnt, lstatbuf->st_rdev & 0xff);
- ipnt += 8;
- }
- else if(sizeof(dev_t) <= 4) {
- set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 8) >> 8);
- ipnt += 8;
- set_733((char*)Rock + ipnt, lstatbuf->st_rdev & 0xffff);
- ipnt += 8;
- }
- else {
- set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 16) >> 16);
- ipnt += 8;
- set_733((char*)Rock + ipnt, lstatbuf->st_rdev);
- ipnt += 8;
- }
-#endif
- };
-#endif
- /*
- * Check for and symbolic links. VMS does not have these.
- */
- if (S_ISLNK(lstatbuf->st_mode)){
- int lenpos, lenval, j0, j1;
- int nchar;
- unsigned char * cpnt, *cpnt1;
- nchar = readlink(whole_name, (char *)symlink_buff, sizeof(symlink_buff));
- symlink_buff[nchar < 0 ? 0 : nchar] = 0;
- nchar = strlen((char *) symlink_buff);
- set_733(s_entry->isorec.size, 0);
- cpnt = &symlink_buff[0];
- flagval |= (1<<2);
-
- if (! split_SL_field)
- {
- int sl_bytes = 0;
- for (cpnt1 = cpnt; *cpnt1 != '\0'; cpnt1++)
- {
- if (*cpnt1 == '/')
- {
- sl_bytes += 4;
- }
- else
- {
- sl_bytes += 1;
- }
- }
- if (sl_bytes > 250)
- {
- /*
- * the symbolic link won't fit into one SL System Use Field
- * print an error message and continue with splited one
- */
- fprintf (stderr, _("symbolic link `%s' too long for one SL System Use Field, splitting"), cpnt);
- }
- if(MAYBE_ADD_CE_ENTRY(SL_SIZE + sl_bytes)) add_CE_entry();
- }
-
- while(nchar){
- if(MAYBE_ADD_CE_ENTRY(SL_SIZE)) add_CE_entry();
- Rock[ipnt++] ='S';
- Rock[ipnt++] ='L';
- lenpos = ipnt;
- Rock[ipnt++] = SL_SIZE;
- Rock[ipnt++] = SU_VERSION;
- Rock[ipnt++] = 0; /* Flags */
- lenval = 5;
- while(*cpnt){
- cpnt1 = (unsigned char *) strchr((char *) cpnt, '/');
- if(cpnt1) {
- nchar--;
- *cpnt1 = 0;
- };
-
- /* We treat certain components in a special way. */
- if(cpnt[0] == '.' && cpnt[1] == '.' && cpnt[2] == 0){
- if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry();
- Rock[ipnt++] = SL_PARENT;
- Rock[ipnt++] = 0; /* length is zero */
- lenval += 2;
- nchar -= 2;
- } else if(cpnt[0] == '.' && cpnt[1] == 0){
- if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry();
- Rock[ipnt++] = SL_CURRENT;
- Rock[ipnt++] = 0; /* length is zero */
- lenval += 2;
- nchar -= 1;
- } else if(cpnt[0] == 0){
- if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry();
- Rock[ipnt++] = SL_ROOT;
- Rock[ipnt++] = 0; /* length is zero */
- lenval += 2;
- } else {
- /* If we do not have enough room for a component, start
- a new continuations segment now */
- if(split_SL_component ? MAYBE_ADD_CE_ENTRY(6) :
- MAYBE_ADD_CE_ENTRY(6 + strlen ((char *) cpnt)))
- {
- add_CE_entry();
- if(cpnt1)
- {
- *cpnt1 = '/';
- nchar++;
- cpnt1 = NULL; /* A kluge so that we can restart properly */
- }
- break;
- }
- j0 = strlen((char *) cpnt);
- while(j0) {
- j1 = j0;
- if(j1 > 0xf8) j1 = 0xf8;
- need_ce = 0;
- if(j1 + currlen + CE_SIZE + (ipnt - recstart) > reclimit) {
- j1 = reclimit - currlen - CE_SIZE - (ipnt - recstart);
- need_ce++;
- }
- Rock[ipnt++] = (j1 != j0 ? SL_CONTINUE : 0);
- Rock[ipnt++] = j1;
- strncpy((char *) Rock + ipnt, (char *) cpnt, j1);
- ipnt += j1;
- lenval += j1 + 2;
- cpnt += j1;
- nchar -= j1; /* Number we processed this time */
- j0 -= j1;
- if(need_ce) {
- add_CE_entry();
- if(cpnt1) {
- *cpnt1 = '/';
- nchar++;
- cpnt1 = NULL; /* A kluge so that we can restart properly */
- }
- break;
- }
- }
- };
- if(cpnt1) {
- cpnt = cpnt1 + 1;
- } else
- break;
- }
- Rock[lenpos] = lenval;
- if(nchar) Rock[lenpos + 2] = SL_CONTINUE; /* We need another SL entry */
- } /* while nchar */
- } /* Is a symbolic link */
- /*
- * Add in the Rock Ridge TF time field
- */
- if(MAYBE_ADD_CE_ENTRY(TF_SIZE)) add_CE_entry();
- Rock[ipnt++] ='T';
- Rock[ipnt++] ='F';
- Rock[ipnt++] = TF_SIZE;
- Rock[ipnt++] = SU_VERSION;
-#ifdef __QNX__
- Rock[ipnt++] = 0x0f;
-#else
- Rock[ipnt++] = 0x0e;
-#endif
- flagval |= (1<<7);
-#ifdef __QNX__
- iso9660_date((char *) &Rock[ipnt], lstatbuf->st_ftime);
- ipnt += 7;
-#endif
- iso9660_date((char *) &Rock[ipnt], lstatbuf->st_mtime);
- ipnt += 7;
- iso9660_date((char *) &Rock[ipnt], lstatbuf->st_atime);
- ipnt += 7;
- iso9660_date((char *) &Rock[ipnt], lstatbuf->st_ctime);
- ipnt += 7;
-
- /*
- * Add in the Rock Ridge RE time field
- */
- if(deep_opt & NEED_RE){
- if(MAYBE_ADD_CE_ENTRY(RE_SIZE)) add_CE_entry();
- Rock[ipnt++] ='R';
- Rock[ipnt++] ='E';
- Rock[ipnt++] = RE_SIZE;
- Rock[ipnt++] = SU_VERSION;
- flagval |= (1<<6);
- };
- /*
- * Add in the Rock Ridge PL record, if required.
- */
- if(deep_opt & NEED_PL){
- if(MAYBE_ADD_CE_ENTRY(PL_SIZE)) add_CE_entry();
- Rock[ipnt++] ='P';
- Rock[ipnt++] ='L';
- Rock[ipnt++] = PL_SIZE;
- Rock[ipnt++] = SU_VERSION;
- set_733((char*)Rock + ipnt, 0);
- ipnt += 8;
- flagval |= (1<<5);
- };
-
- /*
- * Add in the Rock Ridge CL field, if required.
- */
- if(deep_opt & NEED_CL){
- if(MAYBE_ADD_CE_ENTRY(CL_SIZE)) add_CE_entry();
- Rock[ipnt++] ='C';
- Rock[ipnt++] ='L';
- Rock[ipnt++] = CL_SIZE;
- Rock[ipnt++] = SU_VERSION;
- set_733((char*)Rock + ipnt, 0);
- ipnt += 8;
- flagval |= (1<<4);
- };
-
-#ifndef VMS
- /* If transparent compression was requested, fill in the correct
- field for this file */
- if(transparent_compression &&
- S_ISREG(lstatbuf->st_mode) &&
- strlen(name) > 3 &&
- strcmp(name + strlen(name) - 3,".gZ") == 0){
- FILE * zipfile;
- char * checkname;
- unsigned int file_size;
- unsigned char header[8];
- int OK_flag;
-
- /* First open file and verify that the correct algorithm was used */
- file_size = 0;
- OK_flag = 1;
-
- zipfile = fopen(whole_name, "rb");
- if (fread (header, 1, sizeof (header), zipfile) != sizeof(header))
- error (1, errno, "fread");
-
- /* Check some magic numbers from gzip. */
- if(header[0] != 0x1f || header[1] != 0x8b || header[2] != 8) OK_flag = 0;
- /* Make sure file was blocksized. */
- if(((header[3] & 0x40) == 0)) OK_flag = 0;
- /* OK, now go to the end of the file and get some more info */
- if(OK_flag){
- int status;
- status = (long)lseek(fileno(zipfile), (off_t)(-8), SEEK_END);
- if(status == -1) OK_flag = 0;
- }
- if(OK_flag){
- if(read(fileno(zipfile), (char*)header, sizeof(header)) != sizeof(header))
- OK_flag = 0;
- else {
- int blocksize;
- blocksize = (header[3] << 8) | header[2];
- file_size = ((unsigned int)header[7] << 24) |
- ((unsigned int)header[6] << 16) |
- ((unsigned int)header[5] << 8) | header[4];
-#if 0
- fprintf(stderr,"Blocksize = %d %d\n", blocksize, file_size);
-#endif
- if(blocksize != SECTOR_SIZE) OK_flag = 0;
- }
- }
- fclose(zipfile);
-
- checkname = strdup(whole_name);
- checkname[strlen(whole_name)-3] = 0;
- zipfile = fopen(checkname, "rb");
- if(zipfile) {
- OK_flag = 0;
- fprintf (stderr, _("Unable to insert transparent compressed file - name conflict\n"));
- fclose(zipfile);
- }
-
- free(checkname);
-
- if(OK_flag){
- if(MAYBE_ADD_CE_ENTRY(ZZ_SIZE)) add_CE_entry();
- Rock[ipnt++] ='Z';
- Rock[ipnt++] ='Z';
- Rock[ipnt++] = ZZ_SIZE;
- Rock[ipnt++] = SU_VERSION;
- Rock[ipnt++] = 'g'; /* Identify compression technique used */
- Rock[ipnt++] = 'z';
- Rock[ipnt++] = 3;
- set_733((char*)Rock + ipnt, file_size); /* Real file size */
- ipnt += 8;
- };
- }
-#endif
- /*
- * Add in the Rock Ridge CE field, if required. We use this for the
- * extension record that is stored in the root directory.
- */
- if(deep_opt & NEED_CE) add_CE_entry();
- /*
- * Done filling in all of the fields. Now copy it back to a buffer for the
- * file in question.
- */
-
- /* Now copy this back to the buffer for the file */
- Rock[flagpos] = flagval;
-
- /* If there was a CE, fill in the size field */
- if(recstart)
- set_733((char*)Rock + recstart - 8, ipnt - recstart);
-
- s_entry->rr_attributes = (unsigned char *) e_malloc(ipnt);
- s_entry->total_rr_attr_size = ipnt;
- s_entry->rr_attr_size = (mainrec ? mainrec : ipnt);
- memcpy(s_entry->rr_attributes, Rock, ipnt);
- return ipnt;
-}
-
-/* Guaranteed to return a single sector with the relevant info */
-
-char * FDECL4(generate_rr_extension_record, char *, id, char *, descriptor,
- char *, source, int *, size){
- int lipnt = 0;
- char * pnt;
- int len_id, len_des, len_src;
-
- len_id = strlen(id);
- len_des = strlen(descriptor);
- len_src = strlen(source);
- Rock[lipnt++] ='E';
- Rock[lipnt++] ='R';
- Rock[lipnt++] = ER_SIZE + len_id + len_des + len_src;
- Rock[lipnt++] = 1;
- Rock[lipnt++] = len_id;
- Rock[lipnt++] = len_des;
- Rock[lipnt++] = len_src;
- Rock[lipnt++] = 1;
-
- memcpy(Rock + lipnt, id, len_id);
- lipnt += len_id;
-
- memcpy(Rock + lipnt, descriptor, len_des);
- lipnt += len_des;
-
- memcpy(Rock + lipnt, source, len_src);
- lipnt += len_src;
-
- if(lipnt > SECTOR_SIZE)
- error (1, 0, _("Extension record too long\n"));
- pnt = (char *) e_malloc(SECTOR_SIZE);
- memset(pnt, 0, SECTOR_SIZE);
- memcpy(pnt, Rock, lipnt);
- *size = lipnt;
- return pnt;
-}
+++ /dev/null
-/*
- * File tree.c - scan directory tree and build memory structures for iso9660
- * filesystem
-
- Written by Eric Youngdale (1993).
-
- Copyright 1993 Yggdrasil Computing, Incorporated
-
- Copyright (C) 2009 Free Software Foundation, Inc.
-
- 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 3, 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, see <http://www.gnu.org/licenses/>.
- */
-
-/* ADD_FILES changes made by Ross Biro biro@yggdrasil.com 2/23/95 */
-
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-
-#include "config.h"
-
-#ifndef VMS
-#if defined(MAJOR_IN_SYSMACROS)
-#include <sys/sysmacros.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <fctldefs.h>
-
-#if defined(MAJOR_IN_MKDEV)
-#include <sys/types.h>
-#include <sys/mkdev.h>
-#endif
-#else
-#include <sys/file.h>
-#include <vms/fabdef.h>
-#include "vms.h"
-extern char * strdup(const char *);
-#endif
-
-/*
- * Autoconf should be able to figure this one out for us and let us know
- * whether the system has memmove or not.
- */
-# ifndef HAVE_MEMMOVE
-# define memmove(d, s, n) bcopy ((s), (d), (n))
-# endif
-
-#include "mkisofs.h"
-#include "iso9660.h"
-#include "match.h"
-
-#include <sys/stat.h>
-
-#include "exclude.h"
-
-#ifdef DOESNT_WORK
-
-#ifdef NON_UNIXFS
-#define S_ISLNK(m) (0)
-#define S_ISSOCK(m) (0)
-#define S_ISFIFO(m) (0)
-#else
-#ifndef S_ISLNK
-#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
-#endif
-#ifndef S_ISSOCK
-# ifdef S_IFSOCK
-# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
-# else
-# define S_ISSOCK(m) (0)
-# endif
-#endif
-#endif
-
-#else
-#include <statdefs.h>
-#endif
-
-
-#ifdef __SVR4
-extern char * strdup(const char *);
-#endif
-
-static unsigned char symlink_buff[256];
-
-static void stat_fix __PR((struct stat * st));
-static void generate_reloc_directory __PR((void));
-
-static void DECL(attach_dot_entries, (struct directory * dirnode,
- struct stat * parent_stat));
-static void DECL(delete_directory, (struct directory * parent, struct directory * child));
-
-extern int verbose;
-
-struct stat fstatbuf; /* We use this for the artificial entries we create */
-
-struct stat root_statbuf; /* Stat buffer for root directory */
-
-struct directory * reloc_dir = NULL;
-
-static void
-FDECL1(stat_fix, struct stat *, st)
-{
- /* Remove the uid and gid, they will only be useful on the author's
- system. */
- st->st_uid = 0;
- st->st_gid = 0;
-
- /*
- * Make sure the file modes make sense. Turn on all read bits. Turn
- * on all exec/search bits if any exec/search bit is set. Turn off
- * all write bits, and all special mode bits (on a r/o fs lock bits
- * are useless, and with uid+gid 0 don't want set-id bits, either).
- */
- st->st_mode |= 0444;
-#ifndef _WIN32 /* make all file "executable" */
- if (st->st_mode & 0111)
-#endif /* _WIN32 */
- st->st_mode |= 0111;
- st->st_mode &= ~07222;
-}
-
-int
-FDECL2(stat_filter, char *, path, struct stat *, st)
-{
- int result = stat(path, st);
- if (result >= 0 && rationalize)
- stat_fix(st);
-
- if ((unsigned) st->st_size > UINT32_MAX)
- result = -1;
-
- return result;
-}
-
-int
-FDECL2(lstat_filter, char *, path, struct stat *, st)
-{
- int result = lstat(path, st);
- if (result >= 0 && rationalize)
- stat_fix(st);
-
- if ((unsigned) st->st_size > UINT32_MAX)
- result = -1;
-
- return result;
-}
-
-static int FDECL1(sort_n_finish, struct directory *, this_dir)
-{
- struct directory_entry * s_entry;
- struct directory_entry * s_entry1;
- struct directory_entry * table;
- int count;
- int d1;
- int d2;
- int d3;
- int new_reclen;
- char * c;
- int status = 0;
- int tablesize = 0;
- char newname[34];
- char rootname[34];
-
- /* Here we can take the opportunity to toss duplicate entries from the
- directory. */
-
- /* ignore if it's hidden */
- if(this_dir->dir_flags & INHIBIT_ISO9660_ENTRY)
- {
- return 0;
- }
-
- table = NULL;
-
- init_fstatbuf();
-
- /*
- * If we had artificially created this directory, then we might be
- * missing the required '.' entries. Create these now if we need
- * them.
- */
- if( (this_dir->dir_flags & (DIR_HAS_DOT | DIR_HAS_DOTDOT)) !=
- (DIR_HAS_DOT | DIR_HAS_DOTDOT) )
- {
- attach_dot_entries(this_dir, &fstatbuf);
- }
-
- flush_file_hash();
- s_entry = this_dir->contents;
- while(s_entry)
- {
- /* ignore if it's hidden */
- if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY)
- {
- s_entry = s_entry->next;
- continue;
- }
-
- /*
- * First assume no conflict, and handle this case
- */
- if(!(s_entry1 = find_file_hash(s_entry->isorec.name)))
- {
- add_file_hash(s_entry);
- s_entry = s_entry->next;
- continue;
- }
-
- if(s_entry1 == s_entry)
- error (1, 0, _("Fatal goof\n"));
-
- /*
- * OK, handle the conflicts. Try substitute names until we come
- * up with a winner
- */
- strcpy(rootname, s_entry->isorec.name);
- if(full_iso9660_filenames)
- {
- if(strlen(rootname) > 27) rootname[27] = 0;
- }
-
- /*
- * Strip off the non-significant part of the name so that we are left
- * with a sensible root filename. If we don't find a '.', then try
- * a ';'.
- */
- c = strchr(rootname, '.');
- if (c)
- *c = 0;
- else
- {
- c = strchr(rootname, ';');
- if (c) *c = 0;
- }
- for(d1 = 0; d1 < 36; d1++)
- {
- for(d2 = 0; d2 < 36; d2++)
- {
- for(d3 = 0; d3 < 36; d3++)
- {
- sprintf(newname,"%s.%c%c%c%s", rootname,
- (d1 <= 9 ? '0' + d1 : 'A' + d1 - 10),
- (d2 <= 9 ? '0' + d2 : 'A' + d2 - 10),
- (d3 <= 9 ? '0' + d3 : 'A' + d3 - 10),
- (s_entry->isorec.flags[0] == 2 ||
- omit_version_number ? "" : ";1"));
-
-#ifdef VMS
- /* Sigh. VAXCRTL seems to be broken here */
- {
- int ijk = 0;
- while(newname[ijk])
- {
- if(newname[ijk] == ' ') newname[ijk] = '0';
- ijk++;
- }
- }
-#endif
-
- if(!find_file_hash(newname)) goto got_valid_name;
- }
- }
- }
-
- /*
- * If we fell off the bottom here, we were in real trouble.
- */
- error (1, 0, _("Unable to generate unique name for file %s\n"), s_entry->name);
-
-got_valid_name:
- /*
- * OK, now we have a good replacement name. Now decide which one
- * of these two beasts should get the name changed
- */
- if(s_entry->priority < s_entry1->priority)
- {
- if( verbose > 0 )
- {
- fprintf (stderr, _("Using %s for %s%s%s (%s)\n"), newname,
- this_dir->whole_name, SPATH_SEPARATOR,
- s_entry->name, s_entry1->name);
- }
- s_entry->isorec.name_len[0] = strlen(newname);
- new_reclen = sizeof(struct iso_directory_record) -
- sizeof(s_entry->isorec.name) +
- strlen(newname);
- if(use_RockRidge)
- {
- if (new_reclen & 1) new_reclen++; /* Pad to an even byte */
- new_reclen += s_entry->rr_attr_size;
- }
- if (new_reclen & 1) new_reclen++; /* Pad to an even byte */
- s_entry->isorec.length[0] = new_reclen;
- strcpy(s_entry->isorec.name, newname);
- }
- else
- {
- delete_file_hash(s_entry1);
- if( verbose > 0 )
- {
- fprintf(stderr, _("Using %s for %s%s%s (%s)\n"), newname,
- this_dir->whole_name, SPATH_SEPARATOR,
- s_entry1->name, s_entry->name);
- }
- s_entry1->isorec.name_len[0] = strlen(newname);
- new_reclen = sizeof(struct iso_directory_record) -
- sizeof(s_entry1->isorec.name) +
- strlen(newname);
- if(use_RockRidge)
- {
- if (new_reclen & 1) new_reclen++; /* Pad to an even byte */
- new_reclen += s_entry1->rr_attr_size;
- }
- if (new_reclen & 1) new_reclen++; /* Pad to an even byte */
- s_entry1->isorec.length[0] = new_reclen;
- strcpy(s_entry1->isorec.name, newname);
- add_file_hash(s_entry1);
- }
- add_file_hash(s_entry);
- s_entry = s_entry->next;
- }
-
- if(generate_tables
- && !find_file_hash("TRANS.TBL")
- && (reloc_dir != this_dir)
- && (this_dir->extent == 0) )
- {
- /*
- * First we need to figure out how big this table is
- */
- for (s_entry = this_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) continue;
- if(s_entry->table) tablesize += 35 + strlen(s_entry->table);
- }
- }
-
- if( tablesize > 0 )
- {
- table = (struct directory_entry *)
- e_malloc(sizeof (struct directory_entry));
- memset(table, 0, sizeof(struct directory_entry));
- table->table = NULL;
- table->next = this_dir->contents;
- this_dir->contents = table;
-
- table->filedir = root;
- table->isorec.flags[0] = 0;
- table->priority = 32768;
- iso9660_date(table->isorec.date, fstatbuf.st_mtime);
- table->inode = TABLE_INODE;
- table->dev = (dev_t) UNCACHED_DEVICE;
- set_723(table->isorec.volume_sequence_number, volume_sequence_number);
- set_733((char *) table->isorec.size, tablesize);
- table->size = tablesize;
- table->filedir = this_dir;
-#ifdef ERIC_neverdef
- table->de_flags |= INHIBIT_JOLIET_ENTRY;
-#endif
- table->name = strdup("<translation table>");
- table->table = (char *) e_malloc(ROUND_UP(tablesize));
- memset(table->table, 0, ROUND_UP(tablesize));
- iso9660_file_length ("TRANS.TBL", table, 0);
-
- if(use_RockRidge)
- {
- fstatbuf.st_mode = 0444 | S_IFREG;
- fstatbuf.st_nlink = 1;
- generate_rock_ridge_attributes("",
- "TRANS.TBL", table,
- &fstatbuf, &fstatbuf, 0);
- }
- }
-
- /*
- * We have now chosen the 8.3 names and we should now know the length
- * of every entry in the directory.
- */
- for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next)
- {
- /* skip if it's hidden */
- if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY)
- {
- continue;
- }
-
- new_reclen = strlen(s_entry->isorec.name);
-
- /*
- * First update the path table sizes for directories.
- */
- if(s_entry->isorec.flags[0] == 2)
- {
- if (strcmp(s_entry->name,".") && strcmp(s_entry->name,".."))
- {
- path_table_size += new_reclen + sizeof(struct iso_path_table) - 1;
- if (new_reclen & 1) path_table_size++;
- }
- else
- {
- new_reclen = 1;
- if (this_dir == root && strlen(s_entry->name) == 1)
- {
- path_table_size += sizeof(struct iso_path_table);
- }
- }
- }
- if(path_table_size & 1) path_table_size++; /* For odd lengths we pad */
- s_entry->isorec.name_len[0] = new_reclen;
-
- new_reclen +=
- sizeof(struct iso_directory_record) -
- sizeof(s_entry->isorec.name);
-
- if (new_reclen & 1)
- new_reclen++;
-
- new_reclen += s_entry->rr_attr_size;
-
- if (new_reclen & 1) new_reclen++;
-
- if(new_reclen > 0xff)
- error (1, 0, _("Fatal error - RR overflow for file %s\n"),
- s_entry->name);
- s_entry->isorec.length[0] = new_reclen;
- }
-
- status = sort_directory(&this_dir->contents);
- if( status > 0 )
- {
- fprintf (stderr, _("Unable to sort directory %s\n"),
- this_dir->whole_name);
- }
-
- /*
- * If we are filling out a TRANS.TBL, generate the entries that will
- * go in the thing.
- */
- if(table)
- {
- count = 0;
- for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next){
- if(s_entry == table) continue;
- if(!s_entry->table) continue;
- if(strcmp(s_entry->name, ".") == 0 ||
- strcmp(s_entry->name, "..") == 0) continue;
- if(s_entry->de_flags & INHIBIT_ISO9660_ENTRY) continue;
- /*
- * Warning: we cannot use the return value of sprintf because
- * old BSD based sprintf() implementations will return
- * a pointer to the result instead of a count.
- */
- sprintf(table->table + count, "%c %-34s%s",
- s_entry->table[0],
- s_entry->isorec.name, s_entry->table+1);
- count += strlen(table->table + count);
- free(s_entry->table);
- s_entry->table = NULL;
- }
-
- if(count != tablesize)
- error (1, 0, _("Translation table size mismatch %d %d\n"),
- count, tablesize);
- }
-
- /*
- * Now go through the directory and figure out how large this one will be.
- * Do not split a directory entry across a sector boundary
- */
- s_entry = this_dir->contents;
- this_dir->ce_bytes = 0;
- while(s_entry)
- {
- /* skip if it's hidden */
- if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) {
- s_entry = s_entry->next;
- continue;
- }
-
- new_reclen = s_entry->isorec.length[0];
- if ((this_dir->size & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE)
- this_dir->size = (this_dir->size + (SECTOR_SIZE - 1)) &
- ~(SECTOR_SIZE - 1);
- this_dir->size += new_reclen;
-
- /* See if continuation entries were used on disc */
- if(use_RockRidge &&
- s_entry->rr_attr_size != s_entry->total_rr_attr_size)
- {
- unsigned char * pnt;
- int len;
- int nbytes;
-
- pnt = s_entry->rr_attributes;
- len = s_entry->total_rr_attr_size;
-
- /*
- * We make sure that each continuation entry record is not
- * split across sectors, but each file could in theory have more
- * than one CE, so we scan through and figure out what we need.
- */
- while(len > 3)
- {
- if(pnt[0] == 'C' && pnt[1] == 'E')
- {
- nbytes = get_733((char *) pnt+20);
-
- if((this_dir->ce_bytes & (SECTOR_SIZE - 1)) + nbytes >=
- SECTOR_SIZE) this_dir->ce_bytes =
- ROUND_UP(this_dir->ce_bytes);
- /* Now store the block in the ce buffer */
- this_dir->ce_bytes += nbytes;
- if(this_dir->ce_bytes & 1) this_dir->ce_bytes++;
- }
- len -= pnt[2];
- pnt += pnt[2];
- }
- }
- s_entry = s_entry->next;
- }
- return status;
-}
-
-static void generate_reloc_directory()
-{
- time_t current_time;
- struct directory_entry *s_entry;
-
- /* Create an entry for our internal tree */
- time (¤t_time);
- reloc_dir = (struct directory *)
- e_malloc(sizeof(struct directory));
- memset(reloc_dir, 0, sizeof(struct directory));
- reloc_dir->parent = root;
- reloc_dir->next = root->subdir;
- root->subdir = reloc_dir;
- reloc_dir->depth = 1;
- reloc_dir->whole_name = strdup("./rr_moved");
- reloc_dir->de_name = strdup("rr_moved");
- reloc_dir->extent = 0;
-
-
- /* Now create an actual directory entry */
- s_entry = (struct directory_entry *)
- e_malloc(sizeof (struct directory_entry));
- memset(s_entry, 0, sizeof(struct directory_entry));
- s_entry->next = root->contents;
- reloc_dir->self = s_entry;
-
- /*
- * The rr_moved entry will not appear in the Joliet tree.
- */
- reloc_dir->dir_flags |= INHIBIT_JOLIET_ENTRY;
- s_entry->de_flags |= INHIBIT_JOLIET_ENTRY;
-
- root->contents = s_entry;
- root->contents->name = strdup(reloc_dir->de_name);
- root->contents->filedir = root;
- root->contents->isorec.flags[0] = 2;
- root->contents->priority = 32768;
- iso9660_date(root->contents->isorec.date, current_time);
- root->contents->inode = UNCACHED_INODE;
- root->contents->dev = (dev_t) UNCACHED_DEVICE;
- set_723(root->contents->isorec.volume_sequence_number, volume_sequence_number);
- iso9660_file_length (reloc_dir->de_name, root->contents, 1);
-
- if(use_RockRidge){
- fstatbuf.st_mode = 0555 | S_IFDIR;
- fstatbuf.st_nlink = 2;
- generate_rock_ridge_attributes("",
- "rr_moved", s_entry,
- &fstatbuf, &fstatbuf, 0);
- };
-
- /* Now create the . and .. entries in rr_moved */
- /* Now create an actual directory entry */
- attach_dot_entries(reloc_dir, &root_statbuf);
-}
-
-/*
- * Function: attach_dot_entries
- *
- * Purpose: Create . and .. entries for a new directory.
- *
- * Notes: Only used for artificial directories that
- * we are creating.
- */
-static void FDECL2(attach_dot_entries, struct directory *, dirnode,
- struct stat *, parent_stat)
-{
- struct directory_entry *s_entry;
- struct directory_entry *orig_contents;
- int deep_flag = 0;
-
- init_fstatbuf();
-
- orig_contents = dirnode->contents;
-
- if( (dirnode->dir_flags & DIR_HAS_DOTDOT) == 0 )
- {
- s_entry = (struct directory_entry *)
- e_malloc(sizeof (struct directory_entry));
- memcpy(s_entry, dirnode->self,
- sizeof(struct directory_entry));
- s_entry->name = strdup("..");
- s_entry->whole_name = NULL;
- s_entry->isorec.name_len[0] = 1;
- s_entry->isorec.flags[0] = 2; /* Mark as a directory */
- iso9660_file_length ("..", s_entry, 1);
- iso9660_date(s_entry->isorec.date, fstatbuf.st_mtime);
- s_entry->filedir = dirnode->parent;
-
- dirnode->contents = s_entry;
- dirnode->contents->next = orig_contents;
- orig_contents = s_entry;
-
- if(use_RockRidge)
- {
- if( parent_stat == NULL )
- {
- parent_stat = &fstatbuf;
- }
- generate_rock_ridge_attributes("",
- "..", s_entry,
- parent_stat,
- parent_stat, 0);
- }
- dirnode->dir_flags |= DIR_HAS_DOTDOT;
- }
-
- if( (dirnode->dir_flags & DIR_HAS_DOT) == 0 )
- {
- s_entry = (struct directory_entry *)
- e_malloc(sizeof (struct directory_entry));
- memcpy(s_entry, dirnode->self,
- sizeof(struct directory_entry));
- s_entry->name = strdup(".");
- s_entry->whole_name = NULL;
- s_entry->isorec.name_len[0] = 1;
- s_entry->isorec.flags[0] = 2; /* Mark as a directory */
- iso9660_file_length (".", s_entry, 1);
- iso9660_date(s_entry->isorec.date, fstatbuf.st_mtime);
- s_entry->filedir = dirnode;
-
- dirnode->contents = s_entry;
- dirnode->contents->next = orig_contents;
-
- if(use_RockRidge)
- {
- fstatbuf.st_mode = 0555 | S_IFDIR;
- fstatbuf.st_nlink = 2;
-
- if( dirnode == root )
- {
- deep_flag |= NEED_CE | NEED_SP; /* For extension record */
- }
-
- generate_rock_ridge_attributes("",
- ".", s_entry,
- &fstatbuf, &fstatbuf, deep_flag);
- }
-
- dirnode->dir_flags |= DIR_HAS_DOT;
- }
-
-}
-
-static void FDECL2(update_nlink, struct directory_entry *, s_entry, int, value)
-{
- unsigned char * pnt;
- int len;
-
- pnt = s_entry->rr_attributes;
- len = s_entry->total_rr_attr_size;
- while(len)
- {
- if(pnt[0] == 'P' && pnt[1] == 'X')
- {
- set_733((char *) pnt+12, value);
- break;
- }
- len -= pnt[2];
- pnt += pnt[2];
- }
-}
-
-static void FDECL1(increment_nlink, struct directory_entry *, s_entry)
-{
- unsigned char * pnt;
- int len, nlink;
-
- pnt = s_entry->rr_attributes;
- len = s_entry->total_rr_attr_size;
- while(len)
- {
- if(pnt[0] == 'P' && pnt[1] == 'X')
- {
- nlink = get_733((char *) pnt+12);
- set_733((char *) pnt+12, nlink+1);
- break;
- }
- len -= pnt[2];
- pnt += pnt[2];
- }
-}
-
-void finish_cl_pl_entries(){
- struct directory_entry *s_entry, *s_entry1;
- struct directory * d_entry;
-
- /* if the reloc_dir is hidden (empty), then return */
- if (reloc_dir->dir_flags & INHIBIT_ISO9660_ENTRY)
- return;
-
- s_entry = reloc_dir->contents;
- s_entry = s_entry->next->next; /* Skip past . and .. */
- for(; s_entry; s_entry = s_entry->next){
- /* skip if it's hidden */
- if(s_entry->de_flags & INHIBIT_ISO9660_ENTRY) {
- continue;
- }
- d_entry = reloc_dir->subdir;
- while(d_entry){
- if(d_entry->self == s_entry) break;
- d_entry = d_entry->next;
- };
- if(!d_entry)
- error (1, 0, _("Unable to locate directory parent\n"));
-
- /* First fix the PL pointer in the directory in the rr_reloc dir */
- s_entry1 = d_entry->contents->next;
- set_733((char *) s_entry1->rr_attributes + s_entry1->total_rr_attr_size - 8,
- s_entry->filedir->extent);
-
- /* Now fix the CL pointer */
- s_entry1 = s_entry->parent_rec;
-
- set_733((char *) s_entry1->rr_attributes + s_entry1->total_rr_attr_size - 8,
- d_entry->extent);
-
- s_entry->filedir = reloc_dir; /* Now we can fix this */
- }
- /* Next we need to modify the NLINK terms in the assorted root directory records
- to account for the presence of the RR_MOVED directory */
-
- increment_nlink(root->self);
- increment_nlink(root->self->next);
- d_entry = root->subdir;
- while(d_entry){
- increment_nlink(d_entry->contents->next);
- d_entry = d_entry->next;
- };
-}
-
-/*
- * Function: scan_directory_tree
- *
- * Purpose: Walk through a directory on the local machine
- * filter those things we don't want to include
- * and build our representation of a dir.
- *
- * Notes:
- */
-int
-FDECL3(scan_directory_tree,struct directory *, this_dir,
- char *, path,
- struct directory_entry *, de)
-{
- DIR * current_dir;
- char whole_path[1024];
- struct dirent * d_entry;
- struct directory * parent;
- int dflag;
- char * old_path;
-
- if (verbose > 1)
- {
- fprintf (stderr, _("Scanning %s\n"), path);
- }
-
- current_dir = opendir(path);
- d_entry = NULL;
-
- /* Apparently NFS sometimes allows you to open the directory, but
- then refuses to allow you to read the contents. Allow for this */
-
- old_path = path;
-
- if(current_dir) d_entry = readdir(current_dir);
-
- if(!current_dir || !d_entry)
- {
- fprintf (stderr, _("Unable to open directory %s\n"), path);
- de->isorec.flags[0] &= ~2; /* Mark as not a directory */
- if(current_dir) closedir(current_dir);
- return 0;
- }
-
- parent = de->filedir;
- /* Set up the struct for the current directory, and insert it into the
- tree */
-
-#ifdef VMS
- vms_path_fixup(path);
-#endif
-
- /*
- * if entry for this sub-directory is hidden, then hide this directory
- */
- if (de->de_flags & INHIBIT_ISO9660_ENTRY)
- this_dir->dir_flags |= INHIBIT_ISO9660_ENTRY;
-
- if (de->de_flags & INHIBIT_JOLIET_ENTRY)
- this_dir->dir_flags |= INHIBIT_JOLIET_ENTRY;
-
- /*
- * Now we scan the directory itself, and look at what is inside of it.
- */
- dflag = 0;
- while(1==1){
-
- /* The first time through, skip this, since we already asked for
- the first entry when we opened the directory. */
- if(dflag) d_entry = readdir(current_dir);
- dflag++;
-
- if(!d_entry) break;
-
- /* OK, got a valid entry */
-
- /* If we do not want all files, then pitch the backups. */
- if(!all_files){
- if( strchr(d_entry->d_name,'~')
- || strchr(d_entry->d_name,'#'))
- {
- if( verbose > 0 )
- {
- fprintf (stderr, _("Ignoring file %s\n"), d_entry->d_name);
- }
- continue;
- }
- }
-
- if(strlen(path)+strlen(d_entry->d_name) + 2 > sizeof(whole_path))
- error (1, 0, _("Overflow of stat buffer\n"));
-
- /* Generate the complete ASCII path for this file */
- strcpy(whole_path, path);
-#ifndef VMS
- if(whole_path[strlen(whole_path)-1] != '/')
- strcat(whole_path, "/");
-#endif
- strcat(whole_path, d_entry->d_name);
-
- /** Should we exclude this file ? */
- if (matches(d_entry->d_name) || matches(whole_path)) {
- if (verbose > 1) {
- fprintf (stderr, _("Excluded by match: %s\n"), whole_path);
- }
- continue;
- }
-
- if( generate_tables
- && strcmp(d_entry->d_name, "TRANS.TBL") == 0 )
- {
- /*
- * Ignore this entry. We are going to be generating new
- * versions of these files, and we need to ignore any
- * originals that we might have found.
- */
- if (verbose > 1)
- {
- fprintf (stderr, _("Excluded: %s\n"), whole_path);
- }
- continue;
- }
-
- /*
- * If we already have a '.' or a '..' entry, then don't
- * insert new ones.
- */
- if( strcmp(d_entry->d_name, ".") == 0
- && this_dir->dir_flags & DIR_HAS_DOT )
- {
- continue;
- }
-
- if( strcmp(d_entry->d_name, "..") == 0
- && this_dir->dir_flags & DIR_HAS_DOTDOT )
- {
- continue;
- }
-
-#if 0
- if (verbose > 1) fprintf(stderr, "%s\n",whole_path);
-#endif
- /*
- * This actually adds the entry to the directory in question.
- */
- insert_file_entry(this_dir, whole_path, d_entry->d_name);
- }
- closedir(current_dir);
-
- return 1;
-}
-
-
-/*
- * Function: insert_file_entry
- *
- * Purpose: Insert one entry into our directory node.
- *
- * Note:
- * This function inserts a single entry into the directory. It
- * is assumed that all filtering and decision making regarding what
- * we want to include has already been made, so the purpose of this
- * is to insert one entry (file, link, dir, etc), into this directory.
- * Note that if the entry is a dir (or if we are following links,
- * and the thing it points to is a dir), then we will scan those
- * trees before we return.
- */
-int
-FDECL3(insert_file_entry,struct directory *, this_dir,
- char *, whole_path,
- char *, short_name)
-{
- struct stat statbuf, lstatbuf;
- struct directory_entry * s_entry, *s_entry1;
- int lstatus;
- int status;
- int deep_flag;
-
- status = stat_filter(whole_path, &statbuf);
-
- lstatus = lstat_filter(whole_path, &lstatbuf);
-
- if( (status == -1) && (lstatus == -1) )
- {
- /*
- * This means that the file doesn't exist, or isn't accessible.
- * Sometimes this is because of NFS permissions problems.
- */
- fprintf (stderr, _("Non-existant or inaccessible: %s\n"),whole_path);
- return 0;
- }
-
- if(this_dir == root && strcmp(short_name, ".") == 0)
- root_statbuf = statbuf; /* Save this for later on */
-
- /* We do this to make sure that the root entries are consistent */
- if(this_dir == root && strcmp(short_name, "..") == 0)
- {
- statbuf = root_statbuf;
- lstatbuf = root_statbuf;
- }
-
- if(S_ISLNK(lstatbuf.st_mode))
- {
-
- /* Here we decide how to handle the symbolic links. Here
- we handle the general case - if we are not following
- links or there is an error, then we must change
- something. If RR is in use, it is easy, we let RR
- describe the file. If not, then we punt the file. */
-
- if((status || !follow_links))
- {
- if(use_RockRidge)
- {
- status = 0;
- statbuf.st_size = 0;
- STAT_INODE(statbuf) = UNCACHED_INODE;
- statbuf.st_dev = (dev_t) UNCACHED_DEVICE;
- statbuf.st_mode = (statbuf.st_mode & ~S_IFMT) | S_IFREG;
- } else {
- if(follow_links)
- {
- fprintf (stderr,
- _("Unable to stat file %s - ignoring and continuing.\n"),
- whole_path);
- }
- else
- {
- fprintf (stderr,
- _("Symlink %s ignored - continuing.\n"),
- whole_path);
- return 0; /* Non Rock Ridge discs - ignore all symlinks */
- }
- }
- }
-
- /* Here we handle a different kind of case. Here we have
- a symlink, but we want to follow symlinks. If we run
- across a directory loop, then we need to pretend that
- we are not following symlinks for this file. If this
- is the first time we have seen this, then make this
- seem as if there was no symlink there in the first
- place */
-
- if( follow_links
- && S_ISDIR(statbuf.st_mode) )
- {
- if( strcmp(short_name, ".")
- && strcmp(short_name, "..") )
- {
- if(find_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)))
- {
- if(!use_RockRidge)
- {
- fprintf (stderr, _("Already cached directory seen (%s)\n"),
- whole_path);
- return 0;
- }
- statbuf.st_size = 0;
- STAT_INODE(statbuf) = UNCACHED_INODE;
- statbuf.st_dev = (dev_t) UNCACHED_DEVICE;
- statbuf.st_mode = (statbuf.st_mode & ~S_IFMT) | S_IFREG;
- }
- else
- {
- lstatbuf = statbuf;
- add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf));
- }
- }
- }
-
- /*
- * For non-directories, we just copy the stat information over
- * so we correctly include this file.
- */
- if( follow_links
- && !S_ISDIR(statbuf.st_mode) )
- {
- lstatbuf = statbuf;
- }
- }
-
- /*
- * Add directories to the cache so that we don't waste space even
- * if we are supposed to be following symlinks.
- */
- if( follow_links
- && strcmp(short_name, ".")
- && strcmp(short_name, "..")
- && S_ISDIR(statbuf.st_mode) )
- {
- add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf));
- }
-
- if(S_ISREG(lstatbuf.st_mode) && (status = access(whole_path, R_OK)))
- {
- fprintf (stderr, _("File %s is not readable (%s) - ignoring\n"),
- whole_path, strerror (errno));
- return 0;
- }
-
- /* Add this so that we can detect directory loops with hard links.
- If we are set up to follow symlinks, then we skip this checking. */
- if( !follow_links
- && S_ISDIR(lstatbuf.st_mode)
- && strcmp(short_name, ".")
- && strcmp(short_name, "..") )
- {
- if(find_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)))
- error (1, 0, _("Directory loop - fatal goof (%s %lx %lu).\n"),
- whole_path, (unsigned long) statbuf.st_dev,
- (unsigned long) STAT_INODE(statbuf));
- add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf));
- }
-
- if (!S_ISCHR(lstatbuf.st_mode) && !S_ISBLK(lstatbuf.st_mode) &&
- !S_ISFIFO(lstatbuf.st_mode) && !S_ISSOCK(lstatbuf.st_mode)
- && !S_ISLNK(lstatbuf.st_mode) && !S_ISREG(lstatbuf.st_mode) &&
- !S_ISDIR(lstatbuf.st_mode)) {
- fprintf (stderr, _("Unknown file type %s - ignoring and continuing.\n"),
- whole_path);
- return 0;
- }
-
- /* Who knows what trash this is - ignore and continue */
-
- if(status)
- {
- fprintf (stderr,
- _("Unable to stat file %s - ignoring and continuing.\n"),
- whole_path);
- return 0;
- }
-
- /*
- * Check to see if we have already seen this directory node.
- * If so, then we don't create a new entry for it, but we do want
- * to recurse beneath it and add any new files we do find.
- */
- if (S_ISDIR(statbuf.st_mode))
- {
- int dflag;
-
- for( s_entry = this_dir->contents; s_entry; s_entry = s_entry->next)
- {
- if( strcmp(s_entry->name, short_name) == 0 )
- {
- break;
- }
- }
- if ( s_entry != NULL
- && strcmp(short_name,".")
- && strcmp(short_name,".."))
- {
- struct directory * child;
-
- if ( (s_entry->de_flags & RELOCATED_DIRECTORY) != 0)
- {
- for( s_entry = reloc_dir->contents; s_entry; s_entry = s_entry->next)
- {
- if( strcmp(s_entry->name, short_name) == 0 )
- {
- break;
- }
- }
- child = find_or_create_directory(reloc_dir, whole_path,
- s_entry, 1);
- }
- else
- {
- child = find_or_create_directory(this_dir, whole_path,
- s_entry, 1);
- /* If unable to scan directory, mark this as a non-directory */
- }
- dflag = scan_directory_tree(child, whole_path, s_entry);
- if(!dflag)
- {
- lstatbuf.st_mode = (lstatbuf.st_mode & ~S_IFMT) | S_IFREG;
- }
- return 0;
- }
- }
-
- s_entry = (struct directory_entry *)
- e_malloc(sizeof (struct directory_entry));
- s_entry->next = this_dir->contents;
- memset(s_entry->isorec.extent, 0, 8);
- this_dir->contents = s_entry;
- deep_flag = 0;
- s_entry->table = NULL;
-
- s_entry->name = strdup(short_name);
- s_entry->whole_name = strdup (whole_path);
-
- s_entry->de_flags = 0;
-
- /*
- * If the current directory is hidden, then hide all it's members
- * otherwise check if this entry needs to be hidden as well */
- if (this_dir->dir_flags & INHIBIT_ISO9660_ENTRY) {
- s_entry->de_flags |= INHIBIT_ISO9660_ENTRY;
- }
- else if (strcmp(short_name,".") && strcmp(short_name,"..")) {
- if (i_matches(short_name) || i_matches(whole_path)) {
- if (verbose > 1) {
- fprintf (stderr, _("Hidden from ISO9660 tree: %s\n"), whole_path);
- }
- s_entry->de_flags |= INHIBIT_ISO9660_ENTRY;
- }
- }
-
- if (this_dir != reloc_dir && this_dir->dir_flags & INHIBIT_JOLIET_ENTRY) {
- s_entry->de_flags |= INHIBIT_JOLIET_ENTRY;
- }
- else if (strcmp(short_name,".") && strcmp(short_name,"..")) {
- if (j_matches(short_name) || j_matches(whole_path)) {
- if (verbose > 1) {
- fprintf (stderr, _("Hidden from Joliet tree: %s\n"), whole_path);
- }
- s_entry->de_flags |= INHIBIT_JOLIET_ENTRY;
- }
- }
-
- s_entry->filedir = this_dir;
- s_entry->isorec.flags[0] = 0;
- s_entry->isorec.ext_attr_length[0] = 0;
- iso9660_date(s_entry->isorec.date, statbuf.st_mtime);
- s_entry->isorec.file_unit_size[0] = 0;
- s_entry->isorec.interleave[0] = 0;
-
- if( strcmp(short_name, ".") == 0)
- {
- this_dir->dir_flags |= DIR_HAS_DOT;
- }
-
- if( strcmp(short_name, "..") == 0)
- {
- this_dir->dir_flags |= DIR_HAS_DOTDOT;
- }
-
- if( this_dir->parent
- && this_dir->parent == reloc_dir
- && strcmp(short_name, "..") == 0)
- {
- s_entry->inode = UNCACHED_INODE;
- s_entry->dev = (dev_t) UNCACHED_DEVICE;
- deep_flag = NEED_PL;
- }
- else
- {
- s_entry->inode = STAT_INODE(statbuf);
- s_entry->dev = statbuf.st_dev;
- }
- set_723(s_entry->isorec.volume_sequence_number, volume_sequence_number);
- iso9660_file_length(short_name, s_entry, S_ISDIR(statbuf.st_mode));
- s_entry->rr_attr_size = 0;
- s_entry->total_rr_attr_size = 0;
- s_entry->rr_attributes = NULL;
-
- /* Directories are assigned sizes later on */
- if (!S_ISDIR(statbuf.st_mode))
- {
- if (S_ISCHR(lstatbuf.st_mode) || S_ISBLK(lstatbuf.st_mode) ||
- S_ISFIFO(lstatbuf.st_mode) || S_ISSOCK(lstatbuf.st_mode)
- || S_ISLNK(lstatbuf.st_mode))
- {
- s_entry->size = 0;
- statbuf.st_size = 0;
- }
- else
- {
- s_entry->size = statbuf.st_size;
- }
-
- set_733((char *) s_entry->isorec.size, statbuf.st_size);
- }
- else
- {
- s_entry->isorec.flags[0] = 2;
- }
-
- if (strcmp(short_name,".") && strcmp(short_name,"..") &&
- S_ISDIR(statbuf.st_mode) && this_dir->depth > RR_relocation_depth)
- {
- struct directory * child;
-
- if(!reloc_dir) generate_reloc_directory();
-
- /*
- * Replicate the entry for this directory. The old one will stay where it
- * is, and it will be neutered so that it no longer looks like a directory.
- * The new one will look like a directory, and it will be put in the reloc_dir.
- */
- s_entry1 = (struct directory_entry *)
- e_malloc(sizeof (struct directory_entry));
- memcpy(s_entry1, s_entry, sizeof(struct directory_entry));
- s_entry1->table = NULL;
- s_entry1->name = strdup(this_dir->contents->name);
- s_entry1->whole_name = strdup(this_dir->contents->whole_name);
- s_entry1->next = reloc_dir->contents;
- reloc_dir->contents = s_entry1;
- s_entry1->priority = 32768;
- s_entry1->parent_rec = this_dir->contents;
-
- deep_flag = NEED_RE;
-
- if(use_RockRidge)
- {
- generate_rock_ridge_attributes(whole_path,
- short_name, s_entry1,
- &statbuf, &lstatbuf, deep_flag);
- }
-
- deep_flag = 0;
-
- /* We need to set this temporarily so that the parent to this
- is correctly determined. */
- s_entry1->filedir = reloc_dir;
- child = find_or_create_directory(reloc_dir, whole_path,
- s_entry1, 0);
- scan_directory_tree(child, whole_path, s_entry1);
- s_entry1->filedir = this_dir;
-
- statbuf.st_size = 0;
- statbuf.st_mode &= 0777;
- set_733((char *) s_entry->isorec.size, 0);
- s_entry->size = 0;
- s_entry->isorec.flags[0] = 0;
- s_entry->inode = UNCACHED_INODE;
- s_entry->de_flags |= RELOCATED_DIRECTORY;
- deep_flag = NEED_CL;
- }
-
- if(generate_tables
- && strcmp(s_entry->name, ".")
- && strcmp(s_entry->name, ".."))
- {
- char buffer[2048];
- int nchar;
- switch(lstatbuf.st_mode & S_IFMT)
- {
- case S_IFDIR:
- sprintf(buffer,"D\t%s\n",
- s_entry->name);
- break;
-#ifdef S_IFBLK
-/* extra for WIN32 - if it doesn't have the major/minor defined, then
- S_IFBLK and S_IFCHR type files are unlikely to exist anyway ...
- code similar to that in rock.c */
-
-/* for some reason, MAJOR_IN_SYSMACROS isn't defined on a SunOS when
- it should be, so see if major() is defined instead */
-/*
-#if !(defined(MAJOR_IN_SYSMACROS) || defined(MAJOR_IN_MKDEV))
-*/
-#ifndef major
-#define major(dev) (sizeof(dev_t) <= 2 ? ((dev) >> 8) : \
- (sizeof(dev_t) <= 4 ? (((dev) >> 8) >> 8) : \
- (((dev) >> 16) >> 16)))
-#define minor(dev) (sizeof(dev_t) <= 2 ? (dev) & 0xff : \
- (sizeof(dev_t) <= 4 ? (dev) & 0xffff : \
- (dev) & 0xffffffff))
-#endif
- case S_IFBLK:
- sprintf(buffer,"B\t%s\t%lu %lu\n",
- s_entry->name,
- (unsigned long) major(statbuf.st_rdev),
- (unsigned long) minor(statbuf.st_rdev));
- break;
-#endif
-#ifdef S_IFIFO
- case S_IFIFO:
- sprintf(buffer,"P\t%s\n",
- s_entry->name);
- break;
-#endif
-#ifdef S_IFCHR
- case S_IFCHR:
- sprintf(buffer,"C\t%s\t%lu %lu\n",
- s_entry->name,
- (unsigned long) major(statbuf.st_rdev),
- (unsigned long) minor(statbuf.st_rdev));
- break;
-#endif
-#ifdef S_IFLNK
- case S_IFLNK:
- nchar = readlink(whole_path,
- (char *)symlink_buff,
- sizeof(symlink_buff));
- symlink_buff[nchar < 0 ? 0 : nchar] = 0;
- sprintf(buffer,"L\t%s\t%s\n",
- s_entry->name, symlink_buff);
- break;
-#endif
-#ifdef S_IFSOCK
- case S_IFSOCK:
- sprintf(buffer,"S\t%s\n",
- s_entry->name);
- break;
-#endif
- case S_IFREG:
- default:
- sprintf(buffer,"F\t%s\n",
- s_entry->name);
- break;
- };
- s_entry->table = strdup(buffer);
- }
-
- if(S_ISDIR(statbuf.st_mode))
- {
- int dflag;
- if (strcmp(short_name,".") && strcmp(short_name,".."))
- {
- struct directory * child;
-
- child = find_or_create_directory(this_dir, whole_path,
- s_entry, 1);
- dflag = scan_directory_tree(child, whole_path, s_entry);
-
- if(!dflag)
- {
- lstatbuf.st_mode = (lstatbuf.st_mode & ~S_IFMT) | S_IFREG;
- if( child->contents == NULL )
- {
- delete_directory(this_dir, child);
- }
- }
- }
- /* If unable to scan directory, mark this as a non-directory */
- }
-
- if(use_RockRidge && this_dir == root && strcmp(s_entry->name, ".") == 0)
- {
- deep_flag |= NEED_CE | NEED_SP; /* For extension record */
- }
-
- /* Now figure out how much room this file will take in the
- directory */
-
- if(use_RockRidge)
- {
- generate_rock_ridge_attributes(whole_path,
- short_name, s_entry,
- &statbuf, &lstatbuf, deep_flag);
-
- }
-
- return 1;
-}
-
-
-void FDECL2(generate_iso9660_directories, struct directory *, node, FILE*, outfile){
- struct directory * dpnt;
-
- dpnt = node;
-
- while (dpnt){
- if( dpnt->extent > session_start )
- {
- generate_one_directory(dpnt, outfile);
- }
- if(dpnt->subdir) generate_iso9660_directories(dpnt->subdir, outfile);
- dpnt = dpnt->next;
- }
-}
-
-/*
- * Function: find_or_create_directory
- *
- * Purpose: Locate a directory entry in the tree, create if needed.
- *
- * Arguments:
- */
-struct directory * FDECL4(find_or_create_directory, struct directory *, parent,
- const char *, path,
- struct directory_entry *, de, int, flag)
-{
- struct directory * dpnt;
- struct directory_entry * orig_de;
- struct directory * next_brother;
- const char * cpnt;
- const char * pnt;
-
- orig_de = de;
-
- pnt = strrchr(path, PATH_SEPARATOR);
- if( pnt == NULL )
- {
- pnt = path;
- }
- else
- {
- pnt++;
- }
-
- if( parent != NULL )
- {
- dpnt = parent->subdir;
-
- while (dpnt)
- {
- /*
- * Weird hack time - if there are two directories by the
- * same name in the reloc_dir, they are not treated as the
- * same thing unless the entire path matches completely.
- */
- if( flag && strcmp(dpnt->de_name, pnt) == 0 )
- {
- return dpnt;
- }
- dpnt = dpnt->next;
- }
- }
-
- /*
- * We don't know if we have a valid directory entry for this one
- * yet. If not, we need to create one.
- */
- if( de == NULL )
- {
- de = (struct directory_entry *)
- e_malloc(sizeof (struct directory_entry));
- memset(de, 0, sizeof(struct directory_entry));
- de->next = parent->contents;
- parent->contents = de;
- de->name = strdup(pnt);
- de->filedir = parent;
- de->isorec.flags[0] = 2;
- de->priority = 32768;
- de->inode = UNCACHED_INODE;
- de->dev = (dev_t) UNCACHED_DEVICE;
- set_723(de->isorec.volume_sequence_number, volume_sequence_number);
- iso9660_file_length (pnt, de, 1);
-
- init_fstatbuf();
- /*
- * It doesn't exist for real, so we cannot add any Rock Ridge.
- */
- if(use_RockRidge)
- {
- fstatbuf.st_mode = 0555 | S_IFDIR;
- fstatbuf.st_nlink = 2;
- generate_rock_ridge_attributes("",
- (char *) pnt, de,
- &fstatbuf,
- &fstatbuf, 0);
- }
- iso9660_date(de->isorec.date, fstatbuf.st_mtime);
-
- }
-
- /*
- * If we don't have a directory for this one yet, then allocate it
- * now, and patch it into the tree in the appropriate place.
- */
- dpnt = (struct directory *) e_malloc(sizeof(struct directory));
- memset(dpnt, 0, sizeof(struct directory));
- dpnt->next = NULL;
- dpnt->subdir = NULL;
- dpnt->self = de;
- dpnt->contents = NULL;
- dpnt->whole_name = strdup(path);
- cpnt = strrchr(path, PATH_SEPARATOR);
- if(cpnt)
- cpnt++;
- else
- cpnt = path;
- dpnt->de_name = strdup(cpnt);
- dpnt->size = 0;
- dpnt->extent = 0;
- dpnt->jextent = 0;
- dpnt->jsize = 0;
-
- if( orig_de == NULL )
- {
- struct stat xstatbuf;
- int sts;
-
- /*
- * Now add a . and .. entry in the directory itself.
- * This is a little tricky - if the real directory
- * exists, we need to stat it first. Otherwise, we
- * use the fictitious fstatbuf which points to the time
- * at which mkisofs was started.
- */
- sts = stat_filter(parent->whole_name, &xstatbuf);
- if( sts == 0 )
- {
- attach_dot_entries(dpnt, &xstatbuf);
- }
- else
- {
- attach_dot_entries(dpnt, &fstatbuf);
- }
- }
-
- if(!parent || parent == root)
- {
- if (!root)
- {
- root = dpnt; /* First time through for root directory only */
- root->depth = 0;
- root->parent = root;
- } else {
- dpnt->depth = 1;
- if(!root->subdir)
- {
- root->subdir = dpnt;
- }
- else
- {
- next_brother = root->subdir;
- while(next_brother->next) next_brother = next_brother->next;
- next_brother->next = dpnt;
- }
- dpnt->parent = parent;
- }
- }
- else
- {
- /* Come through here for normal traversal of tree */
-#ifdef DEBUG
- fprintf(stderr,"%s(%d) ", path, dpnt->depth);
-#endif
- if(parent->depth > RR_relocation_depth)
- error (1, 0, _("Directories too deep %s\n"), path);
-
- dpnt->parent = parent;
- dpnt->depth = parent->depth + 1;
-
- if(!parent->subdir)
- {
- parent->subdir = dpnt;
- }
- else
- {
- next_brother = parent->subdir;
- while(next_brother->next) next_brother = next_brother->next;
- next_brother->next = dpnt;
- }
- }
-
- return dpnt;
-}
-
-/*
- * Function: delete_directory
- *
- * Purpose: Locate a directory entry in the tree, create if needed.
- *
- * Arguments:
- */
-static void FDECL2(delete_directory, struct directory *, parent, struct directory *, child)
-{
- struct directory * tdir;
-
- if( child->contents != NULL )
- error (1, 0, _("Unable to delete non-empty directory\n"));
-
- free(child->whole_name);
- child->whole_name = NULL;
-
- free(child->de_name);
- child->de_name = NULL;
-
- if( parent->subdir == child )
- {
- parent->subdir = child->next;
- }
- else
- {
- for( tdir = parent->subdir; tdir->next != NULL; tdir = tdir->next )
- {
- if( tdir->next == child )
- {
- tdir->next = child->next;
- break;
- }
- }
- if( tdir == NULL )
- error (1, 0, _("Unable to locate child directory in parent list\n"));
- }
- free(child);
- return;
-}
-
-int FDECL1(sort_tree, struct directory *, node){
- struct directory * dpnt;
- int ret = 0;
-
- dpnt = node;
-
- while (dpnt){
- ret = sort_n_finish(dpnt);
- if( ret )
- {
- break;
- }
-
- if(dpnt->subdir) sort_tree(dpnt->subdir);
- dpnt = dpnt->next;
- }
- return ret;
-}
-
-void FDECL1(dump_tree, struct directory *, node){
- struct directory * dpnt;
-
- dpnt = node;
-
- while (dpnt){
- fprintf(stderr,"%4d %5d %s\n",dpnt->extent, dpnt->size, dpnt->de_name);
- if(dpnt->subdir) dump_tree(dpnt->subdir);
- dpnt = dpnt->next;
- }
-}
-
-void FDECL1(update_nlink_field, struct directory *, node)
-{
- struct directory * dpnt;
- struct directory * xpnt;
- struct directory_entry * s_entry;
- int i;
-
- dpnt = node;
-
- while (dpnt)
- {
- if (dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) {
- dpnt = dpnt->next;
- continue;
- }
-
- /*
- * First, count up the number of subdirectories this guy has.
- */
- for(i=0, xpnt = dpnt->subdir; xpnt; xpnt = xpnt->next)
- if ((xpnt->dir_flags & INHIBIT_ISO9660_ENTRY) == 0)
- i++;
- /*
- * Next check to see if we have any relocated directories
- * in this directory. The nlink field will include these
- * as real directories when they are properly relocated.
- *
- * In the non-rockridge disk, the relocated entries appear
- * as zero length files.
- */
- for(s_entry = dpnt->contents; s_entry; s_entry = s_entry->next)
- {
- if( (s_entry->de_flags & RELOCATED_DIRECTORY) != 0 &&
- (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) == 0)
- {
- i++;
- }
- }
- /*
- * Now update the field in the Rock Ridge entry.
- */
- update_nlink(dpnt->self, i + 2);
-
- /*
- * Update the '.' entry for this directory.
- */
- update_nlink(dpnt->contents, i + 2);
-
- /*
- * Update all of the '..' entries that point to this guy.
- */
- for(xpnt = dpnt->subdir; xpnt; xpnt = xpnt->next)
- update_nlink(xpnt->contents->next, i + 2);
-
- if(dpnt->subdir) update_nlink_field(dpnt->subdir);
- dpnt = dpnt->next;
- }
-}
-
-/*
- * something quick and dirty to locate a file given a path
- * recursively walks down path in filename until it finds the
- * directory entry for the desired file
- */
-struct directory_entry * FDECL2(search_tree_file, struct directory *,
- node,char *, filename)
-{
- struct directory_entry * depnt;
- struct directory * dpnt;
- char * p1;
- char * rest;
- char * subdir;
-
- /*
- * strip off next directory name from filename
- */
- subdir = strdup(filename);
-
- if( (p1=strchr(subdir, '/')) == subdir )
- {
- fprintf (stderr, _("call to search_tree_file with an absolute path, stripping\n"));
- fprintf (stderr, _("initial path separator. Hope this was intended...\n"));
- memmove(subdir, subdir+1, strlen(subdir)-1);
- p1 = strchr(subdir, '/');
- }
-
- /*
- * do we need to find a subdirectory
- */
- if (p1)
- {
- *p1 = '\0';
-
-#ifdef DEBUG_TORITO
- fprintf(stderr,"Looking for subdir called %s\n",p1);
-#endif
-
- rest = p1+1;
-
-#ifdef DEBUG_TORITO
- fprintf(stderr,"Remainder of path name is now %s\n", rest);
-#endif
-
- dpnt = node->subdir;
- while( dpnt )
- {
-#ifdef DEBUG_TORITO
- fprintf(stderr,"%4d %5d %s\n", dpnt->extent, dpnt->size,
- dpnt->de_name);
-#endif
- if (!strcmp(subdir, dpnt->de_name))
- {
-#ifdef DEBUG_TORITO
- fprintf(stderr,"Calling next level with filename = %s", rest);
-#endif
- return(search_tree_file( dpnt, rest ));
- }
- dpnt = dpnt->next;
- }
-
- /* if we got here means we couldnt find the subdir */
- return (NULL);
- }
- else
- {
- /*
- * look for a normal file now
- */
- depnt = node->contents;
- while (depnt)
- {
-#ifdef DEBUG_TORITO
- fprintf(stderr,"%4d %5d %s\n",depnt->isorec.extent,
- depnt->size, depnt->name);
-#endif
- if (!strcmp(filename, depnt->name))
- {
-#ifdef DEBUG_TORITO
- fprintf(stderr,"Found our file %s", filename);
-#endif
- return(depnt);
- }
- depnt = depnt->next;
- }
- /*
- * if we got here means we couldnt find the subdir
- */
- return (NULL);
- }
- fprintf (stderr, "We cant get here in search_tree_file :-/ \n");
-}
-
-void init_fstatbuf()
-{
- time_t current_time;
-
- if(fstatbuf.st_ctime == 0)
- {
- time (¤t_time);
- if( rationalize )
- {
- fstatbuf.st_uid = 0;
- fstatbuf.st_gid = 0;
- }
- else
- {
- fstatbuf.st_uid = getuid();
- fstatbuf.st_gid = getgid();
- }
- fstatbuf.st_ctime = current_time;
- fstatbuf.st_mtime = current_time;
- fstatbuf.st_atime = current_time;
- }
-}
+++ /dev/null
-/*
- * Program write.c - dump memory structures to file for iso9660 filesystem.
-
- Written by Eric Youngdale (1993).
-
- Copyright 1993 Yggdrasil Computing, Incorporated
-
- Copyright (C) 2009 Free Software Foundation, Inc.
-
- 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 3, 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-#include <errno.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <assert.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "mkisofs.h"
-#include "iso9660.h"
-#include "msdos_partition.h"
-
-#ifdef __SVR4
-extern char * strdup(const char *);
-#endif
-
-#ifdef VMS
-extern char * strdup(const char *);
-#endif
-
-
-/* Max number of sectors we will write at one time */
-#define NSECT 16
-
-/* Counters for statistics */
-
-static int table_size = 0;
-static int total_dir_size = 0;
-static int rockridge_size = 0;
-static struct directory ** pathlist;
-static int next_path_index = 1;
-static int sort_goof;
-
-struct output_fragment * out_tail;
-struct output_fragment * out_list;
-
-struct iso_primary_descriptor vol_desc;
-
-static int root_gen __PR((void));
-static int generate_path_tables __PR((void));
-static int file_gen __PR((void));
-static int dirtree_dump __PR((void));
-
-/* Routines to actually write the disc. We write sequentially so that
- we could write a tape, or write the disc directly */
-
-
-#define FILL_SPACE(X) memset(vol_desc.X, ' ', sizeof(vol_desc.X))
-
-void FDECL2(set_721, char *, pnt, unsigned int, i)
-{
- pnt[0] = i & 0xff;
- pnt[1] = (i >> 8) & 0xff;
-}
-
-void FDECL2(set_722, char *, pnt, unsigned int, i)
-{
- pnt[0] = (i >> 8) & 0xff;
- pnt[1] = i & 0xff;
-}
-
-void FDECL2(set_723, char *, pnt, unsigned int, i)
-{
- pnt[3] = pnt[0] = i & 0xff;
- pnt[2] = pnt[1] = (i >> 8) & 0xff;
-}
-
-void FDECL2(set_731, char *, pnt, unsigned int, i)
-{
- pnt[0] = i & 0xff;
- pnt[1] = (i >> 8) & 0xff;
- pnt[2] = (i >> 16) & 0xff;
- pnt[3] = (i >> 24) & 0xff;
-}
-
-void FDECL2(set_732, char *, pnt, unsigned int, i)
-{
- pnt[3] = i & 0xff;
- pnt[2] = (i >> 8) & 0xff;
- pnt[1] = (i >> 16) & 0xff;
- pnt[0] = (i >> 24) & 0xff;
-}
-
-int FDECL1(get_731, char *, p)
-{
- return ((p[0] & 0xff)
- | ((p[1] & 0xff) << 8)
- | ((p[2] & 0xff) << 16)
- | ((p[3] & 0xff) << 24));
-}
-
-int FDECL1(get_733, char *, p)
-{
- return ((p[0] & 0xff)
- | ((p[1] & 0xff) << 8)
- | ((p[2] & 0xff) << 16)
- | ((p[3] & 0xff) << 24));
-}
-
-void FDECL2(set_733, char *, pnt, unsigned int, i)
-{
- pnt[7] = pnt[0] = i & 0xff;
- pnt[6] = pnt[1] = (i >> 8) & 0xff;
- pnt[5] = pnt[2] = (i >> 16) & 0xff;
- pnt[4] = pnt[3] = (i >> 24) & 0xff;
-}
-
-void FDECL4(xfwrite, void *, buffer, uint64_t, count, uint64_t, size, FILE *, file)
-{
- /*
- * This is a hack that could be made better. XXXIs this the only place?
- * It is definitely needed on Operating Systems that do not
- * allow to write files that are > 2GB.
- * If the system is fast enough to be able to feed 1400 KB/s
- * writing speed of a DVD-R drive, use stdout.
- * If the system cannot do this reliable, you need to use this
- * hacky option.
- */
- static int idx = 0;
- if (split_output != 0 &&
- (idx == 0 || ftell(file) >= (1024 * 1024 * 1024) )) {
- char nbuf[512];
- extern char *outfile;
-
- if (idx == 0)
- unlink(outfile);
- sprintf(nbuf, "%s_%02d", outfile, idx++);
- file = freopen(nbuf, "wb", file);
- if (file == NULL)
- error (1, errno, _("Cannot open `%s'"), nbuf);
-
- }
- while(count)
- {
- size_t got = fwrite (buffer, size, count, file);
-
- if (got != count)
- error (1, errno, _("cannot fwrite %llu*%llu\n"), size, count);
- count-=got,*(char**)&buffer+=size*got;
- }
-}
-
-struct deferred_write
-{
- struct deferred_write * next;
- char * table;
- uint64_t extent;
- uint64_t size;
- char * name;
-};
-
-static struct deferred_write * dw_head = NULL, * dw_tail = NULL;
-
-uint64_t last_extent_written = 0;
-static unsigned int path_table_index;
-static time_t begun;
-
-/* We recursively walk through all of the directories and assign extent
- numbers to them. We have already assigned extent numbers to everything that
- goes in front of them */
-
-static int FDECL1(assign_directory_addresses, struct directory *, node)
-{
- int dir_size;
- struct directory * dpnt;
-
- dpnt = node;
-
- while (dpnt)
- {
- /* skip if it's hidden */
- if(dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) {
- dpnt = dpnt->next;
- continue;
- }
-
- /*
- * If we already have an extent for this (i.e. it came from
- * a multisession disc), then don't reassign a new extent.
- */
- dpnt->path_index = next_path_index++;
- if( dpnt->extent == 0 )
- {
- dpnt->extent = last_extent;
- dir_size = (dpnt->size + (SECTOR_SIZE - 1)) >> 11;
-
- last_extent += dir_size;
-
- /*
- * Leave room for the CE entries for this directory. Keep them
- * close to the reference directory so that access will be
- * quick.
- */
- if(dpnt->ce_bytes)
- {
- last_extent += ROUND_UP(dpnt->ce_bytes) >> 11;
- }
- }
-
- if(dpnt->subdir)
- {
- assign_directory_addresses(dpnt->subdir);
- }
-
- dpnt = dpnt->next;
- }
- return 0;
-}
-
-static void FDECL3(write_one_file, char *, filename,
- uint64_t, size, FILE *, outfile)
-{
- char buffer[SECTOR_SIZE * NSECT];
- FILE * infile;
- int64_t remain;
- size_t use;
-
-
- if ((infile = fopen(filename, "rb")) == NULL)
- error (1, errno, _("cannot open %s\n"), filename);
- remain = size;
-
- while(remain > 0)
- {
- use = (remain > SECTOR_SIZE * NSECT - 1 ? NSECT*SECTOR_SIZE : remain);
- use = ROUND_UP(use); /* Round up to nearest sector boundary */
- memset(buffer, 0, use);
- if (fread(buffer, 1, use, infile) == 0)
- error (1, errno, _("cannot read %llu bytes from %s"), use, filename);
- xfwrite(buffer, 1, use, outfile);
- last_extent_written += use/SECTOR_SIZE;
-#if 0
- if((last_extent_written % 1000) < use/SECTOR_SIZE)
- {
- fprintf(stderr,"%d..", last_extent_written);
- }
-#else
- if((last_extent_written % 5000) < use/SECTOR_SIZE)
- {
- time_t now;
- time_t the_end;
- double frac;
-
- time(&now);
- frac = last_extent_written / (double)last_extent;
- the_end = begun + (now - begun) / frac;
- fprintf (stderr, _("%6.2f%% done, estimate finish %s"),
- frac * 100., ctime(&the_end));
- }
-#endif
- remain -= use;
- }
- fclose(infile);
-} /* write_one_file(... */
-
-static void FDECL1(write_files, FILE *, outfile)
-{
- struct deferred_write * dwpnt, *dwnext;
- dwpnt = dw_head;
- while(dwpnt)
- {
- if(dwpnt->table)
- {
- write_one_file (dwpnt->table, dwpnt->size, outfile);
- table_size += dwpnt->size;
- free (dwpnt->table);
- }
- else
- {
-
-#ifdef VMS
- vms_write_one_file(dwpnt->name, dwpnt->size, outfile);
-#else
- write_one_file(dwpnt->name, dwpnt->size, outfile);
-#endif
- free(dwpnt->name);
- }
-
- dwnext = dwpnt;
- dwpnt = dwpnt->next;
- free(dwnext);
- }
-} /* write_files(... */
-
-#if 0
-static void dump_filelist()
-{
- struct deferred_write * dwpnt;
- dwpnt = dw_head;
- while(dwpnt)
- {
- fprintf(stderr, "File %s\n",dwpnt->name);
- dwpnt = dwpnt->next;
- }
- fprintf(stderr,"\n");
-}
-#endif
-
-static int FDECL2(compare_dirs, const void *, rr, const void *, ll)
-{
- char * rpnt, *lpnt;
- struct directory_entry ** r, **l;
-
- r = (struct directory_entry **) rr;
- l = (struct directory_entry **) ll;
- rpnt = (*r)->isorec.name;
- lpnt = (*l)->isorec.name;
-
- /*
- * If the entries are the same, this is an error.
- */
- if( strcmp(rpnt, lpnt) == 0 )
- {
- sort_goof++;
- }
-
- /*
- * Put the '.' and '..' entries on the head of the sorted list.
- * For normal ASCII, this always happens to be the case, but out of
- * band characters cause this not to be the case sometimes.
- *
- * FIXME(eric) - these tests seem redundant, in taht the name is
- * never assigned these values. It will instead be \000 or \001,
- * and thus should always be sorted correctly. I need to figure
- * out why I thought I needed this in the first place.
- */
-#if 0
- if( strcmp(rpnt, ".") == 0 ) return -1;
- if( strcmp(lpnt, ".") == 0 ) return 1;
-
- if( strcmp(rpnt, "..") == 0 ) return -1;
- if( strcmp(lpnt, "..") == 0 ) return 1;
-#else
- /*
- * The code above is wrong (as explained in Eric's comment), leading to incorrect
- * sort order iff the -L option ("allow leading dots") is in effect and a directory
- * contains entries that start with a dot.
- *
- * (TF, Tue Dec 29 13:49:24 CET 1998)
- */
- if((*r)->isorec.name_len[0] == 1 && *rpnt == 0) return -1; /* '.' */
- if((*l)->isorec.name_len[0] == 1 && *lpnt == 0) return 1;
-
- if((*r)->isorec.name_len[0] == 1 && *rpnt == 1) return -1; /* '..' */
- if((*l)->isorec.name_len[0] == 1 && *lpnt == 1) return 1;
-#endif
-
- while(*rpnt && *lpnt)
- {
- if(*rpnt == ';' && *lpnt != ';') return -1;
- if(*rpnt != ';' && *lpnt == ';') return 1;
-
- if(*rpnt == ';' && *lpnt == ';') return 0;
-
- if(*rpnt == '.' && *lpnt != '.') return -1;
- if(*rpnt != '.' && *lpnt == '.') return 1;
-
- if((unsigned char)*rpnt < (unsigned char)*lpnt) return -1;
- if((unsigned char)*rpnt > (unsigned char)*lpnt) return 1;
- rpnt++; lpnt++;
- }
- if(*rpnt) return 1;
- if(*lpnt) return -1;
- return 0;
-}
-
-/*
- * Function: sort_directory
- *
- * Purpose: Sort the directory in the appropriate ISO9660
- * order.
- *
- * Notes: Returns 0 if OK, returns > 0 if an error occurred.
- */
-int FDECL1(sort_directory, struct directory_entry **, sort_dir)
-{
- int dcount = 0;
- int xcount = 0;
- int j;
- int i, len;
- struct directory_entry * s_entry;
- struct directory_entry ** sortlist;
-
- /* need to keep a count of how many entries are hidden */
- s_entry = *sort_dir;
- while(s_entry)
- {
- if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY)
- xcount++;
- dcount++;
- s_entry = s_entry->next;
- }
-
- if( dcount == 0 )
- {
- return 0;
- }
-
- /*
- * OK, now we know how many there are. Build a vector for sorting.
- */
- sortlist = (struct directory_entry **)
- e_malloc(sizeof(struct directory_entry *) * dcount);
-
- j = dcount - 1;
- dcount = 0;
- s_entry = *sort_dir;
- while(s_entry)
- {
- if(s_entry->de_flags & INHIBIT_ISO9660_ENTRY)
- {
- /* put any hidden entries at the end of the vector */
- sortlist[j--] = s_entry;
- }
- else
- {
- sortlist[dcount] = s_entry;
- dcount++;
- }
- len = s_entry->isorec.name_len[0];
- s_entry->isorec.name[len] = 0;
- s_entry = s_entry->next;
- }
-
- /*
- * Each directory is required to contain at least . and ..
- */
- if( dcount < 2 )
- {
- sort_goof = 1;
-
- }
- else
- {
- /* only sort the non-hidden entries */
- sort_goof = 0;
-#ifdef __STDC__
- qsort(sortlist, dcount, sizeof(struct directory_entry *),
- (int (*)(const void *, const void *))compare_dirs);
-#else
- qsort(sortlist, dcount, sizeof(struct directory_entry *),
- compare_dirs);
-#endif
-
- /*
- * Now reassemble the linked list in the proper sorted order
- * We still need the hidden entries, as they may be used in the
- * Joliet tree.
- */
- for(i=0; i<dcount+xcount-1; i++)
- {
- sortlist[i]->next = sortlist[i+1];
- }
-
- sortlist[dcount+xcount-1]->next = NULL;
- *sort_dir = sortlist[0];
- }
-
- free(sortlist);
- return sort_goof;
-}
-
-static int root_gen()
-{
- init_fstatbuf();
-
- root_record.length[0] = 1 + sizeof(struct iso_directory_record)
- - sizeof(root_record.name);
- root_record.ext_attr_length[0] = 0;
- set_733((char *) root_record.extent, root->extent);
- set_733((char *) root_record.size, ROUND_UP(root->size));
- iso9660_date(root_record.date, root_statbuf.st_mtime);
- root_record.flags[0] = 2;
- root_record.file_unit_size[0] = 0;
- root_record.interleave[0] = 0;
- set_723(root_record.volume_sequence_number, volume_sequence_number);
- root_record.name_len[0] = 1;
- return 0;
-}
-
-static void FDECL1(assign_file_addresses, struct directory *, dpnt)
-{
- struct directory * finddir;
- struct directory_entry * s_entry;
- struct file_hash *s_hash;
- struct deferred_write * dwpnt;
- char whole_path[1024];
-
- while (dpnt)
- {
- s_entry = dpnt->contents;
- for(s_entry = dpnt->contents; s_entry; s_entry = s_entry->next)
- {
- /*
- * If we already have an extent for this entry,
- * then don't assign a new one. It must have come
- * from a previous session on the disc. Note that
- * we don't end up scheduling the thing for writing
- * either.
- */
- if( isonum_733((unsigned char *) s_entry->isorec.extent) != 0 )
- {
- continue;
- }
-
- /*
- * This saves some space if there are symlinks present
- */
- s_hash = find_hash(s_entry->dev, s_entry->inode);
- if(s_hash)
- {
- if(verbose > 2)
- {
- fprintf (stderr, _("Cache hit for %s%s%s\n"), s_entry->filedir->de_name,
- SPATH_SEPARATOR, s_entry->name);
- }
- set_733((char *) s_entry->isorec.extent, s_hash->starting_block);
- set_733((char *) s_entry->isorec.size, s_hash->size);
- continue;
- }
-
- /*
- * If this is for a directory that is not a . or a .. entry,
- * then look up the information for the entry. We have already
- * assigned extents for directories, so we just need to
- * fill in the blanks here.
- */
- if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..") &&
- s_entry->isorec.flags[0] == 2)
- {
- finddir = dpnt->subdir;
- while(1==1)
- {
- if(finddir->self == s_entry) break;
- finddir = finddir->next;
- if (!finddir)
- error (1, 0, _("Fatal goof\n"));
- }
- set_733((char *) s_entry->isorec.extent, finddir->extent);
- s_entry->starting_block = finddir->extent;
- s_entry->size = ROUND_UP(finddir->size);
- total_dir_size += s_entry->size;
- add_hash(s_entry);
- set_733((char *) s_entry->isorec.size, ROUND_UP(finddir->size));
- continue;
- }
-
-
- /*
- * If this is . or .., then look up the relevant info from the
- * tables.
- */
- if(strcmp(s_entry->name,".") == 0)
- {
- set_733((char *) s_entry->isorec.extent, dpnt->extent);
-
- /*
- * Set these so that the hash table has the
- * correct information
- */
- s_entry->starting_block = dpnt->extent;
- s_entry->size = ROUND_UP(dpnt->size);
-
- add_hash(s_entry);
- s_entry->starting_block = dpnt->extent;
- set_733((char *) s_entry->isorec.size, ROUND_UP(dpnt->size));
- continue;
- }
-
- if(strcmp(s_entry->name,"..") == 0)
- {
- if(dpnt == root)
- {
- total_dir_size += root->size;
- }
- set_733((char *) s_entry->isorec.extent, dpnt->parent->extent);
-
- /*
- * Set these so that the hash table has the
- * correct information
- */
- s_entry->starting_block = dpnt->parent->extent;
- s_entry->size = ROUND_UP(dpnt->parent->size);
-
- add_hash(s_entry);
- s_entry->starting_block = dpnt->parent->extent;
- set_733((char *) s_entry->isorec.size, ROUND_UP(dpnt->parent->size));
- continue;
- }
-
- /*
- * Some ordinary non-directory file. Just schedule the
- * file to be written. This is all quite
- * straightforward, just make a list and assign extents
- * as we go. Once we get through writing all of the
- * directories, we should be ready write out these
- * files
- */
- if(s_entry->size)
- {
- dwpnt = (struct deferred_write *)
- e_malloc(sizeof(struct deferred_write));
- if(dw_tail)
- {
- dw_tail->next = dwpnt;
- dw_tail = dwpnt;
- }
- else
- {
- dw_head = dwpnt;
- dw_tail = dwpnt;
- }
- if(s_entry->inode == TABLE_INODE)
- {
- dwpnt->table = s_entry->table;
- dwpnt->name = NULL;
- sprintf(whole_path,"%s%sTRANS.TBL",
- s_entry->filedir->whole_name, SPATH_SEPARATOR);
- }
- else
- {
- dwpnt->table = NULL;
- strcpy(whole_path, s_entry->whole_name);
- dwpnt->name = strdup(whole_path);
- }
- dwpnt->next = NULL;
- dwpnt->size = s_entry->size;
- dwpnt->extent = last_extent;
- set_733((char *) s_entry->isorec.extent, last_extent);
- s_entry->starting_block = last_extent;
- add_hash(s_entry);
- last_extent += ROUND_UP(s_entry->size) >> 11;
- if(verbose > 2)
- {
- fprintf(stderr,"%llu %llu %s\n", s_entry->starting_block,
- last_extent-1, whole_path);
- }
-#ifdef DBG_ISO
- if((ROUND_UP(s_entry->size) >> 11) > 500)
- {
- fprintf (stderr, "Warning: large file %s\n", whole_path);
- fprintf (stderr, "Starting block is %d\n", s_entry->starting_block);
- fprintf (stderr, "Reported file size is %d extents\n", s_entry->size);
-
- }
-#endif
-#ifdef NOT_NEEDED /* Never use this code if you like to create a DVD */
-
- if(last_extent > (800000000 >> 11))
- {
- /*
- * More than 800Mb? Punt
- */
- fprintf(stderr,"Extent overflow processing file %s\n", whole_path);
- fprintf(stderr,"Starting block is %d\n", s_entry->starting_block);
- fprintf(stderr,"Reported file size is %d extents\n", s_entry->size);
- exit(1);
- }
-#endif
- continue;
- }
-
- /*
- * This is for zero-length files. If we leave the extent 0,
- * then we get screwed, because many readers simply drop files
- * that have an extent of zero. Thus we leave the size 0,
- * and just assign the extent number.
- */
- set_733((char *) s_entry->isorec.extent, last_extent);
- }
- if(dpnt->subdir)
- {
- assign_file_addresses(dpnt->subdir);
- }
- dpnt = dpnt->next;
- }
-} /* assign_file_addresses(... */
-
-static void FDECL1(free_one_directory, struct directory *, dpnt)
-{
- struct directory_entry * s_entry;
- struct directory_entry * s_entry_d;
-
- s_entry = dpnt->contents;
- while(s_entry)
- {
- s_entry_d = s_entry;
- s_entry = s_entry->next;
-
- if( s_entry_d->name != NULL )
- {
- free (s_entry_d->name);
- }
- if( s_entry_d->whole_name != NULL )
- {
- free (s_entry_d->whole_name);
- }
- free (s_entry_d);
- }
- dpnt->contents = NULL;
-} /* free_one_directory(... */
-
-static void FDECL1(free_directories, struct directory *, dpnt)
-{
- while (dpnt)
- {
- free_one_directory(dpnt);
- if(dpnt->subdir) free_directories(dpnt->subdir);
- dpnt = dpnt->next;
- }
-}
-
-void FDECL2(generate_one_directory, struct directory *, dpnt, FILE *, outfile)
-{
- unsigned int ce_address = 0;
- char * ce_buffer;
- unsigned int ce_index = 0;
- unsigned int ce_size;
- unsigned int dir_index;
- char * directory_buffer;
- int new_reclen;
- struct directory_entry * s_entry;
- struct directory_entry * s_entry_d;
- unsigned int total_size;
-
- total_size = (dpnt->size + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1);
- directory_buffer = (char *) e_malloc(total_size);
- memset(directory_buffer, 0, total_size);
- dir_index = 0;
-
- ce_size = (dpnt->ce_bytes + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1);
- ce_buffer = NULL;
-
- if(ce_size)
- {
- ce_buffer = (char *) e_malloc(ce_size);
- memset(ce_buffer, 0, ce_size);
-
- ce_index = 0;
-
- /*
- * Absolute byte address of CE entries for this directory
- */
- ce_address = last_extent_written + (total_size >> 11);
- ce_address = ce_address << 11;
- }
-
- s_entry = dpnt->contents;
- while(s_entry)
- {
- /* skip if it's hidden */
- if(s_entry->de_flags & INHIBIT_ISO9660_ENTRY) {
- s_entry = s_entry->next;
- continue;
- }
-
- /*
- * We do not allow directory entries to cross sector boundaries.
- * Simply pad, and then start the next entry at the next sector
- */
- new_reclen = s_entry->isorec.length[0];
- if( (dir_index & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE )
- {
- dir_index = (dir_index + (SECTOR_SIZE - 1)) &
- ~(SECTOR_SIZE - 1);
- }
-
- memcpy(directory_buffer + dir_index, &s_entry->isorec,
- sizeof(struct iso_directory_record) -
- sizeof(s_entry->isorec.name) + s_entry->isorec.name_len[0]);
- dir_index += sizeof(struct iso_directory_record) -
- sizeof (s_entry->isorec.name)+ s_entry->isorec.name_len[0];
-
- /*
- * Add the Rock Ridge attributes, if present
- */
- if(s_entry->rr_attr_size)
- {
- if(dir_index & 1)
- {
- directory_buffer[dir_index++] = 0;
- }
-
- /*
- * If the RR attributes were too long, then write the
- * CE records, as required.
- */
- if(s_entry->rr_attr_size != s_entry->total_rr_attr_size)
- {
- unsigned char * pnt;
- int len, nbytes;
-
- /*
- * Go through the entire record and fix up the CE entries
- * so that the extent and offset are correct
- */
-
- pnt = s_entry->rr_attributes;
- len = s_entry->total_rr_attr_size;
- while(len > 3)
- {
-#ifdef DEBUG
- if (!ce_size)
- {
- fprintf(stderr,"Warning: ce_index(%d) && ce_address(%d) not initialized\n",
- ce_index, ce_address);
- }
-#endif
-
- if(pnt[0] == 'C' && pnt[1] == 'E')
- {
- nbytes = get_733( (char *) pnt+20);
-
- if((ce_index & (SECTOR_SIZE - 1)) + nbytes >=
- SECTOR_SIZE)
- {
- ce_index = ROUND_UP(ce_index);
- }
-
- set_733( (char *) pnt+4,
- (ce_address + ce_index) >> 11);
- set_733( (char *) pnt+12,
- (ce_address + ce_index) & (SECTOR_SIZE - 1));
-
-
- /*
- * Now store the block in the ce buffer
- */
- memcpy(ce_buffer + ce_index,
- pnt + pnt[2], nbytes);
- ce_index += nbytes;
- if(ce_index & 1)
- {
- ce_index++;
- }
- }
- len -= pnt[2];
- pnt += pnt[2];
- }
-
- }
-
- rockridge_size += s_entry->total_rr_attr_size;
- memcpy(directory_buffer + dir_index, s_entry->rr_attributes,
- s_entry->rr_attr_size);
- dir_index += s_entry->rr_attr_size;
- }
- if(dir_index & 1)
- {
- directory_buffer[dir_index++] = 0;
- }
-
- s_entry_d = s_entry;
- s_entry = s_entry->next;
-
- /*
- * Joliet doesn't use the Rock Ridge attributes, so we free it here.
- */
- if (s_entry_d->rr_attributes)
- {
- free(s_entry_d->rr_attributes);
- s_entry_d->rr_attributes = NULL;
- }
- }
-
- if(dpnt->size != dir_index)
- {
- fprintf (stderr, _("Unexpected directory length %d %d %s\n"), dpnt->size,
- dir_index, dpnt->de_name);
- }
-
- xfwrite(directory_buffer, 1, total_size, outfile);
- last_extent_written += total_size >> 11;
- free(directory_buffer);
-
- if(ce_size)
- {
- if(ce_index != dpnt->ce_bytes)
- {
- fprintf (stderr, _("Continuation entry record length mismatch (%d %d).\n"),
- ce_index, dpnt->ce_bytes);
- }
- xfwrite(ce_buffer, 1, ce_size, outfile);
- last_extent_written += ce_size >> 11;
- free(ce_buffer);
- }
-
-} /* generate_one_directory(... */
-
-static
-void FDECL1(build_pathlist, struct directory *, node)
-{
- struct directory * dpnt;
-
- dpnt = node;
-
- while (dpnt)
- {
- /* skip if it's hidden */
- if( (dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) == 0 )
- pathlist[dpnt->path_index] = dpnt;
-
- if(dpnt->subdir) build_pathlist(dpnt->subdir);
- dpnt = dpnt->next;
- }
-} /* build_pathlist(... */
-
-static int FDECL2(compare_paths, void const *, r, void const *, l)
-{
- struct directory const *ll = *(struct directory * const *)l;
- struct directory const *rr = *(struct directory * const *)r;
-
- if (rr->parent->path_index < ll->parent->path_index)
- {
- return -1;
- }
-
- if (rr->parent->path_index > ll->parent->path_index)
- {
- return 1;
- }
-
- return strcmp(rr->self->isorec.name, ll->self->isorec.name);
-
-} /* compare_paths(... */
-
-static int generate_path_tables()
-{
- struct directory_entry * de;
- struct directory * dpnt;
- int fix;
- int i;
- int j;
- int namelen;
- char * npnt;
- char * npnt1;
- int tablesize;
-
- /*
- * First allocate memory for the tables and initialize the memory
- */
- tablesize = path_blocks << 11;
- path_table_m = (char *) e_malloc(tablesize);
- path_table_l = (char *) e_malloc(tablesize);
- memset(path_table_l, 0, tablesize);
- memset(path_table_m, 0, tablesize);
-
- /*
- * Now start filling in the path tables. Start with root directory
- */
- if( next_path_index > 0xffff )
- {
- error (1, 0, _("Unable to generate sane path tables - too many directories (%d)\n"),
- next_path_index);
- }
-
- path_table_index = 0;
- pathlist = (struct directory **) e_malloc(sizeof(struct directory *)
- * next_path_index);
- memset(pathlist, 0, sizeof(struct directory *) * next_path_index);
- build_pathlist(root);
-
- do
- {
- fix = 0;
-#ifdef __STDC__
- qsort(&pathlist[1], next_path_index-1, sizeof(struct directory *),
- (int (*)(const void *, const void *))compare_paths);
-#else
- qsort(&pathlist[1], next_path_index-1, sizeof(struct directory *),
- compare_paths);
-#endif
-
- for(j=1; j<next_path_index; j++)
- {
- if(pathlist[j]->path_index != j)
- {
- pathlist[j]->path_index = j;
- fix++;
- }
- }
- } while(fix);
-
- for(j=1; j<next_path_index; j++)
- {
- dpnt = pathlist[j];
- if(!dpnt)
- {
- error (1, 0, _("Entry %d not in path tables\n"), j);
- }
- npnt = dpnt->de_name;
-
- /*
- * So the root comes out OK
- */
- if( (*npnt == 0) || (dpnt == root) )
- {
- npnt = ".";
- }
- npnt1 = strrchr(npnt, PATH_SEPARATOR);
- if(npnt1)
- {
- npnt = npnt1 + 1;
- }
-
- de = dpnt->self;
- if(!de)
- {
- error (1, 0, _("Fatal goof\n"));
- }
-
-
- namelen = de->isorec.name_len[0];
-
- path_table_l[path_table_index] = namelen;
- path_table_m[path_table_index] = namelen;
- path_table_index += 2;
-
- set_731(path_table_l + path_table_index, dpnt->extent);
- set_732(path_table_m + path_table_index, dpnt->extent);
- path_table_index += 4;
-
- set_721(path_table_l + path_table_index,
- dpnt->parent->path_index);
- set_722(path_table_m + path_table_index,
- dpnt->parent->path_index);
- path_table_index += 2;
-
- for(i =0; i<namelen; i++)
- {
- path_table_l[path_table_index] = de->isorec.name[i];
- path_table_m[path_table_index] = de->isorec.name[i];
- path_table_index++;
- }
- if(path_table_index & 1)
- {
- path_table_index++; /* For odd lengths we pad */
- }
- }
-
- free(pathlist);
- if(path_table_index != path_table_size)
- {
- fprintf (stderr, _("Path table lengths do not match %d %d\n"),
- path_table_index,
- path_table_size);
- }
- return 0;
-} /* generate_path_tables(... */
-
-void
-FDECL3(memcpy_max, char *, to, char *, from, int, max)
-{
- int n = strlen(from);
- if (n > max)
- {
- n = max;
- }
- memcpy(to, from, n);
-
-} /* memcpy_max(... */
-
-void FDECL1(outputlist_insert, struct output_fragment *, frag)
-{
- if( out_tail == NULL )
- {
- out_list = out_tail = frag;
- }
- else
- {
- out_tail->of_next = frag;
- out_tail = frag;
- }
-}
-
-static int FDECL1(file_write, FILE *, outfile)
-{
- int should_write;
-
- /*
- * OK, all done with that crap. Now write out the directories.
- * This is where the fur starts to fly, because we need to keep track of
- * each file as we find it and keep track of where we put it.
- */
-
- should_write = last_extent - session_start;
-
- if( print_size > 0 )
- {
- fprintf (stderr, _("Total extents scheduled to be written = %llu\n"),
- last_extent - session_start);
- exit (0);
- }
- if( verbose > 2 )
- {
-#ifdef DBG_ISO
- fprintf(stderr,"Total directory extents being written = %llu\n", last_extent);
-#endif
-
- fprintf (stderr, _("Total extents scheduled to be written = %llu\n"),
- last_extent - session_start);
- }
-
- /*
- * Now write all of the files that we need.
- */
- write_files(outfile);
-
- /*
- * The rest is just fluff.
- */
- if( verbose == 0 )
- {
- return 0;
- }
-
- fprintf (stderr, _("Total extents actually written = %llu\n"),
- last_extent_written - session_start);
-
- /*
- * Hard links throw us off here
- */
- assert (last_extent > session_start);
- if(should_write + session_start != last_extent)
- {
- fprintf (stderr, _("Number of extents written different than what was predicted. Please fix.\n"));
- fprintf (stderr, _("Predicted = %d, written = %llu\n"), should_write, last_extent);
- }
-
- fprintf (stderr, _("Total translation table size: %d\n"), table_size);
- fprintf (stderr, _("Total rockridge attributes bytes: %d\n"), rockridge_size);
- fprintf (stderr, _("Total directory bytes: %d\n"), total_dir_size);
- fprintf (stderr, _("Path table size(bytes): %d\n"), path_table_size);
-
-#ifdef DEBUG
- fprintf(stderr, "next extent, last_extent, last_extent_written %d %d %d\n",
- next_extent, last_extent, last_extent_written);
-#endif
-
- return 0;
-
-} /* iso_write(... */
-
-char *creation_date = NULL;
-char *modification_date = NULL;
-char *expiration_date = NULL;
-char *effective_date = NULL;
-
-/*
- * Function to write the PVD for the disc.
- */
-static int FDECL1(pvd_write, FILE *, outfile)
-{
- char iso_time[17];
- int should_write;
- struct tm local;
- struct tm gmt;
-
-
- time(&begun);
-
- local = *localtime(&begun);
- gmt = *gmtime(&begun);
-
- /*
- * This will break in the year 2000, I supose, but there is no good way
- * to get the top two digits of the year.
- */
- sprintf(iso_time, "%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d00", 1900 + local.tm_year,
- local.tm_mon+1, local.tm_mday,
- local.tm_hour, local.tm_min, local.tm_sec);
-
- local.tm_min -= gmt.tm_min;
- local.tm_hour -= gmt.tm_hour;
- local.tm_yday -= gmt.tm_yday;
- iso_time[16] = (local.tm_min + 60*(local.tm_hour + 24*local.tm_yday)) / 15;
-
- /*
- * Next we write out the primary descriptor for the disc
- */
- memset(&vol_desc, 0, sizeof(vol_desc));
- vol_desc.type[0] = ISO_VD_PRIMARY;
- memcpy(vol_desc.id, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID));
- vol_desc.version[0] = 1;
-
- memset(vol_desc.system_id, ' ', sizeof(vol_desc.system_id));
- memcpy_max(vol_desc.system_id, system_id, strlen(system_id));
-
- memset(vol_desc.volume_id, ' ', sizeof(vol_desc.volume_id));
- memcpy_max(vol_desc.volume_id, volume_id, strlen(volume_id));
-
- should_write = last_extent - session_start;
- set_733((char *) vol_desc.volume_space_size, should_write);
- set_723(vol_desc.volume_set_size, volume_set_size);
- set_723(vol_desc.volume_sequence_number, volume_sequence_number);
- set_723(vol_desc.logical_block_size, 2048);
-
- /*
- * The path tables are used by DOS based machines to cache directory
- * locations
- */
-
- set_733((char *) vol_desc.path_table_size, path_table_size);
- set_731(vol_desc.type_l_path_table, path_table[0]);
- set_731(vol_desc.opt_type_l_path_table, path_table[1]);
- set_732(vol_desc.type_m_path_table, path_table[2]);
- set_732(vol_desc.opt_type_m_path_table, path_table[3]);
-
- /*
- * Now we copy the actual root directory record
- */
- memcpy(vol_desc.root_directory_record, &root_record,
- sizeof(struct iso_directory_record) + 1);
-
- /*
- * The rest is just fluff. It looks nice to fill in many of these fields,
- * though.
- */
- FILL_SPACE(volume_set_id);
- if(volset_id) memcpy_max(vol_desc.volume_set_id, volset_id, strlen(volset_id));
-
- FILL_SPACE(publisher_id);
- if(publisher) memcpy_max(vol_desc.publisher_id, publisher, strlen(publisher));
-
- FILL_SPACE(preparer_id);
- if(preparer) memcpy_max(vol_desc.preparer_id, preparer, strlen(preparer));
-
- FILL_SPACE(application_id);
- if(appid) memcpy_max(vol_desc.application_id, appid, strlen(appid));
-
- FILL_SPACE(copyright_file_id);
- if(copyright) memcpy_max(vol_desc.copyright_file_id, copyright,
- strlen(copyright));
-
- FILL_SPACE(abstract_file_id);
- if(abstract) memcpy_max(vol_desc.abstract_file_id, abstract,
- strlen(abstract));
-
- FILL_SPACE(bibliographic_file_id);
- if(biblio) memcpy_max(vol_desc.bibliographic_file_id, biblio,
- strlen(biblio));
-
- FILL_SPACE(creation_date);
- FILL_SPACE(modification_date);
- FILL_SPACE(expiration_date);
- FILL_SPACE(effective_date);
- vol_desc.file_structure_version[0] = 1;
- FILL_SPACE(application_data);
-
- memcpy(vol_desc.creation_date, creation_date ? creation_date : iso_time, 17);
- memcpy(vol_desc.modification_date, modification_date ? modification_date : iso_time, 17);
- memcpy(vol_desc.expiration_date, expiration_date ? expiration_date : "0000000000000000", 17);
- memcpy(vol_desc.effective_date, effective_date ? effective_date : iso_time, 17);
-
- /*
- * if not a bootable cd do it the old way
- */
- xfwrite(&vol_desc, 1, 2048, outfile);
- last_extent_written++;
- return 0;
-}
-
-/*
- * Function to write the EVD for the disc.
- */
-static int FDECL1(evd_write, FILE *, outfile)
-{
- struct iso_primary_descriptor evol_desc;
-
- /*
- * Now write the end volume descriptor. Much simpler than the other one
- */
- memset(&evol_desc, 0, sizeof(evol_desc));
- evol_desc.type[0] = ISO_VD_END;
- memcpy(evol_desc.id, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID));
- evol_desc.version[0] = 1;
- xfwrite(&evol_desc, 1, 2048, outfile);
- last_extent_written += 1;
- return 0;
-}
-
-/*
- * Function to write the EVD for the disc.
- */
-static int FDECL1(pathtab_write, FILE *, outfile)
-{
- /*
- * Next we write the path tables
- */
- xfwrite(path_table_l, 1, path_blocks << 11, outfile);
- xfwrite(path_table_m, 1, path_blocks << 11, outfile);
- last_extent_written += 2*path_blocks;
- free(path_table_l);
- free(path_table_m);
- path_table_l = NULL;
- path_table_m = NULL;
- return 0;
-}
-
-static int FDECL1(exten_write, FILE *, outfile)
-{
- xfwrite(extension_record, 1, SECTOR_SIZE, outfile);
- last_extent_written++;
- return 0;
-}
-
-/*
- * Functions to describe padding block at the start of the disc.
- */
-int FDECL1(oneblock_size, int, starting_extent)
-{
- last_extent++;
- return 0;
-}
-
-/*
- * Functions to describe padding block at the start of the disc.
- */
-
-#define PADBLOCK_SIZE 16
-
-static int FDECL1(pathtab_size, int, starting_extent)
-{
- path_table[0] = starting_extent;
-
- path_table[1] = 0;
- path_table[2] = path_table[0] + path_blocks;
- path_table[3] = 0;
- last_extent += 2*path_blocks;
- return 0;
-}
-
-static int FDECL1(padblock_size, int, starting_extent)
-{
- last_extent += PADBLOCK_SIZE;
- return 0;
-}
-
-static int file_gen()
-{
- assign_file_addresses(root);
- return 0;
-}
-
-static int dirtree_dump()
-{
- if (verbose > 2)
- {
- dump_tree(root);
- }
- return 0;
-}
-
-static int FDECL1(dirtree_fixup, int, starting_extent)
-{
- if (use_RockRidge && reloc_dir)
- finish_cl_pl_entries();
-
- if (use_RockRidge )
- update_nlink_field(root);
- return 0;
-}
-
-static int FDECL1(dirtree_size, int, starting_extent)
-{
- assign_directory_addresses(root);
- return 0;
-}
-
-static int FDECL1(ext_size, int, starting_extent)
-{
- extern int extension_record_size;
- struct directory_entry * s_entry;
- extension_record_extent = starting_extent;
- s_entry = root->contents;
- set_733((char *) s_entry->rr_attributes + s_entry->rr_attr_size - 24,
- extension_record_extent);
- set_733((char *) s_entry->rr_attributes + s_entry->rr_attr_size - 8,
- extension_record_size);
- last_extent++;
- return 0;
-}
-
-static int FDECL1(dirtree_write, FILE *, outfile)
-{
- generate_iso9660_directories(root, outfile);
- return 0;
-}
-
-static int FDECL1(dirtree_cleanup, FILE *, outfile)
-{
- free_directories(root);
- return 0;
-}
-
-static int FDECL1(padblock_write, FILE *, outfile)
-{
- char *buffer;
-
- buffer = e_malloc (2048 * PADBLOCK_SIZE);
- memset (buffer, 0, 2048 * PADBLOCK_SIZE);
-
- if (use_embedded_boot)
- {
- FILE *fp = fopen (boot_image_embed, "rb");
- if (! fp)
- error (1, errno, _("Unable to open %s"), boot_image_embed);
-
- if (fread (buffer, 1, 2048 * PADBLOCK_SIZE, fp) == 0)
- error (1, errno, _("cannot read %d bytes from %s"),
- 2048 * PADBLOCK_SIZE, boot_image_embed);
- if (fgetc (fp) != EOF)
- error (1, 0, _("%s is too big for embed area"), boot_image_embed);
- }
-
- if (use_protective_msdos_label)
- {
- struct msdos_partition_mbr *mbr = (void *) buffer;
-
- memset (mbr->entries, 0, sizeof(mbr->entries));
-
- /* Some idiotic BIOSes refuse to boot if they don't find at least
- one partition with active bit set. */
- mbr->entries[0].flag = 0x80;
-
- /* Doesn't really matter, as long as it's non-zero. It seems that
- 0xCD is used elsewhere, so we follow suit. */
- mbr->entries[0].type = 0xcd;
-
- /* Start immediately (sector 1). */
- mbr->entries[0].start = 1;
-
- /* We don't know yet. Let's keep it safe. */
- mbr->entries[0].length = UINT32_MAX;
-
- mbr->signature = MSDOS_PARTITION_SIGNATURE;
- }
-
- xfwrite (buffer, 1, 2048 * PADBLOCK_SIZE, outfile);
- last_extent_written += PADBLOCK_SIZE;
-
- return 0;
-}
-
-struct output_fragment padblock_desc = {NULL, padblock_size, NULL, padblock_write};
-struct output_fragment voldesc_desc = {NULL, oneblock_size, root_gen, pvd_write};
-struct output_fragment end_vol = {NULL, oneblock_size, NULL, evd_write};
-struct output_fragment pathtable_desc = {NULL, pathtab_size, generate_path_tables, pathtab_write};
-struct output_fragment dirtree_desc = {NULL, dirtree_size, NULL, dirtree_write};
-struct output_fragment dirtree_clean = {NULL, dirtree_fixup, dirtree_dump, dirtree_cleanup};
-struct output_fragment extension_desc = {NULL, ext_size, NULL, exten_write};
-struct output_fragment files_desc = {NULL, NULL, file_gen, file_write};