source: git/findexec/omFindExec.c @ 08a955

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