int Man(void) { SectionList *list = NULL; char *ptr, *lang = NULL, manpath[BUFSIZ], buf[BUFSIZ], *path, *current_label; int sect, num_alloced; /* * Get the environment variable MANPATH, and if it doesn't exist then use * SYSMANPATH and LOCALMANPATH. */ /* if MANPATH variable ends in ':'. So, should extend it's value to the * default search path. */ *manpath = '\0'; if ((ptr = getenv("MANPATH")) != NULL) strcpy(manpath, ptr); if (ptr == NULL || streq(ptr, "") || ptr[strlen(ptr) - 1] == ':') { lang = getenv("LANG"); #ifdef MANCONF if (!ReadManConfig(manpath + strlen(manpath))) #endif { #ifdef MANCONF if (manpath[strlen(manpath) - 1] != ':') strcat(manpath, ":"); #endif strcat(manpath, SYSMANPATH); #ifdef LOCALMANPATH strcat(manpath, ":"); strcat(manpath, LOCALMANPATH); #endif } } /* * Get the list of manual directories in the users MANPATH that we should * open to look for manual pages. The ``mandesc'' file is read here. */ for (path = manpath; (ptr = strchr(path, ':')) != NULL; path = ++ptr) { *ptr = '\0'; if (lang != NULL) { strcpy(buf, path); strcat(buf, "/"); strncat(buf, lang, sizeof(buf) - strlen(path) + 1); buf[sizeof(buf) - strlen(path) + 1] = '\0'; ReadMandescFile(&list, buf); } ReadMandescFile(&list, path); } if (lang != NULL) { strcpy(buf, path); strcat(buf, "/"); strncat(buf, lang, sizeof(buf) - strlen(path) + 1); buf[sizeof(buf) - strlen(path) + 1] = '\0'; ReadMandescFile(&list, buf); } ReadMandescFile(&list, path); SortList(&list); sect = 0; num_alloced = SECTALLOC; manual = (Manual *) XtMalloc(sizeof(Manual) * num_alloced); InitManual(manual, list->label); manual[sect].flags = list->flags; current_label = NULL; while (list != NULL) { SectionList *old_list; if (current_label == NULL || streq(list->label, current_label)) AddToCurrentSection(manual + sect, list->directory); else { if (manual[sect].nentries == 0) { /* empty section, re-use it. */ XtFree(manual[sect].blabel); manual[sect].blabel = list->label; manual[sect].flags = list->flags; } else { if (++sect >= num_alloced) { num_alloced += SECTALLOC; manual = (Manual *) XtRealloc((char *) manual, (sizeof(Manual) * num_alloced)); if (manual == NULL) PrintError ("Could not allocate memory for manual sections."); } InitManual(manual + sect, list->label); manual[sect].flags = list->flags; } AddToCurrentSection(manual + sect, list->directory); } /* Save label to see if it matches next entry. */ current_label = list->label; old_list = list; list = list->next; XtFree((char *) old_list); /* free what you allocate. */ } if (manual[sect].nentries != 0) sect++; /* don't forget that last section. */ SortAndRemove(manual, sect); #ifdef notdef /* dump info. */ DumpManual(sect); #endif /* * realloc manual to be minimum space necessary. */ if (sect == 0) PrintError("No manual pages found."); manual = (Manual *) XtRealloc((char *) manual, (sizeof(Manual) * sect)); if (manual == NULL) PrintError("Could not allocate memory for manual sections."); return (sect); /* return the number of man sections. */ }
FILE * DoSearch(ManpageGlobals * man_globals, int type) { char cmdbuf[BUFSIZ], *mantmp, *manpath; char tmp[BUFSIZ], path[BUFSIZ]; char string_buf[BUFSIZ], cmp_str[BUFSIZ], error_buf[BUFSIZ]; char *search_string = SearchString(man_globals); FILE *file; int fd; int count; Boolean flag; if (search_string == NULL) return (NULL); /* If the string is empty or starts with a space then do not search */ if (streq(search_string, "")) { PopupWarning(man_globals, "Search string is empty."); return (NULL); } if (strlen(search_string) >= BUFSIZ) { PopupWarning(man_globals, "Search string too long."); return (NULL); } if (search_string[0] == ' ') { PopupWarning(man_globals, "First character cannot be a space."); return (NULL); } if (type == APROPOS) { char label[BUFSIZ]; strlcpy(tmp, MANTEMP, sizeof(tmp)); /* get a temp file. */ fd = mkstemp(tmp); if (fd < 0) { PopupWarning(man_globals, "Cant create temp file"); return NULL; } mantmp = tmp; manpath = getenv("MANPATH"); if (manpath == NULL || streq(manpath, "")) { #ifdef MANCONF if (!ReadManConfig(path)) #endif { strlcpy(path, SYSMANPATH, sizeof(path)); #ifdef LOCALMANPATH strlcat(path, ":", sizeof(path)); strlcat(path, LOCALMANPATH, sizeof(path)); #endif } } else { strlcpy(path, manpath, sizeof(path)); } snprintf(label, sizeof(label), "Results of apropos search on: %s", search_string); #ifdef NO_MANPATH_SUPPORT /* not quite correct, but the best I can do. */ snprintf(cmdbuf, sizeof(cmdbuf), APROPOS_FORMAT, search_string, mantmp); #else snprintf(cmdbuf, sizeof(cmdbuf), APROPOS_FORMAT, path, search_string, mantmp); #endif if (system(cmdbuf) != 0) { /* execute search. */ snprintf(error_buf, sizeof(error_buf), "Something went wrong trying to run %s\n", cmdbuf); PopupWarning(man_globals, error_buf); } if ((file = fdopen(fd, "r")) == NULL) PrintError("lost temp file? out of temp space?"); /* * Since we keep the FD open we can remove the file safely, this * will keep extra files out of /tmp. */ remove(mantmp); snprintf(string_buf, sizeof(string_buf), "%s: nothing appropriate", search_string); /* * Check first LOOKLINES lines for "nothing appropriate". */ count = 0; flag = FALSE; while ((fgets(cmp_str, BUFSIZ, file) != NULL) && (count < LOOKLINES)) { size_t len = strlen(cmp_str); if (len > 0 && cmp_str[len - 1] == '\n') /* strip off the '\n' */ cmp_str[len - 1] = '\0'; if (streq(cmp_str, string_buf)) { flag = TRUE; break; } count++; } /* * If the file is less than this number of lines then assume that there is * nothing appropriate found. This does not confuse the apropos filter. */ if (flag) { fclose(file); file = NULL; ChangeLabel(man_globals->label, string_buf); return (NULL); } snprintf(man_globals->manpage_title, sizeof(man_globals->manpage_title), "%s", label); ChangeLabel(man_globals->label, label); fseek(file, 0L, SEEK_SET); /* reset file to point at top. */ } else { /* MANUAL SEARCH */ file = DoManualSearch(man_globals, search_string); if (file == NULL) { snprintf(string_buf, sizeof(string_buf), "No manual entry for %s.", search_string); ChangeLabel(man_globals->label, string_buf); if (man_globals->label == NULL) PopupWarning(man_globals, string_buf); return (NULL); } } if (resources.clear_search_string) { Arg arglist[1]; Widget dialog; dialog = XtNameToWidget(man_globals->search_widget, DIALOG); if (dialog == NULL) PopupWarning(man_globals, "Could not clear the search string."); XtSetArg(arglist[0], XtNvalue, ""); XtSetValues(dialog, arglist, (Cardinal) 1); } return (file); }