X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/1bbd10fe070d8b07a8c4991e17d1fc04295fe42e..32f761755e2cfee243a1513c9ea9871586463fa6:/flist.c diff --git a/flist.c b/flist.c index 9c35d364..77f2995c 100644 --- a/flist.c +++ b/flist.c @@ -83,22 +83,31 @@ static void start_filelist_progress(char *kind) rflush(FINFO); } + static void emit_filelist_progress(const struct file_list *flist) { rprintf(FINFO, " %d files...\r", flist->count); } +static void maybe_emit_filelist_progress(const struct file_list *flist) +{ + if (do_progress && show_filelist_p() && ((flist->count % 100) == 0)) + emit_filelist_progress(flist); +} + + static void finish_filelist_progress(const struct file_list *flist) { if (do_progress) { /* This overwrites the progress line */ - rprintf(FINFO, "%d files to consider\n", flist->count); - } else + rprintf(FINFO, "%d file%sto consider\n", + flist->count, flist->count == 1 ? " " : "s "); + } else { rprintf(FINFO, "done\n"); + } } - void show_flist_stats(void) { /* Nothing yet */ @@ -183,44 +192,56 @@ static void list_file_entry(struct file_struct *f) } -int readlink_stat(const char *Path, STRUCT_STAT * Buffer, char *Linkbuf) +/** + * Stat either a symlink or its referent, depending on the settings of + * copy_links, copy_unsafe_links, etc. + * + * @retval -1 on error + * + * @retval 0 for success + * + * @post If @p path is a symlink, then @p linkbuf (of size @c + * MAXPATHLEN) contains the symlink target. + * + * @post @p buffer contains information about the link or the + * referrent as appropriate, if they exist. + **/ +int readlink_stat(const char *path, STRUCT_STAT * buffer, char *linkbuf) { #if SUPPORT_LINKS if (copy_links) { - return do_stat(Path, Buffer); + return do_stat(path, buffer); } - if (do_lstat(Path, Buffer) == -1) { + if (do_lstat(path, buffer) == -1) { return -1; } - if (S_ISLNK(Buffer->st_mode)) { + if (S_ISLNK(buffer->st_mode)) { int l; - if ((l = - readlink((char *) Path, Linkbuf, - MAXPATHLEN - 1)) == -1) { + l = readlink((char *) path, linkbuf, MAXPATHLEN - 1); + if (l == -1) return -1; - } - Linkbuf[l] = 0; + linkbuf[l] = 0; if (copy_unsafe_links && (topsrcname[0] != '\0') && - unsafe_symlink(Linkbuf, topsrcname)) { - return do_stat(Path, Buffer); + unsafe_symlink(linkbuf, topsrcname)) { + return do_stat(path, buffer); } } return 0; #else - return do_stat(Path, Buffer); + return do_stat(path, buffer); #endif } -int link_stat(const char *Path, STRUCT_STAT * Buffer) +int link_stat(const char *path, STRUCT_STAT * buffer) { #if SUPPORT_LINKS if (copy_links) { - return do_stat(Path, Buffer); + return do_stat(path, buffer); } else { - return do_lstat(Path, Buffer); + return do_lstat(path, buffer); } #else - return do_stat(Path, Buffer); + return do_stat(path, buffer); #endif } @@ -293,7 +314,10 @@ static void flist_expand(struct file_list *flist) new_bytes = sizeof(flist->files[0]) * flist->malloced; - new_ptr = realloc(flist->files, new_bytes); + if (flist->files) + new_ptr = realloc(flist->files, new_bytes); + else + new_ptr = malloc(new_bytes); if (verbose >= 2) { rprintf(FINFO, "expand file_list to %.0f bytes, did%s move\n", @@ -330,6 +354,8 @@ static void send_file_entry(struct file_struct *file, int f, return; } + io_write_phase = "send_file_entry"; + fname = f_name(file); flags = base_flags; @@ -425,6 +451,8 @@ static void send_file_entry(struct file_struct *file, int f, strlcpy(lastname, fname, MAXPATHLEN); lastname[MAXPATHLEN - 1] = 0; + + io_write_phase = "unknown"; } @@ -594,7 +622,21 @@ static int skip_filesystem(char *fname, STRUCT_STAT * st) /* IRIX cc cares that the operands to the ternary have the same type. */ #define MALLOC(ap, i) (ap ? (void*) string_area_malloc(ap, i) : malloc(i)) -/* create a file_struct for a named file */ +/** + * Create a file_struct for a named file by reading its stat() + * information and performing extensive checks against global + * options. + * + * @return the new file, or NULL if there was an error or this file + * should be excluded. + * + * @todo There is a small optimization opportunity here to avoid + * stat()ing the file in some circumstances, which has a certain cost. + * We are called immediately after doing readdir(), and so we may + * already know the d_type of the file. We could for example avoid + * statting directories if we're not recursing, but this is not a very + * important case. Some systems may not have d_type. + **/ struct file_struct *make_file(int f, char *fname, struct string_area **ap, int noexcludes) { @@ -740,8 +782,7 @@ void send_file_name(int f, struct file_list *flist, char *fname, if (!file) return; - if (do_progress && show_filelist_p() && ((flist->count % 100) == 0)) - emit_filelist_progress(flist); + maybe_emit_filelist_progress(flist); flist_expand(flist); @@ -826,11 +867,11 @@ static void send_directory(int f, struct file_list *flist, char *dir) } -/* +/** * - * I *think* f==-1 means that the list should just be built in memory - * and not transmitted. But who can tell? -- mbp - */ + * I think f==-1 means that the list should just be built in + * memory and not transmitted. But who can tell? -- mbp + **/ struct file_list *send_file_list(int f, int argc, char *argv[]) { int i, l; @@ -963,8 +1004,9 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) send_file_entry(NULL, f, 0); } - if (show_filelist_p()) + if (show_filelist_p() && f != -1) { finish_filelist_progress(flist); + } clean_flist(flist, 0); @@ -1032,8 +1074,7 @@ struct file_list *recv_file_list(int f) flist->count++; - if (do_progress && show_filelist_p() && ((flist->count % 100) == 0)) - emit_filelist_progress(flist); + maybe_emit_filelist_progress(flist); if (verbose > 2) rprintf(FINFO, "recv_file_name(%s)\n",