/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* 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 #ifdef __linux__ # include #else # include #endif #include "b_export_next.h" #include "d_define.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 b_set_oldpwd(t_msh *msh) { char pwd[PATH_MAX]; char tmp[PATH_MAX]; u_get_var_value(pwd, "$PWD", PATH_MAX, msh); if (pwd[0] == C_NUL) { ft_strlcpy(pwd, msh->cwd, PATH_MAX); } u_get_var_value(tmp, "$OLDPWD", PATH_MAX, msh); if (tmp[0] == C_NUL) { ft_sprintf(tmp, "%s=%s", "OLDPWD", pwd); b_export_with_equals(tmp, msh); } else { u_subst_var_value("$OLDPWD", pwd, msh); } } static void b_fill_repath(char rpath[], char *splited[]) { size_t i; size_t j; i = 0; rpath[0] = (splited[0] == NULL) ? '/' : rpath[0]; while (splited[i] != NULL) { if (ft_strncmp(splited[i], "..", 3) == 0) { j = (rpath[0] == '\0') ? (0) : (ft_strlen(rpath)); while (rpath[j] != '/' && j > 0) j--; rpath[j] = '\0'; } else if (ft_strncmp(splited[i], ".", 2) == 0) { } else { j = (ft_strncmp(rpath, "/", 2) == 0) ? (1) : (ft_strlen(rpath) + 1); rpath[j - 1] = '/'; ft_strlcpy(rpath + j, splited[i], ft_strlen(splited[i]) + 1); } i++; } } static void b_upgrade_pwd(const char path[], t_msh *msh) { char **splited; char repath[262144]; char fmt[262144]; b_set_oldpwd(msh); splited = NULL; repath[0] = '\0'; if (path[0] != '/') ft_memcpy(repath, msh->cwd, (ft_strlen(msh->cwd) + 1) * sizeof(char)); if (path[0] == '/' && path[1] == '\0') ft_memcpy(repath, "/", 2 * sizeof(char)); else if ((splited = ft_split(path, '/')) == NULL) f_alloc_and_destroy_msh(msh); if (splited != NULL) { b_fill_repath(repath, splited); ft_delwords(splited); } repath[0] = (repath[0] == '\0') ? '/' : repath[0]; 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); } unsigned char b_cd(char *args[], t_msh *msh) { const unsigned long argc = u_builtins_get_argc((const char**)args); char path[PATH_MAX]; if (argc >= 2) f_fail_too_many_args("cd", msh); if (argc >= 2) return (1); else if (argc == 0) { if (u_get_var_value(path, "$HOME", PATH_MAX, msh) == 1) { ft_dprintf(STDERR_FILENO, "minishell: cd: %s\n", F_HOME_NOT_SET); return (2); } } else ft_strlcpy(path, *args, PATH_MAX); if (chdir(path) != 0) { f_fail_chd("cd", path, msh); return (1); } b_upgrade_pwd(path, msh); return (0); }