libs-base/Source/find_exec.c
netc 5f7871270a Remove dependency upon config.h by headers files and include
directly in source files because the config.h file is system
dependent, used just for compiling the source, and should
not be installed.
Some minor bug fixes.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@2619 72102866-910b-0410-8b05-ffd578937521
1997-11-06 00:51:23 +00:00

241 lines
5 KiB
C

/*
find_exec.c - routine to find the executable path
From the dld distribution -- copyrighted below.
Modified by Adam Fedor - traverse links
Given a filename, objc_find_executable searches the directories listed in
environment variable PATH for a file with that filename.
A new copy of the complete path name of that file is returned. This new
string may be disposed by free() later on.
*/
/* This file is part of DLD, a dynamic link/unlink editor for C.
Copyright (C) 1990 by W. Wilson Ho.
The author can be reached electronically by how@cs.ucdavis.edu or
through physical mail at:
W. Wilson Ho
Division of Computer Science
University of California at Davis
Davis, CA 95616
*/
/* 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 1, or (at your option) any
later version.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <config.h>
#ifdef __WIN32__
#include <limits.h>
#define S_IFLNK 0120000
int readlink(char *path, char *buf, int bufsiz) { return (-1); }
int lstat(char *path, struct stat *buf) { return (-1); }
#define MAXPATHLEN 255
#else
#include <sys/file.h>
#include <sys/param.h>
#include <unistd.h>
#endif /* __WIN32__ */
#include <stdlib.h>
#include <string.h>
#define DEFAULT_PATH ".:~/bin::/usr/local/bin:/usr/new:/usr/ucb:/usr/bin:/bin:/usr/hosts"
#if defined(__WIN32__) || defined(_WIN32)
#define PATH_SEPARATOR ';'
#define PATH_COMPONENT "\\"
#else
#define PATH_SEPARATOR ':'
#define PATH_COMPONENT "/"
#endif
/* ABSOLUTE_FILENAME_P (fname): True if fname is an absolute filename */
#if defined(atarist) || defined(__WIN32__) || defined(_WIN32)
#define ABSOLUTE_FILENAME_P(fname) ((fname[0] == '/') || \
(fname[0] && (fname[1] == ':')))
#else
#define ABSOLUTE_FILENAME_P(fname) (fname[0] == '/')
#endif /* atarist */
static char *
copy_of (s)
register char *s;
{
register char *p = (char *) malloc (strlen(s)+1);
if (!p) return 0;
*p = 0;
strcpy (p, s);
return p;
}
static int
find_full_path(char *path)
{
struct stat statbuf;
if ( stat(path, &statbuf) != 0)
return -1;
if ( (lstat(path, &statbuf) == 0)
&& (statbuf.st_mode & S_IFLNK) == S_IFLNK) {
char link[MAXPATHLEN+1];
int cc;
cc = readlink(path, link, MAXPATHLEN);
if (cc == -1)
return -1;
link[cc] = '\0';
if (ABSOLUTE_FILENAME_P(link)) {
strcpy(path, link);
} else if (strlen(path)+strlen(link) < MAXPATHLEN) {
char *p;
p = strrchr(path, '/');
if (p)
*(p+1) = '\0';
strcat(path, link);
} else
return -1;
}
return 0;
}
char *
objc_find_executable (const char *file)
{
char *search;
register char *p;
int cwd_in_path = 0;
if (ABSOLUTE_FILENAME_P(file)) {
search = copy_of(file);
find_full_path(search);
return search;
/*
return copy_of (file);
*/
}
if ((search = (char *) getenv("PATH")) == 0)
search = DEFAULT_PATH;
p = search;
while (*p) {
char name[MAXPATHLEN];
register char *next;
next = name;
/* copy directory name into [name] */
while (*p && *p != PATH_SEPARATOR) *next++ = *p++;
*next = 0;
if (*p) p++;
if (name[0] == '.' && name[1] == 0) {
#ifdef HAVE_GETCWD
getcwd (name, MAXPATHLEN);
#else
getwd (name);
#endif
cwd_in_path = 1;
}
strcat (name, PATH_COMPONENT);
strcat (name, file);
/*
if (access (name, X_OK) == 0)
*/
if (find_full_path (name) == 0)
return copy_of (name);
/* Also add common executable extensions on windows */
#if defined(__WIN32__) || defined(_WIN32)
{
int fl = strlen(name);
strcat (name, ".com");
if (find_full_path (name) == 0)
return copy_of (name);
name[fl] = '\0';
strcat (name, ".exe");
if (find_full_path (name) == 0)
return copy_of (name);
name[fl] = '\0';
strcat (name, ".bat");
if (find_full_path (name) == 0)
return copy_of (name);
name[fl] = '\0';
strcat (name, ".cmd");
if (find_full_path (name) == 0)
return copy_of (name);
name[fl] = '\0';
}
#endif
}
/*
If '.' not in PATH, check this too
*/
if (!cwd_in_path) {
char name[MAXPATHLEN];
#ifdef HAVE_GETCWD
getcwd (name, MAXPATHLEN);
#else
getwd (name);
#endif
strcat (name, PATH_COMPONENT);
strcat (name, file);
/*
if (access (name, X_OK) == 0)
*/
if (find_full_path (name) == 0)
return copy_of (name);
/* Also add common executable extensions on windows */
#if defined(__WIN32__) || defined(_WIN32)
{
int fl = strlen(name);
strcat (name, ".com");
if (find_full_path (name) == 0)
return copy_of (name);
name[fl] = '\0';
strcat (name, ".exe");
if (find_full_path (name) == 0)
return copy_of (name);
name[fl] = '\0';
strcat (name, ".bat");
if (find_full_path (name) == 0)
return copy_of (name);
name[fl] = '\0';
strcat (name, ".cmd");
if (find_full_path (name) == 0)
return copy_of (name);
name[fl] = '\0';
}
#endif
}
return 0;
}