#define XMIT_TOP_DIR (1<<0)
#define XMIT_SAME_MODE (1<<1)
#define XMIT_EXTENDED_FLAGS (1<<2)
-#define XMIT_SAME_RDEV_pre28 XMIT_EXTENDED_FLAGS /* Only in protocols < 28 */
+#define XMIT_SAME_RDEV_pre28 XMIT_EXTENDED_FLAGS /* protocols < 28 */
#define XMIT_SAME_UID (1<<3)
#define XMIT_SAME_GID (1<<4)
#define XMIT_SAME_NAME (1<<5)
#define XMIT_LONG_NAME (1<<6)
#define XMIT_SAME_TIME (1<<7)
#define XMIT_SAME_RDEV_MAJOR (1<<8)
-#define XMIT_HAS_IDEV_DATA (1<<9)
-#define XMIT_SAME_DEV (1<<10)
+#define XMIT_HLINKED (1<<9)
+#define XMIT_SAME_DEV_pre30 (1<<10) /* protocols < 30 */
+#define XMIT_HLINK_FIRST (1<<10) /* protocols >= 30 */
#define XMIT_RDEV_MINOR_IS_SMALL (1<<11)
/* These flags are used in the live flist data. */
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#define schar char
#endif
+#ifndef int16
+#if SIZEOF_INT16_T == 2
+# define int16 int16_t
+#else
+# define int16 short
+#endif
+#endif
+
+#ifndef uint16
+#if SIZEOF_UINT16_T == 2
+# define uint16 uint16_t
+#else
+# define uint16 unsigned int16
+#endif
+#endif
+
/* Find a variable that is either exactly 32-bits or longer.
* If some code depends on 32-bit truncation, it will need to
* take special action in a "#if SIZEOF_INT32 > 4" section. */
#ifndef int32
-#if SIZEOF_INT == 4
+#if SIZEOF_INT32_T == 4
+# define int32 int32_t
+# define SIZEOF_INT32 4
+#elif SIZEOF_INT == 4
# define int32 int
# define SIZEOF_INT32 4
#elif SIZEOF_LONG == 4
#endif
#ifndef uint32
-#define uint32 unsigned int32
+#if SIZEOF_UINT32_T == 4
+# define uint32 uint32_t
+#else
+# define uint32 unsigned int32
+#endif
#endif
#if SIZEOF_OFF_T == 8 || !SIZEOF_OFF64_T || !defined HAVE_STRUCT_STAT64
* to ensure that any code that really requires a 64-bit integer has
* it (e.g. the checksum code uses two 32-bit integers for its 64-bit
* counter). */
-#if SIZEOF_LONG == 8
+#if SIZEOF_INT64_T == 8
+# define int64 int64_t
+# define SIZEOF_INT64 8
+#elif SIZEOF_LONG == 8
# define int64 long
# define SIZEOF_INT64 8
#elif SIZEOF_INT == 8
* where dev_t is a struct.
*/
-struct idev {
- int64 ino;
- int64 dev;
+struct idev_node {
+ int64 key;
+ void *data;
};
#ifndef MIN
#define GID_NONE ((gid_t)-1)
+union file_extras {
+ int32 num;
+ uint32 unum;
+};
+
struct file_struct {
- union flist_extras {
- uid_t uid; /* The user ID number */
- uid_t gid; /* The group ID number or GID_NONE */
- struct idev *idev; /* The hard-link info during matching */
- int32 num; /* A signed number */
- uint32 unum; /* An unsigned number */
- } extras[1];
- time_t modtime; /* When the item was last modified */
- const char *dirname; /* The dir info inside the transfer */
- union {
- const char *root; /* Sender-side dir info outside transfer */
- int32 depth; /* Receiver-side directory depth info */
- } dir;
- uint32 len32; /* Lowest 32 bits of the file's length */
- unsigned short mode; /* The item's type and permissions */
- unsigned short flags; /* This item MUST remain last! */
+ const char *dirname; /* The dir info inside the transfer */
+ time_t modtime; /* When the item was last modified */
+ uint32 len32; /* Lowest 32 bits of the file's length */
+ uint16 mode; /* The item's type and permissions */
+ uint16 flags; /* The FLAG_* bits for this item */
+ const char basename[1]; /* The basename (AKA filename) follows */
};
-extern int flist_extra_cnt;
+extern int file_extra_cnt;
extern int preserve_uid;
extern int preserve_gid;
-#define FILE_STRUCT_LEN (offsetof(struct file_struct, flags) \
- + sizeof (unsigned short))
-#define EXTRA_LEN (sizeof (union flist_extras))
+#define FILE_STRUCT_LEN (offsetof(struct file_struct, basename))
+#define EXTRA_LEN (sizeof (union file_extras))
+#define PTR_EXTRA_LEN ((sizeof (char *) + EXTRA_LEN - 1) / EXTRA_LEN)
#define SUM_EXTRA_CNT ((MD4_SUM_LENGTH + EXTRA_LEN - 1) / EXTRA_LEN)
-#define REQ_EXTRA(f,ndx) ((f)->extras - (ndx - 1))
-#define OPT_EXTRA(f,bump) ((f)->extras - flist_extra_cnt - (bump))
+#define REQ_EXTRA(f,ndx) ((union file_extras*)(f) - (ndx))
+#define OPT_EXTRA(f,bump) ((union file_extras*)(f) - file_extra_cnt - 1 - (bump))
#define LEN64_BUMP(f) ((f)->flags & FLAG_LENGTH64 ? 1 : 0)
#define HLINK_BUMP(f) (F_IS_HLINKED(f) ? 1 : 0)
-/* Basename (AKA filename) and length applies to all items */
-#define F_BASENAME(f) ((const char*)(f) + FILE_STRUCT_LEN)
+/* The length applies to all items. */
#if SIZEOF_INT64 < 8
#define F_LENGTH(f) ((int64)(f)->len32)
#else
#endif
/* If there is a symlink string, it is always right after the basename */
-#define F_SYMLINK(f) (F_BASENAME(f) + strlen(F_BASENAME(f)) + 1)
+#define F_SYMLINK(f) ((f)->basename + strlen((f)->basename) + 1)
+
+/* The sending side always has this available: */
+#define F_ROOTDIR(f) (*(const char**)REQ_EXTRA(f, PTR_EXTRA_LEN))
+
+/* The receiving side always has this available: */
+#define F_DEPTH(f) REQ_EXTRA(f, 1)->num
/* When the associated option is on, all entries will have these present: */
-#define F_UID(f) REQ_EXTRA(f, preserve_uid)->uid
-#define F_GID(f) REQ_EXTRA(f, preserve_gid)->gid
+#define F_UID(f) REQ_EXTRA(f, preserve_uid)->unum
+#define F_GID(f) REQ_EXTRA(f, preserve_gid)->unum
/* These items are per-entry optional and mutally exclusive: */
-#define F_HL_IDEV(f) OPT_EXTRA(f, LEN64_BUMP(f))->idev
+#define F_HL_GNUM(f) OPT_EXTRA(f, LEN64_BUMP(f))->num
#define F_HL_PREV(f) OPT_EXTRA(f, LEN64_BUMP(f))->num
/* This optional item might follow an F_HL_*() item.
+ SUM_EXTRA_CNT - 1))
/* Some utility defines: */
-#define F_IS_ACTIVE(f) F_BASENAME(f)[0]
+#define F_IS_ACTIVE(f) (f)->basename[0]
#define F_IS_HLINKED(f) ((f)->flags & FLAG_HLINKED)
-#define F_NOT_HLINK_FIRST(f) BITS_SETnUNSET((f)->flags, FLAG_HLINKED, FLAG_HLINK_FIRST)
-#define F_NOT_HLINK_LAST(f) BITS_SETnUNSET((f)->flags, FLAG_HLINKED, FLAG_HLINK_LAST)
+#define F_HLINK_NOT_FIRST(f) BITS_SETnUNSET((f)->flags, FLAG_HLINKED, FLAG_HLINK_FIRST)
+#define F_HLINK_NOT_LAST(f) BITS_SETnUNSET((f)->flags, FLAG_HLINKED, FLAG_HLINK_LAST)
#define DEV_MAJOR(a) (a)[0]
#define DEV_MINOR(a) (a)[1]