#define XATTR_ABBREV(x) ((size_t)((x).name - (x).datum) < (x).datum_len)
-#define XSTATE_ABBREV 0
-#define XSTATE_DONE 1
-#define XSTATE_TODO 2
+#define XSTATE_ABBREV 1
+#define XSTATE_DONE 2
+#define XSTATE_TODO 3
#define USER_PREFIX "user."
#define UPRE_LEN ((int)sizeof USER_PREFIX - 1)
return !xattrs_equal;
}
-/* When called by the generator with a NULL fname, this tells the sender
- * which abbreviated xattr values we need. When called by the sender
- * (with a non-NULL fname), we send all the extra xattr data it needs. */
+/* When called by the generator (with a NULL fname), this tells the sender
+ * all the abbreviated xattr values we need. When called by the sender
+ * (with a non-NULL fname), we send all the extra xattr data it needs.
+ * The generator may also call with f_out < 0 to just change all the
+ * XSTATE_ABBREV states into XSTATE_DONE. */
void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
{
item_list *lst = rsync_xal_l.items;
rxa->datum[0] = XSTATE_DONE;
continue;
case XSTATE_TODO:
+ assert(f_out >= 0);
break;
default:
continue;
}
}
- write_byte(f_out, 0); /* end the list */
+ if (f_out >= 0)
+ write_byte(f_out, 0); /* end the list */
}
/* When called by the sender, read the request from the generator and mark
who_am_i(), num, f_name(file, NULL));
exit_cleanup(RERR_STREAMIO);
}
- if (rxa->datum_len <= MAX_FULL_DATUM || rxa->datum[0] != XSTATE_ABBREV) {
- rprintf(FERROR, "[%s] internal abbrev error!\n", who_am_i());
+ if (!XATTR_ABBREV(*rxa) || rxa->datum[0] != XSTATE_ABBREV) {
+ rprintf(FERROR, "[%s] internal abbrev error on %s (%s, len=%ld)!\n",
+ who_am_i(), f_name(file, NULL), rxa->name, (long)rxa->datum_len);
exit_cleanup(RERR_STREAMIO);
}