Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: f92a39ece0
Fetching contributors…

Cannot retrieve contributors at this time

283 lines (248 sloc) 5.844 kb
/*******************************************************************
* File: omFindExec.c
* Purpose: routine which determines absolute pathname of executable
* Author: obachman (Olaf Bachmann)
* Created: 11/99
*******************************************************************/
#include "config.h"
#if defined(HAVE_UNISTD_H) && defined(STDC_HEADERS)
#ifdef HAVE_UNISTD_H
#include <unistd.h> /* always defiend */
#endif
#include <stdlib.h>
#include <string.h>
#include "omFindExec.h"
#ifndef MAXPATHLEN
#define MAXPATHLEN 1024
#endif
/* ABSOLUTE_FILENAME_P (fname): True if fname is an absolute filename */
#define ABSOLUTE_FILENAME_P(fname) (fname[0] == '/')
/* Return the absolute name of the program named NAME. This function
searches the directories in the PATH environment variable if PROG
has no directory components. */
#ifndef HAVE_READLINK
char * omFindExec (const char *name, char* executable)
#else
static char * omFindExec_link (const char *name, char* executable)
#endif
{
char *search;
char *p;
#ifdef WINNT
char *extra = NULL;
#endif
char tbuf[MAXPATHLEN];
if (ABSOLUTE_FILENAME_P(name))
{
/* If we can execute the named file then return it. */
if (! access (name, X_OK))
{
strcpy(executable, name);
#ifdef __CYGWIN__
strcat(executable, ".exe");
#endif
return executable;
}
}
else
{
if (((name[0] == '.') && (name[1] == '/')) ||
((name[0] == '.') && (name[1] == '.') && (name[2] == '/')) ||
strchr(name, '/') != NULL)
{
#ifdef HAVE_GETCWD
getcwd (tbuf, MAXPATHLEN);
#else
# ifdef HAVE_GETWD
getwd (tbuf);
# endif
#endif
strcat (tbuf, "/");
strcat (tbuf, name);
if (! access(tbuf, X_OK))
{
strcpy(executable, tbuf);
#ifdef __CYGWIN__
strcat(executable, ".exe");
#endif
return executable;
}
}
search = getenv("PATH");
/* for winnt under msdos, cwd is implictly in the path */
#ifdef WINNT
p = getenv("SHELL");
if (p == NULL || strlen(p) < 2)
{
char *extra = NULL;
/* we are under msdos display */
extra = (char*) malloc((search != NULL ? strlen(search) : 0) + 3);
strcpy(extra, ".:");
if (search != NULL) strcat(extra, search);
search = extra;
}
#endif
p = search;
if (p != NULL)
{
while (1)
{
char *next;
next = tbuf;
/* Copy directory name into [tbuf]. */
/* This is somewhat tricky: empty names mean cwd, w.r.t. some
shell spec */
while (*p && *p != ':')
*next ++ = *p ++;
*next = '\0';
if ((tbuf[0] == '.' && tbuf[1] == '\0') || tbuf[0] == '\0') {
#ifdef HAVE_GETCWD
getcwd (tbuf, MAXPATHLEN);
#else
# ifdef HAVE_GETWD
getwd (tbuf);
# endif
#endif
}
if (tbuf[strlen(tbuf)-1] != '/') strcat(tbuf, "/");
strcat (tbuf, name);
/* If we can execute the named file, then return it. */
if (! access (tbuf, X_OK))
{
#ifdef WINNT
if (extra != NULL)
free(extra);
#endif
strcpy(executable, tbuf);
#ifdef __CYGWIN__
strcat(executable, ".exe");
#endif
return executable;
}
if (*p != '\0')
{
p ++;
}
else
{
break;
}
}
}
}
return NULL;
}
#ifdef HAVE_READLINK
/* similar to readlink, but dont' mess up absolute pathnames */
static int my_readlink(const char* name, char* buf, size_t bufsize)
{
char buf2[MAXPATHLEN];
int ret;
if ((ret = readlink(name, buf2, bufsize)) > 0)
{
buf2[ret] = 0;
if (*name == '/' && *buf2 != '/')
{
char* last = strrchr(name, '/');
int i = 0;
while (&(name[i]) != last)
{
buf[i] = name[i];
i++;
}
buf[i] = '/';
i++;
strcpy(&(buf[i]), buf2);
return i + ret;
}
else
{
strcpy(buf, buf2);
}
}
return ret;
}
#define MAX_LINK_LEVEL 10
/* similar to readlink (cf. man readlink), except that symbolic links are
followed up to MAX_LINK_LEVEL
*/
static int full_readlink(const char* name, char* buf, size_t bufsize)
{
int ret;
if ((ret=my_readlink(name, buf, bufsize)) > 0)
{
char buf2[MAXPATHLEN];
int ret2, i = 0;
do
{
buf[ret] = '\0';
if ((ret2 = my_readlink(buf, buf2, MAXPATHLEN)) > 0)
{
i++;
buf2[ret2] = '\0';
strcpy(buf, buf2);
ret = ret2;
}
else
{
return ret;
}
}
while (i<MAX_LINK_LEVEL);
}
return -1;
}
#ifdef WINNT
char * _omFindExec (const char *name, char* exec);
/* for windows, serch first for .exe */
char* omFindExec(const char *name, char* exec)
{
if (strstr(name, ".exe") == NULL)
{
char buf[MAXPATHLEN];
char* ret;
strcpy(buf, name);
strcat(buf, ".exe");
ret = _omFindExec(buf, exec);
if (ret != NULL) return ret;
}
return _omFindExec(name, exec);
}
#else
#define _omFindExec omFindExec
#endif
char * _omFindExec (const char *name, char* exec)
{
char * link = omFindExec_link(name, exec);
char buf[MAXPATHLEN];
int ret;
if (link == NULL && (ret=full_readlink(name, buf, MAXPATHLEN)) > 0)
{
buf[ret] ='\0';
link = omFindExec_link(buf, exec);
}
if (link != NULL && (ret=full_readlink(link, buf, MAXPATHLEN)) > 0)
{
char *p = strrchr(link, '/');
if(p!=NULL) *(p+1)='\0';
buf[ret]='\0';
if (buf[0] != '/')
{
strcpy(exec, link);
strcat(exec, buf);
}
else
{
strcpy(exec, buf);
}
return exec;
}
return link;
}
#endif /* HAVE_READLINK */
#else
char* omFindExec (const char *name, char* exec)
{
return name;
}
#endif /* defined(HAVE_UNISTD_H) && defined(STDC_HEADERS) */
Jump to Line
Something went wrong with that request. Please try again.