aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDylan Simon <dylan@dylex.net>2010-06-27 12:37:58 -0400
committerDylan Simon <dylan@dylex.net>2010-06-27 12:37:58 -0400
commit2ee87bd118ff706c5a6db93b6ff6d0dcc0f7cb54 (patch)
treec6ed3c70341c1b3b2aa9d186200f24caf3fc9004
parentb1f36fb98cbc5646cf79dd6c3ec61f270923bbaf (diff)
parente51bb8f330d6b6ee3979bb0538e42da997c50d75 (diff)
downloadandroid_external_rsync-2ee87bd118ff706c5a6db93b6ff6d0dcc0f7cb54.tar.gz
android_external_rsync-2ee87bd118ff706c5a6db93b6ff6d0dcc0f7cb54.tar.bz2
android_external_rsync-2ee87bd118ff706c5a6db93b6ff6d0dcc0f7cb54.zip
Merge remote branch 'rsync/b3.0.x'
-rw-r--r--compat.c2
-rw-r--r--flist.c16
-rw-r--r--hashtable.c9
-rw-r--r--hlink.c24
-rw-r--r--io.c3
5 files changed, 37 insertions, 17 deletions
diff --git a/compat.c b/compat.c
index c2b475ba..3a4b38e2 100644
--- a/compat.c
+++ b/compat.c
@@ -24,6 +24,7 @@
int remote_protocol = 0;
int file_extra_cnt = 0; /* count of file-list extras that everyone gets */
int inc_recurse = 0;
+int compat_flags = 0;
int use_safe_inc_flist = 0;
extern int verbose;
@@ -248,7 +249,6 @@ void setup_protocol(int f_out,int f_in)
exit_cleanup(RERR_PROTOCOL);
}
} else if (protocol_version >= 30) {
- int compat_flags;
if (am_server) {
compat_flags = allow_inc_recurse ? CF_INC_RECURSE : 0;
#if defined HAVE_LUTIMES && defined HAVE_UTIMES
diff --git a/flist.c b/flist.c
index 3a3fc878..d8d69094 100644
--- a/flist.c
+++ b/flist.c
@@ -118,7 +118,7 @@ int flist_eof = 0; /* all the file-lists are now known */
* will survive just long enough to be used by send_file_entry(). */
static DEV_T tmp_rdev;
#ifdef SUPPORT_HARD_LINKS
-static int64 tmp_dev, tmp_ino;
+static int64 tmp_dev = -1, tmp_ino;
#endif
static char tmp_sum[MAX_DIGEST_LEN];
@@ -480,7 +480,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
modtime = file->modtime;
#ifdef SUPPORT_HARD_LINKS
- if (tmp_dev != 0) {
+ if (tmp_dev != -1) {
if (protocol_version >= 30) {
struct ht_int64_node *np = idev_find(tmp_dev, tmp_ino);
first_hlink_ndx = (int32)(long)np->data - 1;
@@ -598,15 +598,17 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
#endif
#ifdef SUPPORT_HARD_LINKS
- if (tmp_dev != 0 && protocol_version < 30) {
+ if (tmp_dev != -1 && protocol_version < 30) {
+ /* Older protocols expect the dev number to be transmitted
+ * 1-incremented so that it is never zero. */
if (protocol_version < 26) {
/* 32-bit dev_t and ino_t */
- write_int(f, (int32)dev);
+ write_int(f, (int32)(dev+1));
write_int(f, (int32)tmp_ino);
} else {
/* 64-bit dev_t and ino_t */
if (!(xflags & XMIT_SAME_DEV_pre30))
- write_longint(f, dev);
+ write_longint(f, dev+1);
write_longint(f, tmp_ino);
}
}
@@ -1259,10 +1261,10 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
if (protocol_version >= 28
? (!S_ISDIR(st.st_mode) && st.st_nlink > 1)
: S_ISREG(st.st_mode)) {
- tmp_dev = (int64)st.st_dev + 1;
+ tmp_dev = (int64)st.st_dev;
tmp_ino = (int64)st.st_ino;
} else
- tmp_dev = 0;
+ tmp_dev = -1;
}
#endif
diff --git a/hashtable.c b/hashtable.c
index ed29ee91..0524e24b 100644
--- a/hashtable.c
+++ b/hashtable.c
@@ -41,7 +41,7 @@ struct hashtable *hashtable_create(int size, int key64)
tbl->size = size;
tbl->entries = 0;
tbl->node_size = node_size;
- tbl->key64 = key64;
+ tbl->key64 = key64 ? 1 : 0;
return tbl;
}
@@ -60,6 +60,11 @@ void *hashtable_find(struct hashtable *tbl, int64 key, int allocate_if_missing)
struct ht_int32_node *node;
uint32 ndx;
+ if (key64 ? key == 0 : (int32)key == 0) {
+ rprintf(FERROR, "Internal hashtable error: illegal key supplied!\n");
+ exit_cleanup(RERR_MESSAGEIO);
+ }
+
if (allocate_if_missing && tbl->entries > HASH_LOAD_LIMIT(tbl->size)) {
void *old_nodes = tbl->nodes;
int size = tbl->size * 2;
@@ -142,7 +147,7 @@ void *hashtable_find(struct hashtable *tbl, int64 key, int allocate_if_missing)
if (key64)
((struct ht_int64_node*)node)->key = key;
else
- node->key = key;
+ node->key = (int32)key;
tbl->entries++;
return node;
}
diff --git a/hlink.c b/hlink.c
index 5ab9bb86..cfa1065e 100644
--- a/hlink.c
+++ b/hlink.c
@@ -57,7 +57,7 @@ static struct file_list *hlink_flist;
void init_hard_links(void)
{
if (am_sender || protocol_version < 30)
- dev_tbl = hashtable_create(16, SIZEOF_INT64 == 8);
+ dev_tbl = hashtable_create(16, 1);
else if (inc_recurse)
prior_hlinks = hashtable_create(1024, 0);
}
@@ -67,11 +67,12 @@ struct ht_int64_node *idev_find(int64 dev, int64 ino)
static struct ht_int64_node *dev_node = NULL;
struct hashtable *tbl;
- if (!dev_node || dev_node->key != dev) {
+ /* Note that some OSes have a dev == 0, so increment to avoid storing a 0. */
+ if (!dev_node || dev_node->key != dev+1) {
/* We keep a separate hash table of inodes for every device. */
- dev_node = hashtable_find(dev_tbl, dev, 1);
+ dev_node = hashtable_find(dev_tbl, dev+1, 1);
if (!(tbl = dev_node->data))
- tbl = dev_node->data = hashtable_create(512, SIZEOF_INT64 == 8);
+ tbl = dev_node->data = hashtable_create(512, 1);
} else
tbl = dev_node->data;
@@ -533,8 +534,19 @@ void finish_hard_link(struct file_struct *file, const char *fname, int fin_ndx,
if (inc_recurse) {
int gnum = F_HL_GNUM(file);
struct ht_int32_node *node = hashtable_find(prior_hlinks, gnum, 0);
- assert(node != NULL && node->data != NULL);
- assert(CVAL(node->data, 0) == 0);
+ if (node == NULL) {
+ rprintf(FERROR, "Unable to find a hlink node for %d (%s)\n", gnum, f_name(file, prev_name));
+ exit_cleanup(RERR_MESSAGEIO);
+ }
+ if (node->data == NULL) {
+ rprintf(FERROR, "Hlink node data for %d is NULL (%s)\n", gnum, f_name(file, prev_name));
+ exit_cleanup(RERR_MESSAGEIO);
+ }
+ if (CVAL(node->data, 0) != 0) {
+ rprintf(FERROR, "Hlink node data for %d already has path=%s (%s)\n",
+ gnum, (char*)node->data, f_name(file, prev_name));
+ exit_cleanup(RERR_MESSAGEIO);
+ }
free(node->data);
if (!(node->data = strdup(our_name)))
out_of_memory("finish_hard_link");
diff --git a/io.c b/io.c
index f9fa7c79..6599e5a9 100644
--- a/io.c
+++ b/io.c
@@ -48,6 +48,7 @@ extern int flist_eof;
extern int list_only;
extern int read_batch;
extern int csum_length;
+extern int compat_flags;
extern int protect_args;
extern int checksum_seed;
extern int protocol_version;
@@ -1901,7 +1902,7 @@ void start_write_batch(int fd)
* is involved. */
write_int(batch_fd, protocol_version);
if (protocol_version >= 30)
- write_byte(batch_fd, inc_recurse);
+ write_byte(batch_fd, compat_flags);
write_int(batch_fd, checksum_seed);
if (am_sender)