source: git/resources/omFindExec.c @ 16f511

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