/* By: ljiriste <ljiriste@student.42prague.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/21 08:57:54 by ljiriste #+# #+# */
-/* Updated: 2024/07/21 14:24:33 by ljiriste ### ########.fr */
+/* Updated: 2024/07/21 17:41:29 by ljiriste ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
+#include "libft.h"
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
int cmp_var_name(const char *a, const char *b)
{
eq_ptr = ft_strchr(b, '=');
if (namelen != eq_ptr - b)
return (1);
- return (ft_strcmp(a, b, namelen));
+ return (ft_strncmp(a, b, namelen));
}
void clear_old(t_vec *assignments, const char *new)
int add_assignment(t_vec *assignments, const char *assignment)
{
- size_t i;
char *copy;
- copy = ft_strdup(subnode->token.str);
+ copy = ft_strdup(assignment);
if (!copy)
return (1);
clear_old(assignments, copy);
if (ft_vec_append(assignments, ©) == success)
return (0);
- free(copy);
return (1);
}
int save_assignments_prefix(t_vec *assignments, t_parse_tree_node *prefix)
{
size_t i;
- char *assignment;
t_parse_tree_node *subnode;
i = 0;
return (0);
}
+char *get_word(const t_parse_tree_node *parent)
+{
+ char *res;
+ const t_parse_tree_node *word = ft_vec_caccess(&parent->children, 2);
+
+ res = ft_strdup(word->token.str);
+ return (res);
+}
+
+int add_redirection_file(t_vec *redirections, t_parse_tree_node *io_file, int fd)
+{
+ t_redirection redir;
+ const t_parse_tree_node *operator;
+ char *filename;
+ int sec_fd;
+
+ filename = get_word(ft_vec_caccess(&io_file->children, 1));
+ if (!filename)
+ return (1);
+ operator = ft_vec_caccess(&io_file->children, 0);
+ if (is_token_type(operator, "LESS"))
+ {
+ if (fd == -1)
+ fd = STDIN_FILENO;
+ sec_fd = open(filename, O_RDONLY);
+ if (sec_fd < 0)
+ return (1);
+ redir = (t_redirection){.from_to_fds[0] = sec_fd, .from_to_fds[1] = fd, .created = 0};
+ }
+ else
+ {
+ if (fd < 0)
+ fd = STDOUT_FILENO;
+ if (is_token_type(operator, "GREAT"))
+ sec_fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
+ else
+ sec_fd = open(filename, O_CREAT | O_WRONLY | O_APPEND, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
+ if (sec_fd == -1)
+ return (1);
+ redir = (t_redirection){.from_to_fds[0] = fd, .from_to_fds[1] = sec_fd, .created = 1};
+ }
+ return (ft_vec_append(redirections, &redir) != success);
+}
+
+char *get_var_name(const char *line)
+{
+ size_t i;
+
+ i = 0;
+ while (line[i] && !ft_isspace(line[i]))
+ ++i;
+ return (ft_strndup(line, i));
+}
+
+char *get_var_value(const t_vec *vars, const char *var_name)
+{
+ size_t len;
+ size_t i;
+ const char *const *line;
+
+ len = ft_strlen(var_name);
+ i = 0;
+ while (i < vars->size)
+ {
+ line = ft_vec_caccess(vars, i);
+ if (ft_strncmp(*line, var_name, len) && (*line)[len + 1] == '=')
+ return (ft_strdup(*line + len + 2));
+ ++i;
+ }
+ return (ft_strdup(""));
+}
+
+char *get_env_var_value(const t_execution_env *env, const char *var_name)
+{
+ char *res;
+
+ res = get_var_value(&env->vars->other, var_name);
+ if (!res || res[0])
+ return (res);
+ res = get_var_value(&env->vars->exported, var_name);
+ return (res);
+}
+
+int write_line_to_pipe(int pipe_fd, const char *line, const t_execution_env *env, int expand)
+{
+ size_t i;
+ char *var;
+ char *value;
+
+ i = 0;
+ while (line[i])
+ {
+ if (line[i] != '$' || !expand)
+ {
+ ft_dprintf(pipe_fd, "%c", line[i]);
+ ++i;
+ continue ;
+ }
+ ++i;
+ var = get_var_name(line + i);
+ if (!var)
+ return (1);
+ value = get_env_var_value(env, var);
+ if (!value)
+ {
+ free(var);
+ return (1);
+ }
+ ft_dprintf(pipe_fd, "%s", value);
+ i += ft_strlen(var);
+ free(var);
+ free(value);
+ }
+ return (0);;
+}
+
+char *unquote_delimiter(const char *str)
+{
+ size_t i;
+ char *res;
+ char quote_char;
+
+ res = ft_strdup(str);
+ if (!res)
+ return (NULL);
+ i = 0;
+ quote_char = '\0';
+ while (res[i])
+ {
+ if ((res[i] == '"' || res[i] == '\''))
+ {
+ if (!quote_char)
+ {
+ quote_char = res[i];
+ ft_memmove(res + i, res + i + 1, ft_strlen(res + i + 1) + 1);
+ continue ;
+ }
+ else if (res[i] == quote_char)
+ {
+ quote_char = '\0';
+ ft_memmove(res + i, res + i + 1, ft_strlen(res + i + 1) + 1);
+ continue ;
+ }
+ }
+ ++i;
+ }
+ return (res);
+}
+
+int here_file_to_pipe(int pipe_fd, const char *delimiter, const t_execution_env *env)
+{
+ int expand;
+ char *line;
+ char *unquoted_delimiter;
+
+ unquoted_delimiter = unquote_delimiter(delimiter);
+ if (!unquoted_delimiter)
+ return (1);
+ expand = !ft_strcmp(unquoted_delimiter, delimiter);
+ ft_printf("> ");
+ line = get_next_line(STDIN_FILENO);
+ while (line && ft_strcmp(line, unquoted_delimiter))
+ {
+ if (write_line_to_pipe(pipe_fd, line, env, expand))
+ {
+ get_next_line(-1);
+ free(line);
+ free(unquoted_delimiter);
+ return (1);
+ }
+ free(line);
+ ft_printf("> ");
+ line = get_next_line(STDIN_FILENO);
+ }
+ if (!line)
+ ft_printf("minishell: warning: here-document delimited by EOF instead of %s!\n", unquoted_delimiter);
+ get_next_line(-1);
+ free(line);
+ free(unquoted_delimiter);
+ return (0);
+}
+
+int add_redirection_here(t_vec *redirections, t_parse_tree_node *io_here, int fd, const t_execution_env *env)
+{
+ char *delimiter;
+ int pipe_fds[2];
+ int err;
+ t_redirection redir;
+
+ delimiter = get_word(ft_vec_caccess(&io_here->children, 1));
+ if (!delimiter)
+ return (1);
+ if (fd == -1)
+ fd = STDIN_FILENO;
+ if (pipe(pipe_fds))
+ {
+ free(delimiter);
+ return (1);
+ }
+ err = here_file_to_pipe(pipe_fds[1], delimiter, env);
+ close(pipe_fds[1]);
+ free(delimiter);
+ if (err)
+ return (1);
+ redir = (t_redirection){.from_to_fds[0] = pipe_fds[0], .from_to_fds[1] = fd, .created = 1};
+ return (ft_vec_append(redirections, &redir) != success);
+}
+
+int add_redirection(t_vec *redirections, t_parse_tree_node *redirect, const t_execution_env *env)
+{
+ int fd;
+ t_parse_tree_node *subnode;
+
+ fd = -1;
+ subnode = ft_vec_access(&redirect->children, 0);
+ if (redirect->children.size == 2)
+ {
+ fd = ft_atoi(subnode->token.str);
+ if (fd < 0)
+ fd = -2;
+ subnode = ft_vec_access(&redirect->children, 1);
+ }
+ if (is_token_type(subnode, "io_file"))
+ return (add_redirection_file(redirections, subnode, fd));
+ else
+ return (add_redirection_here(redirections, subnode, fd, env));
+}
+
+int save_redirections_psfix(t_vec *redirections, t_parse_tree_node *node, const t_execution_env *env)
+{
+ size_t i;
+ t_parse_tree_node *subnode;
+
+ i = 0;
+ while (i < node->children.size)
+ {
+ subnode = ft_vec_access(&node->children, i);
+ if (is_token_type(subnode, "io_redirect"))
+ {
+ if (add_redirection(redirections, subnode, env))
+ return (1);
+ }
+ else if (is_token_type(subnode, "cmd_suffix") || is_token_type(subnode, "cmd_prefix"))
+ if (save_redirections_psfix(redirections, subnode, env))
+ return (1);
+ ++i;
+ }
+ return (0);
+}
+
+int save_redirections(t_vec *redirections, t_parse_tree_node *simple_command, const t_execution_env *env)
+{
+ t_parse_tree_node *subnode;
+
+ if (ft_vec_init(redirections, sizeof(t_redirection)) != success)
+ return (1);
+ subnode = ft_vec_access(&simple_command->children, 0);
+ if (is_token_type(subnode, "cmd_prefix"))
+ if (save_redirections_psfix(redirections, subnode, env))
+ return (1);
+ subnode = ft_vec_access(&simple_command->children, simple_command->children.size - 1);
+ if (is_token_type(subnode, "cmd_suffix"))
+ if (save_redirections_psfix(redirections, subnode, env))
+ return (1);
+ return (0);
+}
+
int ex_simple_command(t_parse_tree_node *simple_command, t_execution_env *env)
{
t_vec redirections;
char **fields;
int res;
- res = save_redirections(&redirections, simple_command);
+ res = save_redirections(&redirections, simple_command, env);
res = res || save_assignments(&assignments, simple_command);
if (!res)
fields = expand(simple_command, env, &redirections, &assignments);