|
|
| version 1.1.1.1, 2012/02/17 15:09:30 | version 1.1.1.3, 2016/11/01 09:54:32 |
|---|---|
| Line 3 | Line 3 |
| * Written by Jay Fenlason, vaguely based on the ACLs patch. | * Written by Jay Fenlason, vaguely based on the ACLs patch. |
| * | * |
| * Copyright (C) 2004 Red Hat, Inc. | * Copyright (C) 2004 Red Hat, Inc. |
| * Copyright (C) 2006-2009 Wayne Davison | * Copyright (C) 2006-2015 Wayne Davison |
| * | * |
| * This program is free software; you can redistribute it and/or modify | * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by |
| Line 21 | Line 21 |
| #include "rsync.h" | #include "rsync.h" |
| #include "ifuncs.h" | #include "ifuncs.h" |
| #include "inums.h" | |
| #include "lib/sysxattrs.h" | #include "lib/sysxattrs.h" |
| #ifdef SUPPORT_XATTRS | #ifdef SUPPORT_XATTRS |
| Line 122 static int rsync_xal_compare_names(const void *x1, con | Line 123 static int rsync_xal_compare_names(const void *x1, con |
| static ssize_t get_xattr_names(const char *fname) | static ssize_t get_xattr_names(const char *fname) |
| { | { |
| ssize_t list_len; | ssize_t list_len; |
| double arg; | int64 arg; |
| if (!namebuf) { | if (!namebuf) { |
| namebuf_len = 1024; | namebuf_len = 1024; |
| Line 140 static ssize_t get_xattr_names(const char *fname) | Line 141 static ssize_t get_xattr_names(const char *fname) |
| } else if (errno == ENOTSUP) | } else if (errno == ENOTSUP) |
| return 0; | return 0; |
| else if (errno != ERANGE) { | else if (errno != ERANGE) { |
| arg = (double)namebuf_len; | arg = namebuf_len; |
| got_error: | got_error: |
| rsyserr(FERROR_XFER, errno, | rsyserr(FERROR_XFER, errno, |
| "get_xattr_names: llistxattr(\"%s\",%.0f) failed", | "get_xattr_names: llistxattr(\"%s\",%s) failed", |
| full_fname(fname), arg); | full_fname(fname), big_num(arg)); |
| return -1; | return -1; |
| } | } |
| list_len = sys_llistxattr(fname, NULL, 0); | list_len = sys_llistxattr(fname, NULL, 0); |
| Line 218 static int rsync_xal_get(const char *fname, item_list | Line 219 static int rsync_xal_get(const char *fname, item_list |
| size_t datum_len, name_offset; | size_t datum_len, name_offset; |
| char *name, *ptr; | char *name, *ptr; |
| #ifdef HAVE_LINUX_XATTRS | #ifdef HAVE_LINUX_XATTRS |
| int user_only = am_sender ? 0 : am_root <= 0; | int user_only = am_sender ? 0 : !am_root; |
| #endif | #endif |
| rsync_xa *rxa; | rsync_xa *rxa; |
| int count; | int count; |
| Line 307 int get_xattr(const char *fname, stat_x *sxp) | Line 308 int get_xattr(const char *fname, stat_x *sxp) |
| if (!preserve_devices) | if (!preserve_devices) |
| #endif | #endif |
| return 0; | return 0; |
| } | } else if (IS_MISSING_FILE(sxp->st)) |
| return 0; | |
| if (rsync_xal_get(fname, sxp->xattr) < 0) { | if (rsync_xal_get(fname, sxp->xattr) < 0) { |
| free_xattr(sxp); | free_xattr(sxp); |
| Line 322 int copy_xattrs(const char *source, const char *dest) | Line 324 int copy_xattrs(const char *source, const char *dest) |
| size_t datum_len; | size_t datum_len; |
| char *name, *ptr; | char *name, *ptr; |
| #ifdef HAVE_LINUX_XATTRS | #ifdef HAVE_LINUX_XATTRS |
| int user_only = am_root <= 0; | int user_only = am_sender ? 0 : am_root <= 0; |
| #endif | #endif |
| /* This puts the name list into the "namebuf" buffer. */ | /* This puts the name list into the "namebuf" buffer. */ |
| Line 450 int send_xattr(int f, stat_x *sxp) | Line 452 int send_xattr(int f, stat_x *sxp) |
| if (rxa->datum_len > MAX_FULL_DATUM) | if (rxa->datum_len > MAX_FULL_DATUM) |
| write_buf(f, rxa->datum + 1, MAX_DIGEST_LEN); | write_buf(f, rxa->datum + 1, MAX_DIGEST_LEN); |
| else | else |
| write_buf(f, rxa->datum, rxa->datum_len); | write_bigbuf(f, rxa->datum, rxa->datum_len); |
| } | } |
| ndx = rsync_xal_l.count; /* pre-incremented count */ | ndx = rsync_xal_l.count; /* pre-incremented count */ |
| rsync_xal_store(sxp->xattr); /* adds item to rsync_xal_l */ | rsync_xal_store(sxp->xattr); /* adds item to rsync_xal_l */ |
| Line 578 void send_xattr_request(const char *fname, struct file | Line 580 void send_xattr_request(const char *fname, struct file |
| } | } |
| write_varint(f_out, len); /* length might have changed! */ | write_varint(f_out, len); /* length might have changed! */ |
| write_buf(f_out, ptr, len); | write_bigbuf(f_out, ptr, len); |
| free(ptr); | free(ptr); |
| } | } |
| } | } |
| Line 609 int recv_xattr_request(struct file_struct *file, int f | Line 611 int recv_xattr_request(struct file_struct *file, int f |
| num = 0; | num = 0; |
| while ((rel_pos = read_varint(f_in)) != 0) { | while ((rel_pos = read_varint(f_in)) != 0) { |
| num += rel_pos; | num += rel_pos; |
| while (cnt && rxa->num < num) { | /* Note that the sender-related num values may not be in order on the receiver! */ |
| rxa++; | while (cnt && (am_sender ? rxa->num < num : rxa->num != num)) { |
| cnt--; | rxa++; |
| cnt--; | |
| } | } |
| if (!cnt || rxa->num != num) { | if (!cnt || rxa->num != num) { |
| rprintf(FERROR, "[%s] could not find xattr #%d for %s\n", | rprintf(FERROR, "[%s] could not find xattr #%d for %s\n", |
| Line 665 void receive_xattr(int f, struct file_struct *file) | Line 668 void receive_xattr(int f, struct file_struct *file) |
| if (ndx < 0 || (size_t)ndx > rsync_xal_l.count) { | if (ndx < 0 || (size_t)ndx > rsync_xal_l.count) { |
| rprintf(FERROR, "receive_xattr: xa index %d out of" | rprintf(FERROR, "receive_xattr: xa index %d out of" |
| " range for %s\n", ndx, f_name(file, NULL)); | " range for %s\n", ndx, f_name(file, NULL)); |
| exit_cleanup(RERR_PROTOCOL); | exit_cleanup(RERR_STREAMIO); |
| } | } |
| if (ndx != 0) { | if (ndx != 0) { |