omFindExec.c
Go to the documentation of this file.
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 
9 #include "resourcesconfig.h"
10 
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
34 char * omFindExec (const char *name, char* executable)
35 #else
36 static char * omFindExec_link (const char *name, char* executable)
37 #endif
38 {
39  char *search;
40  char *p;
41  char tbuf[MAXPATHLEN];
42 
43  if (ABSOLUTE_FILENAME_P(name))
44  {
45  /* If we can execute the named file then return it. */
46  if (! access (name, X_OK))
47  {
48  strcpy(executable, name);
49  return executable;
50  }
51  }
52  else
53  {
54  if (((name[0] == '.') && (name[1] == '/')) ||
55  ((name[0] == '.') && (name[1] == '.') && (name[2] == '/')) ||
56  strchr(name, '/') != NULL)
57  {
58 
59 #ifdef HAVE_GETCWD
60  getcwd (tbuf, MAXPATHLEN);
61 #else
62 # ifdef HAVE_GETWD
63  getwd (tbuf);
64 # endif
65 #endif
66  strcat (tbuf, "/");
67  strcat (tbuf, name);
68  if (! access(tbuf, X_OK))
69  {
70  strcpy(executable, tbuf);
71  return executable;
72  }
73  }
74 
75 
76  search = getenv("PATH");
77 /* for winnt under msdos, cwd is implictly in the path */
78  p = search;
79 
80  if (p != NULL)
81  {
82  while (1)
83  {
84  char *next;
85  next = tbuf;
86 
87  /* Copy directory name into [tbuf]. */
88  /* This is somewhat tricky: empty names mean cwd, w.r.t. some
89  shell spec */
90  while (*p && *p != ':')
91  *next ++ = *p ++;
92  *next = '\0';
93 
94  if ((tbuf[0] == '.' && tbuf[1] == '\0') || tbuf[0] == '\0') {
95 #ifdef HAVE_GETCWD
96  getcwd (tbuf, MAXPATHLEN);
97 #else
98 # ifdef HAVE_GETWD
99  getwd (tbuf);
100 # endif
101 #endif
102  }
103 
104  if (tbuf[strlen(tbuf)-1] != '/') strcat(tbuf, "/");
105  strcat (tbuf, name);
106 
107  /* If the named file exists, then return it. */
108  if (! access (tbuf, F_OK))
109  {
110  strcpy(executable, tbuf);
111  return executable;
112  }
113 
114  if (*p != '\0')
115  {
116  p ++;
117  }
118  else
119  {
120  break;
121  }
122  }
123  }
124  }
125  return NULL;
126 }
127 
128 #ifdef HAVE_READLINK
129 /* similar to readlink, but dont' mess up absolute pathnames */
130 static int my_readlink(const char* name, char* buf, size_t bufsize)
131 {
132  char buf2[MAXPATHLEN];
133  int ret;
134 
135  if ((ret = readlink(name, buf2, bufsize)) > 0)
136  {
137  buf2[ret] = 0;
138  if (*name == '/' && *buf2 != '/')
139  {
140  char* last = strrchr(name, '/');
141  int i = 0;
142  while (&(name[i]) != last)
143  {
144  buf[i] = name[i];
145  i++;
146  }
147  buf[i] = '/';
148  i++;
149  strcpy(&(buf[i]), buf2);
150  return i + ret;
151  }
152  else
153  {
154  strcpy(buf, buf2);
155  }
156  }
157  return ret;
158 }
159 
160 #define MAX_LINK_LEVEL 10
161 /* similar to readlink (cf. man readlink), except that symbolic links are
162  followed up to MAX_LINK_LEVEL
163 */
164 static int full_readlink(const char* name, char* buf, size_t bufsize)
165 {
166  int ret;
167 
168  if ((ret=my_readlink(name, buf, bufsize)) > 0)
169  {
170  char buf2[MAXPATHLEN];
171  int ret2, i = 0;
172 
173  do
174  {
175  buf[ret] = '\0';
176  if ((ret2 = my_readlink(buf, buf2, MAXPATHLEN)) > 0)
177  {
178  i++;
179  buf2[ret2] = '\0';
180  strcpy(buf, buf2);
181  ret = ret2;
182  }
183  else
184  {
185  return ret;
186  }
187  }
188  while (i<MAX_LINK_LEVEL);
189  }
190  return -1;
191 }
192 
193 #ifdef __CYGWIN__
194 /* for windows, serch first for .exe */
195 char * _omFindExec (const char *name, char* exec);
196 char* omFindExec(const char *name, char* exec)
197 {
198 
199  if (strstr(name, ".exe") == NULL)
200  {
201  char buf[MAXPATHLEN];
202  char* ret;
203  strcpy(buf, name);
204  strcat(buf, ".exe");
205  ret = _omFindExec(buf, exec);
206  if (ret != NULL) return ret;
207  }
208  return _omFindExec(name, exec);
209 }
210 #else
211 #define _omFindExec omFindExec
212 #endif
213 
214 char * _omFindExec (const char *name, char* exec)
215 {
216  char * link = omFindExec_link(name, exec);
217  char buf[MAXPATHLEN];
218  int ret;
219 
220  if (link == NULL && (ret=full_readlink(name, buf, MAXPATHLEN)) > 0)
221  {
222  buf[ret] ='\0';
223  link = omFindExec_link(buf, exec);
224  }
225  if (link != NULL && (ret=full_readlink(link, buf, MAXPATHLEN)) > 0)
226  {
227  char *p = strrchr(link, '/');
228 
229 
230  if(p!=NULL) *(p+1)='\0';
231  buf[ret]='\0';
232 
233  if (buf[0] != '/')
234  {
235  strcpy(exec, link);
236  strcat(exec, buf);
237  }
238  else
239  {
240  strcpy(exec, buf);
241  }
242 
243  return exec;
244  }
245  return link;
246 }
247 #endif /* HAVE_READLINK */
248 
249 #else
250 
251 char* omFindExec (const char *name, char* exec)
252 {
253  return name;
254 }
255 
256 #endif /* defined(HAVE_UNISTD_H) && defined(STDC_HEADERS) */
#define MAXPATHLEN
Definition: omRet2Info.c:22
return P p
Definition: myNF.cc:203
static poly last
Definition: hdegree.cc:1077
char * getenv()
int search(const CFArray &A, const CanonicalForm &F, int i, int j)
search for F in A between index i and j
int status int void * buf
Definition: si_signals.h:59
int i
Definition: cfEzgcd.cc:123
char name(const Variable &v)
Definition: factory.h:178
CanonicalForm buf2
Definition: facFqBivar.cc:71
#define NULL
Definition: omList.c:10
char * omFindExec(const char *name, char *exec)
Definition: omFindExec.c:251
ListNode * next
Definition: janet.h:31