Tweaked a sentence.
[rsync/rsync.git] / util.c
diff --git a/util.c b/util.c
index 42b5e10..6cbe7e1 100644 (file)
--- a/util.c
+++ b/util.c
@@ -245,7 +245,8 @@ static int safe_read(int desc, char *ptr, size_t len)
 
 /** Copy a file.
  *
- * This is used in conjunction with the --temp-dir and --backup options */
+ * This is used in conjunction with the --temp-dir, --backup, and
+ * --copy-dest options. */
 int copy_file(char *source, char *dest, mode_t mode)
 {
        int ifd;
@@ -876,12 +877,13 @@ int pop_dir(char *dir)
        return 1;
 }
 
-/* Return the filename, turning any non-printable characters into '?'s.
- * This ensures that outputting it on a line of its own cannot generate an
- * empty line.  This function can return only MAX_SAFE_NAMES values at a
- * time!  The returned value can be longer than MAXPATHLEN (because we
- * may be trying to output an error about a too-long filename)! */
-const char *safe_fname(const char *fname)
+/* Return the filename, turning any non-printable characters into escaped
+ * characters (e.g. \n -> \012, \ -> \\).  This ensures that outputting it
+ * cannot generate an empty line nor corrupt the screen.  This function can
+ * return only MAX_SAFE_NAMES values at a time!  The returned value can be
+ * longer than MAXPATHLEN (because we may be trying to output an error about
+ * a too-long filename)! */
+char *safe_fname(const char *fname)
 {
 #define MAX_SAFE_NAMES 4
        static char fbuf[MAX_SAFE_NAMES][MAXPATHLEN*2];
@@ -891,12 +893,21 @@ const char *safe_fname(const char *fname)
 
        ndx = (ndx + 1) % MAX_SAFE_NAMES;
        for (t = fbuf[ndx]; *fname; fname++) {
-               if (!isprint(*fname))
-                       *t++ = '?';
-               else
+               if (*fname == '\\') {
+                       if ((limit -= 2) < 0)
+                               break;
+                       *t++ = '\\';
+                       *t++ = '\\';
+               } else if (!isprint(*(uchar*)fname)) {
+                       if ((limit -= 4) < 0)
+                               break;
+                       sprintf(t, "\\%03o", *(uchar*)fname);
+                       t += 4;
+               } else {
+                       if (--limit < 0)
+                               break;
                        *t++ = *fname;
-               if (--limit == 0)
-                       break;
+               }
        }
        *t = '\0';
 
@@ -922,25 +933,21 @@ char *full_fname(const char *fn)
                p1 = p2 = "";
        else {
                p1 = curr_dir;
-               p2 = "/";
+               for (p2 = p1; *p2 == '/'; p2++) {}
+               if (*p2)
+                       p2 = "/";
        }
        if (module_id >= 0) {
                m1 = " (in ";
                m2 = lp_name(module_id);
                m3 = ")";
-               if (*p1) {
+               if (p1 == curr_dir) {
                        if (!lp_use_chroot(module_id)) {
                                char *p = lp_path(module_id);
                                if (*p != '/' || p[1])
                                        p1 += strlen(p);
                        }
-                       if (!*p1)
-                               p2++;
-                       else
-                               p1++;
                }
-               else
-                       fn++;
        } else
                m1 = m2 = m3 = "";
 
@@ -1254,15 +1261,15 @@ const char *find_filename_suffix(const char *fn, int fn_len, int *len_ptr)
                        break;
                s_len = fn_len - (s - fn);
                fn_len = s - fn;
-               if (s_len == 3) {
+               if (s_len == 4) {
                        if (strcmp(s+1, "bak") == 0
                         || strcmp(s+1, "old") == 0)
                                continue;
-               } else if (s_len == 4) {
+               } else if (s_len == 5) {
                        if (strcmp(s+1, "orig") == 0)
                                continue;
                } else if (s_len > 2 && had_tilde
-                   && s[1] == '~' && isdigit(s[2]))
+                   && s[1] == '~' && isdigit(*(uchar*)(s+2)))
                        continue;
                *len_ptr = s_len;
                suf = s;
@@ -1270,7 +1277,7 @@ const char *find_filename_suffix(const char *fn, int fn_len, int *len_ptr)
                        break;
                /* Determine if the suffix is all digits. */
                for (s++, s_len--; s_len > 0; s++, s_len--) {
-                       if (!isdigit(*s))
+                       if (!isdigit(*(uchar*)s))
                                return suf;
                }
                /* An all-digit suffix may not be that signficant. */