NO_SYMLINK_XATTRS is defined.
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';
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)
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);
#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
extern int dry_run;
extern int am_root;
+extern int am_sender;
extern int read_only;
extern int list_only;
extern int preserve_perms;
{
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
int dry_run = 0;
int am_root = 0;
+int am_sender = 1;
int read_only = 0;
int list_only = 0;
int human_readable = 0;
/* 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;
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;
/* 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;