envmap.c (2841B)
1 #include <string.h> /* memset() */ 2 #include <unistd.h> /* write() */ 3 #include <assert.h> 4 5 #include <skalibs/stralloc.h> 6 #include <skalibs/env.h> 7 #include <skalibs/exec.h> 8 9 #include "envmap.h" 10 #include "verify_common.h" 11 12 extern char **environ; 13 14 void miniroon_env_map_zero(miniroon_env_map *emap) { 15 memset(emap, 0, sizeof(miniroon_env_map)); 16 } 17 18 void miniroon_env_map_add(miniroon_env_map *emap, const bytebuffer name) { 19 assert(miniroon_env_map_find(emap, name) == NULL); 20 assert(emap->env_count < MAX_ENV_ALLOW); // TODO: proper check 21 emap->env[emap->env_count++].name = name; 22 } 23 24 miniroon_env_entry * miniroon_env_map_find(miniroon_env_map *emap, const bytebuffer name) { 25 for(size_t i=0; i < emap->env_count; i++) { 26 if(bbcmp(emap->env[i].name, name) == 0) { 27 return &emap->env[i]; 28 } 29 } 30 return NULL; 31 } 32 33 void miniroon_env_map_init(miniroon_env_map *emap) { 34 miniroon_env_map_zero(emap); 35 char **env = environ; 36 char *var; 37 while(var = *(env++)) { 38 39 write(2, "env >", 5); 40 write(2, var, strlen(var)); 41 write(2, "<\n", 2); 42 43 for(size_t i=0; var[i]; i++) { 44 if(var[i] == '-') { continue; } 45 if(var[i] >= '0' && var[i] <= '9') { continue; } 46 if(var[i] >= 'A' && var[i] <= 'z') { continue; } 47 if(var[i] == '=') { 48 if(var[i+1]) { break; } 49 write(2, "env [allowed]\n", 14); 50 bytebuffer bb = {var, i}; 51 miniroon_env_map_add(emap, bb); 52 } 53 } 54 55 } 56 } 57 58 #define stralloc_catbb(sa, bb) stralloc_catb(sa, bb.data, bb.len) 59 60 void env_add(stralloc *modif, miniroon_env_entry *entry) { 61 assert(entry->state == ENV_SET || entry->state == ENV_REMOVE); 62 assert(entry->name.len); 63 assert(entry->name.data); 64 for(size_t i=0; i<entry->name.len; i++) { 65 if(entry->name.data[i] == '\0') { 66 strerr_dief1x(111, "invalid environment variable name"); 67 } 68 } 69 if(!stralloc_catbb(modif, entry->name)) { goto errenv; } 70 if(entry->state == ENV_SET) { 71 assert(entry->value.len); 72 assert(entry->value.data); 73 for(size_t i=0; i<entry->value.len; i++) { 74 if(entry->value.data[i] == '\0') { 75 strerr_dief1x(111, "invalid environment variable value"); 76 } 77 } 78 if(!stralloc_catb(modif, "=", 1)) { goto errenv; } 79 if(!stralloc_catbb(modif, entry->value)) { goto errenv; } 80 } 81 if(!stralloc_catb(modif, "\0", 1)) { goto errenv; } 82 return; 83 errenv: 84 strerr_dief1x(111, "error preparing environment"); 85 } 86 87 void miniroon_env_map_exec(miniroon_env_map *emap, char const *const *argv) { 88 if(emap->env_count == 0) { 89 xexec(argv); 90 } 91 stralloc modif = STRALLOC_ZERO; 92 for(size_t i=0; i < emap->env_count; i++) { 93 if(emap->env[i].state == ENV_NO_CHANGE) { 94 continue; 95 } 96 env_add(&modif, &emap->env[i]); 97 } 98 if(modif.len) { 99 xmexec_m(argv, modif.s, modif.len); 100 } else { 101 xexec(argv); 102 } 103 } 104 105 /* vim: sts=2 sw=2 et 106 */