source: git/findexec/omFindExec.c @ 9840b5

fieker-DuValspielwiese
Last change on this file since 9840b5 was ae030d, checked in by Hans Schoenemann <hannes@…>, 12 years ago
removed depencies on omalloc from feResource
  • Property mode set to 100644
File size: 5.7 KB
Line 
1/*******************************************************************
2 *  File:    omFindExec.c
3 *  Purpose: routine which determines absolute pathname of executable
4 *  Author:  obachman (Olaf Bachmann)
5 *  Created: 11/99
6 *  Version: $Id$
7 *******************************************************************/
8
9#include "config.h"
10
11#if defined(HAVE_UNISTD_H) && defined(STDC_HEADERS)
12
13#ifdef HAVE_UNISTD_H
14#include <unistd.h> /* always defiend */
15#endif
16
17#include <stdlib.h>
18#include <string.h>
19
20#include "omFindExec.h"
21
22#ifndef MAXPATHLEN
23#define MAXPATHLEN 1024
24#endif
25
26/* ABSOLUTE_FILENAME_P (fname): True if fname is an absolute filename */
27#define ABSOLUTE_FILENAME_P(fname)        (fname[0] == '/')
28
29/* Return the absolute name of the program named NAME.  This function
30   searches the directories in the PATH environment variable if PROG
31   has no directory components. */
32#ifndef HAVE_READLINK
33char * omFindExec (const char *name, char* executable)
34#else
35static char * omFindExec_link (const char *name, char* executable)
36#endif
37{
38  char *search;
39  char *p;
40#ifdef WINNT
41  char *extra = NULL;
42#endif
43  char tbuf[MAXPATHLEN];
44
45  if (ABSOLUTE_FILENAME_P(name))
46  {
47      /* If we can execute the named file then return it. */
48      if (! access (name, X_OK))
49      {
50        strcpy(executable, name);
51#ifdef __CYGWIN__
52        strcat(executable, ".exe");
53#endif
54        return executable;
55      }
56  }
57  else
58  {
59    if (((name[0] == '.') && (name[1] == '/')) ||
60        ((name[0] == '.') && (name[1] == '.') && (name[2] == '/')) ||
61        strchr(name, '/') != NULL)
62    {
63
64#ifdef HAVE_GETCWD
65      getcwd (tbuf, MAXPATHLEN);
66#else
67# ifdef HAVE_GETWD
68      getwd (tbuf);
69# endif
70#endif
71      strcat (tbuf, "/");
72      strcat (tbuf, name);
73      if (! access(tbuf, X_OK))
74      {
75        strcpy(executable, tbuf);
76#ifdef __CYGWIN__
77        strcat(executable, ".exe");
78#endif
79        return executable;
80      }
81    }
82
83
84    search = getenv("PATH");
85/* for winnt under msdos, cwd is implictly in the path */
86#ifdef WINNT
87    p = getenv("SHELL");
88    if (p == NULL || strlen(p) < 2)
89    {
90      char *extra = NULL;
91      /* we are under msdos display */
92      extra = (char*) malloc((search != NULL ? strlen(search) : 0) + 3);
93      strcpy(extra, ".:");
94      if (search != NULL) strcat(extra, search);
95      search = extra;
96    }
97#endif
98    p = search;
99
100    if (p != NULL)
101    {
102      while (1)
103      {
104        char *next;
105        next = tbuf;
106
107        /* Copy directory name into [tbuf]. */
108        /* This is somewhat tricky: empty names mean cwd, w.r.t. some
109           shell spec */
110        while (*p && *p != ':')
111          *next ++ = *p ++;
112        *next = '\0';
113
114        if ((tbuf[0] == '.' && tbuf[1] == '\0') || tbuf[0] == '\0') {
115#ifdef HAVE_GETCWD
116          getcwd (tbuf, MAXPATHLEN);
117#else
118# ifdef HAVE_GETWD
119          getwd (tbuf);
120# endif
121#endif
122        }
123
124        if (tbuf[strlen(tbuf)-1] != '/') strcat(tbuf, "/");
125        strcat (tbuf, name);
126
127        /* If we can execute the named file, then return it. */
128        if (! access (tbuf, X_OK))
129        {
130#ifdef WINNT
131          if (extra != NULL)
132            free(extra);
133#endif
134          strcpy(executable, tbuf);
135#ifdef __CYGWIN__
136          strcat(executable, ".exe");
137#endif
138          return executable;
139        }
140
141        if (*p != '\0')
142        {
143          p ++;
144        }
145        else
146        {
147          break;
148        }
149      }
150    }
151  }
152  return NULL;
153}
154
155#ifdef HAVE_READLINK
156/* similar to readlink, but dont' mess up absolute pathnames */
157static int my_readlink(const char* name, char* buf, size_t bufsize)
158{
159  char buf2[MAXPATHLEN];
160  int ret;
161
162  if ((ret = readlink(name, buf2, bufsize)) > 0)
163  {
164    buf2[ret] = 0;
165    if (*name == '/' && *buf2 != '/')
166    {
167      char* last = strrchr(name, '/');
168      int i = 0;
169      while (&(name[i]) != last)
170      {
171        buf[i] = name[i];
172        i++;
173      }
174      buf[i] = '/';
175      i++;
176      strcpy(&(buf[i]), buf2);
177      return i + ret;
178    }
179    else
180    {
181      strcpy(buf, buf2);
182    }
183  }
184  return ret;
185}
186
187#define MAX_LINK_LEVEL 10
188/* similar to readlink (cf. man readlink), except that symbolic links are
189   followed up to MAX_LINK_LEVEL
190*/
191static int full_readlink(const char* name, char* buf, size_t bufsize)
192{
193  int ret;
194
195  if ((ret=my_readlink(name, buf, bufsize)) > 0)
196  {
197    char buf2[MAXPATHLEN];
198    int ret2, i = 0;
199
200    do
201    {
202      buf[ret] = '\0';
203      if ((ret2 = my_readlink(buf, buf2, MAXPATHLEN)) > 0)
204      {
205        i++;
206        buf2[ret2] = '\0';
207        strcpy(buf, buf2);
208        ret = ret2;
209      }
210      else
211      {
212        return ret;
213      }
214    }
215    while (i<MAX_LINK_LEVEL);
216  }
217  return -1;
218}
219
220#ifdef WINNT
221char * _omFindExec (const char *name, char* exec);
222/* for windows, serch first for .exe */
223char* omFindExec(const char *name, char* exec)
224{
225
226  if (strstr(name, ".exe") == NULL)
227  {
228    char buf[MAXPATHLEN];
229    char* ret;
230    strcpy(buf, name);
231    strcat(buf, ".exe");
232    ret = _omFindExec(buf, exec);
233    if (ret != NULL) return ret;
234  }
235  return _omFindExec(name, exec);
236}
237#else
238#define _omFindExec omFindExec
239#endif
240
241char * _omFindExec (const char *name, char* exec)
242{
243  char * link = omFindExec_link(name, exec);
244  char buf[MAXPATHLEN];
245  int ret;
246
247  if (link == NULL && (ret=full_readlink(name, buf, MAXPATHLEN)) > 0)
248  {
249    buf[ret] ='\0';
250    link = omFindExec_link(buf, exec);
251  }
252  if (link != NULL && (ret=full_readlink(link, buf, MAXPATHLEN)) > 0)
253  {
254    char *p = strrchr(link, '/');
255
256
257    if(p!=NULL) *(p+1)='\0';
258    buf[ret]='\0';
259
260    if (buf[0] != '/')
261    {
262      strcpy(exec, link);
263      strcat(exec, buf);
264    }
265    else
266    {
267      strcpy(exec, buf);
268    }
269
270    return exec;
271  }
272  return link;
273}
274#endif /* HAVE_READLINK */
275
276#else
277
278char* omFindExec (const char *name, char* exec)
279{
280  return name;
281}
282
283#endif /* defined(HAVE_UNISTD_H) && defined(STDC_HEADERS) */
Note: See TracBrowser for help on using the repository browser.