X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/3e13004b6b0d4aef64b592066c3b14442627b478..0417c34e2d641cbac292ba5cf8a619249c87d4e3:/util.c diff --git a/util.c b/util.c index 735173d8..9ebd6ba7 100644 --- a/util.c +++ b/util.c @@ -120,7 +120,7 @@ void out_of_memory(char *str) exit_cleanup(RERR_MALLOC); } -void overflow(char *str) +void overflow_exit(char *str) { rprintf(FERROR, "ERROR: buffer overflow in %s\n", str); exit_cleanup(RERR_MALLOC); @@ -128,8 +128,13 @@ void overflow(char *str) -int set_modtime(char *fname, time_t modtime) +int set_modtime(char *fname, time_t modtime, mode_t mode) { +#if !defined HAVE_LUTIMES || !defined HAVE_UTIMES + if (S_ISLNK(mode)) + return 1; +#endif + if (verbose > 2) { rprintf(FINFO, "set modtime of %s to (%ld) %s", safe_fname(fname), (long)modtime, @@ -140,7 +145,18 @@ int set_modtime(char *fname, time_t modtime) return 0; { -#ifdef HAVE_UTIMBUF +#ifdef HAVE_UTIMES + struct timeval t[2]; + t[0].tv_sec = time(NULL); + t[0].tv_usec = 0; + t[1].tv_sec = modtime; + t[1].tv_usec = 0; +# ifdef HAVE_LUTIMES + if (S_ISLNK(mode)) + return lutimes(fname, t); +# endif + return utimes(fname, t); +#elif defined HAVE_UTIMBUF struct utimbuf tbuf; tbuf.actime = time(NULL); tbuf.modtime = modtime; @@ -151,12 +167,7 @@ int set_modtime(char *fname, time_t modtime) t[1] = modtime; return utime(fname,t); #else - struct timeval t[2]; - t[0].tv_sec = time(NULL); - t[0].tv_usec = 0; - t[1].tv_sec = modtime; - t[1].tv_usec = 0; - return utimes(fname,t); +#error No file-time-modification routine found! #endif } } @@ -517,7 +528,6 @@ static void glob_expand_one(char *s, char ***argv_ptr, int *argc_ptr, filter_server_path(s); #else glob_t globbuf; - int i; if (maxargs <= argc) return; @@ -542,9 +552,9 @@ static void glob_expand_one(char *s, char ***argv_ptr, int *argc_ptr, if (globbuf.gl_pathc == 0) argv[argc++] = s; else { - int j = globbuf.gl_pathc; + int i; free(s); - for (i = 0; i < j; i++) { + for (i = 0; i < (int)globbuf.gl_pathc; i++) { if (!(argv[argc++] = strdup(globbuf.gl_pathv[i]))) out_of_memory("glob_expand_one"); } @@ -877,12 +887,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]; @@ -892,12 +903,21 @@ const char *safe_fname(const char *fname) ndx = (ndx + 1) % MAX_SAFE_NAMES; for (t = fbuf[ndx]; *fname; fname++) { - if (!isprint(*(uchar*)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'; @@ -1251,11 +1271,11 @@ 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