Пример #1
0
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. */
}
Пример #2
0
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);
}