/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* p_redirs.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 #ifdef __linux__ # include #else # include #endif #include "d_define.h" #include "p_redirs.h" #include "p_redirs_heredoc.h" #include "s_lredir.h" #include "s_struct.h" #include "s_lredir.h" #include "u_utils.h" #include "u_parse.h" #include "u_vars.h" static unsigned char p_append_redir(const char path[], int fd_rdr[], t_com *com, t_msh *msh) { struct s_lredir *new; int fd; char redir; fd = fd_rdr[FD]; redir = fd_rdr[RDR]; new = s_lredir_new(path, fd, redir); if (new == NULL) { return (1); } new->heredoc = NULL; if (redir == -2 || redir == -3) { new->heredoc = p_get_heredoc(path, redir, msh); } s_lredir_add_back(&com->rdr, new); return (0); } static size_t p_get_path(char path[], struct s_rdr_tmp tmp, t_msh *msh) { char h[PATH_MAX]; size_t pos[2]; size_t hlen; size_t len; hlen = 0; tmp.ptr += (tmp.redir == 3) ? (2) : (ft_abs(tmp.redir)); while (*tmp.ptr != C_NUL && ft_iswhitespace(*tmp.ptr) == TRUE) tmp.ptr++; if (*tmp.ptr == C_TILDE && u_get_var_value(h, "$HOME", PATH_MAX, msh) == 0) { ft_strlcpy(path, h, PATH_MAX); hlen = ft_strlen(h); tmp.ptr++; } pos[0] = (tmp.ptr - tmp.word); while (*tmp.ptr != C_NUL && ft_iswhitespace(*tmp.ptr) == FALSE && u_is_not_escaped(tmp.word, tmp.ptr) == TRUE) tmp.ptr++; pos[1] = (tmp.ptr - tmp.word); len = (pos[1] - pos[0]); len = ((hlen + len + 1) > PATH_MAX) ? (PATH_MAX - 1) : (len); ft_strlcpy(path + hlen, tmp.word + pos[0], len + 1); return (pos[1]); } static int p_get_fd(const char word[], char *ptr) { char digit[255]; char *tmp; if (*ptr == '<' || (ptr - word) == 0) return (-1); tmp = ptr; tmp -= 1; if (ft_isdigit(*tmp) == FALSE) return (1); while ((tmp - word) > 0 && ft_isdigit(*tmp) == TRUE) tmp--; if ((tmp - word) > 0 && ft_iswhitespace(*tmp) == FALSE) return (0); if (ft_atoi(tmp) == 1 || ft_atoi(tmp) == 0) return (-2); else { tmp += ((tmp - word) > 0) ? (1) : (0); ft_strlcpy(digit, word + (tmp - word), (ptr - tmp) + 1); } return (ft_atoi(digit)); } static unsigned char p_get_redir(char word[], char *ptr, t_com *com, t_msh *msh) { struct s_rdr_tmp tmp; char path[PATH_MAX]; size_t pos[2]; int fd_rdr[2]; pos[0] = 0; if ((fd_rdr[FD] = p_get_fd(word, ptr)) == -1) fd_rdr[FD] = STDOUT_FILENO; fd_rdr[RDR] = (*ptr == '>') ? (1) : (-1); fd_rdr[RDR] = (fd_rdr[RDR] == 1 && *(ptr + 1) == '>') ? (2) : (fd_rdr[1]); fd_rdr[RDR] = (fd_rdr[RDR] == 1 && *(ptr + 1) == '&') ? (3) : (fd_rdr[1]); fd_rdr[RDR] = (fd_rdr[RDR] == -1 && *(ptr + 1) == '<') ? (-2) : (fd_rdr[1]); fd_rdr[RDR] = (fd_rdr[RDR] == -2 && *(ptr + 2) == '-') ? (-3) : (fd_rdr[1]); pos[0] = (fd_rdr[FD] == STDOUT_FILENO) ? (ptr - word) : ((ptr - word) - ft_intlen(fd_rdr[FD])); pos[0] = (fd_rdr[FD] == -2) ? (size_t)((ptr - word) - 1) : (pos[0]); fd_rdr[FD] = (fd_rdr[FD] == -2) ? (STDOUT_FILENO) : (fd_rdr[FD]); tmp.word = word; tmp.ptr = ptr; tmp.redir = fd_rdr[RDR]; pos[1] = p_get_path(path, tmp, msh); (void)ft_memmove(word + pos[0], word + pos[1], (ft_strlen(word + pos[1]) + 1) * sizeof(char)); return (p_append_redir(path, fd_rdr, com, msh)); } char p_redirs(char word[], t_com **com, t_msh *msh) { char *ptr; t_quote_mode mode; mode = Q_NONE; ptr = (char *)word; while (*ptr != C_NUL) { if (*ptr == C_DQUOTE) mode = u_meet_dquote(word, ptr, mode); else if (*ptr == C_SQUOTE) mode = u_meet_squote(word, ptr, mode); else if (mode == Q_NONE && (*ptr == '<' || *ptr == '>') == 1 && u_is_not_escaped(word, ptr) == TRUE) { if (p_get_redir(word, ptr, *com, msh) != 0) return (1); ptr = word; } ptr++; } return (0); }