There's a problem with the patch. While it will indeed convert a relative path to an absolute one, it will also convert any absolute paths it finds in to relative ones.

Attached is an updated patch that avoids this.

                                          Brian
                                  ( [EMAIL PROTECTED] )

-------------------------------------------------------------------------------
            The only bad mistakes are those you fail to learn from.
--- symlinks-1.2.orig/symlinks.8
+++ symlinks-1.2/symlinks.8
@@ -26,7 +26,10 @@
 .PP
 .B relative
 links are those expressed as paths relative to the directory in which
-the links reside, usually independent of the mount point of the filesystem.
+the links reside, usually independent of the mount point of the
+filesystem.  These are changed when
+.B -a
+is specified.
 .PP
 .B absolute
 links are those given as an absolute path from the root directory
@@ -76,6 +79,21 @@
 links are also shortened.
 Links affected by
 .B -c
+are prefixed with
+.B changed
+in the output.
+.TP
+.I -a
+make absolute links from relative links.  This permits links to remain
+valid when the link itself is moved.  This is especially useful for
+moving directories of links; using
+.B -a
+first, moving the directory, and then using
+.B -c
+restores relative links even if they pointed outside (or "above") the
+moved tree.
+Links affected by
+.B -a
 are prefixed with
 .B changed
 in the output.
--- symlinks-1.2.orig/symlinks.c
+++ symlinks-1.2/symlinks.c
--- symlinks.c.orig	2007-01-21 20:55:42.000000000 -0500
+++ symlinks.c	2007-01-21 21:04:05.000000000 -0500
@@ -3,6 +3,7 @@
 #define _LARGEFILE64_SOURCE
 
 #include <unistd.h>
+#include <stdlib.h>
 #ifndef _POSIX_SOURCE
 #define _POSIX_SOURCE
 #endif
@@ -28,7 +29,7 @@
 
 #define progver "%s: scan/change symbolic links - v1.2 - by Mark Lord\n\n"
 static char *progname;
-static int verbose = 0, fix_links = 0, recurse = 0, delete = 0, shorten = 0, testing = 0;
+static int verbose = 0, fix_links = 0, recurse = 0, delete = 0, shorten = 0, testing = 0, make_absolute_links = 0;
 
 /*
  * tidypath removes excess slashes and "." references from a path string
@@ -155,7 +156,7 @@
 static void fix_symlink (char *path, dev_t my_dev)
 {
 	static char lpath[PATH_MAX], new[PATH_MAX], abspath[PATH_MAX];
-	char *p, *np, *lp, *tail, *msg;
+	char *p, *np, *lp, *tail, *msg = NULL;
 	struct stat stbuf;
 	int c, fix_abs = 0, fix_messy = 0, fix_long = 0;
 
@@ -192,12 +193,16 @@
 	if (stbuf.st_dev != my_dev) {
 		msg = "other_fs:";
 	} else if (lpath[0] == '/') {
-		msg = "absolute:";
-		fix_abs = 1;
+		if (!make_absolute_links || verbose) {
+			msg = "absolute:";
+		}
+		if (!make_absolute_links) {
+			fix_abs = 1;
+		}
 	} else if (verbose) {
 		msg = "relative:";
-	} else
-		msg = NULL;
+	}
+
 	fix_messy = tidy_path(strcpy(new,lpath));
 	if (shorten)
 		fix_long = shorten_path(new, path);
@@ -209,7 +214,8 @@
 	}
 	if (msg != NULL)
 		printf("%s %s -> %s\n", msg, path, lpath);
-	if (!(fix_links || testing) || !(fix_messy || fix_abs || fix_long))
+
+	if (!(fix_links || testing || make_absolute_links) || !(fix_messy || fix_abs || fix_long || make_absolute_links))
 		return;
 
 	if (fix_abs) {
@@ -238,7 +244,14 @@
 		}
 		strcpy (np, tail);
 		(void) tidy_path(new);
+	} else if (make_absolute_links) {
+		/* turn relative link into an absolute one */
+		if (!realpath(path, new)) {
+			perror(path);
+			return;
+		}
 	}
+
 	if (!testing) {
 		if (unlink (path)) {
 			perror(path);
@@ -291,6 +304,7 @@
 	fprintf(stderr, progver, progname);
 	fprintf(stderr, "Usage:\t%s [-crsv] dirlist\n\n", progname);
 	fprintf(stderr, "Flags:\t-c == change absolute/messy links to relative\n"
+		"\t-a == make absolute links from relative\n"
 		"\t-d == delete dangling links\n"
 		"\t-r == recurse into subdirs\n"
 		"\t-s == shorten lengthy links\n"
@@ -324,6 +338,7 @@
 			while ((c = *p++)) {
 				     if (c == 'v')	verbose   = 1;
 				else if (c == 'c')	fix_links = 1;
+				else if (c == 'a')	make_absolute_links = 1;
 				else if (c == 'r')	recurse   = 1;
 				else if (c == 'd')	delete    = 1;
 				else if (c == 's')	shorten   = 1;

Reply via email to