+#ifdef SUPPORT_LINKS
+ linkname_len = S_ISLNK(st.st_mode) ? strlen(linkname) + 1 : 0;
+#else
+ linkname_len = 0;
+#endif
+
+ if (st.st_size > 0xFFFFFFFFu && S_ISREG(st.st_mode))
+ extra_len += EXTRA_LEN;
+
+#if EXTRA_ROUNDING > 0
+ if (extra_len & (EXTRA_ROUNDING * EXTRA_LEN))
+ extra_len = (extra_len | (EXTRA_ROUNDING * EXTRA_LEN)) + EXTRA_LEN;
+#endif
+
+ alloc_len = FILE_STRUCT_LEN + extra_len + basename_len
+ + linkname_len;
+ if (pool)
+ bp = pool_alloc(pool, alloc_len, "make_file");
+ else {
+ if (!(bp = new_array(char, alloc_len)))
+ out_of_memory("make_file");
+ }
+
+ memset(bp, 0, extra_len + FILE_STRUCT_LEN);
+ bp += extra_len;
+ file = (struct file_struct *)bp;
+ bp += FILE_STRUCT_LEN;
+
+ memcpy(bp, basename, basename_len);
+
+#ifdef SUPPORT_HARD_LINKS
+ if (preserve_hard_links && flist && flist->prev) {
+ if (protocol_version >= 28
+ ? (!S_ISDIR(st.st_mode) && st.st_nlink > 1)
+ : S_ISREG(st.st_mode)) {
+ tmp_dev = st.st_dev;
+ tmp_ino = st.st_ino;
+ } else
+ tmp_dev = 0;
+ }
+#endif
+
+#ifdef HAVE_STRUCT_STAT_ST_RDEV
+ if (IS_DEVICE(st.st_mode) || IS_SPECIAL(st.st_mode)) {
+ tmp_rdev = st.st_rdev;
+ st.st_size = 0;
+ }
+#endif
+
+ file->flags = flags;
+ file->modtime = st.st_mtime;
+ file->len32 = (uint32)st.st_size;
+ if (st.st_size > 0xFFFFFFFFu && S_ISREG(st.st_mode)) {
+ file->flags |= FLAG_LENGTH64;
+ OPT_EXTRA(file, 0)->unum = (uint32)(st.st_size >> 32);
+ }
+ file->mode = st.st_mode;
+ if (uid_ndx) /* Check uid_ndx instead of preserve_uid for del support */
+ F_OWNER(file) = st.st_uid;
+ if (gid_ndx) /* Check gid_ndx instead of preserve_gid for del support */
+ F_GROUP(file) = st.st_gid;
+
+ if (basename != thisname)
+ file->dirname = lastdir;
+
+#ifdef SUPPORT_LINKS
+ if (linkname_len)
+ memcpy(bp + basename_len, linkname, linkname_len);
+#endif
+
+ if (always_checksum && am_sender && S_ISREG(st.st_mode))
+ file_checksum(thisname, tmp_sum, st.st_size);
+
+ if (am_sender)
+ F_PATHNAME(file) = pathname;
+ else if (!pool)
+ F_DEPTH(file) = extra_len / EXTRA_LEN;
+
+ /* This code is only used by the receiver when it is building
+ * a list of files for a delete pass. */
+ if (keep_dirlinks && linkname_len && flist) {
+ STRUCT_STAT st2;
+ int save_mode = file->mode;
+ file->mode = S_IFDIR; /* Find a directory with our name. */
+ if (flist_find(dir_flist, file) >= 0
+ && x_stat(thisname, &st2, NULL) == 0 && S_ISDIR(st2.st_mode)) {
+ file->modtime = st2.st_mtime;
+ file->len32 = 0;
+ file->mode = st2.st_mode;
+ if (uid_ndx)
+ F_OWNER(file) = st2.st_uid;
+ if (gid_ndx)
+ F_GROUP(file) = st2.st_gid;
+ } else
+ file->mode = save_mode;
+ }
+
+ if (basename_len == 0+1) {
+ if (!pool)
+ unmake_file(file);
+ return NULL;
+ }
+
+ if (unsort_ndx)
+ F_NDX(file) = dir_count;
+
+ return file;
+}
+
+/* Only called for temporary file_struct entries created by make_file(). */
+void unmake_file(struct file_struct *file)