- static mode_t last_mode=0;
- static dev_t last_dev=0;
- static uid_t last_uid=0;
- static gid_t last_gid=0;
- static char lastdir[MAXPATHLEN]="";
- char *p=NULL;
- int l1,l2;
-
- if (flags & SAME_DIR) {
- l1 = read_byte(f);
- l2 = strlen(lastdir);
- } else {
- l1 = read_int(f);
- l2 = 0;
- }
-
- file->name = (char *)malloc(l1+l2+1);
- if (!file->name) out_of_memory("receive_file_entry");
-
- strncpy(file->name,lastdir,l2);
- read_buf(f,file->name+l2,l1);
- file->name[l1+l2] = 0;
-
- file->modtime = (time_t)read_int(f);
- file->length = (off_t)read_int(f);
- file->mode = (flags & SAME_MODE) ? last_mode : (mode_t)read_int(f);
- if (preserve_uid)
- file->uid = (flags & SAME_UID) ? last_uid : (uid_t)read_int(f);
- if (preserve_gid)
- file->gid = (flags & SAME_GID) ? last_gid : (gid_t)read_int(f);
- if (preserve_devices && IS_DEVICE(file->mode))
- file->dev = (flags & SAME_DEV) ? last_dev : (dev_t)read_int(f);
-
-#if SUPPORT_LINKS
- if (preserve_links && S_ISLNK(file->mode)) {
- int l = read_int(f);
- file->link = (char *)malloc(l+1);
- if (!file->link) out_of_memory("receive_file_entry");
- read_buf(f,file->link,l);
- file->link[l] = 0;
- }
-#endif
-
- if (always_checksum)
- read_buf(f,file->sum,csum_length);
-
- last_mode = file->mode;
- last_dev = file->dev;
- last_uid = file->uid;
- last_gid = file->gid;
- p = strrchr(file->name,'/');
- if (p) {
- int l = (int)(p - file->name) + 1;
- strncpy(lastdir,file->name,l);
- lastdir[l] = 0;
- } else {
- strcpy(lastdir,"");
- }
+ if (am_sender)
+ file_extra_cnt += PTR_EXTRA_LEN;
+ else
+ file_extra_cnt++;
+ if (preserve_uid)
+ preserve_uid = ++file_extra_cnt;
+ if (preserve_gid)
+ preserve_gid = ++file_extra_cnt;
+ if (preserve_acls && !am_sender)
+ preserve_acls = ++file_extra_cnt;
+ if (preserve_xattrs)
+ preserve_xattrs = ++file_extra_cnt;
+
+ if (remote_protocol == 0) {
+ if (am_server && !local_server)
+ check_sub_protocol();
+ if (!read_batch)
+ write_int(f_out, protocol_version);
+ remote_protocol = read_int(f_in);
+ if (protocol_version > remote_protocol)
+ protocol_version = remote_protocol;
+ }
+ if (read_batch && remote_protocol > protocol_version) {
+ rprintf(FERROR, "The protocol version in the batch file is too new (%d > %d).\n",
+ remote_protocol, protocol_version);
+ exit_cleanup(RERR_PROTOCOL);
+ }
+
+ if (verbose > 3) {
+ rprintf(FINFO, "(%s) Protocol versions: remote=%d, negotiated=%d\n",
+ am_server? "Server" : "Client", remote_protocol, protocol_version);
+ }
+ if (remote_protocol < MIN_PROTOCOL_VERSION
+ || remote_protocol > MAX_PROTOCOL_VERSION) {
+ rprintf(FERROR,"protocol version mismatch -- is your shell clean?\n");
+ rprintf(FERROR,"(see the rsync man page for an explanation)\n");
+ exit_cleanup(RERR_PROTOCOL);
+ }
+ if (remote_protocol < OLD_PROTOCOL_VERSION) {
+ rprintf(FINFO,"%s is very old version of rsync, upgrade recommended.\n",
+ am_server? "Client" : "Server");
+ }
+ if (protocol_version < MIN_PROTOCOL_VERSION) {
+ rprintf(FERROR, "--protocol must be at least %d on the %s.\n",
+ MIN_PROTOCOL_VERSION, am_server? "Server" : "Client");
+ exit_cleanup(RERR_PROTOCOL);
+ }
+ if (protocol_version > PROTOCOL_VERSION) {
+ rprintf(FERROR, "--protocol must be no more than %d on the %s.\n",
+ PROTOCOL_VERSION, am_server? "Server" : "Client");
+ exit_cleanup(RERR_PROTOCOL);
+ }
+
+ if (protocol_version < 30) {
+ if (max_delete == 0 && am_sender) {
+ rprintf(FERROR,
+ "--max-delete=0 requires protocol 30 or higher"
+ " (negotiated %d).\n",
+ protocol_version);
+ exit_cleanup(RERR_PROTOCOL);
+ }
+ if (preserve_acls && !local_server) {
+ rprintf(FERROR,
+ "--acls requires protocol 30 or higher"
+ " (negotiated %d).\n",
+ protocol_version);
+ exit_cleanup(RERR_PROTOCOL);
+ }
+ if (preserve_xattrs && !local_server) {
+ rprintf(FERROR,
+ "--xattrs requires protocol 30 or higher"
+ " (negotiated %d).\n",
+ protocol_version);
+ exit_cleanup(RERR_PROTOCOL);
+ }
+ }
+
+ if (delete_mode && !(delete_before+delete_during+delete_after)) {
+ if (protocol_version < 30)
+ delete_before = 1;
+ else
+ delete_during = 1;
+ }
+
+ if (protocol_version < 29) {
+ if (fuzzy_basis) {
+ rprintf(FERROR,
+ "--fuzzy requires protocol 29 or higher"
+ " (negotiated %d).\n",
+ protocol_version);
+ exit_cleanup(RERR_PROTOCOL);
+ }
+
+ if (basis_dir_cnt && inplace) {
+ rprintf(FERROR,
+ "%s with --inplace requires protocol 29 or higher"
+ " (negotiated %d).\n",
+ dest_option, protocol_version);
+ exit_cleanup(RERR_PROTOCOL);
+ }
+
+ if (basis_dir_cnt > 1) {
+ rprintf(FERROR,
+ "Using more than one %s option requires protocol"
+ " 29 or higher (negotiated %d).\n",
+ dest_option, protocol_version);
+ exit_cleanup(RERR_PROTOCOL);
+ }
+
+ if (prune_empty_dirs) {
+ rprintf(FERROR,
+ "--prune-empty-dirs requires protocol 29 or higher"
+ " (negotiated %d).\n",
+ protocol_version);
+ exit_cleanup(RERR_PROTOCOL);
+ }
+ } else if (protocol_version >= 30) {
+ if (recurse && allow_inc_recurse && !preserve_hard_links
+ && !delete_before && !delete_after && !delay_updates
+ && !prune_empty_dirs)
+ inc_recurse = 1;
+ need_messages_from_generator = 1;
+ }
+
+ if (partial_dir && *partial_dir != '/' && (!am_server || local_server)) {
+ int flags = MATCHFLG_NO_PREFIXES | MATCHFLG_DIRECTORY;
+ if (!am_sender || protocol_version >= 30)
+ flags |= MATCHFLG_PERISHABLE;
+ parse_rule(&filter_list, partial_dir, flags, 0);
+ }
+
+ if (am_server) {
+ if (!checksum_seed)
+ checksum_seed = time(NULL);
+ write_int(f_out, checksum_seed);
+ } else {
+ checksum_seed = read_int(f_in);
+ }