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
pathexec_env(const char * s,const char * t)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
pathexec_env_run(const char * file,const char * const * argv)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
pathexec(const char * const * argv)71 void pathexec(const char *const *argv)
72 {
73 return pathexec_env_run(*argv, argv);
74 }
75