mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-24 06:45:27 -04:00
Have --fake-super turn a symlink into a file when
NO_SYMLINK_XATTRS is defined.
This commit is contained in:
2
flist.c
2
flist.c
@@ -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);
|
||||
|
||||
3
rsync.h
3
rsync.h
@@ -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
|
||||
|
||||
41
syscall.c
41
syscall.c
@@ -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;
|
||||
|
||||
5
tls.c
5
tls.c
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user