/******************************************************************* * File: omFindExec.c * Purpose: routine which determines absolute pathname of executable * Author: obachman (Olaf Bachmann) * Created: 11/99 * Version: $Id$ *******************************************************************/ #ifdef HAVE_CONFIG_H #include #endif #if defined(HAVE_UNISTD_H) && defined(STDC_HEADERS) #ifdef HAVE_UNISTD_H #include /* always defiend */ #endif #include #include #include #ifndef MAXPATHLEN #define MAXPATHLEN 1024 #endif #ifdef WINNT #include #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*) omAlloc((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) omFree(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 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) */