diff --git a/includes/minishell.h b/includes/minishell.h index 72aa317..8045992 100644 --- a/includes/minishell.h +++ b/includes/minishell.h @@ -6,7 +6,7 @@ /* By: tmaze +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2018/11/18 13:12:34 by tmaze #+# #+# */ -/* Updated: 2019/10/31 14:38:16 by tmaze ### ########.fr */ +/* Updated: 2019/11/10 20:57:46 by tmaze ### ########.fr */ /* */ /* ************************************************************************** */ @@ -38,12 +38,14 @@ int cmd_unsetenv(char **argv, t_env **env); int cmd_cd(char **argv, t_env **env); int cmd_echo(char **argv, t_env **env); -void lstdelelem(t_env **elem); -void lstdel(t_env **env); -t_env *lstnew(char *env); -t_env *lstaddend(t_env **alst, t_env *new); -t_env *lstgetelem(char *key, t_env *env); -char **lsttotab(t_env *env); +void ft_envdelelem(t_env **elem); +void ft_envdel(t_env **env); +t_env *ft_envnew(char *env); +t_env *ft_envaddend(t_env **alst, t_env *new); +t_env *ft_envgetelem(char *key, t_env *env); +char **ft_envtotab(t_env *env); +char *ft_envupdate(char *key, t_env *env, char *val); +void ft_envclean(t_env **env); char **res_ext(char **argv, t_env *env); diff --git a/srcs/cmd_cd.c b/srcs/cmd_cd.c index 6563093..0249e8e 100644 --- a/srcs/cmd_cd.c +++ b/srcs/cmd_cd.c @@ -5,16 +5,155 @@ /* +:+ +:+ +:+ */ /* By: tmaze +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2019/09/20 14:42:42 by tmaze #+# #+# */ -/* Updated: 2019/11/03 00:39:59 by tmaze ### ########.fr */ +/* Created: 2019/01/07 16:44:40 by tmaze #+# #+# */ +/* Updated: 2019/11/10 15:51:51 by tmaze ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -int cmd_cd(char **argv, t_env **env) +void put_error_cd(char *file, char *msg) { - (void)argv; - (void)env; + ft_putstr("cd: "); + ft_putstr(file); + ft_putstr(": "); + ft_putendl(msg); +} + +char *check_path_slash_cd(char *exec) +{ + int i; + struct stat info; + struct stat info2; + + if (exec[0] == '/') + { + if ((i = access(exec, F_OK)) != 0) + put_error_cd(exec, "no such file or directory"); + if (i != 0) + return (NULL); + if ((i = lstat(exec, &info)) != 0) + put_error_cd(exec, "can't determine info"); + if (i != 0) + return (NULL); + if (!S_ISDIR(info.st_mode) || (S_ISLNK(info.st_mode) && ((i = stat(exec, &info2)) != 0 || !S_ISDIR(info2.st_mode)))) + { + put_error_cd(exec, "not a directory"); + return (NULL); + } + if ((i = access(exec, X_OK)) != 0) + put_error_cd(exec, "permission denied"); + if (i != 0) + return (NULL); + return (exec); + } + return (NULL); +} + +int cmd_cd_update_env(char *path, t_env **env, char opt) +{ + t_env *pwd; + char *oldpwd; + char *c_path; + char p_path[4096]; + + ft_bzero(p_path, 4096); + if (!(pwd = ft_envgetelem("PWD", *env))) + { + put_error_cd(path, "env var PWD undefined"); + return (1); + } + if (getcwd(p_path, 4096) == NULL || (oldpwd = ft_strdup(pwd->val)) == NULL + || ft_realpath(path, &c_path) == NULL) + { + put_error_cd(path, "error"); + return (1); + } + if (ft_envupdate("PWD", *env, ((opt == 'P') ? p_path : c_path)) == NULL + || ft_envupdate("OLDPWD", *env, oldpwd) == NULL) + { + put_error_cd(path, "error"); + ft_strdel(&oldpwd); + ft_strdel(&c_path); + return (1); + } + ft_strdel(&oldpwd); + ft_strdel(&c_path); return (0); } + +int cmd_cd_core(char *path, t_env **env, char opt) +{ + t_env *pwd; + + if (check_path_slash_cd(path) == NULL) + { + put_error_cd(path, "invalid path"); + return (1); + } + if (chdir(path) == -1 + || (pwd = ft_envgetelem("PWD", *env)) == NULL) + { + put_error_cd(path, "error"); + return (1); + } + return (cmd_cd_update_env(path, env, opt)); +} + +char cd_getparams(char **argv, size_t *i) +{ + char ret[2]; + size_t j; + + ret[1] = '\0'; + ret[0] = 'L'; + *i = 0; + while (argv[++(*i)] && argv[*i][0] == '-' && ft_strlen(argv[*i]) > 1) + { + j = 1; + while (argv[*i][j] && (argv[*i][j] == 'L' || argv[*i][j] == 'P')) + ret[0] = argv[*i][j++]; + if (argv[*i][j] && argv[*i][j] != 'L' && argv[*i][j] != 'P') + { + ret[0] = argv[*i][j]; + put_error_cd(ret, "invalid option"); + put_error_cd("usage", "cd [-L|-P] [dir]"); + ret[0] = '\0'; + break ; + } + } + return (ret[0]); +} + +int cmd_cd(char **argv, t_env **env) +{ + t_env *elem; + size_t i; + char *path; + char opt; + int ret; + + i = 0; + if ((opt = cd_getparams(argv, &i)) == '\0') + return (1); + if (!argv[i] && (elem = ft_envgetelem("HOME", *env)) != NULL && elem->val != NULL) + return (cmd_cd_core(elem->val, env, opt)); + else if (argv[i] && argv[i][0] == '/') + return (cmd_cd_core(argv[i], env, opt)); + else if (argv[i] && argv[i][0] == '-' && (elem = ft_envgetelem("OLDPWD", *env)) != NULL) + return (cmd_cd_core(elem->val, env, opt)); + else if (argv[i] && argv[i][0] != '/' && (elem = ft_envgetelem("PWD", *env)) != NULL && elem->val != NULL) + { + if ((path = ft_strnew(ft_strlen(elem->val) + ft_strlen(argv[i]) + 1)) == NULL) + put_error_cd(argv[i], "memory error"); + if (path == NULL) + return (1); + ft_strcpy(path, elem->val); + path[ft_strlen(path)] = '/'; + ft_strcat(path, argv[i]); + ret = cmd_cd_core(path, env, opt); + ft_strdel(&path); + return (ret); + } + return (1); +} diff --git a/srcs/cmd_env.c b/srcs/cmd_env.c index 83dcc4c..01eaa54 100644 --- a/srcs/cmd_env.c +++ b/srcs/cmd_env.c @@ -6,7 +6,7 @@ /* By: tmaze +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/09/20 14:33:48 by tmaze #+# #+# */ -/* Updated: 2019/10/17 10:07:21 by tmaze ### ########.fr */ +/* Updated: 2019/11/08 21:55:51 by tmaze ### ########.fr */ /* */ /* ************************************************************************** */ @@ -35,7 +35,7 @@ t_env *envcpy(t_env *env) if (env != NULL && (cpy = (t_env*)ft_memalloc(sizeof(t_env))) != NULL) if ((cpy->key = ft_strdup(env->key)) == NULL || (cpy->val = ft_strdup(env->val)) == NULL) - lstdelelem(&cpy); + ft_envdelelem(&cpy); return (cpy); } @@ -55,11 +55,11 @@ int cmd_env(char **argv, t_env **env) { if ((new = envcpy(it)) == NULL) { - lstdel(&env_cp); + ft_envdel(&env_cp); ft_putstr_fd("minishell: env: Env copy error\n", 2); return (2); } - lstaddend(&env_cp, new); + ft_envaddend(&env_cp, new); it = it->next; } } @@ -69,6 +69,6 @@ int cmd_env(char **argv, t_env **env) exec_cmd(argv + i, &env_cp); else put_env(env_cp); - lstdel(&env_cp); + ft_envdel(&env_cp); return (0); } diff --git a/srcs/cmd_setenv.c b/srcs/cmd_setenv.c index 55498d1..65295d0 100644 --- a/srcs/cmd_setenv.c +++ b/srcs/cmd_setenv.c @@ -6,7 +6,7 @@ /* By: tmaze +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/09/20 14:41:08 by tmaze #+# #+# */ -/* Updated: 2019/11/02 23:10:32 by tmaze ### ########.fr */ +/* Updated: 2019/11/10 21:38:30 by tmaze ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,20 +15,25 @@ int cmd_setenv(char **argv, t_env **env) { t_env *new; + t_env *tmp; - if (argv[1] && (new = lstnew(argv[1])) != NULL) + if (argv[1] && (new = ft_envnew(argv[1])) != NULL) { - lstaddend(env, new); + if (argv[1] && (tmp = ft_envgetelem(new->key, *env)) != NULL) + { + ft_strdel(&(tmp->val)); + tmp->val = new->val; + ft_strdel(&(new->key)); + ft_memdel((void**)&new); + } + else + ft_envaddend(env, new); + ft_envclean(env); return (0); } - else if (argv[1]) - { + else if (argv[1] && argv[1][0] != '=' && !ft_strchr(argv[1], '=')) ft_printf("minishell: setenv: memory error\n"); - return (2); - } else - { ft_printf("usage: setenv [KEY]=[value]\n"); - return (1); - } + return (1); } diff --git a/srcs/cmd_unsetenv.c b/srcs/cmd_unsetenv.c index 8e02988..ad757f7 100644 --- a/srcs/cmd_unsetenv.c +++ b/srcs/cmd_unsetenv.c @@ -6,7 +6,7 @@ /* By: tmaze +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/09/20 14:42:01 by tmaze #+# #+# */ -/* Updated: 2019/10/17 10:58:23 by tmaze ### ########.fr */ +/* Updated: 2019/11/10 15:52:09 by tmaze ### ########.fr */ /* */ /* ************************************************************************** */ @@ -29,7 +29,7 @@ int cmd_unsetenv(char **argv, t_env **env) { tmp = *it; *it = tmp->next; - lstdelelem(&tmp); + ft_envdelelem(&tmp); return (0); } it = &((*it)->next); diff --git a/srcs/main.c b/srcs/main.c index ad4e88a..e9ad6d7 100644 --- a/srcs/main.c +++ b/srcs/main.c @@ -6,7 +6,7 @@ /* By: tmaze +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/09/19 17:08:46 by tmaze #+# #+# */ -/* Updated: 2019/10/31 14:36:15 by tmaze ### ########.fr */ +/* Updated: 2019/11/10 21:24:36 by tmaze ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,12 +22,12 @@ t_env *env2lst(char **env) ret = NULL; while (env[i]) { - if ((new = lstnew(env[i])) != NULL) - lstaddend(&ret, new); + if ((new = ft_envnew(env[i])) != NULL) + ft_envaddend(&ret, new); else { - lstdelelem(&new); - lstdel(&ret); + ft_envdelelem(&new); + ft_envdel(&ret); return (NULL); } i++; @@ -57,24 +57,12 @@ int main(void) && (argv = ft_strsplit(cmd, ' ')) != NULL) { ft_strdel(&cmd); - i = 0; - ft_printf("before:\n"); - while (argv[i]) - { - ft_printf("%s\n", argv[i++]); - } if ((res_ext(argv, env)) != NULL) { - i = 0; - ft_printf("after:\n"); - while (argv[i]) - { - ft_printf("%s\n", argv[i++]); - } if (ft_strequ(argv[0], "exit")) { ft_del_words_tables(&argv); - lstdel(&env); + ft_envdel(&env); return (0); } i = 0; @@ -88,9 +76,7 @@ int main(void) i++; } if (i == S_BIN) - { exec_cmd(argv, &env); - } } } ft_strdel(&cmd); @@ -98,6 +84,6 @@ int main(void) } ft_del_words_tables(&argv); ft_strdel(&cmd); - lstdel(&env); + ft_envdel(&env); return (0); } diff --git a/srcs/ms_env.c b/srcs/ms_env.c index 09c8e27..4b31def 100644 --- a/srcs/ms_env.c +++ b/srcs/ms_env.c @@ -6,13 +6,13 @@ /* By: tmaze +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/09/20 11:43:53 by tmaze #+# #+# */ -/* Updated: 2019/10/18 14:20:41 by tmaze ### ########.fr */ +/* Updated: 2019/11/10 20:49:35 by tmaze ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -void lstdelelem(t_env **elem) +void ft_envdelelem(t_env **elem) { if (elem) { @@ -22,7 +22,7 @@ void lstdelelem(t_env **elem) } } -void lstdel(t_env **env) +void ft_envdel(t_env **env) { t_env *tmp; @@ -30,11 +30,11 @@ void lstdel(t_env **env) { tmp = *env; *env = (*env)->next; - lstdelelem(&tmp); + ft_envdelelem(&tmp); } } -t_env *lstnew(char *env) +t_env *ft_envnew(char *env) { t_env *ret; int i; @@ -46,11 +46,11 @@ t_env *lstnew(char *env) if (env[i] == '=' && (ret = (t_env*)ft_memalloc(sizeof(t_env))) != NULL) if ((ret->val = ft_strsub(env, i + 1, ft_strlen(env) - i - 1)) == NULL || (ret->key = ft_strsub(env, 0, i)) == NULL) - lstdelelem(&ret); + ft_envdelelem(&ret); return (ret); } -t_env *lstaddend(t_env **alst, t_env *new) +t_env *ft_envaddend(t_env **alst, t_env *new) { t_env *tmp; @@ -68,7 +68,7 @@ t_env *lstaddend(t_env **alst, t_env *new) return (*alst); } -t_env *lstgetelem(char *key, t_env *env) +t_env *ft_envgetelem(char *key, t_env *env) { t_env *it; @@ -78,41 +78,79 @@ t_env *lstgetelem(char *key, t_env *env) return (it); } -char **lsttotab(t_env *env) +char *ft_envtochar(t_env *env) +{ + int size; + char *ret; + + size = ft_strlen(env->key) + ft_strlen(env->val) + 1; + if ((ret = ft_strnew(size)) != NULL) + { + ft_strlcpy(ret, env->key, size); + ft_strlcat(ret, "=", size); + ft_strlcat(ret, env->val, size); + } + return (ret); +} + +char **ft_envtotab(t_env *env) { t_env *it; char *new; char **ret; - size_t size; int i; i = 0; ret = NULL; it = env; - while (it) - { - i++; + while (it && (++i)) it = it->next; - } if ((ret = (char**)ft_memalloc(sizeof(char*) * (i + 1))) == NULL) return (NULL); - while (i >= 0) - ret[i--] = NULL; it = env; i = 0; while (it) { - size = ft_strlen(it->key) + ft_strlen(it->val) + 1; - if ((new = ft_strnew(size)) == NULL) - { + if ((new = ft_envtochar(it)) == NULL) ft_del_words_tables(&ret); + if (new == NULL) break ; - } - ft_strlcpy(new, it->key, size); - ft_strlcat(new, "=", size); - ft_strlcat(new, it->val, size); ret[i++] = new; it = it->next; } return (ret); } + +char *ft_envupdate(char *key, t_env *env, char *val) +{ + t_env *elem; + char *new; + + new = NULL; + if ((elem = ft_envgetelem(key, env)) != NULL) + if ((new = ft_strdup(val)) != NULL) + { + ft_strdel(&elem->val); + elem->val = new; + } + return (new); +} + +void ft_envclean(t_env **env) +{ + t_env **it; + t_env *tmp; + + it = env; + while (*it) + { + if (ft_strequ((*it)->val, "")) + { + tmp = *it; + *it = tmp->next; + ft_envdelelem(&tmp); + } + else + it = &((*it)->next); + } +} diff --git a/srcs/ms_exec.c b/srcs/ms_exec.c index 3d1f068..a3cede5 100644 --- a/srcs/ms_exec.c +++ b/srcs/ms_exec.c @@ -6,7 +6,7 @@ /* By: tmaze +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/09/26 16:25:00 by tmaze #+# #+# */ -/* Updated: 2019/10/18 14:22:23 by tmaze ### ########.fr */ +/* Updated: 2019/11/10 15:52:54 by tmaze ### ########.fr */ /* */ /* ************************************************************************** */ @@ -62,7 +62,7 @@ char *check_path_dot(char *exec, t_env *env) char *tmp; char *ret; - if ((path = lstgetelem("PWD", env)) == NULL + if ((path = ft_envgetelem("PWD", env)) == NULL || path->val == NULL || (tmp = ft_strjoin(path->val, "/")) == NULL) { put_error(exec, "memory error"); @@ -101,7 +101,7 @@ char *check_path(char *exec, t_env *env) return (check_path_slash(exec)); if (exec[0] == '.') return (check_path_dot(exec, env)); - if ((path = lstgetelem("PATH", env)) == NULL + if ((path = ft_envgetelem("PATH", env)) == NULL || path->val == NULL || (path_elems = ft_strsplit(path->val, ':')) == NULL) { @@ -147,7 +147,7 @@ int exec_cmd(char **argv, t_env **env) char **env_tab; char *path; - if ((env_tab = lsttotab(*env)) == NULL) + if ((env_tab = ft_envtotab(*env)) == NULL) return (-1); if ((path = check_path(argv[0], *env)) == NULL) ft_del_words_tables(&env_tab); @@ -161,7 +161,7 @@ int exec_cmd(char **argv, t_env **env) if (ft_strcmp(path, argv[0]) != 0) ft_strdel(&path); ft_del_words_tables(&env_tab); - lstdel(env); + ft_envdel(env); exit(-1); } else if (ret == -1) diff --git a/srcs/ms_ext.c b/srcs/ms_ext.c index 72ae95b..883a94d 100644 --- a/srcs/ms_ext.c +++ b/srcs/ms_ext.c @@ -6,7 +6,7 @@ /* By: tmaze +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/10/25 18:21:47 by tmaze #+# #+# */ -/* Updated: 2019/11/02 00:35:13 by tmaze ### ########.fr */ +/* Updated: 2019/11/10 15:55:39 by tmaze ### ########.fr */ /* */ /* ************************************************************************** */ @@ -49,17 +49,17 @@ char **res_ext(char **argv, t_env *env) { i = 0; while (argv[k] && argv[k][i]) { - if (i == 0 && argv[k][i] == '~' && lstgetelem("HOME", env)) { + if (i == 0 && argv[k][i] == '~' && ft_envgetelem("HOME", env)) { res_len = - ft_strlen(argv[k]) - 1 + ft_strlen(lstgetelem("HOME", env)->val); + ft_strlen(argv[k]) - 1 + ft_strlen(ft_envgetelem("HOME", env)->val); if ((ret = ft_strnew(res_len)) != NULL) { - ft_strcpy(ret, lstgetelem("HOME", env)->val); + ft_strcpy(ret, ft_envgetelem("HOME", env)->val); if (ret[ft_strlen(ret) - 1] != '/') ft_strcat(ret, "/"); ft_strcat(ret, argv[k] + 1); ft_strdel(&(argv[k])); argv[k] = ret; - i = ft_strlen(lstgetelem("HOME", env)->val); + i = ft_strlen(ft_envgetelem("HOME", env)->val); } else { ft_printf("minishell: memory error\n"); return (NULL);