/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* cmd_cd.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: tmaze +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/01/07 16:44:40 by tmaze #+# #+# */ /* Updated: 2019/01/26 16:58:39 by tmaze ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" void put_error_cd(char *file, char *msg) { ft_putstr("cd: "); ft_putstr(file); ft_putstr(": "); ft_putendl(msg); } char *check_path_slash_cd(char *exec) { int i; struct stat info; if (ft_isin(exec, '/') != -1 && ft_isin(exec, '.') == -1) { if ((i = access(exec, F_OK)) != 0) put_error_cd(exec, "no such file or directory"); if (i != 0) return (NULL); if ((i = stat(exec, &info)) != 0) put_error_cd(exec, "can't determine info"); if (i != 0) return (NULL); if (!S_ISDIR(info.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); } char *ft_tabtopath(char **tab_path) { size_t total_size; size_t i; char *ret; i = 0; total_size = 0; while (tab_path[i]) total_size += ft_strlen(tab_path[i++]); if ((ret = ft_strnew(total_size + i)) == NULL) return (NULL); i = 0; while (tab_path[i]) { ft_strcat(ret, "/"); ft_strcat(ret, tab_path[i++]); } return (ret); } char *ft_realpath(char *r_path, char **a_path) { char **tab_path; size_t i; size_t j; int strcmp; i = 0; *a_path = NULL; if ((tab_path = ft_strsplit(r_path, '/')) == NULL) return (*a_path); while (tab_path[i]) { if (ft_strcmp(tab_path[i], ".") == 0 || (strcmp = ft_strcmp(tab_path[i], "..")) == 0 || (strcmp == 0 && i == 0)) { j = i; if (strcmp == 0 && i != 0) i = i - 1; ft_strdel(&(tab_path[i])); if (strcmp == 0 && i != 0) ft_strdel(&(tab_path[j])); while (tab_path[++j]) tab_path[j - ((strcmp == 0 && i != 0) ? 2 : 1)] = tab_path[j]; if (strcmp == 0 && i != 0) tab_path[j - 2] = NULL; tab_path[j - 1] = NULL; } else i++; } *a_path = ft_tabtopath(tab_path); ft_del_words_tables(&tab_path); return (*a_path); } int cmd_cd_core(char *path, t_list **env) { t_envelem *pwd; char *oldpwd; if (check_path_slash_cd(path) == NULL) { put_error_cd(path, "invalid path"); return (1); } if (chdir(path) == -1 || (pwd = env_getelemfromkey("PWD", *env)) == NULL) { put_error_cd(path, "error"); return (1); } if ((oldpwd = ft_strdup(pwd->val)) == NULL) { put_error_cd(path, "error"); return (1); } if (env_addupdate("PWD", path, env) == NULL || env_addupdate("OLDPWD", oldpwd, env) == NULL) { put_error_cd(path, "error"); ft_strdel(&oldpwd); return (1); } ft_strdel(&oldpwd); return (0); } char cd_getparams(char **argv, size_t *i) { char ret; size_t j; ret = 'L'; while (argv[++*i] && argv[*i][0] == '-' && ft_strlen(argv[*i]) > 1) { j = 0; while (argv[*i][j] && (argv[*i][j] == 'L' || argv[*i][j] == 'P')) ret = argv[*i][j++]; if (argv[*i][j] && argv[*i][j] != 'L' && argv[*i][j] != 'P') { ret = argv[*i][j]; put_error_cd(&ret, "invalid option"); put_error_cd("usage", "cd [-L|-P] [dir]"); ret = '\0'; break; } } return (ret); } int ft_isfstcmp(char *path, char *cmp) { size_t i; i == 0; while (path[i] == '/') i++; return (ft_strncmp(&path[i], cmp, ft_strlen(cmp))); } int cmd_cd2(char **argv, t_list **env) { t_envelem *elem; char *path; char *tmp; char opt; size_t i; i = 0; if ((opt = cf_getparams(argv, &i)) == '\0') return (1); if (!argv[i] && (elem = env_getelemfromkey("HOME", *env)) != NULL && elem->val != NULL) tmp = elem->val; else if (argv[i] && argv[i][0] != ft_isfstcmp(argv[i]) == 0 && (elem = env_getelemfromkey("PWD", *env)) != NULL && elem->val != NULL) { if ((tmp = ft_strnew(ft_strlen(argv[i]) + ft_strelen(elem->val) + 1)) == NULL) put_error_cd(argv[i], "memory error"); if (tmp == NULL) return (1); ft_strcat(tmp, elem->val); ft_strcat(tmp, "/"); ft_strcat(tmp, argv[i]); } } int cmd_cd(char **argv, t_list **env) { t_envelem *elem; size_t i; char *path; char *tmp; char opt; int ret; i = 0; if ((opt = cd_getparams(argv, &i)) == '\0') return (1); if (!argv[i] && (elem = env_getelemfromkey("HOME", *env)) != NULL && elem->val != NULL) return (cmd_cd_core(elem->val, env)); else if (argv[i] && argv[1][0] == '/') return (cmd_cd_core(argv[1], env)); else if (argv[i] && argv[i][0] == '-' && (elem = env_getelemfromkey("OLDPWD", *env)) != NULL) return (cmd_cd_core(elem->val, env)); else if (argv[i] && argv[i][0] == '.' && (elem = env_getelemfromkey("PWD", *env)) != NULL && elem->val != NULL) { if ((tmp = ft_strnew(ft_strlen(elem->val) + ft_strlen(argv[i]) + 1)) == NULL) put_error_cd(argv[1], "memory error"); if (tmp == NULL) return (1); ft_strcpy(tmp, elem->val); tmp[ft_strlen(tmp)] = '/'; ft_strcat(tmp, argv[1]); if (ft_realpath(tmp, &path) == NULL) put_error_cd(argv[1], "memory error"); ret = cmd_cd_core(path, env); ft_strdel(&tmp); ft_strdel(&path); return (ret); } else if (argv[1] && (elem = env_getelemfromkey("PWD", *env)) != NULL && elem->val != NULL) { if ((path = ft_strnew(ft_strlen(elem->val) + ft_strlen(argv[1]) + 1)) == NULL) put_error_cd(argv[1], "memory error"); if (path == NULL) return (1); ft_strcpy(path, elem->val); path[ft_strlen(path)] = '/'; ft_strcat(path, argv[1]); ft_putendl(path); ft_putendl("plop"); ret = cmd_cd_core(path, env); ft_strdel(&tmp); ft_strdel(&path); return (ret); } return (1); }