From 1d3293d67dabf99bed6dc4e8d22389614821d64c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 17 May 2010 23:33:03 +0200 Subject: [PATCH] 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. --- ChangeLog | 29 + conf/common.rmk | 14 - util/mkisofs/defaults.h | 20 - util/mkisofs/eltorito.c | 343 ------ util/mkisofs/exclude.h | 10 - util/mkisofs/hash.c | 225 ---- util/mkisofs/include/fctldefs.h | 57 - util/mkisofs/include/mconfig.h | 253 ----- util/mkisofs/include/prototyp.h | 74 -- util/mkisofs/include/statdefs.h | 139 --- util/mkisofs/iso9660.h | 174 --- util/mkisofs/joliet.c | 1023 ----------------- util/mkisofs/match.c | 76 -- util/mkisofs/match.h | 29 - util/mkisofs/mkisofs.c | 1422 ----------------------- util/mkisofs/mkisofs.h | 530 --------- util/mkisofs/msdos_partition.h | 75 -- util/mkisofs/multi.c | 1201 -------------------- util/mkisofs/name.c | 394 ------- util/mkisofs/rock.c | 597 ---------- util/mkisofs/tree.c | 1865 ------------------------------- util/mkisofs/write.c | 1483 ------------------------ 22 files changed, 29 insertions(+), 10004 deletions(-) delete mode 100644 util/mkisofs/defaults.h delete mode 100644 util/mkisofs/eltorito.c delete mode 100644 util/mkisofs/exclude.h delete mode 100644 util/mkisofs/hash.c delete mode 100644 util/mkisofs/include/fctldefs.h delete mode 100644 util/mkisofs/include/mconfig.h delete mode 100644 util/mkisofs/include/prototyp.h delete mode 100644 util/mkisofs/include/statdefs.h delete mode 100644 util/mkisofs/iso9660.h delete mode 100644 util/mkisofs/joliet.c delete mode 100644 util/mkisofs/match.c delete mode 100644 util/mkisofs/match.h delete mode 100644 util/mkisofs/mkisofs.c delete mode 100644 util/mkisofs/mkisofs.h delete mode 100644 util/mkisofs/msdos_partition.h delete mode 100644 util/mkisofs/multi.c delete mode 100644 util/mkisofs/name.c delete mode 100644 util/mkisofs/rock.c delete mode 100644 util/mkisofs/tree.c delete mode 100644 util/mkisofs/write.c diff --git a/ChangeLog b/ChangeLog index 5f3410ea1..8258400c0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2010-05-17 Vladimir Serbinenko + + 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 Unify grub-mkimage accross platforms. diff --git a/conf/common.rmk b/conf/common.rmk index 00efa78fb..4186c61b2 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -43,20 +43,6 @@ ifeq ($(enable_grub_fstest), yes) 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 \ diff --git a/util/mkisofs/defaults.h b/util/mkisofs/defaults.h deleted file mode 100644 index 2ce9e8d6b..000000000 --- a/util/mkisofs/defaults.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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" diff --git a/util/mkisofs/eltorito.c b/util/mkisofs/eltorito.c deleted file mode 100644 index 1d2a715e0..000000000 --- a/util/mkisofs/eltorito.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Program eltorito.c - Handle El Torito specific extensions to iso9660. - * - - Written by Michael Fulbright (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 . - */ - - -#include -#include -#include -#include -#include -#include -#include - -#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; isize + 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}; diff --git a/util/mkisofs/exclude.h b/util/mkisofs/exclude.h deleted file mode 100644 index ac1a561ad..000000000 --- a/util/mkisofs/exclude.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * 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)); diff --git a/util/mkisofs/hash.c b/util/mkisofs/hash.c deleted file mode 100644 index 41e76b342..000000000 --- a/util/mkisofs/hash.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * 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 -#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; inext; - free(nh); - nh = nh1; - } - name_hash_table[i] = NULL; - - } -} diff --git a/util/mkisofs/include/fctldefs.h b/util/mkisofs/include/fctldefs.h deleted file mode 100644 index de6b6a394..000000000 --- a/util/mkisofs/include/fctldefs.h +++ /dev/null @@ -1,57 +0,0 @@ -/* @(#)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 -#endif - -#include -#include - -#ifdef HAVE_FCNTL_H - -# include - -#else /* HAVE_FCNTL_H */ - -# include - -#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 */ diff --git a/util/mkisofs/include/mconfig.h b/util/mkisofs/include/mconfig.h deleted file mode 100644 index 1891d7ded..000000000 --- a/util/mkisofs/include/mconfig.h +++ /dev/null @@ -1,253 +0,0 @@ -/* @(#)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 - -#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 - -/* - * 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 */ diff --git a/util/mkisofs/include/prototyp.h b/util/mkisofs/include/prototyp.h deleted file mode 100644 index c74ae0af8..000000000 --- a/util/mkisofs/include/prototyp.h +++ /dev/null @@ -1,74 +0,0 @@ -/* @(#)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 */ diff --git a/util/mkisofs/include/statdefs.h b/util/mkisofs/include/statdefs.h deleted file mode 100644 index 0e34805ce..000000000 --- a/util/mkisofs/include/statdefs.h +++ /dev/null @@ -1,139 +0,0 @@ -/* @(#)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 -#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 */ - diff --git a/util/mkisofs/iso9660.h b/util/mkisofs/iso9660.h deleted file mode 100644 index 78a05db92..000000000 --- a/util/mkisofs/iso9660.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * 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 . - */ - -/* - * $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 - - - diff --git a/util/mkisofs/joliet.c b/util/mkisofs/joliet.c deleted file mode 100644 index b3c755792..000000000 --- a/util/mkisofs/joliet.c +++ /dev/null @@ -1,1023 +0,0 @@ -/* - * 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 . - */ - -/* - * 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 -#include -#include - -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; jjpath_index != j) - { - jpathlist[j]->jpath_index = j; - fix++; - } - } - } while(fix); - - for(j=1; jde_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; ijnext = 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}; diff --git a/util/mkisofs/match.c b/util/mkisofs/match.c deleted file mode 100644 index 0072b504e..000000000 --- a/util/mkisofs/match.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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 . - */ - -#include "config.h" - -#include -#include -#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); -} diff --git a/util/mkisofs/match.h b/util/mkisofs/match.h deleted file mode 100644 index ee346a24c..000000000 --- a/util/mkisofs/match.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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 . - */ - -#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 (); diff --git a/util/mkisofs/mkisofs.c b/util/mkisofs/mkisofs.c deleted file mode 100644 index 16e2f0c7d..000000000 --- a/util/mkisofs/mkisofs.c +++ /dev/null @@ -1,1422 +0,0 @@ -/* - * 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 . - */ - -#include -#include "config.h" -#include "mkisofs.h" -#include "match.h" -#include "getopt.h" - -#include "iso9660.h" -#include - -#ifndef VMS -#include -#else -#include -#include "vms.h" -#endif - -#include -#include - -#ifndef VMS -#ifdef HAVE_UNISTD_H -#include -#endif -#endif -#include - -#include "exclude.h" - -#ifdef __NetBSD__ -#include -#include -#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;iextent, 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; -} diff --git a/util/mkisofs/mkisofs.h b/util/mkisofs/mkisofs.h deleted file mode 100644 index b699516e9..000000000 --- a/util/mkisofs/mkisofs.h +++ /dev/null @@ -1,530 +0,0 @@ -/* - * 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 . - */ - -/* - * $Id: mkisofs.h,v 1.20 1999/03/02 04:16:41 eric Exp $ - */ - -#include -#include -#include -#include - -#if (defined(ENABLE_NLS) && ENABLE_NLS) - -# include -# include - -#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 -#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 -#include -#include - -#if defined(HAVE_DIRENT_H) -# include -# define NAMLEN(dirent) strlen((dirent)->d_name) -#else -# define dirent direct -# define NAMLEN(dirent) (dirent)->d_namlen -# if defined(HAVE_SYS_NDIR_H) -# include -# endif -# if defined(HAVE_SYS_DIR_H) -# include -# endif -# if defined(HAVE_NDIR_H) -# include -# endif -#endif - -#if defined(HAVE_STRING_H) -#include -#else -#if defined(HAVE_STRINGS_H) -#include -#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 -#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 diff --git a/util/mkisofs/msdos_partition.h b/util/mkisofs/msdos_partition.h deleted file mode 100644 index 13985f7bb..000000000 --- a/util/mkisofs/msdos_partition.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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 . - */ - -#ifndef MSDOS_PARTITION_H -#define MSDOS_PARTITION_H 1 - -#include - -/* 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 diff --git a/util/mkisofs/multi.c b/util/mkisofs/multi.c deleted file mode 100644 index d92f14530..000000000 --- a/util/mkisofs/multi.c +++ /dev/null @@ -1,1201 +0,0 @@ -/* - * 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 . - */ - -#include -#include -#include -#include -#include -#include - -#include "config.h" - -#ifndef VMS - -#ifdef HAVE_UNISTD_H -#include -#endif - -#else -#include -#include -#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(""); - 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; iname != 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, "") == 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, "") == 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, "") == 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; -} - diff --git a/util/mkisofs/name.c b/util/mkisofs/name.c deleted file mode 100644 index 272471e93..000000000 --- a/util/mkisofs/name.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * 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 - -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); -} diff --git a/util/mkisofs/rock.c b/util/mkisofs/rock.c deleted file mode 100644 index a7a39f774..000000000 --- a/util/mkisofs/rock.c +++ /dev/null @@ -1,597 +0,0 @@ -/* - * 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 . - */ - -#include - -#include "config.h" - -#ifndef VMS -#if defined(MAJOR_IN_SYSMACROS) -#include -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#endif -#if defined(MAJOR_IN_MKDEV) -#include -#include -#endif - -#include "mkisofs.h" -#include "iso9660.h" -#include -#include - -#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 -#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; -} diff --git a/util/mkisofs/tree.c b/util/mkisofs/tree.c deleted file mode 100644 index 0d9cf6143..000000000 --- a/util/mkisofs/tree.c +++ /dev/null @@ -1,1865 +0,0 @@ -/* - * 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 . - */ - -/* ADD_FILES changes made by Ross Biro biro@yggdrasil.com 2/23/95 */ - -#include -#include -#include -#include - -#include "config.h" - -#ifndef VMS -#if defined(MAJOR_IN_SYSMACROS) -#include -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif -#include - -#if defined(MAJOR_IN_MKDEV) -#include -#include -#endif -#else -#include -#include -#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 - -#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 -#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(""); - 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; - } -} diff --git a/util/mkisofs/write.c b/util/mkisofs/write.c deleted file mode 100644 index e1cdd213e..000000000 --- a/util/mkisofs/write.c +++ /dev/null @@ -1,1483 +0,0 @@ -/* - * 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 . - */ - -#include "config.h" - -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifdef HAVE_UNISTD_H -#include -#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; inext = 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; jpath_index != j) - { - pathlist[j]->path_index = j; - fix++; - } - } - } while(fix); - - for(j=1; jde_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; iisorec.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};