source: git/omalloc/omFindExec.c @ f769719

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