ReactOS  r76032
searchinpath.c File Reference
#include <schily/mconfig.h>
#include <schily/string.h>
#include <schily/unistd.h>
#include <schily/stdlib.h>
#include <schily/stat.h>
#include <schily/standard.h>
#include <schily/schily.h>
#include <schily/errno.h>
Include dependency graph for searchinpath.c:

Go to the source code of this file.

Macros

#define NAMEMAX   4096
 
#define enofile(t)
 

Functions

EXPORT char *searchfileinpath __PR ((char *name, int mode, int file_mode, char *path))
 
LOCAL char *searchonefile __PR ((char *name, int mode, BOOL plain_file, char *xn, char *nbuf, char *np, char *ep))
 
EXPORT charsearchfileinpath (char *name, int mode, int file_mode, char *path)
 
LOCAL charsearchonefile (char *name, int mode, BOOL plain_file, char *xn, char *nbuf, char *np, char *ep)
 

Variables

static UConst char sccsid []
 

Macro Definition Documentation

#define enofile (   t)
Value:
((t) == ENOENT || \
(t) == ENOTDIR || \
(t) == EISDIR || \
(t) == EIO)
GLdouble GLdouble t
Definition: gl.h:2047
Definition: arc.h:50
Definition: arc.h:46
Definition: arc.h:40
Definition: arc.h:41

Definition at line 57 of file searchinpath.c.

Referenced by searchfileinpath().

#define NAMEMAX   4096

Definition at line 37 of file searchinpath.c.

Referenced by searchfileinpath().

Function Documentation

EXPORT char* searchfileinpath __PR ( (char *name, int mode, int file_mode, char *path )
LOCAL char* searchonefile __PR ( (char *name, int mode, BOOL plain_file, char *xn, char *nbuf, char *np, char *ep)  )
EXPORT char* searchfileinpath ( char name,
int  mode,
int  file_mode,
char path 
)

Definition at line 68 of file searchinpath.c.

Referenced by main(), and sic_base().

73 {
74  char pbuf[NAMEMAX];
75  char *nbuf = pbuf;
76  char *np;
77  char *ep;
78  char *xn;
79  int nlen = strlen(name);
80  int oerrno = geterrno();
81  int err = 0;
82 #ifdef HAVE_GETEXECNAME
83  char *pn = (char *)getexecname(); /* pn is on the stack */
84 #else
85  char *pn = getexecpath(); /* pn is from strdup() */
86  char ebuf[NAMEMAX];
87 
88  if (pn) {
89  strlcpy(ebuf, pn, sizeof (ebuf));
90  free(pn);
91  pn = ebuf;
92  }
93 #endif
94 
95  if (pn == NULL)
96  xn = get_progname();
97  else
98  xn = pn;
99  if ((np = strrchr(xn, '/')) != NULL)
100  xn = ++np;
101 
102  /*
103  * getexecname() is the best choice for our seach. getexecname()
104  * returns either "foo" (if called from the current directory) or
105  * an absolute path after symlinks have been resolved.
106  * If getexecname() returns a path with slashes, try to search
107  * first relatively to the known location of the current binary.
108  */
109  if ((file_mode & SIP_ONLY_PATH) == 0 &&
110  pn != NULL && strchr(pn, '/') != NULL) {
111  strlcpy(nbuf, pn, sizeof (pbuf));
112  np = nbuf + strlen(nbuf);
113 
114  while (np > nbuf && np[-1] != '/')
115  *--np = '\0';
116  pn = &nbuf[sizeof (pbuf) - 1];
117  if ((np = searchonefile(name, mode,
118  file_mode & (SIP_PLAIN_FILE|SIP_NO_STRIPBIN),
119  xn,
120  nbuf, np, pn)) != NULL) {
121  seterrno(oerrno);
122  return (np);
123  }
124  }
125 
126  if (file_mode & SIP_NO_PATH)
127  return (NULL);
128 
129  if (path == NULL)
130  path = getenv("PATH");
131  if (path == NULL)
132  return (NULL);
133 
134 
135 #ifdef __DJGPP__
136  path = strdup(path);
137  if (path == NULL)
138  return (NULL);
139  strbs2s(path); /* PATH under DJGPP can contain both slashes */
140 #endif
141 
142  /*
143  * A PATH name search should lead us to the path under which we
144  * called the binary, but not necessarily to the install path as
145  * we may have been called thorugh a symlink or hardlink. In case
146  * of a symlink, we can follow the link. In case of a hardlink, we
147  * are lost.
148  */
149  ep = &nbuf[sizeof (pbuf) - 1];
150  for (;;) {
151  np = nbuf;
152  while (*path != PATH_ENV_DELIM && *path != '\0' &&
153  np < &nbuf[sizeof (pbuf) - nlen])
154  *np++ = *path++;
155  *np = '\0';
156  if ((np = searchonefile(name, mode,
157  file_mode & (SIP_PLAIN_FILE|SIP_NO_STRIPBIN),
158  xn,
159  nbuf, np, ep)) != NULL) {
160 #ifdef __DJGPP__
161  free(path);
162 #endif
163  seterrno(oerrno);
164  return (np);
165  }
166  if (err == 0) {
167  err = geterrno();
168  if (enofile(err))
169  err = 0;
170  }
171  if (*path == '\0')
172  break;
173  path++;
174  }
175 #ifdef __DJGPP__
176  free(path);
177 #endif
178  if (err)
179  seterrno(err);
180  else
181  seterrno(oerrno);
182  return (NULL);
183 }
#define SIP_NO_STRIPBIN
Definition: schily.h:432
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define SIP_PLAIN_FILE
Definition: schily.h:429
#define free
Definition: debug_ros.c:5
size_t strlcpy(char *d, const char *s, size_t bufsize)
Definition: compat.c:3
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
int int int * err
Definition: fci.h:172
_Check_return_ _CRTIMP char *__cdecl strdup(_In_opt_z_ const char *_Src)
LOCAL char * searchonefile(char *name, int mode, BOOL plain_file, char *xn, char *nbuf, char *np, char *ep)
Definition: searchinpath.c:186
smooth NULL
Definition: ftsmooth.c:557
EXPORT int seterrno(int err)
Definition: seterrno.c:34
Definition: pbuf.h:79
EXPORT int geterrno()
Definition: geterrno.c:34
#define SIP_ONLY_PATH
Definition: schily.h:431
EXPORT char * get_progname()
Definition: saveargs.c:151
EXPORT char * getexecpath()
Definition: getexecpath.c:55
#define enofile(t)
Definition: searchinpath.c:57
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
#define NAMEMAX
Definition: searchinpath.c:37
Definition: services.c:311
#define PATH_ENV_DELIM
Definition: mconfig.h:525
char * strchr(const char *String, int ch)
Definition: utclib.c:501
Definition: name.c:23
#define SIP_NO_PATH
Definition: schily.h:430
LOCAL char* searchonefile ( char name,
int  mode,
BOOL  plain_file,
char xn,
char nbuf,
char np,
char ep 
)

Definition at line 186 of file searchinpath.c.

Referenced by searchfileinpath().

194 {
195  struct stat sb;
196 
197  while (np > nbuf && np[-1] == '/')
198  *--np = '\0';
199  if (xn) {
200  *np++ = '/';
201  strlcpy(np, xn, ep - np);
202  if (stat(nbuf, &sb) < 0)
203  return (NULL);
204  if (!S_ISREG(sb.st_mode))
205  return (NULL);
206  *--np = '\0';
207  }
208  if ((plain_file & SIP_NO_STRIPBIN) == 0) {
209  if (np >= &nbuf[4] && streql(&np[-4], "/bin"))
210  np = &np[-4];
211  }
212  plain_file &= SIP_PLAIN_FILE;
213  *np++ = '/';
214  *np = '\0';
215  strlcpy(np, name, ep - np);
216 
217  seterrno(0);
218  if (stat(nbuf, &sb) >= 0) {
219  if ((!plain_file || S_ISREG(sb.st_mode)) &&
220  (eaccess(nbuf, mode) >= 0)) {
221  return (strdup(nbuf));
222  }
223  if (geterrno() == 0)
224  seterrno(EACCES);
225  }
226  return (NULL);
227 }
#define SIP_NO_STRIPBIN
Definition: schily.h:432
#define SIP_PLAIN_FILE
Definition: schily.h:429
size_t strlcpy(char *d, const char *s, size_t bufsize)
Definition: compat.c:3
EXPORT int streql(char *a, const char *b) const
Definition: streql.c:23
superblock * sb
Definition: btrfs.c:3815
_Check_return_ _CRTIMP char *__cdecl strdup(_In_opt_z_ const char *_Src)
smooth NULL
Definition: ftsmooth.c:557
EXPORT int seterrno(int err)
Definition: seterrno.c:34
EXPORT int geterrno()
Definition: geterrno.c:34
Definition: arc.h:34
Definition: stat.h:55
_CRTIMP int __cdecl stat(const char *_Filename, struct stat *_Stat)
Definition: stat.h:345
Definition: name.c:23
EXPORT int eaccess(char *name, int mode) const
Definition: eaccess.c:35
#define S_ISREG(mode)
Definition: various.h:17

Variable Documentation

UConst char sccsid[]
static
Initial value:
=
"@(#)searchinpath.c 1.5 16/08/01 Copyright 1999-2016 J. Schilling"

Definition at line 4 of file searchinpath.c.