/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* b_cd.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: rbousset +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ /* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ /* */ /* ************************************************************************** */ #include #include #include #include #include "b_export_next.h" #include "f_fail.h" #include "s_destroy.h" #include "s_struct.h" #include "u_utils.h" #include "u_vars.h" #include "u_vars_next.h" static void set_path(char **path, char *args[], t_msh *msh) { if ((*path = ft_strdup(*args)) == NULL) { f_alloc_and_destroy_msh(msh); } } static void b_set_oldpwd(t_msh *msh) { char *pwd; char *tmp; char fmt[PATH_MAX]; if ((pwd = u_get_var_value("$PWD", msh)) == NULL) { if ((pwd = ft_strdup(msh->cwd)) == NULL) f_alloc_and_destroy_msh(msh); } if ((tmp = u_get_var_value("$OLDPWD", msh)) == NULL) { ft_sprintf(fmt, "%s=%s", "OLDPWD", pwd); b_export_with_equals(fmt, msh); ft_memdel((void*)pwd); } else { u_subst_var_value("$OLDPWD", pwd, msh); ft_memdel((void*)&pwd); ft_memdel((void*)&tmp); } } static void b_fill_repath(char repath[], char *splited[]) { size_t i; size_t j; i = 0; repath[0] = (splited[0] == NULL) ? '/' : repath[0]; while (splited[i] != NULL) { if (ft_strncmp(splited[i], "..", 3) == 0) { j = ft_strlen(repath); while (repath[j] != '/' && j > 0) j--; repath[j] = '\0'; } else if (ft_strncmp(splited[i], ".", 2) == 0) { } else { j = ft_strlen(repath) + 1; repath[j - 1] = '/'; ft_strlcpy(repath + j, splited[i], ft_strlen(splited[i]) + 1); } i++; } } static void b_upgrade_pwd(const char path[], t_msh *msh) { char *tmp; char **splited; char repath[262144]; char fmt[262144]; b_set_oldpwd(msh); repath[0] = '\0'; if (path[0] != '/') ft_memcpy(repath, msh->cwd, ft_strlen(msh->cwd)); if ((splited = ft_split(path, '/')) == NULL) f_alloc_and_destroy_msh(msh); b_fill_repath(repath, splited); repath[0] = (repath[0] == '\0') ? '/' : repath[0]; ft_delwords(splited); if ((tmp = u_get_var_value("$PWD", msh)) != NULL) u_subst_var_value("$PWD", repath, msh); else { ft_sprintf(fmt, "%s=%s", "PWD", repath); b_export_with_equals(fmt, msh); } ft_memdel((void*)&msh->cwd); if ((msh->cwd = ft_strdup(repath)) == NULL) f_alloc_and_destroy_msh(msh); } uint8_t b_cd(char *args[], t_msh *msh) { const uint64_t argc = u_builtins_get_argc((const char**)args); char *path; if (argc >= 2) { f_fail_too_many_args("cd", msh); return (1); } else if (argc == 0) { if ((path = u_get_var_value("$HOME", msh)) == NULL) { ft_dprintf(STDERR_FILENO, "minishell: cd: %s\n", FT_FAIL_HOME_NOT_SET); return (2); } } else set_path(&path, args, msh); if (chdir(path) != 0) { f_fail_chd("cd", path, msh); ft_memdel((void*)&path); return (1); } b_upgrade_pwd(path, msh); ft_memdel((void*)&path); return (0); }