check for stpcpy
[rsync.git] / generator.c
index 6e1cbe9160f874fc8a099a9ab86f4df43a4e3a89..110db28fc76f097426249a454b9cf999aec56c07 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (C) 1996-2000 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras
  * Copyright (C) 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2003-2020 Wayne Davison
+ * Copyright (C) 2003-2023 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
@@ -35,11 +35,11 @@ extern int inc_recurse;
 extern int relative_paths;
 extern int implied_dirs;
 extern int keep_dirlinks;
+extern int write_devices;
 extern int preserve_acls;
 extern int preserve_xattrs;
 extern int preserve_links;
 extern int preserve_devices;
-extern int write_devices;
 extern int preserve_specials;
 extern int preserve_hard_links;
 extern int preserve_executability;
@@ -532,7 +532,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
                                iflags |= ITEM_REPORT_CRTIME;
                }
 #endif
-#if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST
+#ifndef CAN_CHMOD_SYMLINK
                if (S_ISLNK(file->mode)) {
                        ;
                } else
@@ -783,7 +783,7 @@ static int generate_and_send_sums(int fd, OFF_T len, int f_out, int f_copy)
        for (i = 0; i < sum.count; i++) {
                int32 n1 = (int32)MIN(len, (OFF_T)sum.blength);
                char *map = map_ptr(mapbuf, offset, n1);
-               char sum2[SUM_LENGTH];
+               char sum2[MAX_DIGEST_LEN];
                uint32 sum1;
 
                len -= n1;
@@ -875,9 +875,12 @@ static struct file_struct *find_fuzzy(struct file_struct *file, struct file_list
                        len = strlen(name);
                        suf = find_filename_suffix(name, len, &suf_len);
 
-                       dist = fuzzy_distance(name, len, fname, fname_len);
-                       /* Add some extra weight to how well the suffixes match. */
-                       dist += fuzzy_distance(suf, suf_len, fname_suf, fname_suf_len) * 10;
+                       dist = fuzzy_distance(name, len, fname, fname_len, lowest_dist);
+                       /* Add some extra weight to how well the suffixes match unless we've already disqualified
+                        * this file based on a heuristic. */
+                       if (dist < 0xFFFF0000U) {
+                               dist += fuzzy_distance(suf, suf_len, fname_suf, fname_suf_len, 0xFFFF0000U) * 10;
+                       }
                        if (DEBUG_GTE(FUZZY, 2)) {
                                rprintf(FINFO, "fuzzy distance for %s = %d.%05d\n",
                                        f_name(fp, NULL), (int)(dist>>16), (int)(dist&0xFFFF));
@@ -1793,6 +1796,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                goto cleanup;
        }
 
+       if (write_devices && IS_DEVICE(sx.st.st_mode) && sx.st.st_size == 0) {
+               /* This early open into fd skips the regular open below. */
+               if ((fd = do_open(fnamecmp, O_RDONLY, 0)) >= 0)
+                       real_sx.st.st_size = sx.st.st_size = get_device_size(fd, fnamecmp);
+       }
+
        if (fnamecmp_type <= FNAMECMP_BASIS_DIR_HIGH)
                ;
        else if (fnamecmp_type >= FNAMECMP_FUZZY)
@@ -1813,7 +1822,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                        goto cleanup;
          return_with_success:
                if (!dry_run)
-                       send_msg_int(MSG_SUCCESS, ndx);
+                       send_msg_success(fname, ndx);
                goto cleanup;
        }
 
@@ -1858,7 +1867,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
        }
 
        /* open the file */
-       if ((fd = do_open(fnamecmp, O_RDONLY, 0)) < 0) {
+       if (fd < 0 && (fd = do_open(fnamecmp, O_RDONLY, 0)) < 0) {
                rsyserr(FERROR, errno, "failed to open %s, continuing",
                        full_fname(fnamecmp));
          pretend_missing:
@@ -1875,11 +1884,9 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
 
        if (inplace && make_backups > 0 && fnamecmp_type == FNAMECMP_FNAME) {
                if (!(backupptr = get_backup_name(fname))) {
-                       close(fd);
                        goto cleanup;
                }
                if (!(back_file = make_file(fname, NULL, NULL, 0, NO_FILTERS))) {
-                       close(fd);
                        goto pretend_missing;
                }
                if (robust_unlink(backupptr) && errno != ENOENT) {
@@ -1887,14 +1894,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                                full_fname(backupptr));
                        unmake_file(back_file);
                        back_file = NULL;
-                       close(fd);
                        goto cleanup;
                }
                if ((f_copy = do_open(backupptr, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0) {
                        rsyserr(FERROR_XFER, errno, "open %s", full_fname(backupptr));
                        unmake_file(back_file);
                        back_file = NULL;
-                       close(fd);
                        goto cleanup;
                }
                fnamecmp_type = FNAMECMP_BACKUP;
@@ -1945,7 +1950,6 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                write_sum_head(f_out, NULL);
        else if (sx.st.st_size <= 0) {
                write_sum_head(f_out, NULL);
-               close(fd);
        } else {
                if (generate_and_send_sums(fd, sx.st.st_size, f_out, f_copy) < 0) {
                        rprintf(FWARNING,
@@ -1953,10 +1957,11 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                                fnamecmp);
                        write_sum_head(f_out, NULL);
                }
-               close(fd);
        }
 
   cleanup:
+       if (fd >= 0)
+               close(fd);
        if (back_file) {
                int save_preserve_xattrs = preserve_xattrs;
                if (f_copy >= 0)