summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1998-04-27 03:13:54 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1998-04-27 03:13:54 +0000
commite8b258966600e7c7933cf4f220714812618e87b6 (patch)
tree3905eb4ec50a72770a28ec8b39239591cd03ed20
parent8af129cf4c5a352ae0b6712926fb8b36561ab767 (diff)
Correctly operate on hardlink when source and destination are not on the
same device; freebsd
-rw-r--r--usr.bin/oldrdist/defs.h3
-rw-r--r--usr.bin/oldrdist/server.c86
2 files changed, 62 insertions, 27 deletions
diff --git a/usr.bin/oldrdist/defs.h b/usr.bin/oldrdist/defs.h
index 364e4b96b79..aba2141ac44 100644
--- a/usr.bin/oldrdist/defs.h
+++ b/usr.bin/oldrdist/defs.h
@@ -1,4 +1,4 @@
-/* * $OpenBSD: defs.h,v 1.6 1997/02/09 19:24:55 deraadt Exp $*/
+/* * $OpenBSD: defs.h,v 1.7 1998/04/27 03:13:51 deraadt Exp $*/
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
@@ -133,6 +133,7 @@ struct linkbuf {
dev_t devnum;
int count;
char pathname[BUFSIZ];
+ char src[BUFSIZ];
char target[BUFSIZ];
struct linkbuf *nextp;
};
diff --git a/usr.bin/oldrdist/server.c b/usr.bin/oldrdist/server.c
index 93994ad6336..1f917caba0c 100644
--- a/usr.bin/oldrdist/server.c
+++ b/usr.bin/oldrdist/server.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server.c,v 1.9 1997/07/25 21:05:37 mickey Exp $ */
+/* $OpenBSD: server.c,v 1.10 1998/04/27 03:13:53 deraadt Exp $ */
/*
* Copyright (c) 1983, 1993
@@ -35,7 +35,7 @@
#ifndef lint
/* from: static char sccsid[] = "@(#)server.c 8.1 (Berkeley) 6/9/93"; */
-static char *rcsid = "$OpenBSD: server.c,v 1.9 1997/07/25 21:05:37 mickey Exp $";
+static char *rcsid = "$OpenBSD: server.c,v 1.10 1998/04/27 03:13:53 deraadt Exp $";
#endif /* not lint */
#include <sys/wait.h>
@@ -47,6 +47,7 @@ static char *rcsid = "$OpenBSD: server.c,v 1.9 1997/07/25 21:05:37 mickey Exp $"
struct linkbuf *ihead; /* list of files with more than one link */
char buf[BUFSIZ]; /* general purpose buffer */
char target[BUFSIZ]; /* target/source directory name */
+char source[BUFSIZ]; /* source directory name */
char *tp; /* pointer to end of target name */
char *Tdest; /* pointer to last T dest*/
int catname; /* cat name to target name */
@@ -243,6 +244,11 @@ install(src, dest, destdir, opts)
char *rname;
char destcopy[BUFSIZ];
+ if (opts & WHOLE)
+ source[0] = '\0';
+ else
+ strcpy(source, src);
+
if (dest == NULL) {
opts &= ~WHOLE; /* WHOLE mode only useful if renaming */
dest = src;
@@ -288,7 +294,13 @@ install(src, dest, destdir, opts)
if (response() < 0)
return;
- if (destdir) {
+ /*
+ * Save the name of the remote target destination if we are
+ * in WHOLE mode (destdir > 0) or if the source and destination
+ * are not the same. This info will be used later for maintaining
+ * hardlink info.
+ */
+ if (destdir || (src && dest && strcmp(src, dest))) {
strcpy(destcopy, dest);
Tdest = destcopy;
}
@@ -296,6 +308,48 @@ install(src, dest, destdir, opts)
Tdest = 0;
}
+static char *
+remotename(pathname, src)
+ char *pathname;
+ char *src;
+{
+ char *cp;
+ int len;
+
+ cp = pathname;
+ len = strlen(src);
+ if (0 == strncmp(pathname, src, len))
+ cp += len;
+ if (*cp == '/')
+ cp ++;
+ return(cp);
+}
+
+void
+installlink(lp, rname, opts)
+ struct linkbuf *lp;
+ char *rname;
+ int opts;
+{
+ if (*lp->target == 0)
+ (void) snprintf(buf, sizeof(buf), "k%o %s %s\n",
+ opts, lp->pathname, rname);
+ else
+ (void) snprintf(buf, sizeof(buf), "k%o %s/%s %s\n",
+ opts, lp->target,
+ remotename(lp->pathname, lp->src), rname);
+
+ if (debug) {
+ printf("lp->src = %s\n", lp->src);
+ printf("lp->target = %s\n", lp->target);
+ printf("lp->pathname = %s\n", lp->pathname);
+ printf("rname = %s\n", rname);
+ printf("buf = %s", buf);
+ }
+ (void) write(rem, buf, strlen(buf));
+ (void) response();
+}
+
#define protoname() (pw ? pw->pw_name : user)
#define protogroup() (gr ? gr->gr_name : group)
/*
@@ -409,18 +463,7 @@ sendf(rname, opts)
struct linkbuf *lp;
if ((lp = savelink(&stb)) != NULL) {
- /* install link */
- if (*lp->target == 0)
- (void) snprintf(buf, sizeof(buf), "k%o %s %s\n",
- opts, lp->pathname, rname);
- else
- (void) snprintf(buf, sizeof(buf),
- "k%o %s/%s %s\n", opts, lp->target,
- lp->pathname, rname);
- if (debug)
- printf("buf = %s", buf);
- (void) write(rem, buf, strlen(buf));
- (void) response();
+ installlink(lp, rname, opts);
return;
}
}
@@ -458,17 +501,7 @@ sendf(rname, opts)
struct linkbuf *lp;
if ((lp = savelink(&stb)) != NULL) {
- /* install link */
- if (*lp->target == 0)
- (void) snprintf(buf, sizeof(buf), "k%o %s %s\n", opts,
- lp->pathname, rname);
- else
- (void) snprintf(buf, sizeof(buf), "k%o %s/%s %s\n",
- opts, lp->target, lp->pathname, rname);
- if (debug)
- printf("buf = %s", buf);
- (void) write(rem, buf, strlen(buf));
- (void) response();
+ installlink(lp, rname, opts);
return;
}
}
@@ -546,6 +579,7 @@ savelink(stp)
lp->devnum = stp->st_dev;
lp->count = stp->st_nlink - 1;
strcpy(lp->pathname, target);
+ strcpy(lp->src, source);
if (Tdest)
strcpy(lp->target, Tdest);
else