diff --git a/builtins.c b/builtins.c index 16265e7..882cfa0 100644 --- a/builtins.c +++ b/builtins.c @@ -72,6 +72,8 @@ void (*check_built_ins(char *str))(char *str) builtin_t buildin[] = { {"exit", exit_b}, {"env", env_b}, + {"setenv", setenv_b}, + {"unsetenv", unsetenv_b}, {"cd", cd_b}, {NULL, NULL} }; diff --git a/hbtlib.c b/hbtlib.c index f258edf..d332cb3 100644 --- a/hbtlib.c +++ b/hbtlib.c @@ -40,6 +40,39 @@ char *_strdup(char *src) return (dest); } +/** + * _realloc - reallocate a memory block + * @ptr: pointer to old block + * @old_size: old memory size + * @new_size: new memory size + * Return: pointer to new block, NULL when failed + */ +void *_realloc(void *ptr, unsigned int old_size, unsigned int new_size) +{ + char *p, *orig = (char *)ptr; + unsigned int i; + + if (old_size == new_size) + return (ptr); + if (new_size == 0 && ptr != NULL) + return (NULL); + if (ptr == NULL) + { + p = malloc(new_size); + if (p == NULL) + return (NULL); + } + else + { + p = malloc(new_size); + if (p == NULL) + return (NULL); + for (i = 0; orig[i] != '\0' && i < new_size ; i++) + p[i] = orig[i]; + } + return (p); +} + /** * print_str - Prints a string character by character. * @str: String to be printed. If the string is NULL it will print (null) diff --git a/olaf.h b/olaf.h index 2836480..e35bc4b 100644 --- a/olaf.h +++ b/olaf.h @@ -48,10 +48,17 @@ void (*check_built_ins(char *str))(char *str); void exit_b(char *str); void env_b(char *str); void cd_b(char *directory); +void unsetenv_b(char *str); +void setenv_b(char *str); +int check_env(char *env); +void modify_env(char *env, char *value); +void add_env(char *env, char *value); +void remove_env(char *env); /*Holberton library functions*/ int _strcmp(char *s1, char *s2); char *_strdup(char *src); +void *_realloc(void *ptr, unsigned int old_size, unsigned int new_size); void print_str(char *str, int new_line); #endif diff --git a/setenv.c b/setenv.c new file mode 100644 index 0000000..5b5fc8f --- /dev/null +++ b/setenv.c @@ -0,0 +1,104 @@ +#include "olaf.h" + +/** + * setenv_b - Initialize a new environ variable, or modify an existing one + * @line: A string representing the input from the user. + */ +void setenv_b(char *line) +{ + int check, token_count = 0; + char **path_tokens; + const char *delim = "\n\t "; + char *env, *value; + + path_tokens = token_interface(line, delim, token_count); + env = path_tokens[1], value = path_tokens[2]; + + check = check_env(env); + if (check == 1) + modify_env(env, value); + if (check == 0) + add_env(env, value); + + double_free(path_tokens); +} + +/** + * check_env - Check if an environ variable exists + * @env: Variable to be checked + * Return: 1 - found environ variable, 0 - not found + */ +int check_env(char *env) +{ + int i, j; + + i = 0; + while (environ[i]) + { + j = 0; + while (environ[i][j] == env[j]) + { + j++; + if (environ[i][j] == '=' && !env[j]) + return (1); + } + i++; + } + return (0); +} + +/** + * modify_env - Modify environ variable + * @env: environ variable + * @value: environ variable value + */ +void modify_env(char *env, char *value) +{ + int index, i = 0, j = 0; + + index = find_path(env); + + for (i = 0; env[i]; i++) + environ[index][i] = env[i]; + + environ[index][i] = '=', i++; + + for (j = 0; value[j]; i++, j++) + environ[index][i] = value[j]; + environ[index][i] = '\0'; +} + +/** + * add_env - Add new environ variable + * @env: environ variable + * @value: environ variable value + */ +void add_env(char *env, char *value) +{ + int i = 0, j = 0, t = 0, count = 0, size; + char **new; + + for (i = 0; environ[i]; i++) + count++; + + new = _realloc(environ, sizeof(char *) * count, sizeof(char *) * (count + 2)); + if (new == NULL) + return; + for (i = 0; i < count; i++) + new[i] = _strdup(environ[i]); + size = strlen(env) + strlen(value) + 2; + new[i] = malloc(sizeof(char) * size); + if (new[i] == NULL) + return; + + for (j = 0; env[j]; j++) + new[i][j] = env[j]; + + new[i][j] = '=', j++; + + for (t = 0; value[t]; j++, t++) + new[i][j] = value[t]; + new[i][j] = '\0'; + new[i + 1] = NULL; + environ = new; +} diff --git a/unsetenv.c b/unsetenv.c new file mode 100644 index 0000000..1411200 --- /dev/null +++ b/unsetenv.c @@ -0,0 +1,53 @@ +#include "olaf.h" + +/** + * unsetenv_b - Remove an environ variable + * @line: A string representing the input from the user. + */ +void unsetenv_b(char *line) +{ + int check, token_count = 0; + char **path_tokens; + const char *delim = "\n\t "; + char *env; + + path_tokens = token_interface(line, delim, token_count); + env = path_tokens[1]; + + check = check_env(env); + if (check == 0) + { + printf("unsetenv: %s: variable not found\n", env); + return; + } + if (check == 1) + remove_env(env); + + double_free(path_tokens); +} + +/** + * remove_env - Remove environ variable + * @env: environ variable + */ +void remove_env(char *env) +{ + int i = 0, j = 0, size = 0, index; + char **str; + + for (i = 0; environ[i]; i++) + size++; + str = malloc(sizeof(char *) * size); + if (str == NULL) + return; + + index = find_path(env); + for (i = 0; environ[i]; i++, j++) + { + if (i == index) + i++; + str[j] = _strdup(environ[i]); + } + str[j] = NULL; + environ = str; +}