Diff for /embedaddon/rsync/sender.c between versions 1.1 and 1.1.1.4

version 1.1, 2012/02/17 15:09:30 version 1.1.1.4, 2021/03/17 00:32:36
Line 3 Line 3
  *   *
  * Copyright (C) 1996 Andrew Tridgell   * Copyright (C) 1996 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras   * Copyright (C) 1996 Paul Mackerras
 * Copyright (C) 2003-2009 Wayne Davison * Copyright (C) 2003-2020 Wayne Davison
  *   *
  * This program is free software; you can redistribute it and/or modify   * 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   * it under the terms of the GNU General Public License as published by
Line 20 Line 20
  */   */
   
 #include "rsync.h"  #include "rsync.h"
   #include "inums.h"
   #include "ifuncs.h"
   
 extern int verbose;  
 extern int do_xfers;  extern int do_xfers;
 extern int am_server;  extern int am_server;
 extern int am_daemon;  extern int am_daemon;
Line 29  extern int inc_recurse; Line 30  extern int inc_recurse;
 extern int log_before_transfer;  extern int log_before_transfer;
 extern int stdout_format_has_i;  extern int stdout_format_has_i;
 extern int logfile_format_has_i;  extern int logfile_format_has_i;
   extern int want_xattr_optim;
 extern int csum_length;  extern int csum_length;
 extern int append_mode;  extern int append_mode;
   extern int copy_links;
 extern int io_error;  extern int io_error;
   extern int flist_eof;
 extern int allowed_lull;  extern int allowed_lull;
 extern int preserve_xattrs;  extern int preserve_xattrs;
 extern int protocol_version;  extern int protocol_version;
 extern int remove_source_files;  extern int remove_source_files;
 extern int updating_basis_file;  extern int updating_basis_file;
 extern int make_backups;  extern int make_backups;
extern int do_progress;extern int make_source_backups;
 extern int inplace;  extern int inplace;
   extern int inplace_partial;
 extern int batch_fd;  extern int batch_fd;
 extern int write_batch;  extern int write_batch;
   extern int file_old_total;
   extern BOOL want_progress_now;
   extern char *source_filter;
 extern struct stats stats;  extern struct stats stats;
 extern struct file_list *cur_flist, *first_flist, *dir_flist;  extern struct file_list *cur_flist, *first_flist, *dir_flist;
   
   BOOL extra_flist_sending_enabled;
   
 /**  /**
  * @file   * @file
  *   *
Line 58  extern struct file_list *cur_flist, *first_flist, *dir Line 68  extern struct file_list *cur_flist, *first_flist, *dir
  **/   **/
 static struct sum_struct *receive_sums(int f)  static struct sum_struct *receive_sums(int f)
 {  {
        struct sum_struct *s;        struct sum_struct *s = new(struct sum_struct);
        int32 i;        int lull_mod = protocol_version >= 31 ? 0 : allowed_lull * 5;
        int lull_mod = allowed_lull * 5; 
         OFF_T offset = 0;          OFF_T offset = 0;
           int32 i;
   
         if (!(s = new(struct sum_struct)))  
                 out_of_memory("receive_sums");  
   
         read_sum_head(f, s);          read_sum_head(f, s);
   
         s->sums = NULL;          s->sums = NULL;
   
        if (verbose > 3) {        if (DEBUG_GTE(DELTASUM, 3)) {
                rprintf(FINFO, "count=%.0f n=%ld rem=%ld\n",                rprintf(FINFO, "count=%s n=%ld rem=%ld\n",
                        (double)s->count, (long)s->blength, (long)s->remainder);                        big_num(s->count), (long)s->blength, (long)s->remainder);
         }          }
   
         if (append_mode > 0) {          if (append_mode > 0) {
Line 85  static struct sum_struct *receive_sums(int f) Line 92  static struct sum_struct *receive_sums(int f)
         if (s->count == 0)          if (s->count == 0)
                 return(s);                  return(s);
   
        if (!(s->sums = new_array(struct sum_buf, s->count)))        s->sums = new_array(struct sum_buf, s->count);
                out_of_memory("receive_sums"); 
   
         for (i = 0; i < s->count; i++) {          for (i = 0; i < s->count; i++) {
                 s->sums[i].sum1 = read_int(f);                  s->sums[i].sum1 = read_int(f);
Line 101  static struct sum_struct *receive_sums(int f) Line 107  static struct sum_struct *receive_sums(int f)
                         s->sums[i].len = s->blength;                          s->sums[i].len = s->blength;
                 offset += s->sums[i].len;                  offset += s->sums[i].len;
   
                if (allowed_lull && !(i % lull_mod))                if (lull_mod && !(i % lull_mod))
                        maybe_send_keepalive();                        maybe_send_keepalive(time(NULL), True);
   
                if (verbose > 3) {                if (DEBUG_GTE(DELTASUM, 3)) {
                         rprintf(FINFO,                          rprintf(FINFO,
                                "chunk[%d] len=%d offset=%.0f sum1=%08x\n",                                "chunk[%d] len=%d offset=%s sum1=%08x\n",
                                i, s->sums[i].len, (double)s->sums[i].offset,                                i, s->sums[i].len, big_num(s->sums[i].offset),
                                 s->sums[i].sum1);                                  s->sums[i].sum1);
                 }                  }
         }          }
Line 120  static struct sum_struct *receive_sums(int f) Line 126  static struct sum_struct *receive_sums(int f)
 void successful_send(int ndx)  void successful_send(int ndx)
 {  {
         char fname[MAXPATHLEN];          char fname[MAXPATHLEN];
           char *failed_op;
         struct file_struct *file;          struct file_struct *file;
         struct file_list *flist;          struct file_list *flist;
           STRUCT_STAT st;
           int result;
   
         if (!remove_source_files)          if (!remove_source_files)
                 return;                  return;
Line 132  void successful_send(int ndx) Line 141  void successful_send(int ndx)
                 return;                  return;
         f_name(file, fname);          f_name(file, fname);
   
        if (do_unlink(fname) == 0) {        if ((copy_links ? do_stat(fname, &st) : do_lstat(fname, &st)) < 0) {
                if (verbose > 1)                failed_op = "re-lstat";
                 goto failed;
         }
 
         if (st.st_size != F_LENGTH(file) || st.st_mtime != file->modtime
 #ifdef ST_MTIME_NSEC
          || (NSEC_BUMP(file) && (uint32)st.ST_MTIME_NSEC != F_MOD_NSEC(file))
 #endif
         ) {
                 rprintf(FERROR_XFER, "ERROR: Skipping sender remove for changed file: %s\n", fname);
                 return;
         }
 
         if (make_source_backups)
                 result = !make_backup(fname, True);
         else
                 result = do_unlink(fname);
         if (result < 0) {
                 failed_op = "remove";
           failed:
                 if (errno == ENOENT)
                         rprintf(FINFO, "sender file already removed: %s\n", fname);
                 else
                         rsyserr(FERROR_XFER, errno, "sender failed to %s %s", failed_op, fname);
         } else {
                 if (INFO_GTE(REMOVE, 1))
                         rprintf(FINFO, "sender removed %s\n", fname);                          rprintf(FINFO, "sender removed %s\n", fname);
        } else        }
                rsyserr(FERROR, errno, "sender failed to remove %s", fname); 
 }  }
   
 static void write_ndx_and_attrs(int f_out, int ndx, int iflags,  static void write_ndx_and_attrs(int f_out, int ndx, int iflags,
Line 152  static void write_ndx_and_attrs(int f_out, int ndx, in Line 185  static void write_ndx_and_attrs(int f_out, int ndx, in
         if (iflags & ITEM_XNAME_FOLLOWS)          if (iflags & ITEM_XNAME_FOLLOWS)
                 write_vstring(f_out, buf, len);                  write_vstring(f_out, buf, len);
 #ifdef SUPPORT_XATTRS  #ifdef SUPPORT_XATTRS
        if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers)        if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers
          && !(want_xattr_optim && BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE)))
                 send_xattr_request(fname, file, f_out);                  send_xattr_request(fname, file, f_out);
 #endif  #endif
 }  }
Line 169  void send_files(int f_in, int f_out) Line 203  void send_files(int f_in, int f_out)
         int iflags, xlen;          int iflags, xlen;
         struct file_struct *file;          struct file_struct *file;
         int phase = 0, max_phase = protocol_version >= 29 ? 2 : 1;          int phase = 0, max_phase = protocol_version >= 29 ? 2 : 1;
         struct stats initial_stats;  
         int itemizing = am_server ? logfile_format_has_i : stdout_format_has_i;          int itemizing = am_server ? logfile_format_has_i : stdout_format_has_i;
         enum logcode log_code = log_before_transfer ? FLOG : FINFO;          enum logcode log_code = log_before_transfer ? FLOG : FINFO;
         int f_xfer = write_batch < 0 ? batch_fd : f_out;          int f_xfer = write_batch < 0 ? batch_fd : f_out;
         int save_io_error = io_error;          int save_io_error = io_error;
         int ndx, j;          int ndx, j;
           char *filter_argv[MAX_FILTER_ARGS + 1];
           char *tmp = 0;
           int unlink_tmp = 0;
   
        if (verbose > 2)        if (source_filter) {
                 char *p;
                 char *sep = " \t";
                 int i;
                 for (p = strtok(source_filter, sep), i = 0;
                      p && i < MAX_FILTER_ARGS;
                      p = strtok(0, sep))
                         filter_argv[i++] = p;
                 filter_argv[i] = NULL;
                 if (p) {
                         rprintf(FERROR,
                                 "Too many arguments to source-filter (> %d)\n",
                                 MAX_FILTER_ARGS);
                         exit_cleanup(RERR_SYNTAX);
                 }
         }
 
         if (DEBUG_GTE(SEND, 1))
                 rprintf(FINFO, "send_files starting\n");                  rprintf(FINFO, "send_files starting\n");
   
           progress_init();
   
         while (1) {          while (1) {
                if (inc_recurse)                if (inc_recurse) {
                        send_extra_file_list(f_out, FILECNT_LOOKAHEAD);                        send_extra_file_list(f_out, MIN_FILECNT_LOOKAHEAD);
                         extra_flist_sending_enabled = !flist_eof;
                 }
   
                 /* This call also sets cur_flist. */                  /* This call also sets cur_flist. */
                ndx = read_ndx_and_attrs(f_in, &iflags, &fnamecmp_type,                ndx = read_ndx_and_attrs(f_in, f_out, &iflags, &fnamecmp_type,
                                          xname, &xlen);                                           xname, &xlen);
                   extra_flist_sending_enabled = False;
   
                 if (ndx == NDX_DONE) {                  if (ndx == NDX_DONE) {
                           if (!am_server && cur_flist) {
                                   set_current_file_index(NULL, 0);
                                   if (INFO_GTE(PROGRESS, 2))
                                           end_progress(0);
                           }
                         if (inc_recurse && first_flist) {                          if (inc_recurse && first_flist) {
                                   file_old_total -= first_flist->used;
                                 flist_free(first_flist);                                  flist_free(first_flist);
                                 if (first_flist) {                                  if (first_flist) {
                                           if (first_flist == cur_flist)
                                                   file_old_total = cur_flist->used;
                                         write_ndx(f_out, NDX_DONE);                                          write_ndx(f_out, NDX_DONE);
                                         continue;                                          continue;
                                 }                                  }
                         }                          }
                         if (++phase > max_phase)                          if (++phase > max_phase)
                                 break;                                  break;
                        if (verbose > 2)                        if (DEBUG_GTE(SEND, 1))
                                 rprintf(FINFO, "send_files phase=%d\n", phase);                                  rprintf(FINFO, "send_files phase=%d\n", phase);
                         write_ndx(f_out, NDX_DONE);                          write_ndx(f_out, NDX_DONE);
                         continue;                          continue;
                 }                  }
   
                 if (inc_recurse)                  if (inc_recurse)
                        send_extra_file_list(f_out, FILECNT_LOOKAHEAD);                        send_extra_file_list(f_out, MIN_FILECNT_LOOKAHEAD);
   
                 if (ndx - cur_flist->ndx_start >= 0)                  if (ndx - cur_flist->ndx_start >= 0)
                         file = cur_flist->files[ndx - cur_flist->ndx_start];                          file = cur_flist->files[ndx - cur_flist->ndx_start];
Line 219  void send_files(int f_in, int f_out) Line 286  void send_files(int f_in, int f_out)
                         continue;                          continue;
                 f_name(file, fname);                  f_name(file, fname);
   
                if (verbose > 2)                if (DEBUG_GTE(SEND, 1))
                         rprintf(FINFO, "send_files(%d, %s%s%s)\n", ndx, path,slash,fname);                          rprintf(FINFO, "send_files(%d, %s%s%s)\n", ndx, path,slash,fname);
   
 #ifdef SUPPORT_XATTRS  #ifdef SUPPORT_XATTRS
                if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers)                if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers
                  && !(want_xattr_optim && BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE)))
                         recv_xattr_request(file, f_in);                          recv_xattr_request(file, f_in);
 #endif  #endif
   
                 if (!(iflags & ITEM_TRANSFER)) {                  if (!(iflags & ITEM_TRANSFER)) {
                         maybe_log_item(file, iflags, itemizing, xname);                          maybe_log_item(file, iflags, itemizing, xname);
                        write_ndx_and_attrs(f_out, ndx, iflags, fname, file,                        write_ndx_and_attrs(f_out, ndx, iflags, fname, file, fnamecmp_type, xname, xlen);
                                            fnamecmp_type, xname, xlen);                        if (iflags & ITEM_IS_NEW) {
                                 stats.created_files++;
                                 if (S_ISREG(file->mode)) {
                                         /* Nothing further to count. */
                                 } else if (S_ISDIR(file->mode))
                                         stats.created_dirs++;
 #ifdef SUPPORT_LINKS
                                 else if (S_ISLNK(file->mode))
                                         stats.created_symlinks++;
 #endif
                                 else if (IS_DEVICE(file->mode))
                                         stats.created_devices++;
                                 else
                                         stats.created_specials++;
                         }
                         continue;                          continue;
                 }                  }
                 if (phase == 2) {                  if (phase == 2) {
Line 254  void send_files(int f_in, int f_out) Line 336  void send_files(int f_in, int f_out)
                                 append_mode = -append_mode;                                  append_mode = -append_mode;
                                 csum_length = SHORT_SUM_LENGTH;                                  csum_length = SHORT_SUM_LENGTH;
                         }                          }
                           if (iflags & ITEM_IS_NEW)
                                   stats.created_files++;
                 }                  }
   
                updating_basis_file = inplace && (protocol_version >= 29                updating_basis_file = (inplace_partial && fnamecmp_type == FNAMECMP_PARTIAL_DIR)
                        ? fnamecmp_type == FNAMECMP_FNAME : make_backups <= 0);                    || (inplace && (protocol_version >= 29 ? fnamecmp_type == FNAMECMP_FNAME : make_backups <= 0));
   
                if (!am_server && do_progress)                if (!am_server)
                         set_current_file_index(file, ndx);                          set_current_file_index(file, ndx);
                stats.num_transferred_files++;                stats.xferred_files++;
                 stats.total_transferred_size += F_LENGTH(file);                  stats.total_transferred_size += F_LENGTH(file);
   
                   remember_initial_stats();
   
                 if (!do_xfers) { /* log the transfer */                  if (!do_xfers) { /* log the transfer */
                        log_item(FCLIENT, file, &stats, iflags, NULL);                        log_item(FCLIENT, file, iflags, NULL);
                        write_ndx_and_attrs(f_out, ndx, iflags, fname, file,                        write_ndx_and_attrs(f_out, ndx, iflags, fname, file, fnamecmp_type, xname, xlen);
                                            fnamecmp_type, xname, xlen); 
                         continue;                          continue;
                 }                  }
   
                 initial_stats = stats;  
   
                 if (!(s = receive_sums(f_in))) {                  if (!(s = receive_sums(f_in))) {
                         io_error |= IOERR_GENERAL;                          io_error |= IOERR_GENERAL;
                         rprintf(FERROR_XFER, "receive_sums failed\n");                          rprintf(FERROR_XFER, "receive_sums failed\n");
                         exit_cleanup(RERR_PROTOCOL);                          exit_cleanup(RERR_PROTOCOL);
                 }                  }
   
                   unlink_tmp = 0;
                 fd = do_open(fname, O_RDONLY, 0);                  fd = do_open(fname, O_RDONLY, 0);
                 if (fd == -1) {                  if (fd == -1) {
                         if (errno == ENOENT) {                          if (errno == ENOENT) {
                                enum logcode c = am_daemon                                enum logcode c = am_daemon && protocol_version < 28 ? FERROR : FWARNING;
                                    && protocol_version < 28 ? FERROR 
                                                             : FWARNING; 
                                 io_error |= IOERR_VANISHED;                                  io_error |= IOERR_VANISHED;
                                 rprintf(c, "file has vanished: %s\n",                                  rprintf(c, "file has vanished: %s\n",
                                         full_fname(fname));                                          full_fname(fname));
Line 300  void send_files(int f_in, int f_out) Line 382  void send_files(int f_in, int f_out)
                         continue;                          continue;
                 }                  }
   
                   if (source_filter) {
                           int fd2;
                           char *tmpl = "/tmp/rsync-filtered_sourceXXXXXX";
   
                           tmp = strdup(tmpl);
                           fd2 = mkstemp(tmp);
                           if (fd2 == -1) {
                                   rprintf(FERROR, "mkstemp %s failed: %s\n",
                                           tmp, strerror(errno));
                           } else {
                                   int status;
                                   pid_t pid = run_filter_on_file(filter_argv, fd2, fd);
                                   close(fd);
                                   close(fd2);
                                   wait_process_with_flush(pid, &status);
                                   if (status != 0) {
                                           rprintf(FERROR,
                                               "bypassing source filter %s; exited with code: %d\n",
                                               source_filter, status);
                                           fd = do_open(fname, O_RDONLY, 0);
                                   } else {
                                           fd = do_open(tmp, O_RDONLY, 0);
                                           unlink_tmp = 1;
                                   }
                           }
                   }
   
                 /* map the local file */                  /* map the local file */
                 if (do_fstat(fd, &st) != 0) {                  if (do_fstat(fd, &st) != 0) {
                         io_error |= IOERR_GENERAL;                          io_error |= IOERR_GENERAL;
                         rsyserr(FERROR_XFER, errno, "fstat failed");                          rsyserr(FERROR_XFER, errno, "fstat failed");
                         free_sums(s);                          free_sums(s);
                         close(fd);                          close(fd);
                        exit_cleanup(RERR_PROTOCOL);                        exit_cleanup(RERR_FILEIO);
                 }                  }
   
                   if (IS_DEVICE(st.st_mode) && st.st_size == 0)
                           st.st_size = get_device_size(fd, fname);
   
                 if (st.st_size) {                  if (st.st_size) {
                         int32 read_size = MAX(s->blength * 3, MAX_MAP_SIZE);                          int32 read_size = MAX(s->blength * 3, MAX_MAP_SIZE);
                         mbuf = map_file(fd, st.st_size, read_size, s->blength);                          mbuf = map_file(fd, st.st_size, read_size, s->blength);
                 } else                  } else
                         mbuf = NULL;                          mbuf = NULL;
   
                if (verbose > 2) {                if (DEBUG_GTE(DELTASUM, 2)) {
                        rprintf(FINFO, "send_files mapped %s%s%s of size %.0f\n",                        rprintf(FINFO, "send_files mapped %s%s%s of size %s\n",
                                path,slash,fname, (double)st.st_size);                                path,slash,fname, big_num(st.st_size));
                 }                  }
   
                write_ndx_and_attrs(f_out, ndx, iflags, fname, file,                write_ndx_and_attrs(f_out, ndx, iflags, fname, file, fnamecmp_type, xname, xlen);
                                    fnamecmp_type, xname, xlen); 
                 write_sum_head(f_xfer, s);                  write_sum_head(f_xfer, s);
   
                if (verbose > 2)                if (DEBUG_GTE(DELTASUM, 2))
                         rprintf(FINFO, "calling match_sums %s%s%s\n", path,slash,fname);                          rprintf(FINFO, "calling match_sums %s%s%s\n", path,slash,fname);
   
                 if (log_before_transfer)                  if (log_before_transfer)
                        log_item(FCLIENT, file, &initial_stats, iflags, NULL);                        log_item(FCLIENT, file, iflags, NULL);
                else if (!am_server && verbose && do_progress)                else if (!am_server && INFO_GTE(NAME, 1) && INFO_EQ(PROGRESS, 1))
                         rprintf(FCLIENT, "%s\n", fname);                          rprintf(FCLIENT, "%s\n", fname);
   
                 set_compression(fname);                  set_compression(fname);
   
                 match_sums(f_xfer, s, mbuf, st.st_size);                  match_sums(f_xfer, s, mbuf, st.st_size);
                if (do_progress)                if (INFO_GTE(PROGRESS, 1))
                         end_progress(st.st_size);                          end_progress(st.st_size);
                   else if (want_progress_now)
                           instant_progress(fname);
   
                log_item(log_code, file, &initial_stats, iflags, NULL);                log_item(log_code, file, iflags, NULL);
   
                 if (mbuf) {                  if (mbuf) {
                         j = unmap_file(mbuf);                          j = unmap_file(mbuf);
Line 350  void send_files(int f_in, int f_out) Line 463  void send_files(int f_in, int f_out)
                         }                          }
                 }                  }
                 close(fd);                  close(fd);
                   if (unlink_tmp)
                           unlink(tmp);
   
                 free_sums(s);                  free_sums(s);
   
                if (verbose > 2)                if (DEBUG_GTE(SEND, 1))
                         rprintf(FINFO, "sender finished %s%s%s\n", path,slash,fname);                          rprintf(FINFO, "sender finished %s%s%s\n", path,slash,fname);
   
                 /* Flag that we actually sent this entry. */                  /* Flag that we actually sent this entry. */
Line 365  void send_files(int f_in, int f_out) Line 480  void send_files(int f_in, int f_out)
         if (io_error != save_io_error && protocol_version >= 30)          if (io_error != save_io_error && protocol_version >= 30)
                 send_msg_int(MSG_IO_ERROR, io_error);                  send_msg_int(MSG_IO_ERROR, io_error);
   
        if (verbose > 2)        if (DEBUG_GTE(SEND, 1))
                 rprintf(FINFO, "send files finished\n");                  rprintf(FINFO, "send files finished\n");
   
         match_report();          match_report();

Removed from v.1.1  
changed lines
  Added in v.1.1.1.4


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>