source: git/findexec/omFindExec.c @ 8fee84

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