Subject: bin/12688: Patch for rdist to handle hard links in renamed directories
To: None <gnats-bugs@gnats.netbsd.org>
From: None <polder@azenomei.knuffel.net>
List: netbsd-bugs
Date: 04/18/2001 01:35:06
>Number:         12688
>Category:       bin
>Synopsis:       Patch for rdist to handle hard links in renamed directories
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Apr 17 16:36:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Rhialto
>Release:        NetBSD-current of 9 april 2001
>Organization:
	
>Environment:
	
System: NetBSD azenomei.falu.nl 1.5 NetBSD 1.5 (AZENOMEI) #2: Mon Jan 29 02:04:20 CET 2001 root@azenomei.falu.nl:/usr/src/sys/arch/alpha/compile/AZENOMEI alpha


>Description:

    With this Distfile fragment:

share:
    /vol1/rhialto/destdir.alpha/usr/share -> root@xzan
	install -R /home/rhialto/destdir.vax/usr/share ;

I get the following sort of errors on hard links:

installing: /vol1/rhialto/destdir.alpha/usr/share/zoneinfo/GB-Eire
rdist: xzan.falu.nl:can't link /home/rhialto/destdir.vax/usr/share/zoneinfo/GB-Eire to /vol1/rhialto/destdir.alpha/usr/share/zoneinfo/Europe/London

Of course this link cannot be made, since the file to link to is
expressed as a source-host pathname, not a destination-host pathname...  

>How-To-Repeat:
	Want to copy the share subtree to another location on
	another machine, efficiently. Proceed as above.
>Fix:

cvs server: Diffing .
Index: server.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/rdist/server.c,v
retrieving revision 1.20
diff -u -r1.20 server.c
--- server.c	2001/01/04 23:05:55	1.20
+++ server.c	2001/04/17 23:34:15
@@ -60,6 +60,9 @@
 char	target[BUFSIZ];		/* target/source directory name */
 char	*tp;			/* pointer to end of target name */
 char	*Tdest;			/* pointer to last T dest*/
+char	*Destcopy;		/* pointer to current dest */
+int	Destcopylen;		/* length of destination directory name */
+int	Sourcelen;		/* length of source directory name */
 int	catname;		/* cat name to target name */
 char	*stp[32];		/* stack of saved tp's for directories */
 int	oumask;			/* old umask for creating files */
@@ -253,7 +256,14 @@
 	if (dest == NULL) {
 		opts &= ~WHOLE; /* WHOLE mode only useful if renaming */
 		dest = src;
+	} else if (!(opts & WHOLE)) {
+		/* prepare for proper renaming of directory trees */
+		Destcopy = destcopy;
+		Destcopylen = strlen(dest);
+		while (Destcopylen > 0 && dest[Destcopylen] == '/')
+		    Destcopylen--;
 	}
+	strcpy(destcopy, dest);
 
 	if (nflag || debug) {
 		printf("%s%s%s%s%s %s %s\n", opts & VERIFY ? "verify":"install",
@@ -271,6 +281,12 @@
 	tp = target;
 	while (*tp)
 		tp++;
+	if (Destcopy) {
+		/* We can only do this after expansion of src */
+		Sourcelen = strlen(target);
+		while (Sourcelen > 0 && target[Sourcelen] == '/')
+		    Sourcelen--;
+	}
 	/*
 	 * If we are renaming a directory and we want to preserve
 	 * the directory heirarchy (-w), we must strip off the leading
@@ -302,10 +318,10 @@
 		return;
 
 	if (destdir) {
-		strcpy(destcopy, dest);
 		Tdest = destcopy;
 	}
 	sendf(rname, opts);
+	Destcopy = 0;
 	Tdest = 0;
 }
 
@@ -575,7 +591,16 @@
 		lp->inum = stp->st_ino;
 		lp->devnum = stp->st_dev;
 		lp->count = stp->st_nlink - 1;
-		strcpy(lp->pathname, target);
+		if (Destcopy) {
+			/*
+			 * Change the starting directory of target
+			 * into the destination directory
+			 */
+			strncpy(lp->pathname, Destcopy, Destcopylen);
+			strcpy(lp->pathname + Destcopylen, target + Sourcelen);
+		} else {
+			strcpy(lp->pathname, target);
+		}
 		if (Tdest)
 			strcpy(lp->target, Tdest);
 		else

-Olaf.
-- 
___ Olaf 'Rhialto' Seibert - rhialto@polder --Soep van de dag, wat zal dat zijn
\X/ land.nl     --wat kan dat wezen, beter maar het ergste vrezen -Boy Bensdorp
>Release-Note:
>Audit-Trail:
>Unformatted: