source: git/Singular/find_exec.c @ e5295a

spielwiese
Last change on this file since e5295a was e5295a, checked in by Olaf Bachmann <obachman@…>, 24 years ago
* follow symbolic links up to level MAX_LINK_LEVEL (10) git-svn-id: file:///usr/local/Singular/svn/trunk@3812 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 5.0 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $id:$ */
5
6/* find_exec.c -- Find a program, given an argv[0]
7   Copyright (C) 1996 Free Software Foundation, Inc.
8   Copyright (C) 1990 by W. Wilson Ho.
9   This file is part of the GNU Dld Library. */
10
11/* Adapted for use with Singular by obachman@mathematik.uni-kl.de  4/98*/
12
13#include "mod2.h"
14
15#if ! defined(MSDOS) && ! defined(__MWERKS__)
16
17#include <unistd.h> /* always defiend */
18#include <stdlib.h>
19#include <strings.h>
20
21#ifndef ESINGULAR
22#include "mmemory.h"
23#endif
24
25
26#ifndef MAXPATHLEN
27#define MAXPATHLEN 1024
28#endif
29
30
31/* Do not return copies of sth, but simply the strings
32   -- we make copies later */
33#define copy_of(string) mstrdup(string)
34
35/* ABSOLUTE_FILENAME_P (fname): True if fname is an absolute filename */
36#ifdef atarist
37#define ABSOLUTE_FILENAME_P(fname)        ((fname[0] == '/') || \
38        (fname[0] && (fname[1] == ':')))
39#else
40#define ABSOLUTE_FILENAME_P(fname)        (fname[0] == '/')
41#endif /* atarist */
42
43/* Return the absolute name of the program named NAME.  This function
44   searches the directories in the PATH environment variable if PROG
45   has no directory components. */
46#ifndef HAVE_READLINK
47char * find_executable (const char *name)
48#else
49char * find_executable_link (const char *name)
50#endif
51{
52  char *search;
53  char *p;
54  char *extra = NULL;
55  char tbuf[MAXPATHLEN];
56
57  if (ABSOLUTE_FILENAME_P(name))
58  {
59      /* If we can execute the named file then return it. */
60      if (! access (name, X_OK))
61        return copy_of (name);
62  }
63  else
64  {
65    if (((name[0] == '.') && (name[1] == '/')) ||
66        ((name[0] == '.') && (name[1] == '.') && (name[2] == '/')) ||
67        strchr(name, '/') != NULL)
68    {
69
70#ifdef HAVE_GETCWD
71      getcwd (tbuf, MAXPATHLEN);
72#else
73# ifdef HAVE_GETWD
74      getwd (tbuf);
75# endif
76#endif
77      strcat (tbuf, "/");
78      strcat (tbuf, name);
79      if (! access(name, X_OK))
80        return copy_of (tbuf);
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      /* we are under msdos display */
90      extra = (char*) AllocL((search != NULL ? strlen(search) : 0) + 3);
91      strcpy(extra, ".:");
92      if (search != NULL) strcat(extra, search);
93      search = extra;
94    }
95#endif
96    p = search;
97
98    if (p != NULL)
99    {
100      while (1)
101      {
102        char *next;
103        next = tbuf;
104
105        /* Copy directory name into [tbuf]. */
106        /* This is somewhat tricky: empty names mean cwd, w.r.t. some
107           shell spec */
108        while (*p && *p != ':')
109          *next ++ = *p ++;
110        *next = '\0';
111
112        if ((tbuf[0] == '.' && tbuf[1] == '\0') || tbuf[0] == '\0') {
113#ifdef HAVE_GETCWD
114          getcwd (tbuf, MAXPATHLEN);
115#else
116# ifdef HAVE_GETWD
117          getwd (tbuf);
118# endif
119#endif
120        }
121
122        if (tbuf[strlen(tbuf)-1] != '/') strcat(tbuf, "/");
123        strcat (tbuf, name);
124       
125        /* If we can execute the named file, then return it. */
126        if (! access (tbuf, X_OK))
127        {
128#ifdef WINNT
129          if (extra != NULL)
130            FreeL(extra);
131#endif
132          return copy_of (tbuf);
133        }
134
135        if (*p != '\0')
136        {
137          p ++;
138        }
139        else
140        {
141          break;
142        }
143
144      }
145    }
146  }
147
148  return NULL;
149}
150
151#ifdef HAVE_READLINK
152
153#define MAX_LINK_LEVEL 10
154/* similar to readlink (cf. man readlink), except that symbolic links are
155   followed up to MAX_LINK_LEVEL
156*/
157
158int full_readlink(const char* name, char* buf, size_t bufsize)
159{
160  int ret;
161 
162  if ((ret=readlink(name, buf, bufsize)) > 0)
163  {
164    char buf2[MAXPATHLEN];
165    int ret2, i = 0;
166   
167    do
168    {
169      buf[ret] = '\0';
170      if ((ret2 = readlink(buf, buf2, MAXPATHLEN)) > 0)
171      {
172        i++;
173        buf2[ret2] = '\0';
174        strcpy(buf, buf2);
175        ret = ret2;
176      }
177      else
178      {
179        return ret;
180      }
181    }
182    while (i<MAX_LINK_LEVEL);
183  }
184  return -1;
185}
186 
187 
188char * find_executable (const char *name)
189{
190  char * link = find_executable_link(name);
191  char buf[MAXPATHLEN];
192  int ret;
193
194  if (link == NULL && (ret=full_readlink(name, buf, MAXPATHLEN)) > 0)
195  {
196    buf[ret] ='\0';
197    link = find_executable_link(buf);
198  }
199  if (link != NULL && (ret=full_readlink(link, buf, MAXPATHLEN)) > 0)
200  {
201    /* follow link further until you reach the end of it, or unitl
202       MAX_SYMBOLIC_LINKS are encountered */
203    char *p = strrchr(link, '/');
204    char *executable;
205
206
207    if(p!=NULL) *(p+1)='\0';
208    buf[ret]='\0';
209
210    if (buf[0] != '/')
211    {
212      executable = (char*) AllocL(strlen(link) + ret + 1);
213      strcpy(executable, link);
214      strcat(executable, buf);
215    }
216    else
217    {
218      executable = copy_of(buf);
219    }
220
221    FreeL(link);
222    return executable;
223  }
224
225  return link;
226}
227#endif /* HAVE_READLINK */
228
229#else
230
231char* find_executable (const char *name)
232{
233  return NULL;
234}
235
236#endif /* #if ! defined(MSDOS) && ! defined(__MWERKS__) && defined(HAVE_SYS_TYPES_H) && defined(HAVE_PWD_H)&&defined(HAVE_SYS_PARAM_H) */
237
238
Note: See TracBrowser for help on using the repository browser.