+static struct dumpdir *
+dumpdir_create0 (const char *contents, const char *cmask)
+{
+ struct dumpdir *dump;
+ size_t i, total, ctsize, len;
+ char *p;
+ const char *q;
+
+ for (i = 0, total = 0, ctsize = 1, q = contents; *q; total++, q += len)
+ {
+ len = strlen (q) + 1;
+ ctsize += len;
+ if (!cmask || strchr (cmask, *q))
+ i++;
+ }
+ dump = xmalloc (sizeof (*dump) + ctsize);
+ dump->contents = (char*)(dump + 1);
+ memcpy (dump->contents, contents, ctsize);
+ dump->total = total;
+ dump->elc = i;
+ dump->elv = xcalloc (i + 1, sizeof (dump->elv[0]));
+
+ for (i = 0, p = dump->contents; *p; p += strlen (p) + 1)
+ {
+ if (!cmask || strchr (cmask, *p))
+ dump->elv[i++] = p + 1;
+ }
+ dump->elv[i] = NULL;
+ return dump;
+}
+
+static struct dumpdir *
+dumpdir_create (const char *contents)
+{
+ return dumpdir_create0 (contents, "YND");
+}
+
+static void
+dumpdir_free (struct dumpdir *dump)
+{
+ free (dump->elv);
+ free (dump);
+}
+
+static int
+compare_dirnames (const void *first, const void *second)
+{
+ char const *const *name1 = first;
+ char const *const *name2 = second;
+ return strcmp (*name1, *name2);
+}
+
+/* Locate NAME in the dumpdir array DUMP.
+ Return pointer to the slot in DUMP->contents, or NULL if not found */
+static char *
+dumpdir_locate (struct dumpdir *dump, const char *name)
+{
+ char **ptr;
+ if (!dump)
+ return NULL;
+
+ ptr = bsearch (&name, dump->elv, dump->elc, sizeof (dump->elv[0]),
+ compare_dirnames);
+ return ptr ? *ptr - 1: NULL;
+}
+
+struct dumpdir_iter
+{
+ struct dumpdir *dump; /* Dumpdir being iterated */
+ int all; /* Iterate over all entries, not only D/N/Y */
+ size_t next; /* Index of the next element */
+};
+
+static char *
+dumpdir_next (struct dumpdir_iter *itr)
+{
+ size_t cur = itr->next;
+ char *ret = NULL;
+
+ if (itr->all)
+ {
+ ret = itr->dump->contents + cur;
+ if (*ret == 0)
+ return NULL;
+ itr->next += strlen (ret) + 1;
+ }
+ else if (cur < itr->dump->elc)
+ {
+ ret = itr->dump->elv[cur] - 1;
+ itr->next++;
+ }
+
+ return ret;
+}
+
+static char *
+dumpdir_first (struct dumpdir *dump, int all, struct dumpdir_iter **pitr)
+{
+ struct dumpdir_iter *itr = xmalloc (sizeof (*itr));
+ itr->dump = dump;
+ itr->all = all;
+ itr->next = 0;
+ *pitr = itr;
+ return dumpdir_next (itr);
+}
+
+/* Return size in bytes of the dumpdir array P */
+size_t
+dumpdir_size (const char *p)
+{
+ size_t totsize = 0;
+
+ while (*p)
+ {
+ size_t size = strlen (p) + 1;
+ totsize += size;
+ p += size;
+ }
+ return totsize + 1;
+}
+
+\f
+static struct directory *dirhead, *dirtail;