Commit 6e310d38 authored by Wayne Davison's avatar Wayne Davison

Have --fake-super turn a symlink into a file when

NO_SYMLINK_XATTRS is defined.
parent 3b83a220
......@@ -196,7 +196,7 @@ static int readlink_stat(const char *path, STRUCT_STAT *stp, char *linkbuf)
if (link_stat(path, stp, copy_dirlinks) < 0)
return -1;
if (S_ISLNK(stp->st_mode)) {
int llen = readlink(path, linkbuf, MAXPATHLEN - 1);
int llen = do_readlink(path, linkbuf, MAXPATHLEN - 1);
if (llen < 0)
return -1;
linkbuf[llen] = '\0';
......
......@@ -946,7 +946,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
break;
case TYPE_SYMLINK:
#ifdef SUPPORT_LINKS
if ((len = readlink(cmpbuf, lnk, MAXPATHLEN-1)) <= 0)
if ((len = do_readlink(cmpbuf, lnk, MAXPATHLEN-1)) <= 0)
continue;
lnk[len] = '\0';
if (strcmp(lnk, F_SYMLINK(file)) != 0)
......@@ -1369,7 +1369,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
int len;
if (S_ISLNK(sx.st.st_mode)
&& (len = readlink(fname, lnk, MAXPATHLEN-1)) > 0
&& (len = do_readlink(fname, lnk, MAXPATHLEN-1)) > 0
&& strncmp(lnk, sl, len) == 0 && sl[len] == '\0') {
/* The link is pointing to the right place. */
set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT);
......
......@@ -981,6 +981,9 @@ extern int errno;
#ifdef HAVE_READLINK
#define SUPPORT_LINKS 1
#ifndef NO_SYMLINK_XATTRS
#define do_readlink(path, buf, bufsiz) readlink(path, buf, bufsiz)
#endif
#endif
#ifdef HAVE_LINK
#define SUPPORT_HARD_LINKS 1
......
......@@ -31,6 +31,7 @@
extern int dry_run;
extern int am_root;
extern int am_sender;
extern int read_only;
extern int list_only;
extern int preserve_perms;
......@@ -58,8 +59,48 @@ int do_symlink(const char *lnk, const char *fname)
{
if (dry_run) return 0;
RETURN_ERROR_IF_RO_OR_LO;
#ifdef NO_SYMLINK_XATTRS
/* For --fake-super, we create a normal file with mode 0600
* and write the lnk into it. */
if (am_root < 0) {
int ok, len = strlen(lnk);
int fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, S_IWUSR|S_IRUSR);
if (fd < 0)
return -1;
ok = write(fd, lnk, len) == len;
if (close(fd) < 0)
ok = 0;
return ok ? 0 : -1;
}
#endif
return symlink(lnk, fname);
}
#ifdef NO_SYMLINK_XATTRS
ssize_t do_readlink(const char *path, char *buf, size_t bufsiz)
{
/* For --fake-super, we read the link from the file. */
if (am_root < 0) {
int fd = open(path, O_RDONLY|O_NOFOLLOW);
if (fd >= 0) {
int len = read(fd, buf, bufsiz);
close(fd);
return len;
}
if (errno != ELOOP)
return -1;
/* A real symlink needs to be turned into a fake one on the receiving
* side, so tell the generator that the link has no length. */
if (!am_sender)
return 0;
/* Otherwise fall through and let the sender report the real length. */
}
return readlink(path, buf, bufsiz);
}
#endif
#endif
#ifdef HAVE_LINK
......
......@@ -25,6 +25,7 @@
int dry_run = 0;
int am_root = 0;
int am_sender = 1;
int read_only = 0;
int list_only = 0;
int human_readable = 0;
......
......@@ -43,6 +43,7 @@
/* These are to make syscall.o shut up. */
int dry_run = 0;
int am_root = 0;
int am_sender = 1;
int read_only = 1;
int list_only = 0;
int link_times = 0;
......@@ -147,9 +148,9 @@ static void list_file(const char *fname)
buf.st_uid = buf.st_gid = 0;
strlcpy(linkbuf, " -> ", sizeof linkbuf);
/* const-cast required for silly UNICOS headers */
len = readlink((char *) fname, linkbuf+4, sizeof(linkbuf) - 4);
len = do_readlink((char *) fname, linkbuf+4, sizeof(linkbuf) - 4);
if (len == -1)
failed("readlink", fname);
failed("do_readlink", fname);
else
/* it's not nul-terminated */
linkbuf[4+len] = 0;
......
......@@ -23,6 +23,7 @@
/* These are to make syscall.o shut up. */
int dry_run = 0;
int am_root = 0;
int am_sender = 1;
int read_only = 1;
int list_only = 0;
int preserve_perms = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment