From 50e4ba5f8848a422cf82c5b79ab0e32c8bfa10eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nikola=20Forr=C3=B3?= Date: Tue, 27 Aug 2019 17:53:03 +0200 Subject: [PATCH] man(1): Fix override dir handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, override dir was affecting only some cases of manpath determination. Apply it only when all paths has been gathered instead. (Depending on the definition of when the override dir applies, this might not be correct). Also look for override dir when sorting candidates. Fixes src/tests/man-9 failing when --with-override-dir=od is passed to ./configure. Reported-by: Nikola Forró Tested-by: Nikola Forró --- src/man.c | 33 ++++++++++++++++++++++++++++++++ src/manp.c | 55 +++++++++++++++++++++--------------------------------- 2 files changed, 54 insertions(+), 34 deletions(-) diff --git a/src/man.c b/src/man.c index 207e6f6..9b3d038 100644 --- a/src/man.c +++ b/src/man.c @@ -2688,6 +2688,32 @@ static bool duplicate_candidates (struct candidate *left, return ret; } +static int cand1_differs_by_override_dir (const struct candidate *left, + const struct candidate *right) +{ + size_t ov_len, pre_ov_len; + + ov_len = strlen (OVERRIDE_DIR); + if (!ov_len) + return 0; + + if (!STREQ (left->source->name, right->source->name)) + return 0; + + pre_ov_len = strlen(right->path); + if (!STRNEQ (left->path, right->path, pre_ov_len)) + return 0; + + if (left->path[pre_ov_len] != '/') + return 0; + pre_ov_len++; + + if (STREQ (left->path + pre_ov_len, OVERRIDE_DIR)) + return 1; + + return 0; +} + static int compare_candidates (const struct candidate *left, const struct candidate *right) { @@ -2777,6 +2803,13 @@ static int compare_candidates (const struct candidate *left, if (cmp) return cmp; + /* Sort override dir first + */ + if (cand1_differs_by_override_dir(left, right)) + return -1; + if (cand1_differs_by_override_dir(right, left)) + return 1; + /* Try comparing based on language. We used to prefer to display a * page in the user's preferred language than a page from a better * section, but that attracted objections, so now we prefer to get diff --git a/src/manp.c b/src/manp.c index 588f47c..db34c15 100644 --- a/src/manp.c +++ b/src/manp.c @@ -935,23 +935,6 @@ static char *def_path (enum config_flag flag) return manpath; } -/* - * If specified with configure, append OVERRIDE_DIR to dir param and add it - * to list. - */ -static void insert_override_dir (gl_list_t list, const char *dir) -{ - char *override_dir = NULL; - - if (!strlen (OVERRIDE_DIR)) - return; - - if ((override_dir = xasprintf ("%s/%s", dir, OVERRIDE_DIR))) { - add_dir_to_list (list, override_dir); - free (override_dir); - } -} - /* * For each directory in the user's path, see if it is one of the * directories listed in the man_db.config file. If so, and it is @@ -1000,7 +983,6 @@ char *get_manpath_from_path (const char *path, int mandatory) if (!manpath_map_found) debug ("is in the config file\n"); manpath_map_found = true; - insert_override_dir (tmplist, config_item->cont); add_dir_to_list (tmplist, config_item->cont); } GL_LIST_FOREACH_END (config); @@ -1021,11 +1003,8 @@ char *get_manpath_from_path (const char *path, int mandatory) debug ("\nadding mandatory man directories\n\n"); GL_LIST_FOREACH_START (config, config_item) { - if (config_item->flag == MANDATORY) { - insert_override_dir (tmplist, - config_item->key); + if (config_item->flag == MANDATORY) add_dir_to_list (tmplist, config_item->key); - } } GL_LIST_FOREACH_END (config); } @@ -1113,7 +1092,6 @@ static void add_man_subdirs (gl_list_t list, const char *path) if (subdir) { newpath = xasprintf ("%.*s/man", (int) (subdir - path), path); if (is_directory (newpath) == 1) { - insert_override_dir (list, newpath); add_dir_to_list (list, newpath); found = 1; } @@ -1122,7 +1100,6 @@ static void add_man_subdirs (gl_list_t list, const char *path) newpath = xasprintf ("%s/man", path); if (is_directory (newpath) == 1) { - insert_override_dir (list, newpath); add_dir_to_list (list, newpath); found = 1; } @@ -1132,7 +1109,6 @@ static void add_man_subdirs (gl_list_t list, const char *path) newpath = xasprintf ("%.*s/share/man", (int) (subdir - path), path); if (is_directory (newpath) == 1) { - insert_override_dir (list, newpath); add_dir_to_list (list, newpath); found = 1; } @@ -1141,7 +1117,6 @@ static void add_man_subdirs (gl_list_t list, const char *path) newpath = xasprintf ("%s/share/man", path); if (is_directory (newpath) == 1) { - insert_override_dir (list, newpath); add_dir_to_list (list, newpath); found = 1; } @@ -1193,19 +1168,31 @@ gl_list_t create_pathlist (const char *manp) gl_list_node_t node; const char *p, *end; - /* Expand the manpath into a list for easier handling. */ + /* Expand the manpath into a list for easier handling. + * For each entry, add corresponding OVERRIDE_DIR. + * */ list = new_string_list (GL_LINKEDHASH_LIST, true); for (p = manp;; p = end + 1) { + char *element, *element_override; + ssize_t p_len; + end = strchr (p, ':'); - if (end) { - char *element = xstrndup (p, end - p); - add_dir_to_path_list (list, element); - free (element); - } else { - add_dir_to_path_list (list, p); - break; + p_len = end ? end - p : (ssize_t)strlen(p); + + element = xstrndup (p, p_len); + + if (strlen(OVERRIDE_DIR)) { + element_override = xasprintf("%s/%s", element, OVERRIDE_DIR); + add_dir_to_path_list (list, element_override); + free (element_override); } + + add_dir_to_path_list (list, element); + free (element); + + if (!end) + break; } /* Eliminate duplicates due to symlinks. */ -- 2.21.0