summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2019-01-26 12:55:56 +0000
committerColin Watson <cjwatson@debian.org>2019-01-26 12:55:56 +0000
commit199a6e80e7b4baa27e195f2c1120c45df9ea4e67 (patch)
treed3a6b7b51caa32a576ca2061590c11d7514c178e
parent4f07b2663de8cb7e85c779b9d2c3142134847b35 (diff)
Remove arbitrary limit on manpath size
Fixes Savannah bug #50324. * bootstrap.conf (gnulib_modules): Add hash-pjw-bare, linkedhash-list, stdbool, and xlist. * include/manconfig.h.in (MAXDIRS): Remove. * src/manp.c (tmplist): Remove. (string_equals, string_hash, string_free): New functions. (gripe_overlong_list): Remove. (insert_override_dir, get_manpath_from_path, add_expanded_dir_to_list, add_dir_to_list, add_man_subdirs, add_dir_to_path_list, create_pathlist, free_pathlist): Port manpath list handling to gl_list_t. * src/catman.c (main): Likewise. * src/man.c (do_global_apropos, local_man_loop, locate_page_in_manpath, main): Likewise. * src/mandb.c (main): Likewise. * src/whatis.c (suitable_manpath, search, main): Likewise. * src/zsoelim.l (<<EOF>>, zsoelim_parse_file, zsoelim_open_file, zsoelim_stdin, zsoelim_stdin_data_new): Likewise. * src/zsoelim_main.c (main): Likewise. * src/manp.h (create_pathlist, free_pathlist): Update prototypes. * src/zsoelim.h (zsoelim_open_file, zsoelim_parse_file, zsoelim_stdin_data_new): Likewise. * NEWS: Document this.
-rw-r--r--NEWS2
-rw-r--r--bootstrap.conf4
-rw-r--r--include/manconfig.h.in4
-rw-r--r--src/catman.c28
-rw-r--r--src/man.c46
-rw-r--r--src/mandb.c24
-rw-r--r--src/manp.c207
-rw-r--r--src/manp.h6
-rw-r--r--src/whatis.c37
-rw-r--r--src/zsoelim.h8
-rw-r--r--src/zsoelim.l46
-rw-r--r--src/zsoelim_main.c5
12 files changed, 228 insertions, 189 deletions
diff --git a/NEWS b/NEWS
index 2843df88..244baad4 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,8 @@ Major changes since man-db 2.8.5:
them are now added to the automatically-determined manpath;
previously, only the first was considered.
+ * Remove arbitrary limit on manpath size.
+
man-db 2.8.5 (5 January 2019)
=============================
diff --git a/bootstrap.conf b/bootstrap.conf
index 4e6c149f..df1f07b2 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -36,9 +36,11 @@ gnulib_modules="
gitlog-to-changelog
glob
gnupload
+ hash-pjw-bare
idpriv-drop
idpriv-droptemp
lib-ignore
+ linkedhash-list
localcharset
lock
memmem
@@ -57,6 +59,7 @@ gnulib_modules="
signal
sigprocmask
stat-time
+ stdbool
strcasestr
strerror
strsep
@@ -66,6 +69,7 @@ gnulib_modules="
warnings
xalloc
xgetcwd
+ xlist
xstrndup
xvasprintf
"
diff --git a/include/manconfig.h.in b/include/manconfig.h.in
index 5c3ad648..db24db78 100644
--- a/include/manconfig.h.in
+++ b/include/manconfig.h.in
@@ -75,10 +75,6 @@
/* #define FAVOUR_STRAYCATS */
-/* The maximum number of manual page hierarchies expected in the manpath.
- Also the maximum amount of non-comment lines in the config file. */
-#define MAXDIRS 128
-
/* CATMODE is the mode of the formatted cat pages that we create. The man-db
package can be run in 4 main modes, 3 of which are relatively secure and
allow the cats to be non world writable. The `wide open' mode requires
diff --git a/src/catman.c b/src/catman.c
index 489b33ca..03cc018e 100644
--- a/src/catman.c
+++ b/src/catman.c
@@ -61,6 +61,7 @@
#endif /* !ARG_MAX */
#include "argp.h"
+#include "gl_list.h"
#include "progname.h"
#include "gettext.h"
@@ -164,7 +165,7 @@ static struct argp argp = { options, parse_opt, args_doc };
static char *locale;
-static char *manpathlist[MAXDIRS];
+static gl_list_t manpathlist;
static void post_fork (void)
{
@@ -353,7 +354,8 @@ static int check_access (const char *directory)
int main (int argc, char *argv[])
{
char *sys_manp;
- char **mp;
+ gl_list_iterator_t mpiter;
+ char *mp;
const char **sp;
set_program_name (argv[0]);
@@ -388,14 +390,15 @@ int main (int argc, char *argv[])
debug ("manpath=%s\n", manp);
- /* get the manpath as an array of pointers */
- create_pathlist (manp, manpathlist);
-
- for (mp = manpathlist; *mp; mp++) {
+ /* get the manpath as a list of pointers */
+ manpathlist = create_pathlist (manp);
+
+ mpiter = gl_list_iterator (manpathlist);
+ while (gl_list_iterator_next (&mpiter, (const void **) &mp, NULL)) {
char *catpath;
size_t len;
- catpath = get_catpath (*mp, SYSTEM_CAT | USER_CAT);
+ catpath = get_catpath (mp, SYSTEM_CAT | USER_CAT);
if (catpath) {
if (is_directory (catpath) != 1) {
@@ -404,10 +407,10 @@ int main (int argc, char *argv[])
}
database = mkdbname (catpath);
} else {
- if (is_directory (*mp) != 1)
+ if (is_directory (mp) != 1)
continue;
- database = mkdbname (*mp);
- catpath = xstrdup (*mp);
+ database = mkdbname (mp);
+ catpath = xstrdup (mp);
}
len = strlen (catpath);
@@ -419,14 +422,15 @@ int main (int argc, char *argv[])
continue;
if (check_access (catpath))
continue;
- if (parse_for_sec (*mp, *sp)) {
- error (0, 0, _("unable to update %s"), *mp);
+ if (parse_for_sec (mp, *sp)) {
+ error (0, 0, _("unable to update %s"), mp);
break;
}
}
free (catpath);
}
+ gl_list_iterator_free (&mpiter);
free_pathlist (manpathlist);
free (locale);
diff --git a/src/man.c b/src/man.c
index a1445964..6c16e74d 100644
--- a/src/man.c
+++ b/src/man.c
@@ -68,6 +68,7 @@
#include "argp.h"
#include "dirname.h"
+#include "gl_list.h"
#include "minmax.h"
#include "progname.h"
#include "regex.h"
@@ -182,7 +183,7 @@ struct string_llist {
};
-static char *manpathlist[MAXDIRS];
+static gl_list_t manpathlist;
/* globals */
int quiet = 1;
@@ -3742,7 +3743,6 @@ static int do_global_apropos (const char *name, int *found)
{
const char **my_section_list;
const char **sp;
- char **mp;
if (section) {
my_section_list = XNMALLOC (2, const char *);
@@ -3751,9 +3751,16 @@ static int do_global_apropos (const char *name, int *found)
} else
my_section_list = section_list;
- for (sp = my_section_list; *sp; sp++)
- for (mp = manpathlist; *mp; mp++)
- *found += do_global_apropos_section (*mp, *sp, name);
+ for (sp = my_section_list; *sp; sp++) {
+ gl_list_iterator_t mpiter;
+ char *mp;
+
+ mpiter = gl_list_iterator (manpathlist);
+ while (gl_list_iterator_next (&mpiter, (const void **) &mp,
+ NULL))
+ *found += do_global_apropos_section (mp, *sp, name);
+ gl_list_iterator_free (&mpiter);
+ }
if (section)
free (my_section_list);
@@ -3806,7 +3813,7 @@ static int local_man_loop (const char *argv)
if (directory_on_path (argv_dir)) {
char *argv_base = base_name (argv);
char *new_manp, *nm;
- char **old_manpathlist, **mp;
+ gl_list_t old_manpathlist;
debug ("recalculating manpath for executable "
"in %s\n", argv_dir);
@@ -3821,18 +3828,13 @@ static int local_man_loop (const char *argv)
free (new_manp);
new_manp = nm;
- old_manpathlist = XNMALLOC (MAXDIRS, char *);
- memcpy (old_manpathlist, manpathlist,
- MAXDIRS * sizeof (*manpathlist));
- create_pathlist (new_manp, manpathlist);
+ old_manpathlist = manpathlist;
+ manpathlist = create_pathlist (new_manp);
man (argv_base, &found);
- for (mp = manpathlist; *mp; ++mp)
- free (*mp);
- memcpy (manpathlist, old_manpathlist,
- MAXDIRS * sizeof (*manpathlist));
- free (old_manpathlist);
+ free_pathlist (manpathlist);
+ manpathlist = old_manpathlist;
executable_out:
free (new_manp);
free (argv_base);
@@ -3901,10 +3903,14 @@ static void locate_page_in_manpath (const char *page_section,
struct candidate **candidates,
int *found)
{
- char **mp;
-
- for (mp = manpathlist; *mp; mp++)
- *found += locate_page (*mp, page_section, page_name, candidates);
+ gl_list_iterator_t iter;
+ char *mp;
+
+ iter = gl_list_iterator (manpathlist);
+ while (gl_list_iterator_next (&iter, (const void **) &mp, NULL))
+ *found += locate_page (mp, page_section, page_name,
+ candidates);
+ gl_list_iterator_free (&iter);
}
/*
@@ -4226,7 +4232,7 @@ int main (int argc, char *argv[])
debug ("manpath search path (with duplicates) = %s\n", manp);
- create_pathlist (manp, manpathlist);
+ manpathlist = create_pathlist (manp);
/* man issued with `-l' option */
if (local_man_file) {
diff --git a/src/mandb.c b/src/mandb.c
index 90325d91..0ed5748b 100644
--- a/src/mandb.c
+++ b/src/mandb.c
@@ -48,6 +48,7 @@
#include "argp.h"
#include "dirname.h"
+#include "gl_list.h"
#include "progname.h"
#include "stat-time.h"
#include "timespec.h"
@@ -202,7 +203,7 @@ extern uid_t ruid;
extern uid_t euid;
#endif /* MAN_OWNER */
-static char *manpathlist[MAXDIRS];
+static gl_list_t manpathlist;
extern int pages;
@@ -775,7 +776,8 @@ int main (int argc, char *argv[])
{
char *sys_manp;
int amount = 0;
- char **mp;
+ gl_list_iterator_t mpiter;
+ char *mp;
struct hashtable *tried_catdirs;
#ifdef SIGPIPE
struct sigaction sa;
@@ -848,16 +850,17 @@ int main (int argc, char *argv[])
debug ("manpath=%s\n", manp);
- /* get the manpath as an array of pointers */
- create_pathlist (manp, manpathlist);
+ /* get the manpath as a list of pointers */
+ manpathlist = create_pathlist (manp);
/* finished manpath processing, regain privs */
regain_effective_privs ();
tried_catdirs = hashtable_create (tried_catdirs_free);
- for (mp = manpathlist; *mp; mp++) {
- int global_manpath = is_global_mandir (*mp);
+ mpiter = gl_list_iterator (manpathlist);
+ while (gl_list_iterator_next (&mpiter, (const void **) &mp, NULL)) {
+ int global_manpath = is_global_mandir (mp);
int ret;
DIR *dir;
struct dirent *subdirent;
@@ -869,14 +872,14 @@ int main (int argc, char *argv[])
drop_effective_privs ();
}
- ret = process_manpath (*mp, global_manpath, tried_catdirs);
+ ret = process_manpath (mp, global_manpath, tried_catdirs);
if (ret < 0)
exit (FATAL);
amount += ret;
- dir = opendir (*mp);
+ dir = opendir (mp);
if (!dir) {
- error (0, errno, _("can't search directory %s"), *mp);
+ error (0, errno, _("can't search directory %s"), mp);
goto next_manpath;
}
@@ -890,7 +893,7 @@ int main (int argc, char *argv[])
if (STRNEQ (subdirent->d_name, "man", 3))
continue;
- subdirpath = xasprintf ("%s/%s", *mp,
+ subdirpath = xasprintf ("%s/%s", mp,
subdirent->d_name);
ret = process_manpath (subdirpath, global_manpath,
tried_catdirs);
@@ -908,6 +911,7 @@ next_manpath:
chkr_garbage_detector ();
}
+ gl_list_iterator_free (&mpiter);
purge_catdirs (tried_catdirs);
hashtable_free (tried_catdirs);
diff --git a/src/manp.c b/src/manp.c
index 3002abeb..8d5e612b 100644
--- a/src/manp.c
+++ b/src/manp.c
@@ -54,11 +54,15 @@
#include <assert.h>
#include <errno.h>
#include <dirent.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "canonicalize.h"
+#include "gl_linkedhash_list.h"
+#include "gl_xlist.h"
+#include "hash-pjw-bare.h"
#include "xgetcwd.h"
#include "xvasprintf.h"
@@ -92,19 +96,34 @@ static struct list *namestore, *tailstore;
#define MANPATH_MAP 0
#define MANDATORY 1
-/* DIRLIST list[MAXDIRS]; */
-static char *tmplist[MAXDIRS];
-
char *user_config_file = NULL;
int disable_cache;
int min_cat_width = 80, max_cat_width = 80, cat_width = 0;
-static void add_man_subdirs (const char *p);
+static void add_man_subdirs (gl_list_t list, const char *p);
static char *fsstnd (const char *path);
static char *def_path (int flag);
-static void add_dir_to_list (char **lp, const char *dir);
-static char **add_dir_to_path_list (char **mphead, char **mp, const char *p);
+static void add_dir_to_list (gl_list_t list, const char *dir);
+static void add_dir_to_path_list (gl_list_t list, const char *p);
+
+static bool string_equals (const void *s1, const void *s2)
+{
+ return STREQ ((const char *) s1, (const char *) s2);
+}
+
+static size_t string_hash (const void *s)
+{
+ return hash_pjw_bare (s, strlen ((const char *) s));
+}
+
+static void string_free (const void *s)
+{
+ /* gl_list declares the argument as const, but there doesn't seem to
+ * be a good reason for this.
+ */
+ free ((void *) s);
+}
static void add_to_list (const char *key, const char *cont, int flag)
{
@@ -339,11 +358,6 @@ static void gripe_not_directory (const char *dir)
error (0, 0, _("warning: %s isn't a directory"), dir);
}
-static void gripe_overlong_list (void)
-{
- error (FAIL, 0, _("manpath list too long"));
-}
-
/* accept a manpath list, separated with ':', return the associated
catpath list */
char *cat_manpath (char *manp)
@@ -928,9 +942,9 @@ static char *def_path (int flag)
/*
* If specified with configure, append OVERRIDE_DIR to dir param and add it
- * to the lp list.
+ * to list.
*/
-static void insert_override_dir (char **lp, const char *dir)
+static void insert_override_dir (gl_list_t list, const char *dir)
{
char *override_dir = NULL;
@@ -938,7 +952,7 @@ static void insert_override_dir (char **lp, const char *dir)
return;
if ((override_dir = xasprintf ("%s/%s", dir, OVERRIDE_DIR))) {
- add_dir_to_list (lp, override_dir);
+ add_dir_to_list (list, override_dir);
free (override_dir);
}
}
@@ -956,14 +970,18 @@ static void insert_override_dir (char **lp, const char *dir)
*/
char *get_manpath_from_path (const char *path, int mandatory)
{
+ gl_list_t tmplist;
+ gl_list_iterator_t tmpiter;
int len;
char *tmppath;
char *p;
- char **lp;
char *end;
char *manpathlist;
struct list *list;
+ char *item;
+ tmplist = gl_list_create_empty (GL_LINKEDHASH_LIST, string_equals,
+ string_hash, string_free, false);
tmppath = xstrdup (path);
for (end = p = tmppath; end; p = end + 1) {
@@ -1003,7 +1021,7 @@ char *get_manpath_from_path (const char *path, int mandatory)
} else {
debug ("is not in the config file\n");
- add_man_subdirs (p);
+ add_man_subdirs (tmplist, p);
}
}
@@ -1020,11 +1038,10 @@ char *get_manpath_from_path (const char *path, int mandatory)
}
len = 0;
- lp = tmplist;
- while (*lp != NULL) {
- len += strlen (*lp) + 1;
- lp++;
- }
+ tmpiter = gl_list_iterator (tmplist);
+ while (gl_list_iterator_next (&tmpiter, (const void **) &item, NULL))
+ len += strlen (item) + 1;
+ gl_list_iterator_free (&tmpiter);
if (!len)
/* No path elements in configuration file or with
@@ -1035,38 +1052,31 @@ char *get_manpath_from_path (const char *path, int mandatory)
manpathlist = xmalloc (len);
*manpathlist = '\0';
- lp = tmplist;
p = manpathlist;
- while (*lp != NULL) {
- len = strlen (*lp);
- memcpy (p, *lp, len);
- free (*lp);
- *lp = NULL;
+ tmpiter = gl_list_iterator (tmplist);
+ while (gl_list_iterator_next (&tmpiter, (const void **) &item, NULL)) {
+ len = strlen (item);
+ memcpy (p, item, len);
p += len;
*p++ = ':';
- lp++;
}
+ gl_list_iterator_free (&tmpiter);
p[-1] = '\0';
+ gl_list_free (tmplist);
+
return manpathlist;
}
/* Add a directory to the manpath list if it isn't already there. */
-static void add_expanded_dir_to_list (char **lp, const char *dir)
+static void add_expanded_dir_to_list (gl_list_t list, const char *dir)
{
int status;
- int pos = 0;
-
- while (*lp != NULL) {
- if (pos > MAXDIRS - 1)
- gripe_overlong_list ();
- if (!strcmp (*lp, dir)) {
- debug ("%s is already in the manpath\n", dir);
- return;
- }
- lp++;
- pos++;
+
+ if (gl_list_search (list, dir)) {
+ debug ("%s is already in the manpath\n", dir);
+ return;
}
/* Not found -- add it. */
@@ -1079,8 +1089,7 @@ static void add_expanded_dir_to_list (char **lp, const char *dir)
gripe_not_directory (dir);
else if (status == 1) {
debug ("adding %s to manpath\n", dir);
-
- *lp = xstrdup (dir);
+ gl_list_add_last (list, xstrdup (dir));
}
}
@@ -1088,14 +1097,14 @@ static void add_expanded_dir_to_list (char **lp, const char *dir)
* Add a directory to the manpath list if it isn't already there, expanding
* wildcards.
*/
-static void add_dir_to_list (char **lp, const char *dir)
+static void add_dir_to_list (gl_list_t list, const char *dir)
{
char **expanded_dirs;
int i;
expanded_dirs = expand_path (dir);
for (i = 0; expanded_dirs[i]; i++) {
- add_expanded_dir_to_list (lp, expanded_dirs[i]);
+ add_expanded_dir_to_list (list, expanded_dirs[i]);
free (expanded_dirs[i]);
}
free (expanded_dirs);
@@ -1104,7 +1113,7 @@ static void add_dir_to_list (char **lp, const char *dir)
/* path does not exist in config file: check to see if path/../man,
path/man, path/../share/man, or path/share/man exist, and add them to the
list if they do. */
-static void add_man_subdirs (const char *path)
+static void add_man_subdirs (gl_list_t list, const char *path)
{
char *newpath;
int found = 0;
@@ -1116,8 +1125,8 @@ static void add_man_subdirs (const char *path)
if (subdir) {
newpath = xasprintf ("%.*s/man", (int) (subdir - path), path);
if (is_directory (newpath) == 1) {
- insert_override_dir (tmplist, newpath);
- add_dir_to_list (tmplist, newpath);
+ insert_override_dir (list, newpath);
+ add_dir_to_list (list, newpath);
found = 1;
}
free (newpath);
@@ -1125,8 +1134,8 @@ static void add_man_subdirs (const char *path)
newpath = xasprintf ("%s/man", path);
if (is_directory (newpath) == 1) {
- insert_override_dir (tmplist, newpath);
- add_dir_to_list (tmplist, newpath);
+ insert_override_dir (list, newpath);
+ add_dir_to_list (list, newpath);
found = 1;
}
free (newpath);
@@ -1135,8 +1144,8 @@ static void add_man_subdirs (const char *path)
newpath = xasprintf ("%.*s/share/man",
(int) (subdir - path), path);
if (is_directory (newpath) == 1) {
- insert_override_dir (tmplist, newpath);
- add_dir_to_list (tmplist, newpath);
+ insert_override_dir (list, newpath);
+ add_dir_to_list (list, newpath);
found = 1;
}
free (newpath);
@@ -1144,8 +1153,8 @@ static void add_man_subdirs (const char *path)
newpath = xasprintf ("%s/share/man", path);
if (is_directory (newpath) == 1) {
- insert_override_dir (tmplist, newpath);
- add_dir_to_list (tmplist, newpath);
+ insert_override_dir (list, newpath);
+ add_dir_to_list (list, newpath);
found = 1;
}
free (newpath);
@@ -1155,14 +1164,11 @@ static void add_man_subdirs (const char *path)
"share/man subdirectories\n");
}
-static char **add_dir_to_path_list (char **mphead, char **mp, const char *p)
+static void add_dir_to_path_list (gl_list_t list, const char *p)
{
int status, i;
char *cwd, *d, **expanded_dirs;
- if (mp - mphead > MAXDIRS - 1)
- gripe_overlong_list ();
-
expanded_dirs = expand_path (p);
for (i = 0; expanded_dirs[i]; i++) {
d = expanded_dirs[i];
@@ -1174,68 +1180,73 @@ static char **add_dir_to_path_list (char **mphead, char **mp, const char *p)
else if (status == 0)
gripe_not_directory (d);
else {
+ char *path;
+
/* deal with relative paths */
if (*d != '/') {
cwd = xgetcwd ();
if (!cwd)
error (FATAL, errno,
_("can't determine current directory"));
- *mp = appendstr (cwd, "/", d, (void *) 0);
+ path = appendstr (cwd, "/", d, (void *) 0);
} else
- *mp = xstrdup (d);
+ path = xstrdup (d);
- debug ("adding %s to manpathlist\n", *mp);
- mp++;
+ debug ("adding %s to manpathlist\n", path);
+ gl_list_add_last (list, path);
}
free (d);
}
free (expanded_dirs);
-
- return mp;
}
-void create_pathlist (const char *manp, char **mp)
+gl_list_t create_pathlist (const char *manp)
{
+ gl_list_t list;
+ gl_list_iterator_t iter;
+ gl_list_node_t node;
const char *p, *end;
- char **mphead = mp;
/* Expand the manpath into a list for easier handling. */
+ list = gl_list_create_empty (GL_LINKEDHASH_LIST, string_equals,
+ string_hash, string_free, true);
for (p = manp;; p = end + 1) {
end = strchr (p, ':');
if (end) {
char *element = xstrndup (p, end - p);
- mp = add_dir_to_path_list (mphead, mp, element);
+ add_dir_to_path_list (list, element);
free (element);
} else {
- mp = add_dir_to_path_list (mphead, mp, p);
+ add_dir_to_path_list (list, p);
break;
}
}
- *mp = NULL;
/* Eliminate duplicates due to symlinks. */
- mp = mphead;
- while (*mp) {
+ iter = gl_list_iterator (list);
+ while (gl_list_iterator_next (&iter, (const void **) &p, &node)) {
char *target;
- char **dupcheck;
- int found_dup = 0;
+ gl_list_iterator_t dupcheck_iter;
+ const char *dupcheck;
+ gl_list_node_t dupcheck_node;
/* After resolving all symlinks, is the target also in the
* manpath?
*/
- target = canonicalize_file_name (*mp);
- if (!target) {
- ++mp;
+ target = canonicalize_file_name (p);
+ if (!target)
continue;
- }
/* Only check up to the current list position, to keep item
* order stable across deduplication.
*/
- for (dupcheck = mphead; *dupcheck && dupcheck != mp;
- ++dupcheck) {
+ dupcheck_iter = gl_list_iterator (list);
+ while (gl_list_iterator_next (&dupcheck_iter,
+ (const void **) &dupcheck,
+ &dupcheck_node) &&
+ dupcheck_node != node) {
char *dupcheck_target = canonicalize_file_name
- (*dupcheck);
+ (dupcheck);
if (!dupcheck_target)
continue;
if (!STREQ (target, dupcheck_target)) {
@@ -1243,43 +1254,39 @@ void create_pathlist (const char *manp, char **mp)
continue;
}
free (dupcheck_target);
- debug ("Removing duplicate manpath entry %s (%td) -> "
- "%s (%td)\n",
- *mp, mp - mphead,
- *dupcheck, dupcheck - mphead);
- free (*mp);
- for (dupcheck = mp; *(dupcheck + 1); ++dupcheck)
- *dupcheck = *(dupcheck + 1);
- *dupcheck = NULL;
- found_dup = 1;
+ debug ("Removing duplicate manpath entry %s -> %s\n",
+ p, dupcheck);
+ gl_list_remove_node (list, node);
break;
}
+ gl_list_iterator_free (&dupcheck_iter);
free (target);
- if (!found_dup)
- ++mp;
}
+ gl_list_iterator_free (&iter);
if (debug_level) {
- int first = 1;
+ bool first = true;
debug ("final search path = ");
- for (mp = mphead; *mp; ++mp) {
+ iter = gl_list_iterator (list);
+ while (gl_list_iterator_next (&iter, (const void **) &p,
+ NULL)) {
if (first) {
- debug ("%s", *mp);
- first = 0;
+ debug ("%s", p);
+ first = false;
} else
- debug (":%s", *mp);
+ debug (":%s", p);
}
+ gl_list_iterator_free (&iter);
debug ("\n");
}
+
+ return list;
}
-void free_pathlist (char **mp)
+void free_pathlist (gl_list_t list)
{
- while (*mp) {
- free (*mp);
- *mp++ = NULL;
- }
+ gl_list_free (list);
}
/* Routine to get list of named system and user manpaths (in reverse order). */
diff --git a/src/manp.h b/src/manp.h
index 529bfa6f..1a55e5b9 100644
--- a/src/manp.h
+++ b/src/manp.h
@@ -22,6 +22,8 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "gl_list.h"
+
struct locale_bits {
char *language;
char *territory;
@@ -36,8 +38,8 @@ extern void free_locale_bits (struct locale_bits *bits);
extern char *add_nls_manpaths (const char *manpathlist, const char *locales);
extern char *get_manpath (const char *systems);
extern char *get_manpath_from_path (const char *path, int mandatory);
-extern void create_pathlist (const char *manp, char **mp);
-extern void free_pathlist (char **mp);
+extern gl_list_t create_pathlist (const char *manp);
+extern void free_pathlist (gl_list_t list);
extern char *get_mandb_manpath (void);
extern char *get_catpath (const char *name, int cattype);
extern int is_global_mandir (const char *dir);
diff --git a/src/whatis.c b/src/whatis.c
index ee43f10a..22bbb12b 100644
--- a/src/whatis.c
+++ b/src/whatis.c
@@ -56,6 +56,7 @@
#include "argp.h"
#include "dirname.h"
+#include "gl_list.h"
#include "fnmatch.h"
#include "progname.h"
#include "xvasprintf.h"
@@ -79,7 +80,7 @@
#include "manp.h"
-static char *manpathlist[MAXDIRS];
+static gl_list_t manpathlist;
extern char *user_config_file;
static char **keywords;
@@ -519,7 +520,7 @@ static int do_whatis_section (MYDBM_FILE dbf,
static int suitable_manpath (const char *manpath, const char *page_dir)
{
char *page_manp, *pm;
- char *page_manpathlist[MAXDIRS], **mp;
+ gl_list_t page_manpathlist;
int ret;
page_manp = get_manpath_from_path (page_dir, 0);
@@ -530,18 +531,11 @@ static int suitable_manpath (const char *manpath, const char *page_dir)
pm = locale_manpath (page_manp);
free (page_manp);
page_manp = pm;
- create_pathlist (page_manp, page_manpathlist);
+ page_manpathlist = create_pathlist (page_manp);
- ret = 0;
- for (mp = page_manpathlist; *mp; ++mp) {
- if (STREQ (*mp, manpath)) {
- ret = 1;
- break;
- }
- }
+ ret = gl_list_search (page_manpathlist, manpath) ? 1 : 0;
- for (mp = page_manpathlist; *mp; ++mp)
- free (*mp);
+ free_pathlist (page_manpathlist);
free (page_manp);
return ret;
}
@@ -841,21 +835,23 @@ nextpage:
static int search (const char * const *pages, int num_pages)
{
int *found = XCALLOC (num_pages, int);
- char *catpath, **mp;
+ gl_list_iterator_t mpiter;
+ char *catpath, *mp;
int any_found, i;
- for (mp = manpathlist; *mp; mp++) {
+ mpiter = gl_list_iterator (manpathlist);
+ while (gl_list_iterator_next (&mpiter, (const void **) &mp, NULL)) {
MYDBM_FILE dbf;
- catpath = get_catpath (*mp, SYSTEM_CAT | USER_CAT);
+ catpath = get_catpath (mp, SYSTEM_CAT | USER_CAT);
if (catpath) {
database = mkdbname (catpath);
free (catpath);
} else
- database = mkdbname (*mp);
+ database = mkdbname (mp);
- debug ("path=%s\n", *mp);
+ debug ("path=%s\n", mp);
dbf = MYDBM_RDOPEN (database);
if (dbf && dbver_rd (dbf)) {
@@ -863,7 +859,7 @@ static int search (const char * const *pages, int num_pages)
dbf = NULL;
}
if (!dbf) {
- use_grep (pages, num_pages, *mp, found);
+ use_grep (pages, num_pages, mp, found);
continue;
}
@@ -873,12 +869,13 @@ static int search (const char * const *pages, int num_pages)
if (regex_opt || wildcard)
do_apropos (dbf, pages, num_pages, found);
else
- do_whatis (dbf, pages, num_pages, *mp, found);
+ do_whatis (dbf, pages, num_pages, mp, found);
}
free (database);
database = NULL;
MYDBM_CLOSE (dbf);
}
+ gl_list_iterator_free (&mpiter);
chkr_garbage_detector ();
@@ -969,7 +966,7 @@ int main (int argc, char *argv[])
else
free (get_manpath (NULL));
- create_pathlist (manp, manpathlist);
+ manpathlist = create_pathlist (manp);
display_seen = hashtable_create (&null_hashtable_free);
diff --git a/src/zsoelim.h b/src/zsoelim.h
index f17c08e8..4aaf53d6 100644
--- a/src/zsoelim.h
+++ b/src/zsoelim.h
@@ -20,13 +20,15 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-int zsoelim_open_file (const char *filename, char * const *manpathlist,
+#include "gl_list.h"
+
+int zsoelim_open_file (const char *filename, gl_list_t manpathlist,
const char *parent_path);
-void zsoelim_parse_file (char * const *manpathlist, const char *parent_path);
+void zsoelim_parse_file (gl_list_t manpathlist, const char *parent_path);
struct zsoelim_stdin_data;
void zsoelim_stdin (void *data);
struct zsoelim_stdin_data *zsoelim_stdin_data_new (const char *path,
- char * const *manpathlist);
+ gl_list_t manpathlist);
void zsoelim_stdin_data_free (void *data);
diff --git a/src/zsoelim.l b/src/zsoelim.l
index b3dc7807..c6ce8b4c 100644
--- a/src/zsoelim.l
+++ b/src/zsoelim.l
@@ -59,6 +59,8 @@
#define PIPE so_pipe[so_stack_ptr]
#include "dirname.h"
+#include "gl_linkedhash_list.h"
+#include "gl_xlist.h"
#include "xgetcwd.h"
#include "xvasprintf.h"
@@ -88,12 +90,12 @@ static int so_line[MAX_SO_DEPTH];
static pipeline *so_pipe[MAX_SO_DEPTH];
static int so_stack_ptr;
static int no_newline;
-static char * const *so_manpathlist;
+static gl_list_t so_manpathlist;
static const char *so_parent_path;
struct zsoelim_stdin_data {
char *path;
- char * const *manpathlist;
+ gl_list_t manpathlist;
};
/* The flex documentation says that yyin is only used by YY_INPUT, so we
@@ -286,7 +288,6 @@ W [ \t]
PIPE = NULL;
free (NAME);
NAME = NULL;
- so_manpathlist = NULL;
if (no_newline)
putchar ('\n');
@@ -320,7 +321,7 @@ static void zap_quotes (void)
#endif
/* initialise the stack and call the parser */
-void zsoelim_parse_file (char * const *manpathlist, const char *parent_path)
+void zsoelim_parse_file (gl_list_t manpathlist, const char *parent_path)
{
#ifdef PP_COOKIE
const char *line;
@@ -377,11 +378,10 @@ static pipeline *try_compressed (char **filename)
/* This routine is used to open the specified file or uncompress a compressed
version and open that instead */
-int zsoelim_open_file (const char *filename, char * const *manpathlist,
+int zsoelim_open_file (const char *filename, gl_list_t manpathlist,
const char *parent_path)
{
pipeline *decomp;
- char * const *mp;
if (parent_path)
debug ("opening %s (parent path: %s)\n",
@@ -394,6 +394,8 @@ int zsoelim_open_file (const char *filename, char * const *manpathlist,
NAME = xstrdup (filename);
} else {
char *compfile;
+ gl_list_iterator_t mpiter;
+ const char *mp;
/* If there is no parent path, try opening directly first. */
if (!parent_path) {
@@ -407,7 +409,7 @@ int zsoelim_open_file (const char *filename, char * const *manpathlist,
free (compfile);
}
- if (manpathlist && strchr (filename, '/')) {
+ if (strchr (filename, '/')) {
/* File name with a directory part. Try looking it
* up within each manpath entry.
*/
@@ -424,11 +426,14 @@ int zsoelim_open_file (const char *filename, char * const *manpathlist,
free (compfile);
}
- for (mp = manpathlist; *mp; ++mp) {
- if (parent_path && STREQ (*mp, parent_path))
+ mpiter = gl_list_iterator (manpathlist);
+ while (gl_list_iterator_next (&mpiter,
+ (const void **) &mp,
+ NULL)) {
+ if (parent_path && STREQ (mp, parent_path))
continue;
- compfile = xasprintf ("%s/%s.", *mp, filename);
+ compfile = xasprintf ("%s/%s.", mp, filename);
decomp = try_compressed (&compfile);
if (decomp) {
@@ -438,7 +443,8 @@ int zsoelim_open_file (const char *filename, char * const *manpathlist,
free (compfile);
}
- } else if (manpathlist) {
+ gl_list_iterator_free (&mpiter);
+ } else {
/* File name with no directory part. Try searching
* the manpath.
*/
@@ -470,11 +476,14 @@ int zsoelim_open_file (const char *filename, char * const *manpathlist,
}
}
- for (mp = manpathlist; *mp; ++mp) {
- if (parent_path && STREQ (*mp, parent_path))
+ mpiter = gl_list_iterator (manpathlist);
+ while (gl_list_iterator_next (&mpiter,
+ (const void **) &mp,
+ NULL)) {
+ if (parent_path && STREQ (mp, parent_path))
continue;
- names = look_for_file (*mp, sec, name,
+ names = look_for_file (mp, sec, name,
0, LFF_MATCHCASE);
for (np = names; np && *np; ++np) {
decomp = decompress_open (*np);
@@ -484,6 +493,7 @@ int zsoelim_open_file (const char *filename, char * const *manpathlist,
}
}
}
+ gl_list_iterator_free (&mpiter);
free (name);
}
@@ -520,13 +530,17 @@ out:
void zsoelim_stdin (void *data)
{
struct zsoelim_stdin_data *zsoelim_data = data;
+ gl_list_t empty;
- zsoelim_open_file ("-", NULL, zsoelim_data->path);
+ empty = gl_list_create_empty (GL_LINKEDHASH_LIST, NULL, NULL, NULL,
+ true);
+ zsoelim_open_file ("-", empty, zsoelim_data->path);
+ gl_list_free (empty);
zsoelim_parse_file (zsoelim_data->manpathlist, zsoelim_data->path);
}
struct zsoelim_stdin_data *zsoelim_stdin_data_new (const char *path,
- char * const *manpathlist)
+ gl_list_t manpathlist)
{
struct zsoelim_stdin_data *data = XMALLOC (struct zsoelim_stdin_data);
diff --git a/src/zsoelim_main.c b/src/zsoelim_main.c
index ef6d1b67..ea8eed31 100644
--- a/src/zsoelim_main.c
+++ b/src/zsoelim_main.c
@@ -30,6 +30,7 @@
#include <stdlib.h>
#include "argp.h"
+#include "gl_list.h"
#include "progname.h"
#include "xvasprintf.h"
@@ -52,7 +53,7 @@
int quiet = 1;
man_sandbox *sandbox;
-static char *manpathlist[MAXDIRS];
+static gl_list_t manpathlist;
static char **files;
static int num_files;
@@ -140,7 +141,7 @@ int main (int argc, char *argv[])
manp = add_nls_manpaths (get_manpath (NULL), all_locales);
free (all_locales);
- create_pathlist (manp, manpathlist);
+ manpathlist = create_pathlist (manp);
/* parse files in command line order */
for (i = 0; i < num_files; ++i) {