More tweaks for Actions.
[rsync.git] / flist.c
diff --git a/flist.c b/flist.c
index bbc028bae952a63c23f62178c767e155ade1d390..464d556ec906a572d2c378ac79e6d0fa169dd003 100644 (file)
--- a/flist.c
+++ b/flist.c
@@ -4,7 +4,7 @@
  * Copyright (C) 1996 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras
  * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2002-2020 Wayne Davison
+ * Copyright (C) 2002-2023 Wayne Davison
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -33,7 +33,6 @@ extern int am_sender;
 extern int am_generator;
 extern int inc_recurse;
 extern int always_checksum;
-extern int checksum_type;
 extern int module_id;
 extern int ignore_errors;
 extern int numeric_ids;
@@ -43,6 +42,7 @@ extern int use_qsort;
 extern int xfer_dirs;
 extern int filesfrom_fd;
 extern int one_file_system;
+extern int copy_devices;
 extern int copy_dirlinks;
 extern int preserve_uid;
 extern int preserve_gid;
@@ -56,6 +56,7 @@ extern int delete_during;
 extern int missing_args;
 extern int eol_nulls;
 extern int atimes_ndx;
+extern int crtimes_ndx;
 extern int relative_paths;
 extern int implied_dirs;
 extern int ignore_perishable;
@@ -71,18 +72,20 @@ extern int need_unsorted_flist;
 extern int sender_symlink_iconv;
 extern int output_needs_newline;
 extern int sender_keeps_checksum;
+extern int trust_sender_filter;
 extern int unsort_ndx;
 extern uid_t our_uid;
 extern struct stats stats;
 extern char *filesfrom_host;
 extern char *usermap, *groupmap;
 
+extern struct name_num_item *file_sum_nni;
+
 extern char curr_dir[MAXPATHLEN];
 
 extern struct chmod_mode_struct *chmod_modes;
 
-extern filter_rule_list filter_list;
-extern filter_rule_list daemon_filter_list;
+extern filter_rule_list filter_list, implied_filter_list, daemon_filter_list;
 
 #ifdef ICONV_OPTION
 extern int filesfrom_convert;
@@ -133,6 +136,7 @@ static char empty_sum[MAX_DIGEST_LEN];
 static int flist_count_offset; /* for --delete --progress */
 static int show_filelist_progress;
 
+static struct file_list *flist_new(int flags, const char *msg);
 static void flist_sort_and_clean(struct file_list *flist, int strip_root);
 static void output_flist(struct file_list *flist);
 
@@ -142,7 +146,8 @@ void init_flist(void)
                rprintf(FINFO, "FILE_STRUCT_LEN=%d, EXTRA_LEN=%d\n",
                        (int)FILE_STRUCT_LEN, (int)EXTRA_LEN);
        }
-       flist_csum_len = csum_len_for_type(checksum_type, 1);
+       /* Note that this isn't identical to file_sum_len in the case of CSUM_MD4_ARCHAIC: */
+       flist_csum_len = csum_len_for_type(file_sum_nni->num, 1);
 
        show_filelist_progress = INFO_GTE(FLIST, 1) && xfer_dirs && !am_server && !inc_recurse;
 }
@@ -293,6 +298,8 @@ static void flist_expand(struct file_list *flist, int extra)
                flist->malloced = FLIST_START;
        else if (flist->malloced >= FLIST_LINEAR)
                flist->malloced += FLIST_LINEAR;
+       else if (flist->malloced < FLIST_START_LARGE/16)
+               flist->malloced *= 4;
        else
                flist->malloced *= 2;
 
@@ -301,10 +308,9 @@ static void flist_expand(struct file_list *flist, int extra)
        if (flist->malloced < flist->used + extra)
                flist->malloced = flist->used + extra;
 
-       new_ptr = realloc_array(flist->files, struct file_struct *,
-                               flist->malloced);
+       new_ptr = realloc_array(flist->files, struct file_struct *, flist->malloced);
 
-       if (DEBUG_GTE(FLIST, 1) && flist->malloced != FLIST_START) {
+       if (DEBUG_GTE(FLIST, 1) && flist->files) {
                rprintf(FCLIENT, "[%s] expand file_list pointer array to %s bytes, did%s move\n",
                    who_am_i(),
                    big_num(sizeof flist->files[0] * flist->malloced),
@@ -312,9 +318,6 @@ static void flist_expand(struct file_list *flist, int extra)
        }
 
        flist->files = new_ptr;
-
-       if (!flist->files)
-               out_of_memory("flist_expand");
 }
 
 static void flist_done_allocating(struct file_list *flist)
@@ -381,6 +384,9 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
                            int ndx, int first_ndx)
 {
        static time_t modtime, atime;
+#ifdef SUPPORT_CRTIMES
+       static time_t crtime;
+#endif
        static mode_t mode;
 #ifdef SUPPORT_HARD_LINKS
        static int64 dev;
@@ -447,7 +453,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
                if (protocol_version < 28)
                        xflags |= XMIT_SAME_RDEV_pre28;
                else {
-                       rdev = MAKEDEV(major(rdev), 0);
+                       rdev = MAKEDEV(rdev_major, 0);
                        xflags |= XMIT_SAME_RDEV_MAJOR;
                        if (protocol_version < 30)
                                xflags |= XMIT_RDEV_MINOR_8_pre30;
@@ -486,6 +492,13 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
                else
                        atime = F_ATIME(file);
        }
+#ifdef SUPPORT_CRTIMES
+       if (crtimes_ndx) {
+               crtime = F_CRTIME(file);
+               if (crtime == modtime)
+                       xflags |= XMIT_CRTIME_EQ_MTIME;
+       }
+#endif
 
 #ifdef SUPPORT_HARD_LINKS
        if (tmp_dev != -1) {
@@ -573,6 +586,10 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
        }
        if (xflags & XMIT_MOD_NSEC)
                write_varint(f, F_MOD_NSEC(file));
+#ifdef SUPPORT_CRTIMES
+       if (crtimes_ndx && !(xflags & XMIT_CRTIME_EQ_MTIME))
+               write_varlong(f, crtime, 4);
+#endif
        if (!(xflags & XMIT_SAME_MODE))
                write_int(f, to_wire_mode(mode));
        if (atimes_ndx && !S_ISDIR(mode) && !(xflags & XMIT_SAME_ATIME))
@@ -665,6 +682,9 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file,
 static struct file_struct *recv_file_entry(int f, struct file_list *flist, int xflags)
 {
        static int64 modtime, atime;
+#ifdef SUPPORT_CRTIMES
+       static time_t crtime;
+#endif
        static mode_t mode;
 #ifdef SUPPORT_HARD_LINKS
        static int64 dev;
@@ -683,8 +703,11 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
        int alloc_len, basename_len, linkname_len;
        int extra_len = file_extra_cnt * EXTRA_LEN;
        int first_hlink_ndx = -1;
+       char real_ISREG_entry;
        int64 file_length;
+#ifdef CAN_SET_NSEC
        uint32 modtime_nsec;
+#endif
        const char *basename;
        struct file_struct *file;
        alloc_pool_t *pool;
@@ -733,7 +756,7 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
        if (*thisname
         && (clean_fname(thisname, CFN_REFUSE_DOT_DOT_DIRS) < 0 || (!relative_paths && *thisname == '/'))) {
                rprintf(FERROR, "ABORTING due to unsafe pathname from sender: %s\n", thisname);
-               exit_cleanup(RERR_PROTOCOL);
+               exit_cleanup(RERR_UNSUPPORTED);
        }
 
        if (sanitize_paths)
@@ -771,23 +794,31 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
                        struct file_struct *first = flist->files[first_hlink_ndx - flist->ndx_start];
                        file_length = F_LENGTH(first);
                        modtime = first->modtime;
+#ifdef CAN_SET_NSEC
                        modtime_nsec = F_MOD_NSEC_or_0(first);
+#endif
                        mode = first->mode;
                        if (atimes_ndx && !S_ISDIR(mode))
                                atime = F_ATIME(first);
+#ifdef SUPPORT_CRTIMES
+                       if (crtimes_ndx)
+                               crtime = F_CRTIME(first);
+#endif
                        if (preserve_uid)
                                uid = F_OWNER(first);
                        if (preserve_gid)
                                gid = F_GROUP(first);
                        if (preserve_devices && IS_DEVICE(mode)) {
                                uint32 *devp = F_RDEV_P(first);
-                               rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
+                               rdev_major = DEV_MAJOR(devp);
+                               rdev = MAKEDEV(rdev_major, DEV_MINOR(devp));
                                extra_len += DEV_EXTRA_CNT * EXTRA_LEN;
                        }
                        if (preserve_links && S_ISLNK(mode))
                                linkname_len = strlen(F_SYMLINK(first)) + 1;
                        else
                                linkname_len = 0;
+                       real_ISREG_entry = S_ISREG(mode) ? 1 : 0;
                        goto create_object;
                }
        }
@@ -805,12 +836,31 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
                        }
 #endif
                } else
-                       modtime = read_int(f);
+                       modtime = read_uint(f);
        }
        if (xflags & XMIT_MOD_NSEC)
+#ifndef CAN_SET_NSEC
+               (void)read_varint(f);
+#else
                modtime_nsec = read_varint(f);
        else
                modtime_nsec = 0;
+#endif
+#ifdef SUPPORT_CRTIMES
+       if (crtimes_ndx) {
+               if (xflags & XMIT_CRTIME_EQ_MTIME)
+                       crtime = modtime;
+               else
+                       crtime = read_varlong(f, 4);
+#if SIZEOF_TIME_T < SIZEOF_INT64
+               if (!am_generator && (int64)(time_t)crtime != crtime) {
+                       rprintf(FERROR_XFER,
+                               "Create time value of %s truncated on receiver.\n",
+                               lastname);
+               }
+#endif
+       }
+#endif
        if (!(xflags & XMIT_SAME_MODE))
                mode = from_wire_mode(read_int(f));
        if (atimes_ndx && !S_ISDIR(mode) && !(xflags & XMIT_SAME_ATIME)) {
@@ -896,10 +946,20 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
 #endif
                linkname_len = 0;
 
+       if (copy_devices && IS_DEVICE(mode)) {
+               /* This is impossible in the official release, but some pre-release patches
+                * didn't convert the device into a file before sending, so we'll do it here
+                * (even though the length is typically 0 and any checksum data is zeros). */
+               mode = S_IFREG | (mode & ACCESSPERMS);
+               modtime = time(NULL); /* The mtime on the device is not up-to-date, so set it to "now". */
+               real_ISREG_entry = 0;
+       } else
+               real_ISREG_entry = S_ISREG(mode) ? 1 : 0;
+
 #ifdef SUPPORT_HARD_LINKS
   create_object:
        if (preserve_hard_links) {
-               if (protocol_version < 28 && S_ISREG(mode))
+               if (protocol_version < 28 && real_ISREG_entry)
                        xflags |= XMIT_HLINKED;
                if (xflags & XMIT_HLINKED)
                        extra_len += (inc_recurse+1) * EXTRA_LEN;
@@ -928,6 +988,19 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
                exit_cleanup(RERR_UNSUPPORTED);
        }
 
+       if (*thisname == '/' ? thisname[1] != '.' || thisname[2] != '\0' : *thisname != '.' || thisname[1] != '\0') {
+               int filt_flags = S_ISDIR(mode) ? NAME_IS_DIR : NAME_IS_FILE;
+               if (!trust_sender_filter /* a per-dir filter rule means we must trust the sender's filtering */
+                && filter_list.head && check_server_filter(&filter_list, FINFO, thisname, filt_flags) < 0) {
+                       rprintf(FERROR, "ERROR: rejecting excluded file-list name: %s\n", thisname);
+                       exit_cleanup(RERR_UNSUPPORTED);
+               }
+               if (implied_filter_list.head && check_filter(&implied_filter_list, FINFO, thisname, filt_flags) <= 0) {
+                       rprintf(FERROR, "ERROR: rejecting unrequested file-list name: %s\n", thisname);
+                       exit_cleanup(RERR_UNSUPPORTED);
+               }
+       }
+
        if (inc_recurse && S_ISDIR(mode)) {
                if (one_file_system) {
                        /* Room to save the dir's device for -x */
@@ -992,6 +1065,10 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
        }
        if (atimes_ndx && !S_ISDIR(mode))
                F_ATIME(file) = atime;
+#ifdef SUPPORT_CRTIMES
+       if (crtimes_ndx)
+               F_CRTIME(file) = crtime;
+#endif
        if (unsort_ndx)
                F_NDX(file) = flist->used + flist->ndx_start;
 
@@ -1111,8 +1188,8 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
        }
 #endif
 
-       if (always_checksum && (S_ISREG(mode) || protocol_version < 28)) {
-               if (S_ISREG(mode))
+       if (always_checksum && (real_ISREG_entry || protocol_version < 28)) {
+               if (real_ISREG_entry)
                        bp = F_SUM(file);
                else {
                        /* Prior to 28, we get a useless set of nulls. */
@@ -1311,6 +1388,18 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
        linkname_len = 0;
 #endif
 
+       if (copy_devices && am_sender && IS_DEVICE(st.st_mode)) {
+               if (st.st_size == 0) {
+                       int fd = do_open(fname, O_RDONLY, 0);
+                       if (fd >= 0) {
+                               st.st_size = get_device_size(fd, fname);
+                               close(fd);
+                       }
+               }
+               st.st_mode = S_IFREG | (st.st_mode & ACCESSPERMS);
+               st.st_mtime = time(NULL); /* The mtime on the device is not up-to-date, so set it to "now". */
+       }
+
 #ifdef ST_MTIME_NSEC
        if (st.ST_MTIME_NSEC && protocol_version >= 31)
                extra_len += EXTRA_LEN;
@@ -1335,10 +1424,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
                  + 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");
-       }
+       else
+               bp = new_array(char, alloc_len);
 
        memset(bp, 0, extra_len + FILE_STRUCT_LEN);
        bp += extra_len;
@@ -1391,6 +1478,10 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
                file->flags |= FLAG_OWNED_BY_US;
        if (atimes_ndx && !S_ISDIR(file->mode))
                F_ATIME(file) = st.st_atime;
+#ifdef SUPPORT_CRTIMES
+       if (crtimes_ndx)
+               F_CRTIME(file) = get_create_time(fname, &st);
+#endif
 
        if (basename != thisname)
                file->dirname = lastdir;
@@ -1661,8 +1752,7 @@ static void fsort(struct file_struct **fp, size_t num)
        if (use_qsort)
                qsort(fp, num, PTR_SIZE, file_compare);
        else {
-               struct file_struct **tmp = new_array(struct file_struct *,
-                                                    (num+1) / 2);
+               struct file_struct **tmp = new_array(struct file_struct *, (num+1) / 2);
                fsort_tmp(fp, num, tmp);
                free(tmp);
        }
@@ -1895,13 +1985,11 @@ static void send_implied_dirs(int f, struct file_list *flist, char *fname,
        len = strlen(limit+1);
        memcpy(&relname_list, F_DIR_RELNAMES_P(lastpath_struct), sizeof relname_list);
        if (!relname_list) {
-               if (!(relname_list = new0(item_list)))
-                       out_of_memory("send_implied_dirs");
+               relname_list = new0(item_list);
                memcpy(F_DIR_RELNAMES_P(lastpath_struct), &relname_list, sizeof relname_list);
        }
        rnpp = EXPAND_ITEM_LIST(relname_list, relnamecache *, 32);
-       if (!(*rnpp = (relnamecache*)new_array(char, sizeof (relnamecache) + len)))
-               out_of_memory("send_implied_dirs");
+       *rnpp = (relnamecache*)new_array(char, RELNAMECACHE_LEN + len + 1);
        (*rnpp)->name_type = name_type;
        strlcpy((*rnpp)->fname, limit+1, len + 1);
 
@@ -2059,10 +2147,8 @@ void send_extra_file_list(int f, int at_least)
                }
 
                if (need_unsorted_flist) {
-                       if (!(flist->sorted = new_array(struct file_struct *, flist->used)))
-                               out_of_memory("send_extra_file_list");
-                       memcpy(flist->sorted, flist->files,
-                              flist->used * sizeof (struct file_struct*));
+                       flist->sorted = new_array(struct file_struct *, flist->used);
+                       memcpy(flist->sorted, flist->files, flist->used * PTR_SIZE);
                } else
                        flist->sorted = flist->files;
 
@@ -2142,8 +2228,10 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
 #endif
 
        flist = cur_flist = flist_new(0, "send_file_list");
+       flist_expand(flist, FLIST_START_LARGE);
        if (inc_recurse) {
                dir_flist = flist_new(FLIST_TEMP, "send_file_list");
+               flist_expand(dir_flist, FLIST_START_LARGE);
                flags |= FLAG_DIVERT_DIRS;
        } else
                dir_flist = cur_flist;
@@ -2279,7 +2367,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
                }
 
                dirlen = dir ? strlen(dir) : 0;
-               if (dirlen != lastdir_len || memcmp(lastdir, dir, dirlen) != 0) {
+               if (dirlen != lastdir_len || (dirlen && memcmp(lastdir, dir, dirlen) != 0)) {
                        if (!change_pathname(NULL, dir, -dirlen))
                                goto bad_path;
                        lastdir = pathname;
@@ -2414,10 +2502,8 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
         * recursion mode, the sender marks duplicate dirs so that it can
         * send them together in a single file-list. */
        if (need_unsorted_flist) {
-               if (!(flist->sorted = new_array(struct file_struct *, flist->used)))
-                       out_of_memory("send_file_list");
-               memcpy(flist->sorted, flist->files,
-                      flist->used * sizeof (struct file_struct*));
+               flist->sorted = new_array(struct file_struct *, flist->used);
+               memcpy(flist->sorted, flist->files, flist->used * PTR_SIZE);
        } else
                flist->sorted = flist->files;
        flist_sort_and_clean(flist, 0);
@@ -2425,7 +2511,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
        file_old_total += flist->used;
 
        if (numeric_ids <= 0 && !inc_recurse)
-               send_id_list(f);
+               send_id_lists(f);
 
        /* send the io_error flag */
        if (protocol_version < 30)
@@ -2499,10 +2585,13 @@ struct file_list *recv_file_list(int f, int dir_ndx)
 #endif
 
        flist = flist_new(0, "recv_file_list");
+       flist_expand(flist, FLIST_START_LARGE);
 
        if (inc_recurse) {
-               if (flist->ndx_start == 1)
+               if (flist->ndx_start == 1) {
                        dir_flist = flist_new(FLIST_TEMP, "recv_file_list");
+                       flist_expand(dir_flist, FLIST_START_LARGE);
+               }
                dstart = dir_flist->used;
        } else {
                dir_flist = flist;
@@ -2553,7 +2642,7 @@ struct file_list *recv_file_list(int f, int dir_ndx)
                                        rprintf(FERROR,
                                                "ABORTING due to invalid path from sender: %s/%s\n",
                                                cur_dir, file->basename);
-                                       exit_cleanup(RERR_PROTOCOL);
+                                       exit_cleanup(RERR_UNSUPPORTED);
                                }
                                good_dirname = cur_dir;
                        }
@@ -2570,7 +2659,7 @@ struct file_list *recv_file_list(int f, int dir_ndx)
                } else if (S_ISLNK(file->mode))
                        stats.num_symlinks++;
                else if (IS_DEVICE(file->mode))
-                       stats.num_symlinks++;
+                       stats.num_devices++;
                else
                        stats.num_specials++;
 
@@ -2597,10 +2686,8 @@ struct file_list *recv_file_list(int f, int dir_ndx)
                 * order and for calling flist_find()).  We keep the "files"
                 * list unsorted for our exchange of index numbers with the
                 * other side (since their names may not sort the same). */
-               if (!(flist->sorted = new_array(struct file_struct *, flist->used)))
-                       out_of_memory("recv_file_list");
-               memcpy(flist->sorted, flist->files,
-                      flist->used * sizeof (struct file_struct*));
+               flist->sorted = new_array(struct file_struct *, flist->used);
+               memcpy(flist->sorted, flist->files, flist->used * PTR_SIZE);
                if (inc_recurse && dir_flist->used > dstart) {
                        static int dir_flist_malloced = 0;
                        if (dir_flist_malloced < dir_flist->malloced) {
@@ -2610,7 +2697,7 @@ struct file_list *recv_file_list(int f, int dir_ndx)
                                dir_flist_malloced = dir_flist->malloced;
                        }
                        memcpy(dir_flist->sorted + dstart, dir_flist->files + dstart,
-                              (dir_flist->used - dstart) * sizeof (struct file_struct*));
+                              (dir_flist->used - dstart) * PTR_SIZE);
                        fsort(dir_flist->sorted + dstart, dir_flist->used - dstart);
                }
        } else {
@@ -2742,28 +2829,28 @@ int flist_find(struct file_list *flist, struct file_struct *f)
  * 1=match directories, 0=match non-directories, or -1=match either. */
 int flist_find_name(struct file_list *flist, const char *fname, int want_dir_match)
 {
-       struct { /* We have to create a temporary file_struct for the search. */
-               struct file_struct f;
-               char name_space[MAXPATHLEN];
-       } t;
+       static struct file_struct *f;
        char fbuf[MAXPATHLEN];
        const char *slash = strrchr(fname, '/');
        const char *basename = slash ? slash+1 : fname;
 
-       memset(&t.f, 0, FILE_STRUCT_LEN);
-       memcpy((void *)t.f.basename, basename, strlen(basename)+1);
+       if (!f)
+               f = (struct file_struct*)new_array(char, FILE_STRUCT_LEN + MAXPATHLEN + 1);
+
+       memset(f, 0, FILE_STRUCT_LEN);
+       memcpy((void*)f->basename, basename, strlen(basename)+1);
 
        if (slash) {
                strlcpy(fbuf, fname, slash - fname + 1);
-               t.f.dirname = fbuf;
+               f->dirname = fbuf;
        } else
-               t.f.dirname = NULL;
+               f->dirname = NULL;
 
-       t.f.mode = want_dir_match > 0 ? S_IFDIR : S_IFREG;
+       f->mode = want_dir_match > 0 ? S_IFDIR : S_IFREG;
 
        if (want_dir_match < 0)
-               return flist_find_ignore_dirness(flist, &t.f);
-       return flist_find(flist, &t.f);
+               return flist_find_ignore_dirness(flist, f);
+       return flist_find(flist, f);
 }
 
 /* Search for an identically-named item in the file list.  Differs from
@@ -2804,26 +2891,20 @@ void clear_file(struct file_struct *file)
 }
 
 /* Allocate a new file list. */
-struct file_list *flist_new(int flags, char *msg)
+static struct file_list *flist_new(int flags, const char *msg)
 {
        struct file_list *flist;
 
-       if (!(flist = new0(struct file_list)))
-               out_of_memory(msg);
+       flist = new0(struct file_list);
 
        if (flags & FLIST_TEMP) {
-               if (!(flist->file_pool = pool_create(SMALL_EXTENT, 0,
-                                                    out_of_memory,
-                                                    POOL_INTERN)))
+               if (!(flist->file_pool = pool_create(SMALL_EXTENT, 0, _out_of_memory, POOL_INTERN)))
                        out_of_memory(msg);
        } else {
                /* This is a doubly linked list with prev looping back to
                 * the end of the list, but the last next pointer is NULL. */
                if (!first_flist) {
-                       flist->file_pool = pool_create(NORMAL_EXTENT, 0,
-                                                      out_of_memory,
-                                                      POOL_INTERN);
-                       if (!flist->file_pool)
+                       if (!(flist->file_pool = pool_create(NORMAL_EXTENT, 0, _out_of_memory, POOL_INTERN)))
                                out_of_memory(msg);
 
                        flist->ndx_start = flist->flist_num = inc_recurse ? 1 : 0;