1 --- cdrtools-2.00.3/mkisofs/Makefile 2002-12-07 21:42:32.000000000 +0100
2 +++ cdrtools-2.00.3/mkisofs/Makefile 2002-12-27 20:24:53.000000000 +0100
9 apple.c volume.c desktop.c mac_label.c \
10 ifo_read.c dvd_file.c dvd_reader.c
11 HFILES= apple.h bootinfo.h config.h defaults.h diskmbr.h exclude.h \
12 --- cdrtools-2.00.3/mkisofs/mkisofs.8 2002-12-24 16:39:31.000000000 +0100
13 +++ cdrtools-2.00.3/mkisofs/mkisofs.8 2002-12-27 20:24:53.000000000 +0100
16 Specifying this option automatically enables Rock Ridge extensions.
18 +.BI \-F " root_directory
19 +Follow symbolic links which point outside specified
21 +when generating the filesystem. This allows a symlink farm structure,
22 +where symlinks inside the base directory stay symlinks, but symlinks
23 +outside the base directory become real files on the CD.
26 Switch the behaviour for a GUI. This currently makes the output more verbose
27 but may have other effects in future.
30 If specified in both places, the command line version is used.
32 +.BI \-s " silo_conf_file
33 +Specifies the path and filename of the SILO configuration file to be
34 +used when making a "SILO" bootable CD. The pathname must be relative to the
35 +source path specified to
37 +and start with a slash.
40 +See SILO documentation for the syntax of this file.
42 +.BI \-S " silo_bootblock
43 +Specifies the path and filename of the SILO first stage boot image to be
44 +used when making a "SILO" bootable CD. The pathname must be relative to the
45 +source path specified to
49 +The boot image must come from SILO 0.8.7 and higher.
52 Generate a file TRANS.TBL in each directory on the CDROM, which can be used
53 on non-Rock Ridge capable systems to help establish the correct file names.
54 --- cdrtools-2.00.3/mkisofs/mkisofs.c 2002-12-07 20:59:41.000000000 +0100
55 +++ cdrtools-2.00.3/mkisofs/mkisofs.c 2002-12-27 20:24:53.000000000 +0100
58 int use_RockRidge = 0;
61 int jlen = JMAX; /* maximum Joliet file name length */
65 int all_files = 1; /* New default is to include all files */
67 +int follow_links_sensible = 0;
69 int cache_inodes = 0;/* Do not cache inodes on Cygwin by default */
72 char *boot_catalog = BOOT_CATALOG_DEFAULT;
73 char *boot_image = BOOT_IMAGE_DEFAULT;
74 char *genboot_image = BOOT_IMAGE_DEFAULT;
75 +char *silo_boot_image = SILO_BOOT_IMAGE_DEFAULT;
76 +char *silo_bootblock = SILO_BOOTBLOCK_DEFAULT;
77 +char *silo_conf_file = SILO_CONF_FILE_DEFAULT;
78 +char follow_links_base[PATH_MAX];
79 int ucs_level = 3; /* We now have Unicode tables so use level 3 */
80 int volume_set_size = 1;
81 int volume_sequence_number = 1;
84 #endif /* APPLE_HYB */
86 +#define OPTION_SILO_BOOT 2200
88 static int save_pname = 0;
90 static const struct ld_option ld_options[] =
92 '\0', NULL, "Start specifying alternative El Torito boot parameters", ONE_DASH},
93 {{"sparc-boot", required_argument, NULL, 'B'},
94 'B', "FILES", "Set sparc boot image names", ONE_DASH},
95 + {{"silo-boot", required_argument, NULL, OPTION_SILO_BOOT},
96 + '\0', "FILE", "Set SILO second stage boot image name" , ONE_DASH },
97 {{"generic-boot", required_argument, NULL, 'G'},
98 'G', "FILE", "Set generic boot image name", ONE_DASH},
99 {{"sparc-label", required_argument, NULL, OPTION_SPARCLABEL},
101 '\0', "mode", "Make the mode of all plain files this mode.", ONE_DASH},
102 {{"follow-links", no_argument, NULL, 'f'},
103 'f', NULL, "Follow symbolic links", ONE_DASH},
104 + {{"follow-outside-links", required_argument, NULL, 'F'},
105 + 'F', NULL, "Follow symbolic links which point outside the CD base directory", ONE_DASH },
106 {{"gid", required_argument, NULL, OPTION_GID},
107 '\0', "gid", "Make the group owner of all files this gid.",
110 '\0', "FILE", "Sort file content locations according to rules in FILE" , ONE_DASH },
113 + { {"silo-conf-file", required_argument, NULL, 's'},
114 + 's', "FILE", "Set name of SILO configuration file on the CD", ONE_DASH },
115 + { {"silo-bootblock", required_argument, NULL, 'S'},
116 + 'S', "FILE", "Set SILO first stage bootblock image name", ONE_DASH },
118 {{"split-output", no_argument, NULL, OPTION_SPLIT_OUTPUT},
119 '\0', NULL, "Split output into files of approx. 1GB size", ONE_DASH},
120 {{"sysid", required_argument, NULL, OPTION_SYSID},
121 @@ -1150,7 +1167,7 @@
124 #endif /* APPLE_HYB */
126 + char old_dir[PATH_MAX];
129 /* This gives wildcard expansion with Non-Posix shells with EMX */
130 @@ -1352,6 +1369,34 @@
134 + case OPTION_SILO_BOOT:
136 + silo_boot_image = optarg; /* pathname of the boot image on cd */
137 + if (silo_boot_image == NULL) {
138 + fprintf(stderr,"Required boot image pathname missing\n");
144 + silo_bootblock = optarg; /* pathname of the boot image on cd */
145 + if (silo_bootblock == NULL) {
146 + fprintf(stderr,"Required bootblock pathname missing\n");
152 + silo_conf_file = optarg; /* pathname of the boot image on cd */
153 + if (silo_conf_file == NULL) {
154 + fprintf(stderr,"Required SILO config file pathname missing\n");
157 + if (*silo_conf_file != '/') {
158 + fprintf(stderr,"SILO config file pathname must start with /\n");
162 case OPTION_ABSTRACT:
164 if (strlen(abstract) > 37) {
165 @@ -1446,6 +1491,20 @@
166 "Warning: -follow-links does not always work correctly; be careful.\n");
170 + follow_links_sensible++;
171 + if(getcwd (old_dir, PATH_MAX)) {
173 + if(!getcwd (follow_links_base, PATH_MAX)) {
184 full_iso9660_filenames++;
186 @@ -2967,7 +3026,10 @@
187 outputlist_insert(&sunlabel_desc);
189 outputlist_insert(&genboot_desc);
190 - outputlist_insert(&padblock_desc);
192 + outputlist_insert(&silo_desc);
194 + outputlist_insert(&padblock_desc);
197 outputlist_insert(&voldesc_desc);
198 --- cdrtools-2.00.3/mkisofs/mkisofs.h 2002-12-07 20:59:42.000000000 +0100
199 +++ cdrtools-2.00.3/mkisofs/mkisofs.h 2002-12-27 20:24:53.000000000 +0100
201 extern struct output_fragment *out_tail;
203 extern struct output_fragment padblock_desc;
204 +extern struct output_fragment silo_desc;
205 extern struct output_fragment voldesc_desc;
206 extern struct output_fragment joliet_desc;
207 extern struct output_fragment torito_desc;
209 struct directory_entry *s_entry;
213 + int (*filter)(char *, int, int);
219 +extern struct deferred_write * dw_head, * dw_tail;
221 struct eltorito_boot_entry_info {
222 struct eltorito_boot_entry_info *next;
225 extern int dirmode_to_use;
226 extern int new_dir_mode;
227 extern int follow_links;
228 +extern int follow_links_sensible;
229 +extern char follow_links_base[];
230 extern int cache_inodes;
234 extern char *boot_catalog;
235 extern char *boot_image;
236 extern char *genboot_image;
237 +extern char *silo_boot_image;
238 +extern char *silo_bootblock;
239 +extern char *silo_conf_file;
240 extern int ucs_level;
241 extern int volume_set_size;
242 extern int volume_sequence_number;
243 --- cdrtools-2.00.3/mkisofs/silo.c 1970-01-01 01:00:00.000000000 +0100
244 +++ cdrtools-2.00.3/mkisofs/silo.c 2002-12-27 20:24:53.000000000 +0100
247 + * Program silo.c - Handle SILO bootable iso9660 CD-ROMs.
250 + Copyright (C) 1999 Jakub Jelinek <jakub@redhat.com>.
252 + This program is free software; you can redistribute it and/or modify
253 + it under the terms of the GNU General Public License as published by
254 + the Free Software Foundation; either version 2, or (at your option)
257 + This program is distributed in the hope that it will be useful,
258 + but WITHOUT ANY WARRANTY; without even the implied warranty of
259 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
260 + GNU General Public License for more details.
262 + You should have received a copy of the GNU General Public License
263 + along with this program; if not, write to the Free Software
264 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
267 +static char rcsid[] ="$Id$";
269 +#include <mconfig.h>
271 +#include <sys/types.h>
272 +#include <sys/stat.h>
277 +#include "mkisofs.h"
278 +#include "iso9660.h"
281 +/* used by Win32 for opening binary file - not used by Unix */
284 +#endif /* O_BINARY */
286 +struct sun_disklabel {
287 + char info[128]; /* Informative text string */
295 + char spare1[246]; /* Boot information etc. */
296 + char rspeed[2]; /* 722 - Disk rotational speed */
297 + char pcylcount[2]; /* 722 - Physical cylinder count */
298 + char sparecyl[2]; /* 722 - extra sects per cylinder */
299 + char spare2[4]; /* More magic... */
300 + char ilfact[2]; /* 722 - Interleave factor */
301 + char ncyl[2]; /* 722 - Data cylinder count */
302 + char nacyl[2]; /* 722 - Alt. cylinder count */
303 + char ntrks[2]; /* 722 - Tracks per cylinder */
304 + char nsect[2]; /* 722 - Sectors per track */
305 + char spare3[4]; /* Even more magic... */
306 + struct sun_partition {
307 + char start_cylinder[4]; /* 732 */
308 + char num_sectors[4]; /* 732 */
310 + char magic[2]; /* 722 - Magic number */
311 + char csum[2]; /* 722 - Label xor'd checksum */
312 + struct bootblock_header {
313 + char magic[4]; /* 732 */
317 + char extent[4]; /* 732 */
318 + char size[4]; /* 732 */
319 + char text[2048-512-56];
328 + char conf_file[256];
331 +static int silo_size(int starting_extent)
337 +static int silo_filter(char * buffer, int size, int offset)
339 + if (offset < 0x808 + sizeof(silo_info)
340 + && offset + size > 0x808)
343 + if (offset < 0x808)
345 + offset = 0x808 - offset;
352 + i = sizeof(silo_info) - offset;
353 + if (i > size) i = size;
354 + memcpy (buffer, ((char *)&silo_info) + offset, i);
359 +static int silo_write(FILE * outfile)
361 + struct directory_entry * de;
362 + struct directory_entry * de2;
363 + struct deferred_write * dwpnt;
364 + int bootblock, i, should_write;
365 + struct sun_disklabel silo_bb;
367 + memset (&silo_bb, 0, sizeof (silo_bb));
369 + if (*silo_bootblock == '/') silo_bootblock++;
370 + if (*silo_boot_image == '/') silo_boot_image++;
373 + * search from root of iso fs to find boot catalog
375 + de2 = search_tree_file(root, silo_bootblock);
378 + fprintf(stderr,"Uh oh, I cant find the SILO bootblock!\n");
383 + * now read it from disk
385 + bootblock = open(de2->whole_name, O_RDWR | O_BINARY);
386 + if (bootblock == -1)
388 + fprintf(stderr,"Error opening SILO bootblock for reading.\n");
393 + if (read (bootblock, (char *)&silo_bb.bootblock, 1024) != 1024)
395 + fprintf(stderr,"Error reading SILO bootblock.\n");
402 + if (get_732 (silo_bb.bootblock.magic) != 0x01030107
403 + || strncmp (silo_bb.bootblock.siloid, "SILO", 4)
404 + || silo_bb.bootblock.siloid[5] != '.'
405 + || silo_bb.bootblock.siloid[4] < '0'
406 + || silo_bb.bootblock.siloid[4] > '9'
407 + || silo_bb.bootblock.siloid[6] < '0'
408 + || silo_bb.bootblock.siloid[6] > '9'
409 + || silo_bb.bootblock.siloid[7] < '0'
410 + || silo_bb.bootblock.siloid[7] > '9')
412 + fprintf(stderr,"Error: the file %s is not a valid SILO bootblock.\n", silo_bootblock);
417 + /* Check version number. Only SILO 0.87 and up is valid. */
418 + if (silo_bb.bootblock.siloid[4] == '0'
419 + && (silo_bb.bootblock.siloid[6] < '8'
420 + || (silo_bb.bootblock.siloid[6] == '8'
421 + && silo_bb.bootblock.siloid[7] <= '6')))
423 + fprintf(stderr,"Error: SILO bootblock is too old. Must be at least 0.8.7.\n");
429 + * search from root of iso fs to find boot catalog
431 + de = search_tree_file(root, silo_boot_image);
434 + fprintf(stderr,"Uh oh, I cant find the SILO boot image!\n");
439 + * need to filter second.b, so that we can seed
440 + * silo.conf location and other stuff.
441 + * We could write it into the de->whole_name file,
442 + * but I prefer filtering it like this because
443 + * then the tree can be e.g. read only NFS mounted.
445 + for (dwpnt = dw_head; dwpnt; dwpnt = dwpnt->next)
447 + if (!dwpnt->name) continue;
448 + if (!strcmp (dwpnt->name, de->whole_name))
449 + dwpnt->filter = silo_filter;
452 + set_732 (silo_bb.bootblock.extent, de->starting_block);
453 + set_732 (silo_bb.bootblock.size, de->size);
455 + strcpy (silo_bb.info, "SPARC bootable CD-ROM: ");
456 + strcat (silo_bb.info, volume_id);
458 + should_write = (last_extent - session_start) << 2;
460 + /* Now some magic */
461 + silo_bb.spare0[3] = 1;
462 + silo_bb.spare0[13] = 8;
463 + for (i = 0; i < 8; i++) {
464 + silo_bb.infos[i].id = 0x83;
465 + silo_bb.infos[i].flags = 0x18;
467 + set_732 (silo_bb.spare1 + 14, 0x600ddeee);
468 + set_722 (silo_bb.rspeed, 0x15e);
469 + set_722 (silo_bb.pcylcount, (should_write + 639) / 640);
470 + set_722 (silo_bb.ilfact, 1);
471 + set_722 (silo_bb.ncyl, (should_write + 639) / 640);
472 + set_722 (silo_bb.ntrks, 1);
473 + set_722 (silo_bb.nsect, 640);
474 + set_732 (silo_bb.partitions[0].num_sectors, should_write);
475 + set_722 (silo_bb.magic, 0xdabe);
476 + for (i = 0; i < 510; i+=2) {
477 + silo_bb.csum[0] ^= silo_bb.info[i];
478 + silo_bb.csum[1] ^= silo_bb.info[i+1];
481 + xfwrite(&silo_bb, 1, sizeof(silo_bb), outfile);
482 + memset (&silo_bb, 0, sizeof(silo_bb));
484 + for(i=1; i<16; i++)
486 + xfwrite(&silo_bb, 1, sizeof(silo_bb), outfile);
489 + memset (&silo_info, 0, sizeof(silo_info));
490 + silo_info.id = 'L';
491 + silo_info.conf_part = 1;
492 + strncpy (silo_info.conf_file, silo_conf_file, 256);
493 + silo_info.conf_file[259] = '\0';
495 + last_extent_written += 16;
500 +struct output_fragment silo_desc = {NULL, silo_size, NULL, silo_write};
501 --- cdrtools-2.00.3/mkisofs/tree.c 2002-12-07 21:40:47.000000000 +0100
502 +++ cdrtools-2.00.3/mkisofs/tree.c 2002-12-27 20:24:53.000000000 +0100
504 int scan_directory_tree __PR((struct directory *this_dir,
506 struct directory_entry *de));
507 +static int check_dirlevel __PR((char *name));
509 int insert_file_entry __PR((struct directory *this_dir,
511 @@ -1322,6 +1323,34 @@
515 +/* check_dirlevel: returns 1 if
516 + * name is below the tree of follow_links_base */
518 +check_dirlevel(name)
521 + char old[256] = {0,}, buf[256] = {0,}, b2[256], *c;
524 + c = strrchr (b2, '/');
532 + if (!strncmp (buf, follow_links_base,
533 + strlen (follow_links_base))) {
545 * Function: insert_file_entry
546 @@ -1366,6 +1395,8 @@
547 int htype = TYPE_NONE;
549 #endif /* APPLE_HYB */
550 + char link_buf[256];
551 + int do_follow_links = 0;
553 status = stat_filter(whole_path, &statbuf);
555 @@ -1401,7 +1432,35 @@
556 * is in use, it is easy, we let RR describe the file. If
557 * not, then we punt the file.
559 - if ((status || !follow_links)) {
560 + /* First check for the sensible follow_links option */
561 + if (follow_links_sensible) {
562 + /* Where does the link point to? */
563 + memset (link_buf, 0, 256);
564 + readlink (whole_path, link_buf, 255);
565 + if (check_dirlevel (link_buf)) {
566 + /* Treat it as a symlink */
567 + if (!use_RockRidge) {
568 + fprintf(stderr, "Ignoring symlink %s (which wouldn't be followed)\n",
571 + do_follow_links = 0;
574 + statbuf.st_size = 0;
575 + STAT_INODE(statbuf) = UNCACHED_INODE;
576 + statbuf.st_dev = (dev_t) UNCACHED_DEVICE;
577 + statbuf.st_mode = (statbuf.st_mode & ~S_IFMT) | S_IFREG;
581 + /* Follow the link */
582 + do_follow_links = 1;
585 + else if (!follow_links_sensible)
586 + do_follow_links = follow_links;
588 + if((status || !do_follow_links)) {
591 statbuf.st_size = (off_t)0;
592 @@ -1410,7 +1469,7 @@
594 (statbuf.st_mode & ~S_IFMT) | S_IFREG;
596 - if (follow_links) {
597 + if (do_follow_links) {
599 /* XXX errno may be wrong! */
600 errmsg("Unable to stat file %s - ignoring and continuing.\n",
601 @@ -1443,7 +1502,7 @@
602 * time we have seen this, then make this seem as if there was
603 * no symlink there in the first place
606 + if (do_follow_links
607 && S_ISDIR(statbuf.st_mode)) {
608 if (strcmp(short_name, ".")
609 && strcmp(short_name, "..")) {
610 @@ -1478,7 +1537,7 @@
611 * For non-directories, we just copy the stat information over
612 * so we correctly include this file.
615 + if (do_follow_links
616 && !S_ISDIR(statbuf.st_mode)) {
619 @@ -1487,7 +1546,7 @@
620 * Add directories to the cache so that we don't waste space even if
621 * we are supposed to be following symlinks.
624 + if (do_follow_links
625 && strcmp(short_name, ".")
626 && strcmp(short_name, "..")
627 && S_ISDIR(statbuf.st_mode)) {
628 @@ -1537,7 +1596,7 @@
629 * Add this so that we can detect directory loops with hard links.
630 * If we are set up to follow symlinks, then we skip this checking.
633 + if (!do_follow_links
634 && S_ISDIR(lstatbuf.st_mode)
635 && strcmp(short_name, ".")
636 && strcmp(short_name, "..")) {
637 --- cdrtools-2.00.3/mkisofs/vms.c 2000-12-05 15:25:10.000000000 +0100
638 +++ cdrtools-2.00.3/mkisofs/vms.c 2002-12-27 20:24:53.000000000 +0100
640 extern unsigned int last_extent_written;
643 -vms_write_one_file(char *filename, int size, FILE * outfile)
644 +vms_write_one_file(struct deferred_write * dwpnt, FILE * outfile)
648 @@ -296,10 +296,11 @@
654 - open_file(filename);
655 + open_file(dwpnt->name);
658 + remain = dwpnt->size;
661 use = (remain > SECTOR_SIZE * NSECT - 1 ? NSECT * SECTOR_SIZE : remain);
662 @@ -308,11 +309,14 @@
663 rab->rab$l_ubf = buffer;
664 rab->rab$w_usz = sizeof(buffer);
665 status = sys$read(rab);
667 + (* dwpnt->filter)(buffer, use, offset);
668 fwrite(buffer, 1, use, outfile);
669 last_extent_written += use / SECTOR_SIZE;
670 if ((last_extent_written % 1000) < use / SECTOR_SIZE)
671 fprintf(stderr, "%d..", last_extent_written);
677 --- cdrtools-2.00.3/mkisofs/write.c 2002-12-23 15:16:45.000000000 +0100
678 +++ cdrtools-2.00.3/mkisofs/write.c 2002-12-27 20:24:53.000000000 +0100
681 static int assign_directory_addresses __PR((struct directory *node));
683 -static void write_one_file __PR((char *filename, unsigned int size,
684 +static void write_one_file __PR((struct deferred_write *dwpnt,
685 FILE *outfile, off_t off));
687 -static void write_one_file __PR((char *filename, unsigned int size,
688 +static void write_one_file __PR((struct deferred_write *dwpnt,
691 static void write_files __PR((FILE *outfile));
693 static struct deferred_write mac_boot;
695 #endif /* APPLE_HYB */
696 -static struct deferred_write *dw_head = NULL,
698 +struct deferred_write *dw_head = NULL,
701 unsigned int last_extent_written = 0;
702 static Uint path_table_index;
703 @@ -360,16 +360,14 @@
707 -write_one_file(filename, size, outfile, off)
710 +write_one_file(dwpnt, outfile, off)
711 + struct deferred_write *dwpnt;
716 -write_one_file(filename, size, outfile)
719 +write_one_file(dwpnt, outfile)
720 + struct deferred_write *dwpnt;
722 #endif /* APPLE_HYB */
724 @@ -385,18 +383,18 @@
731 - if ((infile = fopen(filename, "rb")) == NULL) {
732 + if ((infile = fopen(dwpnt->name, "rb")) == NULL) {
734 - comerr("cannot open '%s'\n", filename);
735 + comerr("cannot open '%s'\n", dwpnt->name);
737 #ifndef HAVE_STRERROR
738 fprintf(stderr, "cannot open '%s': (%d)\n",
740 + dwpnt->name, errno);
742 fprintf(stderr, "cannot open '%s': %s\n",
743 - filename, strerror(errno));
744 + dwpnt->name, strerror(errno));
750 fseek(infile, off, SEEK_SET);
751 #endif /* APPLE_HYB */
753 + remain = dwpnt->size;
757 use = (remain > SECTOR_SIZE * NSECT - 1 ?
758 @@ -414,13 +413,16 @@
759 memset(buffer, 0, use);
760 if (fread(buffer, 1, use, infile) == 0) {
762 - comerr("cannot read from '%s'\n", filename);
763 + comerr("cannot read from '%s'\n", dwpnt->name);
765 - fprintf(stderr, "cannot read from '%s'\n", filename);
766 + fprintf(stderr, "cannot read from '%s'\n", dwpnt->name);
771 + (* dwpnt->filter)(buffer, use, offset);
772 xfwrite(buffer, 1, use, outfile);
774 last_extent_written += use / SECTOR_SIZE;
776 if ((last_extent_written % 1000) < use / SECTOR_SIZE) {
777 @@ -480,13 +482,13 @@
781 - vms_write_one_file(dwpnt->name, dwpnt->size, outfile);
782 + vms_write_one_file(dwpnt, outfile);
785 - write_one_file(dwpnt->name, dwpnt->size, outfile,
786 + write_one_file(dwpnt, outfile,
789 - write_one_file(dwpnt->name, dwpnt->size, outfile);
790 + write_one_file(dwpnt, outfile);
791 #endif /* APPLE_HYB */
794 @@ -1151,6 +1153,7 @@
796 dwpnt->size = s_entry->size;
797 dwpnt->extent = last_extent;
798 + dwpnt->filter = NULL;
799 set_733((char *) s_entry->isorec.extent,
801 s_entry->starting_block = last_extent;
802 @@ -1722,8 +1725,7 @@
804 /* write out HFS boot block */
806 - write_one_file(mac_boot.name, mac_boot.size, outfile,
808 + write_one_file(&mac_boot, outfile, mac_boot.off);
810 #endif /* APPLE_HYB */