X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/c7565dad84795355e9e4422a207c1a2acf22b5a4..16edf86595a5a990a942fa045dfb523dae1fe6cb:/rsync.h diff --git a/rsync.h b/rsync.h index 7faffccb..6b25e6c2 100644 --- a/rsync.h +++ b/rsync.h @@ -2,12 +2,11 @@ * Copyright (C) 1996, 2000 Andrew Tridgell * Copyright (C) 1996 Paul Mackerras * Copyright (C) 2001, 2002 Martin Pool - * 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 @@ -43,22 +42,26 @@ #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_HLINKED (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) /* sender/receiver/generator */ -#define FLAG_SENT (1<<1) /* sender/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 */ @@ -68,6 +71,10 @@ #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)) \ @@ -97,6 +104,8 @@ #define OLD_PROTOCOL_VERSION 25 #define MAX_PROTOCOL_VERSION 40 +#define FILECNT_LOOKAHEAD 1000 + #define RSYNC_PORT 873 #define SPARSE_WRITE_SIZE (1024) @@ -178,12 +187,19 @@ enum msgcode { MSG_ERROR=FERROR, MSG_INFO=FINFO, /* remote 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" @@ -215,6 +231,9 @@ enum msgcode { #ifdef HAVE_STRINGS_H # include #endif +#ifdef HAVE_INTTYPES_H +# include +#endif #ifdef HAVE_UNISTD_H # include #endif @@ -354,11 +373,30 @@ enum msgcode { #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 @@ -381,7 +419,11 @@ enum msgcode { #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 @@ -399,7 +441,10 @@ enum msgcode { * 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 @@ -455,9 +500,9 @@ enum msgcode { * where dev_t is a struct. */ -struct idev { - int64 ino; - int64 dev; +struct idev_node { + int64 key; + void *data; }; #ifndef MIN @@ -472,8 +517,6 @@ struct idev { #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 @@ -502,44 +545,44 @@ struct idev { #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) +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; +extern int preserve_acls; +extern int preserve_xattrs; -#define FILE_STRUCT_LEN (offsetof(struct file_struct, flags) \ - + sizeof (unsigned short)) -#define EXTRA_LEN (sizeof (union flist_extras)) -#define SUM_EXTRA_CNT ((MD4_SUM_LENGTH + EXTRA_LEN - 1) / EXTRA_LEN) +#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) -#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 @@ -548,15 +591,26 @@ extern int preserve_gid; #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_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_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 +#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).) */ @@ -567,14 +621,22 @@ extern int preserve_gid; + 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_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 * by doubling until FLIST_LINEAR then grow by FLIST_LINEAR @@ -594,11 +656,17 @@ extern int preserve_gid; #define FILE_EXTENT (256 * 1024) #define HLINK_EXTENT (128 * 1024) +#define FLIST_TEMP (1<<1) + struct file_list { + struct file_list *next, *prev; struct file_struct **files; alloc_pool_t file_pool; 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) @@ -692,8 +760,19 @@ struct stats { 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" @@ -710,6 +789,20 @@ struct chmod_mode_struct; #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" /* We have replacement versions of these if they're missing. */