From 301fb56ce9f7b0a47ede7d03c27ad64ed3ccce15 Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Mon, 14 Mar 2005 17:30:15 +0000 Subject: [PATCH] Split the conditional-directory sending out of send_file_name() into a new function: send_if_directory(). This lets the code that is recursively descending through the directories make its list of a dir's contents and close the DIR handle before recursing into the subdirs. Also, the "recurse" var is just true/false once again. --- flist.c | 62 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/flist.c b/flist.c index 2963cce5..a8308687 100644 --- a/flist.c +++ b/flist.c @@ -962,15 +962,14 @@ skip_filters: } -void send_file_name(int f, struct file_list *flist, char *fname, - int recursive, unsigned short base_flags) +static struct file_struct *send_file_name(int f, struct file_list *flist, + char *fname, unsigned short base_flags) { struct file_struct *file; - char fbuf[MAXPATHLEN]; file = make_file(fname, flist, f == -2 ? SERVER_FILTERS : ALL_FILTERS); if (!file) - return; + return NULL; maybe_emit_filelist_progress(flist); @@ -980,8 +979,15 @@ void send_file_name(int f, struct file_list *flist, char *fname, flist->files[flist->count++] = file; send_file_entry(file, f, base_flags); } + return file; +} + +static void send_if_directory(int f, struct file_list *flist, + struct file_struct *file) +{ + char fbuf[MAXPATHLEN]; - if (recursive && S_ISDIR(file->mode) + if (S_ISDIR(file->mode) && !(file->flags & FLAG_MOUNT_POINT) && f_name_to(file, fbuf)) { void *save_filters; unsigned int len = strlen(fbuf); @@ -1000,13 +1006,11 @@ void send_file_name(int f, struct file_list *flist, char *fname, } -/* Note that the "recurse" value either contains -1, for infinite recursion, or - * a number >= 0 indicating how many levels of recursion we will allow. This - * function is normally called by the sender, but the receiving side also calls - * it from delete_in_dir() with f set to -1 so that we just construct the file - * list in memory without sending it over the wire. Also, get_dirlist() might - * call this with f set to -2, which indicates that local filter rules should - * be ignored. */ +/* This function is normally called by the sender, but the receiving side also + * calls it from delete_in_dir() with f set to -1 so that we just construct the + * file list in memory without sending it over the wire. Also, get_dirlist() + * might call this with f set to -2, which also indicates that local filter + * rules should be ignored. */ static void send_directory(int f, struct file_list *flist, char *fbuf, int len) { @@ -1014,6 +1018,7 @@ static void send_directory(int f, struct file_list *flist, unsigned remainder; char *p; DIR *d; + int start = flist->count; if (!(d = opendir(fbuf))) { io_error |= IOERR_GENERAL; @@ -1032,10 +1037,9 @@ static void send_directory(int f, struct file_list *flist, if (dname[0] == '.' && (dname[1] == '\0' || (dname[1] == '.' && dname[2] == '\0'))) continue; - if (strlcpy(p, dname, remainder) < remainder) { - int do_subdirs = recurse >= 1 ? recurse-- : recurse; - send_file_name(f, flist, fbuf, do_subdirs, 0); - } else { + if (strlcpy(p, dname, remainder) < remainder) + send_file_name(f, flist, fbuf, 0); + else { io_error |= IOERR_GENERAL; rprintf(FINFO, "cannot send long-named file %s\n", @@ -1051,6 +1055,12 @@ static void send_directory(int f, struct file_list *flist, } closedir(d); + + if (recurse) { + int i, end = flist->count - 1; + for (i = start; i <= end; i++) + send_if_directory(f, flist, flist->files[i]); + } } @@ -1084,9 +1094,10 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) } while (1) { + struct file_struct *file; char fname2[MAXPATHLEN]; char *fname = fname2; - int do_subdirs; + int is_dot_dir; if (use_ff_fd) { if (read_filesfrom_line(filesfrom_fd, fname) == 0) @@ -1109,12 +1120,11 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) fname[l++] = '.'; fname[l] = '\0'; } + is_dot_dir = 1; + } else { + is_dot_dir = fname[l-1] == '.' + && (l == 1 || fname[l-2] == '/'); } - if (fname[l-1] == '.' && (l == 1 || fname[l-2] == '/')) { - if (!recurse && xfer_dirs) - recurse = 1; /* allow one level */ - } else if (recurse > 0) - recurse = 0; if (link_stat(fname, &st, keep_dirlinks) != 0) { io_error |= IOERR_GENERAL; @@ -1162,7 +1172,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) xfer_dirs = 1; while ((slash = strchr(slash+1, '/')) != 0) { *slash = 0; - send_file_name(f, flist, fname, 0, 0); + send_file_name(f, flist, fname, 0); *slash = '/'; } copy_links = save_copy_links; @@ -1201,8 +1211,10 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) if (one_file_system) filesystem_dev = st.st_dev; - do_subdirs = recurse >= 1 ? recurse-- : recurse; - send_file_name(f, flist, fname, do_subdirs, XMIT_TOP_DIR); + if ((file = send_file_name(f, flist, fname, XMIT_TOP_DIR))) { + if (recurse || (xfer_dirs && is_dot_dir)) + send_if_directory(f, flist, file); + } if (olddir[0]) { flist_dir = NULL; -- 2.34.1