* Copyright (C) 1996, 2000 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2003, 2004, 2005, 2006 Wayne Davison
+ * Copyright (C) 2003-2007 Wayne Davison
*
* 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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
#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 (1<<2) /* protocols 20 - 27 */
+#define XMIT_EXTENDED_FLAGS (1<<2) /* protocols 28 - NOW */
#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_RDEV_MINOR_IS_SMALL (1<<11)
+#define XMIT_SAME_RDEV_MAJOR (1<<8) /* protocols 28 - NOW */
+#define XMIT_HLINKED (1<<9) /* protocols 28 - NOW */
+#define XMIT_SAME_DEV_pre30 (1<<10) /* protocols 28 - 29 */
+#define XMIT_USER_NAME_FOLLOWS (1<<10) /* protocols 30 - NOW */
+#define XMIT_RDEV_MINOR_8_pre30 (1<<11) /* protocols 28 - 29 */
+#define XMIT_GROUP_NAME_FOLLOWS (1<<11) /* protocols 30 - NOW */
+#define XMIT_HLINK_FIRST (1<<12) /* protocols 30 - NOW */
/* These flags are used in the live flist data. */
-#define FLAG_TOP_DIR (1<<0)
-#define FLAG_SENT (1<<1) /* sender */
-#define FLAG_HLINK_EOL (1<<1) /* receiver/generator */
-#define FLAG_MOUNT_POINT (1<<2) /* sender/generator */
-#define FLAG_DEL_HERE (1<<3) /* receiver/generator */
-#define FLAG_HLINK_TOL (1<<4) /* receiver/generator */
-#define FLAG_NO_FUZZY (1<<5) /* generator */
-#define FLAG_MISSING (1<<6) /* generator */
+#define FLAG_TOP_DIR (1<<0) /* sender/receiver/generator */
+#define FLAG_FILE_SENT (1<<1) /* sender/receiver/generator */
+#define FLAG_DIR_CHANGED (1<<1) /* generator */
+#define FLAG_XFER_DIR (1<<2) /* sender/receiver/generator */
+#define FLAG_MOUNT_DIR (1<<3) /* sender/generator */
+#define FLAG_MISSING_DIR (1<<4) /* generator */
+#define FLAG_HLINKED (1<<5) /* receiver/generator */
+#define FLAG_HLINK_FIRST (1<<6) /* receiver/generator */
+#define FLAG_HLINK_LAST (1<<7) /* receiver/generator */
+#define FLAG_HLINK_DONE (1<<8) /* receiver/generator */
+#define FLAG_LENGTH64 (1<<9) /* sender/receiver/generator */
+
+/* These flags are passed to functions but not stored. */
+
+#define FLAG_DIVERT_DIRS (1<<16)/* sender */
+
+#define BITS_SET(val,bits) (((val) & (bits)) == (bits))
+#define BITS_SETnUNSET(val,onbits,offbits) (((val) & ((onbits)|(offbits))) == (onbits))
+#define BITS_EQUAL(b1,b2,mask) (((unsigned)(b1) & (unsigned)(mask)) \
+ == ((unsigned)(b2) & (unsigned)(mask)))
/* update this if you make incompatible changes */
-#define PROTOCOL_VERSION 29
+#define PROTOCOL_VERSION 30
/* We refuse to interoperate with versions that are not in this range.
* Note that we assume we'll work with later versions: the onus is on
#define OLD_PROTOCOL_VERSION 25
#define MAX_PROTOCOL_VERSION 40
+#define FILECNT_LOOKAHEAD 1000
+
#define RSYNC_PORT 873
#define SPARSE_WRITE_SIZE (1024)
enum msgcode {
MSG_DATA=0, /* raw data on the multiplexed stream */
MSG_ERROR=FERROR, MSG_INFO=FINFO, /* remote logging */
- MSG_LOG=FLOG, MSG_SOCKERR=FSOCKERR, /* sibling logging */
+ MSG_LOG=FLOG, MSG_CLIENT=FCLIENT, MSG_SOCKERR=FSOCKERR, /* sibling logging */
MSG_REDO=9, /* reprocess indicated flist index */
+ MSG_FLIST=20, /* extra file list over sibling socket */
+ MSG_FLIST_EOF=21,/* we've transmitted all the file lists */
+ MSG_IO_ERROR=22,/* the sending side had an I/O error */
+ MSG_NOOP=42, /* a do-nothing message */
MSG_SUCCESS=100,/* successfully updated indicated flist index */
MSG_DELETED=101,/* successfully deleted a file on receiving side */
+ MSG_NO_SEND=102,/* sender failed to open a file we wanted */
MSG_DONE=86 /* current phase is done */
};
+#define NDX_DONE -1
+#define NDX_FLIST_EOF -2
+#define NDX_FLIST_OFFSET -101
+
#include "errcode.h"
#include "config.h"
#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 inode;
- int64 dev;
+struct idev_node {
+ int64 key;
+ void *data;
};
#ifndef MIN
#define MAXHOSTNAMELEN 256
#endif
-/* the length of the md4 checksum */
-#define MD4_SUM_LENGTH 16
#define SUM_LENGTH 16
#define SHORT_SUM_LENGTH 2
#define BLOCKSUM_BIAS 10
#define IN_LOOPBACKNET 127
#endif
+#if HAVE_UNIXWARE_ACLS|HAVE_SOLARIS_ACLS|HAVE_HPUX_ACLS
+#define ACLS_NEED_MASK 1
+#endif
+
#define GID_NONE ((gid_t)-1)
-#define HL_CHECK_MASTER 0
-#define HL_SKIP 1
+union file_extras {
+ int32 num;
+ uint32 unum;
+};
-struct hlink {
- int32 next;
- int32 hlindex;
- unsigned short link_dest_used;
+struct file_struct {
+ 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 */
};
-#define F_DEV link_u.idev->dev
-#define F_INODE link_u.idev->inode
+extern int file_extra_cnt;
+extern int preserve_uid;
+extern int preserve_gid;
+extern int preserve_acls;
+extern int preserve_xattrs;
-#define F_HLINDEX link_u.links->hlindex
-#define F_NEXT link_u.links->next
+#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 ((MAX_DIGEST_LEN + EXTRA_LEN - 1) / EXTRA_LEN)
-struct file_struct {
- union {
- dev_t rdev; /* The device number, if this is a device */
- char *sum; /* Only a normal file can have a checksum */
- char *link; /* Points to symlink string, if a symlink */
- } u;
- OFF_T length;
- char *basename; /* The current item's name (AKA filename) */
- char *dirname; /* The directory info inside the transfer */
- union {
- char *root; /* Sender-side dir info outside transfer */
- int depth; /* Receiver-side directory depth info */
- } dir;
- union {
- struct idev *idev;
- struct hlink *links;
- } link_u;
- time_t modtime;
- uid_t uid;
- gid_t gid;
- mode_t mode;
- uchar flags; /* this item MUST remain last */
-};
+#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)
+
+/* The length applies to all items. */
+#if SIZEOF_INT64 < 8
+#define F_LENGTH(f) ((int64)(f)->len32)
+#else
+#define F_LENGTH(f) ((int64)(f)->len32 + ((f)->flags & FLAG_LENGTH64 \
+ ? (int64)OPT_EXTRA(f, 0)->unum << 32 : 0))
+#endif
+
+/* If there is a symlink string, it is always right after the basename */
+#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_OWNER(f) REQ_EXTRA(f, preserve_uid)->unum
+#define F_GROUP(f) REQ_EXTRA(f, preserve_gid)->unum
+#define F_ACL(f) REQ_EXTRA(f, preserve_acls)->num
+#define F_XATTR(f) REQ_EXTRA(f, preserve_xattrs)->num
+
+/* These items are per-entry optional and mutally exclusive: */
+#define F_HL_GNUM(f) OPT_EXTRA(f, LEN64_BUMP(f))->num
+#define F_HL_PREV(f) OPT_EXTRA(f, LEN64_BUMP(f))->num
+#define F_DEF_ACL(f) OPT_EXTRA(f, LEN64_BUMP(f))->unum
+#define F_DIRDEV_P(f) (&OPT_EXTRA(f, LEN64_BUMP(f) + 2 - 1)->unum)
+#define F_DIRNODE_P(f) (&OPT_EXTRA(f, LEN64_BUMP(f) + 3 - 1)->num)
+
+/* This optional item might follow an F_HL_*() item.
+ * (Note: a device doesn't need to check LEN64_BUMP(f).) */
+#define F_RDEV_P(f) (&OPT_EXTRA(f, HLINK_BUMP(f) + 2 - 1)->unum)
+
+/* The sum is only present on regular files. */
+#define F_SUM(f) ((const char*)OPT_EXTRA(f, LEN64_BUMP(f) + HLINK_BUMP(f) \
+ + SUM_EXTRA_CNT - 1))
+
+/* Some utility defines: */
+#define F_IS_ACTIVE(f) (f)->basename[0]
+#define F_IS_HLINKED(f) ((f)->flags & FLAG_HLINKED)
+
+#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 F_UID(f) ((uid_t)F_OWNER(f))
+#define F_GID(f) ((gid_t)F_GROUP(f))
+
+#define DEV_MAJOR(a) (a)[0]
+#define DEV_MINOR(a) (a)[1]
+
+#define DIR_PARENT(a) (a)[0]
+#define DIR_FIRST_CHILD(a) (a)[1]
+#define DIR_NEXT_SIBLING(a) (a)[2]
/*
* Start the flist array at FLIST_START entries and grow it
#define FLIST_LINEAR (FLIST_START * 512)
/*
- * Extent size for allocation pools A minimum size of 128KB
+ * Extent size for allocation pools: A minimum size of 128KB
* is needed to mmap them so that freeing will release the
* space to the OS.
*
* Larger sizes reduce leftover fragments and speed free calls
- * (when they happen) Smaller sizes increase the chance of
+ * (when they happen). Smaller sizes increase the chance of
* freed allocations freeing whole extents.
*/
#define FILE_EXTENT (256 * 1024)
#define HLINK_EXTENT (128 * 1024)
-#define WITH_HLINK 1
-#define WITHOUT_HLINK 0
+#define FLIST_TEMP (1<<1)
struct file_list {
+ struct file_list *next, *prev;
struct file_struct **files;
alloc_pool_t file_pool;
- alloc_pool_t hlink_pool;
- int count;
- int malloced;
- int low, high;
+ int count, malloced;
+ int low, high; /* 0-relative index values excluding empties */
+ int ndx_start; /* the start offset for inc_recurse mode */
+ int parent_ndx; /* dir_flist index of parent directory */
+ int in_progress, to_redo;
};
#define SUMFLG_SAME_OFFSET (1<<0)
#define MATCHFLG_SENDER_SIDE (1<<16)/* rule applies to the sending side */
#define MATCHFLG_RECEIVER_SIDE (1<<17)/* rule applies to the receiving side */
#define MATCHFLG_CLEAR_LIST (1<<18)/* this item is the "!" token */
+#define MATCHFLG_PERISHABLE (1<<19)/* perishable if parent dir goes away */
#define MATCHFLGS_FROM_CONTAINER (MATCHFLG_ABS_PATH | MATCHFLG_INCLUDE \
| MATCHFLG_DIRECTORY | MATCHFLG_SENDER_SIDE \
- | MATCHFLG_NEGATE | MATCHFLG_RECEIVER_SIDE)
+ | MATCHFLG_NEGATE | MATCHFLG_RECEIVER_SIDE \
+ | MATCHFLG_PERISHABLE)
struct filter_struct {
struct filter_struct *next;
int64 matched_data;
int64 flist_buildtime;
int64 flist_xfertime;
- int flist_size;
+ int64 flist_size;
int num_files;
int num_transferred_files;
int current_file_index;
struct chmod_mode_struct;
+#define EMPTY_ITEM_LIST {NULL, 0, 0}
+
+typedef struct {
+ void *items;
+ size_t count;
+ size_t malloced;
+} item_list;
+
+#define EXPAND_ITEM_LIST(lp, type, incr) \
+ (type*)expand_item_list(lp, sizeof (type), #type, incr)
+
#include "byteorder.h"
-#include "lib/mdfour.h"
+#include "lib/mdigest.h"
#include "lib/wildmatch.h"
#include "lib/permstring.h"
#include "lib/addrinfo.h"
#ifndef __GNUC__
#define __attribute__(x)
+#else
+# if __GNUC__ <= 2
+# define NORETURN
+# endif
#endif
#define UNUSED(x) x __attribute__((__unused__))
+#ifndef NORETURN
#define NORETURN __attribute__((__noreturn__))
+#endif
+
+typedef struct {
+ STRUCT_STAT st;
+#ifdef SUPPORT_ACLS
+ struct rsync_acl *acc_acl; /* access ACL */
+ struct rsync_acl *def_acl; /* default ACL */
+#endif
+#ifdef SUPPORT_XATTRS
+ item_list *xattr;
+#endif
+} statx;
+
+#define ACL_READY(sx) ((sx).acc_acl != NULL)
+#define XATTR_READY(sx) ((sx).xattr != NULL)
#include "proto.h"
#if !defined HAVE_SNPRINTF || !defined HAVE_C99_VSNPRINTF
#define snprintf rsync_snprintf
-int snprintf(char *str,size_t count,const char *fmt,...);
+int snprintf(char *str, size_t count, const char *fmt,...);
#endif