+/*
+ * Check to see if an "etc" path consists of a catman.conf file. If it
+ * does, that means that the path contains a tree created by catman(8)
+ * and should be used for indexing.
+ */
+static int
+pathstop(DIR *dir)
+{
+ struct dirent *d;
+
+ while (NULL != (d = readdir(dir)))
+ if (DT_REG == d->d_type)
+ if (0 == strcmp(d->d_name, "catman.conf"))
+ return(1);
+
+ return(0);
+}
+
+/*
+ * Scan for indexable paths.
+ * This adds all paths with "etc/catman.conf" to the buffer.
+ */
+static void
+pathgen(DIR *dir, char *path, struct req *req)
+{
+ struct dirent *d;
+ char *cp;
+ DIR *cd;
+ int rc;
+ size_t sz, ssz;
+
+ sz = strlcat(path, "/", MAXPATHLEN);
+ if (sz >= MAXPATHLEN) {
+ fprintf(stderr, "%s: Path too long", path);
+ return;
+ }
+
+ /*
+ * First, scan for the "etc" directory.
+ * If it's found, then see if it should cause us to stop. This
+ * happens when a catman.conf is found in the directory.
+ */
+
+ rc = 0;
+ while (0 == rc && NULL != (d = readdir(dir))) {
+ if (DT_DIR != d->d_type || strcmp(d->d_name, "etc"))
+ continue;
+
+ path[(int)sz] = '\0';
+ ssz = strlcat(path, d->d_name, MAXPATHLEN);
+
+ if (ssz >= MAXPATHLEN) {
+ fprintf(stderr, "%s: Path too long", path);
+ return;
+ } else if (NULL == (cd = opendir(path))) {
+ perror(path);
+ return;
+ }
+
+ rc = pathstop(cd);
+ closedir(cd);
+ }
+
+ if (rc > 0) {
+ /* This also strips the trailing slash. */
+ path[(int)--sz] = '\0';
+ req->p = mandoc_realloc
+ (req->p,
+ (req->psz + 1) * sizeof(struct paths));
+ /*
+ * Strip out the leading "./" unless we're just a ".",
+ * in which case use an empty string as our name.
+ */
+ req->p[(int)req->psz].path = mandoc_strdup(path);
+ req->p[(int)req->psz].name =
+ cp = mandoc_strdup(path + (1 == sz ? 1 : 2));
+ req->psz++;
+ /*
+ * The name is just the path with all the slashes taken
+ * out of it. Simple but effective.
+ */
+ for ( ; '\0' != *cp; cp++)
+ if ('/' == *cp)
+ *cp = ' ';
+ return;
+ }
+
+ /*
+ * If no etc/catman.conf was found, recursively enter child
+ * directory and continue scanning.
+ */
+
+ rewinddir(dir);
+ while (NULL != (d = readdir(dir))) {
+ if (DT_DIR != d->d_type || '.' == d->d_name[0])
+ continue;
+
+ path[(int)sz] = '\0';
+ ssz = strlcat(path, d->d_name, MAXPATHLEN);
+
+ if (ssz >= MAXPATHLEN) {
+ fprintf(stderr, "%s: Path too long", path);
+ return;
+ } else if (NULL == (cd = opendir(path))) {
+ perror(path);
+ return;
+ }
+
+ pathgen(cd, path, req);
+ closedir(cd);
+ }
+}