-static void clean_fname(char *name)
-{
- char *p;
- int l;
- int modified = 1;
-
- if (!name) return;
-
- while (modified) {
- modified = 0;
-
- if ((p=strstr(name,"/./"))) {
- modified = 1;
- while (*p) {
- p[0] = p[2];
- p++;
- }
- }
-
- if ((p=strstr(name,"//"))) {
- modified = 1;
- while (*p) {
- p[0] = p[1];
- p++;
- }
- }
-
- if (strncmp(p=name,"./",2) == 0) {
- modified = 1;
- do {
- p[0] = p[2];
- } while (*p++);
- }
-
- l = strlen(p=name);
- if (l > 1 && p[l-1] == '/') {
- modified = 1;
- p[l-1] = 0;
- }
- }
-}
-
-
-
-void send_file_entry(struct file_struct *file,int f,unsigned base_flags)
-{
- unsigned char flags;
- static time_t last_time;
- static mode_t last_mode;
- static dev_t last_rdev;
- static uid_t last_uid;
- static gid_t last_gid;
- static char lastname[MAXPATHLEN];
- char *fname;
- int l1,l2;
-
- if (f == -1) return;
-
- if (!file) {
- write_byte(f,0);
- return;
- }
-
- fname = f_name(file);
-
- flags = base_flags;
-
- if (file->mode == last_mode) flags |= SAME_MODE;
- if (file->rdev == last_rdev) flags |= SAME_RDEV;
- if (file->uid == last_uid) flags |= SAME_UID;
- if (file->gid == last_gid) flags |= SAME_GID;
- if (file->modtime == last_time) flags |= SAME_TIME;
-
- for (l1=0;lastname[l1] && fname[l1] == lastname[l1];l1++) ;
- l2 = strlen(fname) - l1;
-
- if (l1 > 0) flags |= SAME_NAME;
- if (l2 > 255) flags |= LONG_NAME;
-
- write_byte(f,flags);
- if (flags & SAME_NAME)
- write_byte(f,l1);
- if (flags & LONG_NAME)
- write_int(f,l2);
- else
- write_byte(f,l2);
- write_buf(f,fname+l1,l2);
-
- write_longint(f,file->length);
- if (!(flags & SAME_TIME))
- write_int(f,(int)file->modtime);
- if (!(flags & SAME_MODE))
- write_int(f,(int)file->mode);
- if (preserve_uid && !(flags & SAME_UID)) {
- add_uid(file->uid);
- write_int(f,(int)file->uid);
- }
- if (preserve_gid && !(flags & SAME_GID)) {
- add_gid(file->gid);
- write_int(f,(int)file->gid);
- }
- if (preserve_devices && IS_DEVICE(file->mode) && !(flags & SAME_RDEV))
- write_int(f,(int)file->rdev);
+
+/**
+ * Make sure @p flist is big enough to hold at least @p flist->count
+ * entries.
+ **/
+static void flist_expand(struct file_list *flist)
+{
+ if (flist->count >= flist->malloced) {
+ void *new_ptr;
+
+ if (flist->malloced < 1000)
+ flist->malloced += 1000;
+ else
+ flist->malloced *= 2;
+
+ if (flist->files) {
+ new_ptr = realloc_array(flist->files,
+ struct file_struct *,
+ flist->malloced);
+ } else {
+ new_ptr = new_array(struct file_struct *,
+ flist->malloced);
+ }
+
+ if (verbose >= 2) {
+ rprintf(FINFO, "expand file_list to %.0f bytes, did%s move\n",
+ (double)sizeof(flist->files[0])
+ * flist->malloced,
+ (new_ptr == flist->files) ? " not" : "");
+ }
+
+ flist->files = (struct file_struct **) new_ptr;
+
+ if (!flist->files)
+ out_of_memory("flist_expand");
+ }
+}
+
+
+static void send_file_entry(struct file_struct *file, int f,
+ unsigned base_flags)
+{
+ unsigned char flags;
+ static time_t last_time;
+ static mode_t last_mode;
+ static DEV64_T last_rdev;
+ static uid_t last_uid;
+ static gid_t last_gid;
+ static char lastname[MAXPATHLEN];
+ char *fname, buf[MAXPATHLEN];
+ int l1, l2;
+
+ if (f == -1)
+ return;
+
+ if (!file) {
+ write_byte(f, 0);
+ return;
+ }
+
+ io_write_phase = "send_file_entry";
+
+ fname = f_name_to(file, buf, sizeof buf);
+
+ flags = base_flags;
+
+ if (file->mode == last_mode)
+ flags |= SAME_MODE;
+ if (file->rdev == last_rdev)
+ flags |= SAME_RDEV;
+ if (file->uid == last_uid)
+ flags |= SAME_UID;
+ if (file->gid == last_gid)
+ flags |= SAME_GID;
+ if (file->modtime == last_time)
+ flags |= SAME_TIME;
+
+ for (l1 = 0;
+ lastname[l1] && (fname[l1] == lastname[l1]) && (l1 < 255);
+ l1++) {}
+ l2 = strlen(fname) - l1;
+
+ if (l1 > 0)
+ flags |= SAME_NAME;
+ if (l2 > 255)
+ flags |= LONG_NAME;
+
+ /* we must make sure we don't send a zero flags byte or the other
+ end will terminate the flist transfer */
+ if (flags == 0 && !S_ISDIR(file->mode))
+ flags |= FLAG_DELETE;
+ if (flags == 0)
+ flags |= LONG_NAME;
+
+ write_byte(f, flags);
+ if (flags & SAME_NAME)
+ write_byte(f, l1);
+ if (flags & LONG_NAME)
+ write_int(f, l2);
+ else
+ write_byte(f, l2);
+ write_buf(f, fname + l1, l2);
+
+ write_longint(f, file->length);
+ if (!(flags & SAME_TIME))
+ write_int(f, (int) file->modtime);
+ if (!(flags & SAME_MODE))
+ write_int(f, to_wire_mode(file->mode));
+ if (preserve_uid && !(flags & SAME_UID)) {
+ add_uid(file->uid);
+ write_int(f, (int) file->uid);
+ }
+ if (preserve_gid && !(flags & SAME_GID)) {
+ add_gid(file->gid);
+ write_int(f, (int) file->gid);
+ }
+ if (preserve_devices && IS_DEVICE(file->mode)
+ && !(flags & SAME_RDEV))
+ write_int(f, (int) file->rdev);