diff options
Diffstat (limited to 'pathexec_env.c')
-rw-r--r-- | pathexec_env.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/pathexec_env.c b/pathexec_env.c new file mode 100644 index 0000000..1305469 --- /dev/null +++ b/pathexec_env.c | |||
@@ -0,0 +1,74 @@ | |||
1 | /* Public domain. */ | ||
2 | |||
3 | #include "stralloc.h" | ||
4 | #include "alloc.h" | ||
5 | #include "str.h" | ||
6 | #include "byte.h" | ||
7 | #include "env.h" | ||
8 | #include "pathexec.h" | ||
9 | |||
10 | static stralloc plus; | ||
11 | static stralloc tmp; | ||
12 | |||
13 | int pathexec_env(const char *s,const char *t) | ||
14 | { | ||
15 | if (!s) return 1; | ||
16 | if (!stralloc_copys(&tmp,s)) return 0; | ||
17 | if (t) { | ||
18 | if (!stralloc_cats(&tmp,"=")) return 0; | ||
19 | if (!stralloc_cats(&tmp,t)) return 0; | ||
20 | } | ||
21 | if (!stralloc_0(&tmp)) return 0; | ||
22 | return stralloc_cat(&plus,&tmp); | ||
23 | } | ||
24 | |||
25 | void pathexec_env_run(const char *file, const char *const *argv) | ||
26 | { | ||
27 | const char **e; | ||
28 | unsigned int elen; | ||
29 | unsigned int i; | ||
30 | unsigned int j; | ||
31 | unsigned int split; | ||
32 | unsigned int t; | ||
33 | |||
34 | if (!stralloc_cats(&plus,"")) return; | ||
35 | |||
36 | elen = 0; | ||
37 | for (i = 0;environ[i];++i) | ||
38 | ++elen; | ||
39 | for (i = 0;i < plus.len;++i) | ||
40 | if (!plus.s[i]) | ||
41 | ++elen; | ||
42 | |||
43 | e = (const char **) alloc((elen + 1) * sizeof(char *)); | ||
44 | if (!e) return; | ||
45 | |||
46 | elen = 0; | ||
47 | for (i = 0;environ[i];++i) | ||
48 | e[elen++] = environ[i]; | ||
49 | |||
50 | j = 0; | ||
51 | for (i = 0;i < plus.len;++i) | ||
52 | if (!plus.s[i]) { | ||
53 | split = str_chr(plus.s + j,'='); | ||
54 | for (t = 0;t < elen;++t) | ||
55 | if (byte_equal(plus.s + j,split,e[t])) | ||
56 | if (e[t][split] == '=') { | ||
57 | --elen; | ||
58 | e[t] = e[elen]; | ||
59 | break; | ||
60 | } | ||
61 | if (plus.s[j + split]) | ||
62 | e[elen++] = plus.s + j; | ||
63 | j = i + 1; | ||
64 | } | ||
65 | e[elen] = 0; | ||
66 | |||
67 | pathexec_run(file,argv,e); | ||
68 | alloc_free(e); | ||
69 | } | ||
70 | |||
71 | void pathexec(const char *const *argv) | ||
72 | { | ||
73 | return pathexec_env_run(*argv, argv); | ||
74 | } | ||