-
Notifications
You must be signed in to change notification settings - Fork 1
/
findpath.cc
64 lines (60 loc) · 1.53 KB
/
findpath.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#define ICI_CORE
#include "array.h"
#include "fwd.h"
#include "str.h"
#ifndef _WIN32
#include <unistd.h> /* access(2) prototype */
#else
#include <io.h>
#endif
namespace ici
{
/*
* Search for the given file called 'name', with the optional extension 'ext',
* on our path (that is, the current value of 'path' in the current scope).
* 'name' must point to a buffer of at least FILENAME_MAX chars which will be
* overwritten with the full file name should it be found. 'ext' must be less
* than 10 chars long and include any leading dot (or nullptr if not required).
* Returns 1 if the expansion was made, else 0, never errors.
*/
int find_on_path(char name[FILENAME_MAX], const char *ext)
{
array *a;
char *p;
int xlen;
object **e;
str *s;
char realname[FILENAME_MAX];
if ((a = need_path()) == nullptr)
{
return 0;
}
xlen = 1 + strlen(name) + (ext != nullptr ? strlen(ext) : 0) + 1;
for (e = a->astart(); e != a->alimit(); e = a->anext(e))
{
if (!isstring(*e))
{
continue;
}
s = stringof(*e);
if (s->s_nchars + xlen > FILENAME_MAX)
{
continue;
}
strcpy(realname, s->s_chars);
p = realname + s->s_nchars;
*p++ = ICI_DIR_SEP;
strcpy(p, name);
if (ext != nullptr)
{
strcat(p, ext);
}
if (access(realname, 0) == 0)
{
strcpy(name, realname);
return 1;
}
}
return 0;
}
} // namespace ici