+ if (verbose > 4) {
+ rprintf(FINFO, "FILE_STRUCT_LEN=%d, EXTRA_LEN=%d\n",
+ (int)FILE_STRUCT_LEN, (int)EXTRA_LEN);
+ }
+ checksum_len = protocol_version < 21 ? 2 : MD4_SUM_LENGTH;
+}
+
+static int show_filelist_p(void)
+{
+ return verbose && xfer_dirs && !am_server;
+}
+
+static void start_filelist_progress(char *kind)
+{
+ rprintf(FCLIENT, "%s ... ", kind);
+ if (verbose > 1 || do_progress)
+ rprintf(FCLIENT, "\n");
+ rflush(FINFO);
+}
+
+static void emit_filelist_progress(int count)
+{
+ rprintf(FCLIENT, " %d files...\r", count);
+}
+
+static void maybe_emit_filelist_progress(int count)
+{
+ if (do_progress && show_filelist_p() && (count % 100) == 0)
+ emit_filelist_progress(count);
+}
+
+static void finish_filelist_progress(const struct file_list *flist)
+{
+ if (do_progress) {
+ /* This overwrites the progress line */
+ 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 */
+}
+
+static void list_file_entry(struct file_struct *f)
+{
+ char permbuf[PERMSTRING_SIZE];
+ double len;
+
+ if (!F_IS_ACTIVE(f)) {
+ /* this can happen if duplicate names were removed */
+ return;
+ }
+
+ permstring(permbuf, f->mode);
+ len = F_LENGTH(f);
+
+#ifdef SUPPORT_LINKS
+ if (preserve_links && S_ISLNK(f->mode)) {
+ rprintf(FINFO, "%s %11.0f %s %s -> %s\n",
+ permbuf, len, timestring(f->modtime),
+ f_name(f, NULL), F_SYMLINK(f));
+ } else
+#endif
+ {
+ rprintf(FINFO, "%s %11.0f %s %s\n",
+ permbuf, len, timestring(f->modtime),
+ f_name(f, NULL));
+ }
+}
+
+/* Stat either a symlink or its referent, depending on the settings of
+ * copy_links, copy_unsafe_links, etc. Returns -1 on error, 0 on success.
+ *
+ * If path is the name of a symlink, then the linkbuf buffer (which must hold
+ * MAXPATHLEN chars) will be set to the symlink's target string.
+ *
+ * The stat structure pointed to by stp will contain information about the
+ * link or the referent as appropriate, if they exist. */
+static int readlink_stat(const char *path, STRUCT_STAT *stp, char *linkbuf)
+{
+#ifdef SUPPORT_LINKS
+ if (link_stat(path, stp, copy_dirlinks) < 0)
+ return -1;
+ if (S_ISLNK(stp->st_mode)) {
+ int llen = readlink(path, linkbuf, MAXPATHLEN - 1);
+ if (llen < 0)
+ return -1;
+ linkbuf[llen] = '\0';
+ if (copy_unsafe_links && unsafe_symlink(linkbuf, path)) {
+ if (verbose > 1) {
+ rprintf(FINFO,"copying unsafe symlink \"%s\" -> \"%s\"\n",
+ path, linkbuf);
+ }
+ return do_stat(path, stp);
+ }
+ }
+ return 0;