Add support for transferring & setting nsec time values.
[rsync/rsync.git] / rsync.c
diff --git a/rsync.c b/rsync.c
index f26f212..db7abcc 100644 (file)
--- a/rsync.c
+++ b/rsync.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras
- * Copyright (C) 2003-2008 Wayne Davison
+ * Copyright (C) 2003-2009 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
@@ -45,11 +45,10 @@ extern int gid_ndx;
 extern int inc_recurse;
 extern int inplace;
 extern int flist_eof;
+extern int file_old_total;
 extern int msgs2stderr;
 extern int keep_dirlinks;
 extern int make_backups;
-extern int delete_during;
-extern int check_for_io_err;
 extern struct file_list *cur_flist, *first_flist, *dir_flist;
 extern struct chmod_mode_struct *daemon_chmod_modes;
 #ifdef ICONV_OPTION
@@ -222,16 +221,19 @@ void send_protected_args(int fd, char *args[])
        if (DEBUG_GTE(CMD, 1))
                print_child_argv("protected args:", args + i + 1);
        do {
+               if (!args[i][0])
+                       write_buf(fd, ".", 2);
 #ifdef ICONV_OPTION
-               if (convert) {
+               else if (convert) {
                        INIT_XBUF_STRLEN(inbuf, args[i]);
                        iconvbufs(ic_send, &inbuf, &outbuf,
                                  ICB_EXPAND_OUT | ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE);
                        outbuf.buf[outbuf.len] = '\0';
                        write_buf(fd, outbuf.buf, outbuf.len + 1);
                        outbuf.len = 0;
-               } else
+               }
 #endif
+               else
                        write_buf(fd, args[i], strlen(args[i]) + 1);
        } while (args[++i]);
        write_byte(fd, 0);
@@ -254,15 +256,8 @@ int read_ndx_and_attrs(int f_in, int *iflag_ptr, uchar *type_ptr,
        while (1) {
                ndx = read_ndx(f_in);
 
-               if (ndx >= 0) {
-                       if (check_for_io_err) {
-                               /* Let generator know there was no I/O error. */
-                               send_msg_int(MSG_IO_ERROR, 0);
-                               check_for_io_err = 0;
-                       }
+               if (ndx >= 0)
                        break;
-               }
-               check_for_io_err = 0;
                if (ndx == NDX_DONE)
                        return ndx;
                if (!inc_recurse || am_sender) {
@@ -306,10 +301,6 @@ int read_ndx_and_attrs(int f_in, int *iflag_ptr, uchar *type_ptr,
                stop_flist_forward();
                if (!msgs2stderr)
                        negate_output_levels(); /* restore info/debug output */
-               /* If the sender is going to send us an MSG_IO_ERROR value, it
-                * will always be the very next message following a file list. */
-               if (delete_during)
-                       check_for_io_err = 1;
        }
 
        iflags = protocol_version >= 29 ? read_shortint(f_in)
@@ -323,7 +314,15 @@ int read_ndx_and_attrs(int f_in, int *iflag_ptr, uchar *type_ptr,
                goto read_loop;
        }
 
-       cur_flist = flist_for_ndx(ndx, "read_ndx_and_attrs");
+       flist = flist_for_ndx(ndx, "read_ndx_and_attrs");
+       if (flist != cur_flist) {
+               cur_flist = flist;
+               if (am_sender) {
+                       file_old_total = cur_flist->used;
+                       for (flist = first_flist; flist != cur_flist; flist = flist->next)
+                               file_old_total += flist->used;
+               }
+       }
 
        if (iflags & ITEM_BASIS_TYPE_FOLLOWS)
                fnamecmp_type = read_byte(f_in);
@@ -405,12 +404,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
                                full_fname(fname));
                        return 0;
                }
-#ifdef SUPPORT_ACLS
-               sx2.acc_acl = sx2.def_acl = NULL;
-#endif
-#ifdef SUPPORT_XATTRS
-               sx2.xattr = NULL;
-#endif
+               init_stat_x(&sx2);
                sxp = &sx2;
                inherit = !preserve_perms;
        } else
@@ -441,7 +435,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
                flags |= ATTRS_SKIP_MTIME;
        if (!(flags & ATTRS_SKIP_MTIME)
            && cmp_time(sxp->st.st_mtime, file->modtime) != 0) {
-               int ret = set_modtime(fname, file->modtime, sxp->st.st_mode);
+               int ret = set_modtime(fname, file->modtime, F_MOD_NSEC(file), sxp->st.st_mode);
                if (ret < 0) {
                        rsyserr(FERROR_XFER, errno, "failed to set times on %s",
                                full_fname(fname));
@@ -576,9 +570,10 @@ int finish_transfer(const char *fname, const char *fnametmp,
        }
 
        if (make_backups > 0 && overwriting_basis) {
-               if (!make_backup(fname))
+               int ok = make_backup(fname, False);
+               if (!ok)
                        return 1;
-               if (fnamecmp == fname)
+               if (ok == 1 && fnamecmp == fname)
                        fnamecmp = get_backup_name(fname);
        }