[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Man-db-devel] [PATCH v3] Add fallback pager if the compile time default
From: |
nsajko |
Subject: |
[Man-db-devel] [PATCH v3] Add fallback pager if the compile time default is not executable |
Date: |
Sat, 16 Dec 2017 22:01:49 -0800 (PST) |
>A problem with man-db's man is that in the case of the user giving no
>configuration via conf files, argv, or environment variables; man
>defaults to less as pager (PAGER); but less may not be present on the
>system. Sure, other pagers may be selected in aforementioned ways, but
>then the defaults are overrided, making that unsuitable for
>install-time configuration.
>
>This patch makes man check (if that becomes relevant) if PAGER is
>executable, further defaulting to cat (which is basically ubiquitous,
>being in original Unix, POSIX, and GNU Coreutils) if it is not. Thus
>the poor beginner Unix users without less installed will be able to
>get man pages.
>
>Regards,
>Neven
The same thing, but without using sh.
And also a documentation update.
diff --git a/man/man1/man.man1 b/man/man1/man.man1
index 4df2823f..23a059e0 100644
--- a/man/man1/man.man1
+++ b/man/man1/man.man1
@@ -874,7 +874,12 @@ Specify which output pager to use.
By default,
.B %man%
uses
-.BR "%pager%" .
+.BR "%pager%" ,
+further falling back to
+.BR "%cat%"
+in case
+.BR "%pager%"
+is not found or is not executable.
This option overrides the
.RB $ MANPAGER
environment variable, which in turn overrides the
@@ -1240,7 +1245,11 @@ is used in preference), its value is used as the name of
the program used to
display the manual page.
By default,
.B %pager%
-is used.
+is used, with a further fallback to
+.B %cat%
+if
+.B %pager%
+were not to be found.
The value may be a simple command name or a command with arguments, and may
use shell quoting (backslashes, single quotes, or double quotes).
diff --git a/src/man.c b/src/man.c
index 6bc9642c..c0533e77 100644
--- a/src/man.c
+++ b/src/man.c
@@ -4020,6 +4020,84 @@ static const char **get_section_list (void)
}
}
+static void append_char(char *a, int *i, char c)
+{
+ a[*i] = c;
+ (*i)++;
+}
+
+// Returns the first token of a libpipeline/sh-style command. See SUSv4TC2:
+// 2.2 Shell Command Language: Quoting, but restrict to \'" as special symbols.
+//
+// Free the returned value.
+//
+// Examples:
+// sh_lang_first_word ("echo 3") returns "echo"
+// sh_lang_first_word ("'e ho' 3") returns "e ho"
+// sh_lang_first_word ("e\\cho 3") returns "echo"
+// sh_lang_first_word ("e\\\ncho 3") returns "echo"
+// sh_lang_first_word ("\"echo t\" 3") returns "echo t"
+// sh_lang_first_word ("\"ech\\o t\" 3") returns "ech\\o t"
+// sh_lang_first_word ("\"ech\\\\o t\" 3") returns "ech\\o t"
+// sh_lang_first_word ("\"ech\\\no t\" 3") returns "echo t"
+static char *sh_lang_first_word(const char *cmd)
+{
+ int i = 0, o = 0;
+ char *r = xmalloc (strlen (cmd) + 1);
+
+ while (i < strlen (cmd)) {
+ if (cmd[i] == '\\') {
+ // Escape Character (Backslash)
+ i++;
+ if (i == strlen (cmd)) {
+ break;
+ }
+ if (cmd[i] != '\n') {
+ append_char (r, &o, cmd[i]);
+ }
+ } else if (cmd[i] == '\'') {
+ // Single-Quotes
+ i++;
+ while (i < strlen (cmd) && cmd[i] != '\'') {
+ append_char (r, &o, cmd[i]);
+ i++;
+ }
+ } else if (cmd[i] == '"') {
+ // Double-Quotes
+ i++;
+ while (i < strlen (cmd)) {
+ if (cmd[i] == '\\') {
+ if (cmd[i+1] == '"' ||
+ cmd[i+1] == '\\') {
+ i++;
+ append_char (r, &o, cmd[i]);
+ } else if (cmd[i+1] == '\n') {
+ i++;
+ } else {
+ append_char (r, &o, cmd[i]);
+ }
+ } else if (cmd[i] == '"') {
+ break;
+ } else {
+ append_char (r, &o, cmd[i]);
+ }
+
+ i++;
+ }
+ } else if (cmd[i] == '\t' || cmd[i] == ' ' || cmd[i] == '\n') {
+ break;
+ } else {
+ append_char (r, &o, cmd[i]);
+ }
+
+ i++;
+ }
+
+ append_char (r, &o, '\0');
+
+ return r;
+}
+
int main (int argc, char *argv[])
{
int argc_env, exit_status = OK;
@@ -4115,12 +4193,21 @@ int main (int argc, char *argv[])
if (htmlout)
pager = html_pager;
#endif /* TROFF_IS_GROFF */
+
if (pager == NULL) {
pager = getenv ("MANPAGER");
- if (pager == NULL) {
- pager = getenv ("PAGER");
- if (pager == NULL)
- pager = get_def_user ("pager", PAGER);
+ }
+ if (pager == NULL) {
+ pager = getenv ("PAGER");
+ }
+ if (pager == NULL) {
+ pager = get_def_user ("pager", NULL);
+ }
+ if (pager == NULL) {
+ if (pathsearch_executable (sh_lang_first_word (PAGER))) {
+ pager = PAGER;
+ } else {
+ pager = "";
}
}
if (*pager == '\0')
- [Man-db-devel] [PATCH v3] Add fallback pager if the compile time default is not executable,
nsajko <=