diff -rup a/src/filehandling_functions.c b/src/filehandling_functions.c --- a/src/filehandling_functions.c 2018-06-08 13:03:37.182763749 +0530 +++ b/src/filehandling_functions.c 2018-06-08 13:45:23.850352158 +0530 @@ -740,7 +740,8 @@ FILE * openinfo(char *filename, int number) { FILE *id = NULL; - char *buf = xmalloc(1024); /* holds local copy of filename */ +#define BUF_LEN 1024 + char *buf = xmalloc(BUF_LEN); /* holds local copy of filename */ char *bufend; /* points at the trailing 0 of initial name */ char command[1128]; /* holds command to evaluate for decompression of file */ int i, j; @@ -773,9 +774,9 @@ openinfo(char *filename, int number) tmpfilename = tmpfilename2; /* later we will refere only to tmp2 */ } - for (i = -1; i < infopathcount; i++) /* go through all paths */ + for (i = -2; i < infopathcount; i++) /* go through all paths */ { - if (i == -1) + if (i < 0) { /* * no filenameprefix, we don't navigate around any specific @@ -783,12 +784,12 @@ openinfo(char *filename, int number) */ if (!filenameprefix) continue; + /* build a filename: First (i == -2) try filenameprefix/filename, + * then try with a .info appended */ + if (i == -2) + snprintf(buf, BUF_LEN, "%s/%s", filenameprefix, basename(filename)); else - { - strcpy(buf, filenameprefix); /* build a filename */ - strcat(buf, "/"); - strcat(buf, basename(filename)); - } + snprintf(buf, BUF_LEN, "%s/%s.info", filenameprefix, basename(filename)); } else { @@ -842,6 +843,7 @@ openinfo(char *filename, int number) return 0; +#undef BUF_LEN } void diff -rup a/src/mainfunction.c b/src/mainfunction.c --- a/src/mainfunction.c 2006-03-16 20:37:38.000000000 +0530 +++ b/src/mainfunction.c 2018-06-13 11:44:07.548063303 +0530 @@ -40,6 +40,32 @@ int aftersearch = 0; int toggled_by_menu = 0; long pos, cursor, infomenu, infocolumn=0; +/* strdup src string, but when doing so, strip leading/trailing spaces and + * substitute multiple spaces with a single space. This is needed when *Node + * links span multiple lines and the margin is embedded in the string */ +static char * +canonical_strdup(const char *src) +{ + char *dst; + int dstlen, srclen, copylen; + + while (*src == ' ') + ++src; + for (dstlen = 0, srclen = 0; src[srclen]; ++srclen) + { + if (src[srclen] != ' ' || (src[srclen + 1] != 0 && src[srclen + 1] != ' ')) + ++dstlen; + } + dst = xmalloc(dstlen + 1); + for (copylen = 0, srclen = 0; copylen < dstlen; ++srclen) + { + if (src[srclen] != ' ' || src[srclen + 1] != ' ') + dst[copylen++] = src[srclen]; + } + dst[dstlen] = 0; + return dst; +} + WorkRVal work(char ***message, char **type, long *lines, FILE * id, int tag_table_pos) { @@ -533,8 +559,7 @@ work(char ***message, char **type, long infohistory.pos[infohistory.length] = pos; infohistory.cursor[infohistory.length] = cursor; infohistory.menu[infohistory.length] = infomenu; - rval.node = xmalloc(strlen(tag_table[return_value].nodename) + 1); - strcpy(rval.node, tag_table[return_value].nodename); + rval.node = canonical_strdup(tag_table[return_value].nodename); rval.file = xmalloc(1); rval.file[0] = 0; return rval; @@ -668,8 +693,7 @@ skip_search: infohistory.pos[infohistory.length] = pos; infohistory.cursor[infohistory.length] = cursor; infohistory.menu[infohistory.length] = infomenu; - rval.node = xmalloc(strlen(tag_table[return_value].nodename) + 1); - strcpy(rval.node, tag_table[return_value].nodename); + rval.node = canonical_strdup(tag_table[return_value].nodename); rval.file = xmalloc(1); rval.file[0] = 0; aftersearch = 0; @@ -699,8 +723,7 @@ skip_search: break; gotoendptr++; } /* skip spaces */ - rval.node = xmalloc(strlen(gotoendptr) + 1); - strcpy(rval.node, gotoendptr); + rval.node = canonical_strdup(gotoendptr); xfree(token); token = 0; aftersearch = 0; @@ -747,8 +770,7 @@ skip_search: infohistory.pos[infohistory.length] = pos; infohistory.cursor[infohistory.length] = cursor; infohistory.menu[infohistory.length] = infomenu; - rval.node = xmalloc(strlen(tag_table[return_value].nodename) + 1); - strcpy(rval.node, tag_table[return_value].nodename); + rval.node = canonical_strdup(tag_table[return_value].nodename); rval.file = xmalloc(1); rval.file[0] = 0; aftersearch = 0; @@ -769,8 +791,7 @@ skip_search: infohistory.pos[infohistory.length] = pos; infohistory.cursor[infohistory.length] = cursor; infohistory.menu[infohistory.length] = infomenu; - rval.node = xmalloc(strlen(tag_table[return_value].nodename) + 1); - strcpy(rval.node, tag_table[return_value].nodename); + rval.node = canonical_strdup(tag_table[return_value].nodename); rval.file = xmalloc(1); rval.file[0] = 0; aftersearch = 0; @@ -798,8 +819,7 @@ skip_search: infohistory.cursor[infohistory.length] = cursor; infohistory.menu[infohistory.length] = infomenu; } - rval.node = xmalloc(strlen(tag_table[return_value].nodename) + 1); - strcpy(rval.node, tag_table[return_value].nodename); + rval.node = canonical_strdup(tag_table[return_value].nodename); rval.file = xmalloc(1); rval.file[0] = 0; aftersearch = 0; @@ -962,8 +982,7 @@ skip_search: infohistory.pos[infohistory.length] = pos; infohistory.cursor[infohistory.length] = cursor; infohistory.menu[infohistory.length] = infomenu; - rval.node = xmalloc(strlen(FirstNodeName) + 1); - strcpy(rval.node, FirstNodeName); + rval.node = canonical_strdup(FirstNodeName); rval.file = xmalloc(1); rval.file[0] = 0; aftersearch = 0; @@ -978,8 +997,7 @@ skip_search: dellastinfohistory(); /* remove history entry for this node */ /* now we deal with the previous node history entry */ - rval.node = xmalloc(strlen(infohistory.node[infohistory.length]) + 1); - strcpy(rval.node, infohistory.node[infohistory.length]); + rval.node = canonical_strdup(infohistory.node[infohistory.length]); rval.file = xmalloc(strlen(infohistory.file[infohistory.length]) + 1); strcpy(rval.file, infohistory.file[infohistory.length]); @@ -1009,8 +1027,7 @@ skip_search: toggled_by_menu = 0; if (hyperobjects[cursor].type < 4) /* normal info link */ { - rval.node = xmalloc(strlen(hyperobjects[cursor].node) + 1); - strcpy(rval.node, hyperobjects[cursor].node); + rval.node = canonical_strdup(hyperobjects[cursor].node); rval.file = xmalloc(strlen(hyperobjects[cursor].file) + 1); strcpy(rval.file, hyperobjects[cursor].file); aftersearch = 0; diff -rup a/src/manual.c b/src/manual.c --- a/src/manual.c 2018-06-08 13:03:37.185763734 +0530 +++ b/src/manual.c 2018-06-13 10:03:26.347758140 +0530 @@ -190,6 +190,33 @@ set_initial_history(char *name) } } + /* It is essential to know the section name, as otherwise links in the + * man page to the same name but different section would be ignored - + * see man_initializelinks. An example is sleep(1) which has link to + * sleep(3). So we try to find the section directly from man. */ + if (manualhistory[0].sect[0] == 0) { + char buf[1024]; + char *str, *lastSlash, *lastButOneSlash; + FILE *pathFile; + snprintf(buf, sizeof(buf), "man -w -W %s %s", ManOptions, name); + pathFile = popen(buf, "r"); + fgets(buf, sizeof(buf), pathFile); + pclose(pathFile); + /* buf will be of the form "/usr/share/man/man1/sleep.1.gz". We + * find the section from the leaf directory "/man1" */ + for (str = buf, lastSlash = str, lastButOneSlash = 0; *str; ++str) { + if (*str == '/') { + lastButOneSlash = lastSlash; + lastSlash = str; + } + } + if (lastButOneSlash) { + *lastSlash = 0; /* terminate the section */ + lastButOneSlash += 4; /* skip "/man", and land on the section */ + snprintf(manualhistory[0].sect, sizeof(manualhistory[0].sect), lastButOneSlash); + } + } + /* selected unknown */ manualhistory[0].selected = -1; /* pos=0 */ diff -rup a/src/pinfo.c b/src/pinfo.c --- a/src/pinfo.c 2006-03-10 01:14:48.000000000 +0530 +++ b/src/pinfo.c 2018-06-09 12:35:42.907799988 +0530 @@ -476,6 +476,13 @@ main(int argc, char *argv[]) tmp = strdup(work_return_value.file); clearfilenameprefix(); id = openinfo(tmp, 0); + + /* try to lookup the name in dir file */ + if (id == NULL) + { + id = dirpage_lookup(&type, &message, &lines, tmp, &pinfo_start_node); + } + xfree(tmp); tmp = 0; /* if the file doesn't exist */