static void clean_flist(struct file_list *flist, int strip_root);
+
+static int show_build_progress_p(void)
+{
+ extern int do_progress;
+
+ return do_progress && verbose && recurse && !am_server;
+}
+
+/**
+ * True if we're local, etc, and should emit progress emssages.
+ **/
+static void emit_build_progress(const struct file_list *flist)
+{
+ rprintf(FINFO,
+ " %d files...\r",
+ flist->count);
+}
+
+
+static void finish_build_progress(const struct file_list *flist)
+{
+ if (verbose && recurse && !am_server) {
+ /* This overwrites the progress line, if any. */
+ rprintf(FINFO, RSYNC_NAME ": %d files to consider.\n",
+ flist->count);
+ }
+}
+
+
static struct string_area *string_area_new(int size)
{
struct string_area *a;
static gid_t last_gid;
static char lastname[MAXPATHLEN];
char thisname[MAXPATHLEN];
- int l1=0,l2=0;
+ unsigned int l1=0,l2=0;
char *p;
struct file_struct *file;
if (preserve_links && S_ISLNK(file->mode)) {
int l = read_int(f);
+ if (l < 0) {
+ rprintf(FERROR,"overflow: l=%d\n", l);
+ overflow("receive_file_entry");
+ }
file->link = (char *)malloc(l+1);
if (!file->link) out_of_memory("receive_file_entry 2");
read_sbuf(f,file->link,l);
file = make_file(f,fname, &flist->string_area, 0);
- if (!file) return;
+ if (!file) return;
+
+ if (show_build_progress_p() & !(flist->count % 100))
+ emit_build_progress(flist);
if (flist->count >= flist->malloced) {
if (flist->malloced < 1000)
}
+/*
+ *
+ * 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;
int64 start_write;
if (verbose && recurse && !am_server && f != -1) {
- rprintf(FINFO,"building file list ... ");
+ rprintf(FINFO, RSYNC_NAME ": building file list...\n");
if (verbose > 1)
rprintf(FINFO, "\n");
rflush(FINFO);
send_file_entry(NULL,f,0);
}
- if (verbose && recurse && !am_server && f != -1)
- rprintf(FINFO,"done\n");
+ finish_build_progress(flist);
clean_flist(flist, 0);
}
+/*
+ * XXX: This is currently the hottest function while building the file
+ * list, because building f_name()s every time is expensive.
+ **/
int file_compare(struct file_struct **f1,struct file_struct **f2)
{
if (!(*f1)->basename && !(*f2)->basename) return 0;
/*
* return the full filename of a flist entry
+ *
+ * This function is too expensive at the moment, because it copies
+ * strings when often we only want to compare them. In any case,
+ * using strlcat is silly because it will walk the string repeatedly.
*/
char *f_name(struct file_struct *f)
{
n = (n+1)%10;
if (f->dirname) {
- strlcpy(p, f->dirname, MAXPATHLEN);
- strlcat(p, "/", MAXPATHLEN);
- strlcat(p, f->basename, MAXPATHLEN);
+ int off;
+
+ off = strlcpy(p, f->dirname, MAXPATHLEN);
+ off += strlcpy(p+off, "/", MAXPATHLEN-off);
+ off += strlcpy(p+off, f->basename, MAXPATHLEN-off);
} else {
strlcpy(p, f->basename, MAXPATHLEN);
}