+ if (!(d = opendir(fbuf))) {
+ io_error |= IOERR_GENERAL;
+ rsyserr(FERROR, errno, "opendir %s failed", full_fname(fbuf));
+ return;
+ }
+
+ p = fbuf + len;
+ if (len != 1 || *fbuf != '/')
+ *p++ = '/';
+ *p = '\0';
+ remainder = MAXPATHLEN - (p - fbuf);
+
+ for (errno = 0, di = readdir(d); di; errno = 0, di = readdir(d)) {
+ char *dname = d_name(di);
+ if (dname[0] == '.' && (dname[1] == '\0'
+ || (dname[1] == '.' && dname[2] == '\0')))
+ continue;
+ if (strlcpy(p, dname, remainder) >= remainder) {
+ io_error |= IOERR_GENERAL;
+ rprintf(FINFO,
+ "cannot send long-named file %s\n",
+ full_fname(fbuf));
+ continue;
+ }
+
+ send_file_name(f, flist, fbuf, NULL, flags, filter_flags);
+ }
+
+ fbuf[len] = '\0';
+
+ if (errno) {
+ io_error |= IOERR_GENERAL;
+ rsyserr(FERROR, errno, "readdir(%s)", full_fname(fbuf));
+ }
+
+ closedir(d);
+
+ if (f >= 0 && recurse && !divert_dirs) {
+ int i, end = flist->count - 1;
+ /* send_if_directory() bumps flist->count, so use "end". */
+ for (i = start; i <= end; i++)
+ send_if_directory(f, flist, flist->files[i], fbuf, len, flags);
+ }
+}
+
+static void send1extra(int f, struct file_struct *file, struct file_list *flist)
+{
+ char fbuf[MAXPATHLEN];
+ int dlen;
+
+ f_name(file, fbuf);
+ dlen = strlen(fbuf);
+
+ if (F_PATHNAME(file) != pathname) {
+ if (!push_pathname(F_PATHNAME(file), -1))
+ exit_cleanup(RERR_FILESELECT);
+ }
+
+ change_local_filter_dir(fbuf, dlen, send_dir_depth);
+
+ send_directory(f, flist, fbuf, dlen, FLAG_DIVERT_DIRS | FLAG_XFER_DIR);
+}
+
+void send_extra_file_list(int f, int at_least)
+{
+ struct file_list *flist;
+ int64 start_write;
+ int future_cnt, save_io_error = io_error;
+
+ if (flist_eof)
+ return;
+
+ /* Keep sending data until we have the requested number of
+ * files in the upcoming file-lists. */
+ if (cur_flist->next) {
+ flist = first_flist->prev; /* the newest flist */
+ future_cnt = flist->count + flist->ndx_start
+ - cur_flist->next->ndx_start;
+ } else
+ future_cnt = 0;
+ while (future_cnt < at_least) {
+ struct file_struct *file = dir_flist->sorted[send_dir_ndx];
+ int start = dir_flist->count;
+ int32 *dp;
+
+ flist = flist_new(0, "send_extra_file_list");
+ start_write = stats.total_written;
+
+ /* If this is the first of a set of duplicate dirs, we must
+ * send all the dirs together in a single file-list. We must
+ * also send the index of the last dir in the header. */
+ if (file->flags & FLAG_DUPLICATE) {
+ int dir_ndx, end_ndx = send_dir_ndx;
+ struct file_struct *fp = file;
+
+ while (1) {
+ dp = F_DIRNODE_P(fp);
+ end_ndx = DIR_NEXT_SIBLING(dp);
+ fp = dir_flist->sorted[end_ndx];
+ if (!(fp->flags & FLAG_DUPLICATE))
+ break;
+ }
+
+#ifdef ICONV_OPTION
+ if (ic_ndx)
+ dir_ndx = F_NDX(fp);
+ else
+#endif
+ dir_ndx = end_ndx;
+ write_ndx(f, NDX_FLIST_OFFSET - dir_ndx);
+
+ while (1) {
+ send1extra(f, file, flist);
+ if (send_dir_ndx == end_ndx)
+ break;
+ dp = F_DIRNODE_P(file);
+ send_dir_ndx = DIR_NEXT_SIBLING(dp);
+ file = dir_flist->sorted[send_dir_ndx];