X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/b485e0c16ceee1e157f412bf2e93e4986d95b605..89d26123ff63a788e9cb7d07df3538f9e5d536d1:/util.c diff --git a/util.c b/util.c index 42b5e100..cde75717 100644 --- 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]; @@ -890,13 +892,21 @@ const char *safe_fname(const char *fname) char *t; ndx = (ndx + 1) % MAX_SAFE_NAMES; - for (t = fbuf[ndx]; *fname; fname++) { - if (!isprint(*fname)) - *t++ = '?'; - else + for (t = fbuf[ndx]; *fname && limit; fname++) { + 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 { + limit--; *t++ = *fname; - if (--limit == 0) - break; + } } *t = '\0'; @@ -922,25 +932,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 +1260,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 +1276,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. */