aboutsummaryrefslogtreecommitdiff
path: root/src/lib9/searchpath.c
blob: 75e0695fc9835b3baf5f27aa2e63c2df29d93f13 (plain)
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
#include <u.h>
#include <libc.h>

/*
 * Search $PATH for an executable with the given name.
 * Like in rc, mid-name slashes do not disable search.
 * Should probably handle escaped colons,
 * but I don't know what the syntax is.
 */
char*
searchpath(char *name)
{
	char *path, *p, *next;
	char *s, *ss;
	int ns, l;

	s = nil;
	ns = 0;
	if((name[0] == '.' && name[1] == '/')
	|| (name[0] == '.' && name[1] == '.' && name[2] == '/')
	|| (name[0] == '/')){
		if(access(name, AEXEC) >= 0)
			return strdup(name);
		return nil;
	}

	path = getenv("PATH");
	for(p=path; p && *p; p=next){
		if((next = strchr(p, ':')) != nil)
			*next++ = 0;
		if(*p == 0){
			if(access(name, AEXEC) >= 0){
				free(s);
				free(path);
				return strdup(name);
			}
		}else{
			l = strlen(p)+1+strlen(name)+1;
			if(l > ns){
				ss = realloc(s, l);
				if(ss == nil){
					free(s);
					free(path);
					return nil;
				}
				s = ss;
				ns = l;
			}
			strcpy(s, p);
			strcat(s, "/");
			strcat(s, name);
			if(access(s, AEXEC) >= 0){
				free(path);
				return s;
			}
		}
	}
	free(s);
	free(path);
	return nil;
}