Bug#85672: mkisofs: symlink tree support for mkisofs
Package: mkisofs
Version: 3:1.9-1
Severity: important
Tags: patch
(CC'd to debian-cd this report is probably of interest to people there.)
The following patch should cleanly incorporate the symlink tree
support into mkisofs, provide the mkhybrid symlink and man page, and
make the package replace mkhybrid for people running apt-get
dist-upgrade.
I have marked this report as important as people creating Debian CDs
find this functionality useful. I have not tested the patch myself
but it does compile and I didn't change any of the code (except
indentation, to match the current style) from the mkhybrid .diff.gz.
*** mkisofs-tree.diff
diff -urN cdrecord-1.9-official/debian/control cdrecord-1.9/debian/control
--- cdrecord-1.9-official/debian/control Sun Feb 11 17:41:27 2001
+++ cdrecord-1.9/debian/control Sun Feb 11 22:23:19 2001
@@ -18,13 +18,17 @@
Package: mkisofs
Architecture: any
Depends: ${shlibs:Depends}
+Provides: mkhybrid
+Replaces: mkhybrid
+Conflicts: mkhybrid
Suggests: cdrecord
Section: otherosfs
Description: Creates ISO-9660 CD-ROM filesystem images.
mkisofs is a pre-mastering program for creating ISO-9660 CD-ROM
filesystem images, which can then be written to a CD-ROM using the
cdrecord program. mkisofs now includes support for making bootable
- "El Torito" CD-ROMs.
+ "El Torito" CD-ROMs, as well as CD-ROMs with support for the
+ Macintosh HFS filesystem (as in the old "mkhybrid" package).
Package: cdda2wav
Architecture: any
diff -urN cdrecord-1.9-official/debian/mkisofs.files cdrecord-1.9/debian/mkisofs.files
--- cdrecord-1.9-official/debian/mkisofs.files Sun Feb 11 17:41:27 2001
+++ cdrecord-1.9/debian/mkisofs.files Sun Feb 11 22:24:02 2001
@@ -4,4 +4,5 @@
usr/bin/isodump
usr/bin/isovfy
usr/share/man/man8/mkisofs.8
+usr/share/man/man8/mkhybrid.8
usr/share/man/man8/isoinfo.8
diff -urN cdrecord-1.9-official/mkisofs/mkisofs.8 cdrecord-1.9/mkisofs/mkisofs.8
--- cdrecord-1.9-official/mkisofs/mkisofs.8 Thu Jul 20 11:29:10 2000
+++ cdrecord-1.9/mkisofs/mkisofs.8 Sun Feb 11 22:02:31 2001
@@ -93,6 +93,10 @@
.B \-f
]
[
+.B \-F
+.I root_directory
+]
+[
.B \-d
]
[
@@ -709,6 +713,12 @@
in use, symbolic links will be entered using Rock Ridge if enabled, otherwise
the file will be ignored.
.TP
+.BI \-F " root_directory
+Follow symbolic links which point outside specified
+.I root_directory
+when generating the filesystem. This allows a symlink farm structure,
+where symlinks inside the base directory stay symlinks, but symlinks
+outside the base directory become real files on the CD.
.B \-gui
Switch the behaviour for a GUI. This currently makes the output more verbose
but may have other effects in future.
diff -urN cdrecord-1.9-official/mkisofs/mkisofs.c cdrecord-1.9/mkisofs/mkisofs.c
--- cdrecord-1.9-official/mkisofs/mkisofs.c Thu Jul 20 11:31:17 2000
+++ cdrecord-1.9/mkisofs/mkisofs.c Sun Feb 11 22:07:05 2001
@@ -111,6 +111,7 @@
int gui = 0;
int all_files = 1; /* New default is to include all files */
int follow_links = 0;
+int follow_links_sensible = 0;
int rationalize = 0;
int generate_tables = 0;
int dopad = 0;
@@ -130,6 +131,7 @@
char *boot_catalog = BOOT_CATALOG_DEFAULT;
char *boot_image = BOOT_IMAGE_DEFAULT;
char *genboot_image = BOOT_IMAGE_DEFAULT;
+char follow_links_base[PATH_MAX];
int ucs_level = 3; /* We now have Unicode tables so use level 3 */
int volume_set_size = 1;
int volume_sequence_number = 1;
@@ -383,6 +385,8 @@
'D', NULL, "Disable deep directory relocation (violates ISO9660)", ONE_DASH},
{{"follow-links", no_argument, NULL, 'f'},
'f', NULL, "Follow symbolic links", ONE_DASH},
+ {{"follow-outside-links", required_argument, NULL, 'F'},
+ 'F', NULL, "Follow symbolic links which point outside the CD base directory", ONE_DASH },
{{"graft-points", no_argument, NULL, OPTION_USE_GRAFT},
'\0', NULL, "Allow to use graft points for filenames", ONE_DASH},
{{"help", no_argument, NULL, OPTION_HELP},
@@ -1017,7 +1021,7 @@
int hfs_ct = 0;
char *root_info = 0;
#endif /* APPLE_HYB */
-
+ char old_dir[PATH_MAX];
#ifdef __EMX__
/* This gives wildcard expansion with Non-Posix shells with EMX */
@@ -1274,6 +1278,20 @@
break;
case 'f':
follow_links++;
+ break;
+ case 'F':
+ follow_links_sensible++;
+ if(getcwd (old_dir, PATH_MAX)) {
+ chdir (optarg);
+ if(!getcwd (follow_links_base, PATH_MAX)) {
+ perror("getcwd");
+ exit(1);
+ }
+ chdir (old_dir);
+ } else {
+ perror("getcwd");
+ exit(1);
+ }
break;
case 'l':
full_iso9660_filenames++;
diff -urN cdrecord-1.9-official/mkisofs/mkisofs.h cdrecord-1.9/mkisofs/mkisofs.h
--- cdrecord-1.9-official/mkisofs/mkisofs.h Sun May 28 09:03:50 2000
+++ cdrecord-1.9/mkisofs/mkisofs.h Sun Feb 11 22:08:32 2001
@@ -311,6 +311,8 @@
extern int use_Joliet;
extern int rationalize;
extern int follow_links;
+extern int follow_links_sensible;
+extern char follow_links_base[];
extern int verbose;
extern int gui;
extern int all_files;
diff -urN cdrecord-1.9-official/mkisofs/tree.c cdrecord-1.9/mkisofs/tree.c
--- cdrecord-1.9-official/mkisofs/tree.c Sun May 7 08:21:40 2000
+++ cdrecord-1.9/mkisofs/tree.c Sun Feb 11 22:16:54 2001
@@ -91,6 +91,7 @@
int scan_directory_tree __PR((struct directory *this_dir,
char *path,
struct directory_entry *de));
+static int check_dirlevel __PR((char *name));
#ifdef APPLE_HYB
int insert_file_entry __PR((struct directory *this_dir,
char *whole_path,
@@ -1272,6 +1273,34 @@
return 1;
}
+/* check_dirlevel: returns 1 if
+ * name is below the tree of follow_links_base */
+static int
+check_dirlevel(name)
+ char *name;
+{
+ char old[256] = {0,}, buf[256] = {0,}, b2[256], *c;
+
+ strcpy (b2, name);
+ c = strrchr (b2, '/');
+ if (c) {
+ *c = '\0';
+ getcwd (old, 256);
+ chdir (b2);
+ getcwd (buf, 256);
+ chdir (old);
+
+ if (!strncmp (buf, follow_links_base,
+ strlen (follow_links_base))) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
/*
* Function: insert_file_entry
@@ -1316,6 +1345,8 @@
int htype = TYPE_NONE;
#endif /* APPLE_HYB */
+ char link_buf[256];
+ int do_follow_links = 0;
status = stat_filter(whole_path, &statbuf);
@@ -1351,7 +1382,35 @@
* is in use, it is easy, we let RR describe the file. If
* not, then we punt the file.
*/
- if ((status || !follow_links)) {
+ /* First check for the sensible follow_links option */
+ if (follow_links_sensible) {
+ /* Where does the link point to? */
+ memset (link_buf, 0, 256);
+ readlink (whole_path, link_buf, 255);
+ if (check_dirlevel (link_buf)) {
+ /* Treat it as a symlink */
+ if (!use_RockRidge) {
+ fprintf(stderr, "Ignoring symlink %s (which wouldn't be followed)\n",
+ whole_path);
+ } else {
+ do_follow_links = 0;
+ if (status) {
+ 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 {
+ /* Follow the link */
+ do_follow_links = 1;
+ }
+ }
+ else if (!follow_links_sensible)
+ do_follow_links = follow_links;
+
+ if((status || !do_follow_links)) {
if (use_RockRidge) {
status = 0;
statbuf.st_size = 0;
@@ -1360,7 +1419,7 @@
statbuf.st_mode =
(statbuf.st_mode & ~S_IFMT) | S_IFREG;
} else {
- if (follow_links) {
+ if (do_follow_links) {
#ifdef USE_LIBSCHILY
/* XXX errno may be wrong! */
errmsg("Unable to stat file %s - ignoring and continuing.\n",
@@ -1393,7 +1452,7 @@
* time we have seen this, then make this seem as if there was
* no symlink there in the first place
*/
- if (follow_links
+ if (do_follow_links
&& S_ISDIR(statbuf.st_mode)) {
if (strcmp(short_name, ".")
&& strcmp(short_name, "..")) {
@@ -1418,7 +1477,7 @@
* For non-directories, we just copy the stat information over
* so we correctly include this file.
*/
- if (follow_links
+ if (do_follow_links
&& !S_ISDIR(statbuf.st_mode)) {
lstatbuf = statbuf;
}
@@ -1427,7 +1486,7 @@
* Add directories to the cache so that we don't waste space even if
* we are supposed to be following symlinks.
*/
- if (follow_links
+ if (do_follow_links
&& strcmp(short_name, ".")
&& strcmp(short_name, "..")
&& S_ISDIR(statbuf.st_mode)) {
@@ -1458,7 +1517,7 @@
* 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
+ if (!do_follow_links
&& S_ISDIR(lstatbuf.st_mode)
&& strcmp(short_name, ".")
&& strcmp(short_name, "..")) {
-- System Information
Debian Release: testing/unstable
Architecture: i386
Kernel: Linux quango4 2.4.1-ac9 #1 Sun Feb 11 00:13:34 CST 2001 i686
Versions of packages mkisofs depends on:
ii libc6 2.2.1-1 GNU C Library: Shared libraries an
Reply to: