+ struct rectree tree;
+ struct mchars *mc;
+ struct res *ress;
+ int i, mlen, rc;
+
+ memset(&tree, 0, sizeof(struct rectree));
+
+ rc = 0;
+ mc = mchars_alloc();
+
+ /*
+ * Main loop. Change into the directory containing manpage
+ * databases. Run our expession over each database in the set.
+ */
+
+ for (i = 0; i < pathsz; i++) {
+ if (chdir(paths[i]))
+ continue;
+ if ( ! single_search(&tree, opts, expr, terms, mc, i))
+ goto out;
+ }
+
+ /*
+ * Count matching files, transfer to a "clean" array, then feed
+ * them to the output handler.
+ */
+
+ for (mlen = i = 0; i < tree.len; i++)
+ if (tree.node[i].matched)
+ mlen++;
+
+ ress = mandoc_malloc(mlen * sizeof(struct res));
+
+ for (mlen = i = 0; i < tree.len; i++)
+ if (tree.node[i].matched)
+ memcpy(&ress[mlen++], &tree.node[i].res,
+ sizeof(struct res));
+
+ (*res)(ress, mlen, arg);
+ free(ress);
+
+ rc = 1;
+out:
+ for (i = 0; i < tree.len; i++)
+ recfree(&tree.node[i]);
+
+ free(tree.node);
+ mchars_free(mc);
+ return(rc);
+}
+
+static int
+single_search(struct rectree *tree, const struct opts *opts,
+ const struct expr *expr, size_t terms,
+ struct mchars *mc, int vol)
+{
+ int root, leaf, ch;