## root/libutil/usable.c(161.html)

/* [<][>][^][v][top][bottom][index][help] */

## DEFINITIONS

This source file includes following definitions.

1. usable

    /*
     * Copyright (c) 1998, 1999, 2000, 2002
     *      Tama Communications Corporation
     *
     * This file is part of GNU GLOBAL.
     *
     * This program is free software: you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation, either version 3 of the License, or
     * (at your option) any later version.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License
     * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     */

    #ifdef HAVE_CONFIG_H
    #include <config.h>
    #endif
    #include <assert.h>
    #ifdef STDC_HEADERS
    #include <stdlib.h>
    #endif
    #ifdef HAVE_STRING_H
    #include <string.h>
    #else
    #include <strings.h>
    #endif

    #include "gparam.h"
    #include "locatestring.h"
    #include "makepath.h"
    #include "path.h"
    #include "test.h"
    #include "strbuf.h"
    #include "strlimcpy.h"
    #include "usable.h"

    #if defined(_WIN32) || defined(__DJGPP__)
    static const char *suffix[] = {".exe", ".com", ".bat",};
    #endif

    /*
     * usable: check if command is executable or not.
     *
     *      i)      command
     *      r)              ==NULL: not found.
     *                      !=NULL: absolute path of command.
     */
    char *
    usable(const char *command)
    {
            STRBUF *sb;
            char *p;
            const char *dir;
            static char path[MAXPATHLEN+1];

    #if defined(_WIN32) || defined(__DJGPP__)
            int i, lim = sizeof(suffix)/sizeof(char *);
    #endif

            if (isabspath(command) || locatestring(command, "./", MATCH_AT_FIRST)
                    || locatestring(command, "../", MATCH_AT_FIRST)) {
                    if (test("fx", command)) {
                            strlimcpy(path, command, sizeof(path));
                            return path;
                    }
                    return NULL;
            }
            /*
             * If found in BINDIR then use it.
             */
            if (test("fx", makepath(BINDIR, command, NULL))) {
                    strlimcpy(path, makepath(BINDIR, command, NULL), sizeof(path));
                    return path;
            }
            /*
             * Locate the command for each path in PATH.
             */
            *path = 0;
            /* Don't use fixed length buffer for environment variable
             * because it brings buffer overflow. */
            sb = strbuf_open(0);
            strbuf_puts(sb, getenv("PATH"));
            p = strbuf_value(sb);
            while (p) {
                    dir = p;
                    if ((p = locatestring(p, PATHSEP, MATCH_FIRST)) != NULL)
                            *p++ = 0;
                    if (test("fx", makepath(dir, command, NULL))) {
                            strlimcpy(path, makepath(dir, command, NULL), sizeof(path));
                            goto finish;
                    }
    #if defined(_WIN32) || defined(__DJGPP__)
                    for (i = 0; i < lim; i++)
                            if (test("f", makepath(dir, command, suffix[i]))) {
                                    strlimcpy(path, makepath(dir, command, suffix[i]), sizeof(path));
                                    goto finish;
                            }
    #endif
            }
    finish:
            strbuf_close(sb);
            return *path ? path : NULL;
    }

/* [<][>][^][v][top][bottom][index][help] */