diff options
author | Colin Watson <cjwatson@debian.org> | 2019-01-26 12:55:56 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2019-01-26 12:55:56 +0000 |
commit | 199a6e80e7b4baa27e195f2c1120c45df9ea4e67 (patch) | |
tree | d3a6b7b51caa32a576ca2061590c11d7514c178e | |
parent | 4f07b2663de8cb7e85c779b9d2c3142134847b35 (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-- | NEWS | 2 | ||||
-rw-r--r-- | bootstrap.conf | 4 | ||||
-rw-r--r-- | include/manconfig.h.in | 4 | ||||
-rw-r--r-- | src/catman.c | 28 | ||||
-rw-r--r-- | src/man.c | 46 | ||||
-rw-r--r-- | src/mandb.c | 24 | ||||
-rw-r--r-- | src/manp.c | 207 | ||||
-rw-r--r-- | src/manp.h | 6 | ||||
-rw-r--r-- | src/whatis.c | 37 | ||||
-rw-r--r-- | src/zsoelim.h | 8 | ||||
-rw-r--r-- | src/zsoelim.l | 46 | ||||
-rw-r--r-- | src/zsoelim_main.c | 5 |
12 files changed, 228 insertions, 189 deletions
@@ -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); @@ -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); @@ -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). */ @@ -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) { |