1#include <stdbool.h>
2#include <stdlib.h>
3#include <string.h>
4
5static void free_var(const char* string)
6{
7 // TODO: Implement me!
8}
9
10char* getenv(const char* name)
11{
12 size_t len = strlen(name);
13 for (int i = 0; environ[i]; i++) {
14 const char* envv = environ[i];
15 char* eqpos = strchr(envv, '=');
16 if (!eqpos) {
17 continue;
18 }
19 size_t curlen = (size_t)(eqpos - envv);
20 if (curlen == len && strncmp(name, envv, len) == 0) {
21 return (char*)&envv[len + 1];
22 }
23 }
24
25 return NULL;
26}
27
28int setenv(const char* name, const char* value, int overwrite)
29{
30 if (!overwrite && getenv(name)) {
31 return 0;
32 }
33
34 int name_len = strlen(name);
35 int value_len = strlen(value);
36 int len = name_len + 1 + value_len;
37 char* string = (char*)malloc(len + 1);
38 strncpy(string, name, name_len);
39 string[name_len] = '=';
40 strncpy(&string[name_len + 1], value, value_len);
41 string[len] = '\0';
42 return putenv(string);
43}
44
45int putenv(char* string)
46{
47 char* pos = strchr(string, '=');
48 if (!pos) {
49 return unsetenv(string);
50 }
51
52 size_t len = (size_t)(pos - string);
53 int env_i = 0;
54 for (; environ[env_i]; env_i++) {
55 const char* envv = environ[env_i];
56 char* eqpos = strchr(envv, '=');
57 if (!eqpos) {
58 continue;
59 }
60 size_t curlen = (size_t)(eqpos - envv);
61 if (len != curlen) {
62 continue;
63 }
64
65 if (strncmp(string, envv, len) == 0) {
66 free_var(envv);
67 environ[env_i] = string;
68 return 0;
69 }
70 }
71
72 char** new_environ = (char**)malloc(sizeof(char*) * (env_i + 2));
73 for (int i = 0; i < env_i; i++) {
74 new_environ[i] = environ[i];
75 }
76 new_environ[env_i] = string;
77 new_environ[env_i + 1] = NULL;
78
79 extern int __environ_malloced;
80 if (__environ_malloced) {
81 free(environ);
82 }
83 environ = new_environ;
84 __environ_malloced = 1;
85 return 0;
86}
87
88int unsetenv(const char* name)
89{
90 size_t len = strlen(name);
91 int env_i = 0;
92 int remove_pos = 0;
93 const char* remove_env = NULL;
94 for (; environ[env_i]; env_i++) {
95 const char* envv = environ[env_i];
96 char* eqpos = strchr(envv, '=');
97 if (!eqpos) {
98 continue;
99 }
100 size_t curlen = (size_t)(eqpos - envv);
101 if (len != curlen) {
102 continue;
103 }
104
105 if (strncmp(name, envv, len) == 0) {
106 remove_pos = env_i;
107 remove_env = envv;
108 }
109 }
110
111 size_t move_len = ((env_i - 1) - remove_pos) * sizeof(char*);
112 memmove(&environ[remove_pos], &environ[remove_pos + 1], move_len);
113 free_var(remove_env);
114 return 0;
115}