From 46a39c17cb1e0d9525378ff9bcd18bca0b243e85 Mon Sep 17 00:00:00 2001 From: Quinten Mennen Date: Wed, 26 Feb 2025 16:24:30 +0100 Subject: [PATCH] validating redirects WIP --- inc/redirect.h | 2 +- inc/utils.h | 2 + sources.mk | 40 +++---- src/expander/expander_get_variable.c | 16 +-- src/parser/parser_get_commands.c | 109 +++++++++-------- src/redirect/redirect_get_inputs.c | 169 +++++++++++++++------------ src/redirect/redirect_get_outputs.c | 2 +- src/redirect/redirect_valid_type.c | 78 +++++++------ src/utils/free_minishell_line.c | 14 +-- src/utils/ft_substr_safe.c | 23 ++++ 10 files changed, 259 insertions(+), 196 deletions(-) create mode 100644 src/utils/ft_substr_safe.c diff --git a/inc/redirect.h b/inc/redirect.h index d9b5911..720e2d8 100644 --- a/inc/redirect.h +++ b/inc/redirect.h @@ -17,7 +17,7 @@ t_redirect *redirect_new(t_minishell *minishell, t_token_type type, char *value); t_list *redirect_get_inputs(t_minishell *minishell, t_list *list); t_list *redirect_get_outputs(t_minishell *minishell, t_list *list); -int redirect_is_valid(t_list *lst, t_token *token); +int redirect_is_valid(t_list *lst, t_token *token, int mode); int redirect_token_type(t_token *token); int redirect_is_delimiter(t_token *token); diff --git a/inc/utils.h b/inc/utils.h index 274ba80..a3d77af 100644 --- a/inc/utils.h +++ b/inc/utils.h @@ -23,6 +23,8 @@ void simple_builtins(t_minishell *minishell); void error_msg(char *func, char *msg); void check_malloc(t_minishell *minishell, void *ptr); char *ft_strdup_safe(t_minishell *minishell, const char *str); +char *ft_substr_safe(t_minishell *minishell, const char *str, + unsigned int start, size_t len); char *ft_strjoin_safe(t_minishell *minishell, const char *s1, const char *s2); void *malloc_safe(t_minishell *minishell, size_t size); diff --git a/sources.mk b/sources.mk index 3fa9ed9..5ee83b6 100644 --- a/sources.mk +++ b/sources.mk @@ -1,23 +1,23 @@ VPATH = src:src/prompt:src/utils:src/lexer:src/token:src/environment:src/executor:src/parser:src/debug:src/expander:src/builtin:src/signal:src/redirect: -SOURCES = history_load.c history_write.c prompt.c error_msg.c \ -ft_lstclear_safe.c ft_lstnew_safe.c ft_strdup_safe.c \ -ft_strjoin_safe.c init_minishell.c malloc_safe.c print_banner.c \ -check_malloc.c free_command_list.c free_freelist.c free_lexer.c \ -free_minishell.c free_minishell_line.c free_safe.c free_token.c \ -free_token_list.c lexer_read_char.c lexer_new.c lexer_parse_input.c \ -lexer_read_word.c lexer_token_next.c token_new.c token_parse.c \ -environment_add.c environment_del.c environment_free.c \ -environment_free_list.c environment_get.c environment_get_arr.c \ -environment_parse.c environment_print.c executor_close_fds.c \ -executor_absolute_path.c executor_child.c executor_count_fds.c \ -executor_create_pipes.c executor_create_redirects.c \ -executor_execute_pipeline.c executor_fork.c executor_open_fds.c \ -parser_get_arguments.c parser_get_commands.c parser_new_command.c \ -print_commands.c print_freelist.c expander_is_character.c \ -expander_expand_dollar.c expander_allocate_memory.c \ -expander_get_variable.c expander_parse_string.c \ -expander_parse_variables.c builtin_echo.c builtin_router.c \ -simple_builtins.c is_builtin.c builtin_cd.c builtin_env.c \ +SOURCES = history_load.c history_write.c prompt.c ft_lstclear_safe.c \ +ft_lstnew_safe.c init_minishell.c malloc_safe.c print_banner.c \ +free_minishell_line.c error_msg.c free_command_list.c \ +ft_strdup_safe.c ft_strjoin_safe.c ft_substr_safe.c check_malloc.c \ +free_freelist.c free_lexer.c free_minishell.c free_safe.c \ +free_token.c free_token_list.c lexer_parse_input.c lexer_read_word.c \ +lexer_token_next.c lexer_read_char.c lexer_new.c token_parse.c \ +token_new.c environment_free.c environment_free_list.c \ +environment_print.c environment_add.c environment_del.c \ +environment_get.c environment_get_arr.c environment_parse.c \ +executor_close_fds.c executor_count_fds.c executor_create_pipes.c \ +executor_create_redirects.c executor_execute_pipeline.c \ +executor_fork.c executor_open_fds.c executor_absolute_path.c \ +executor_child.c parser_get_commands.c parser_get_arguments.c \ +parser_new_command.c print_commands.c print_freelist.c \ +expander_is_character.c expander_allocate_memory.c \ +expander_expand_dollar.c expander_get_variable.c \ +expander_parse_string.c expander_parse_variables.c builtin_echo.c \ +builtin_router.c simple_builtins.c builtin_cd.c builtin_env.c \ builtin_exit.c builtin_export.c builtin_pwd.c builtin_unset.c \ -signal.c redirect_valid_type.c redirect_get_inputs.c \ +is_builtin.c signal.c redirect_valid_type.c redirect_get_inputs.c \ redirect_get_outputs.c redirect_new.c main.c \ diff --git a/src/expander/expander_get_variable.c b/src/expander/expander_get_variable.c index a899083..014448d 100644 --- a/src/expander/expander_get_variable.c +++ b/src/expander/expander_get_variable.c @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ -/* :::::::: */ -/* expander_get_variable.c :+: :+: */ -/* +:+ */ -/* By: qmennen +#+ */ -/* +#+ */ -/* Created: 2025/02/19 13:59:03 by qmennen #+# #+# */ -/* Updated: 2025/02/25 15:26:36 by whaffman ######## odam.nl */ +/* ::: :::::::: */ +/* expander_get_variable.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/19 13:59:03 by qmennen #+# #+# */ +/* Updated: 2025/02/26 14:10:53 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,7 +21,7 @@ t_environment *expander_get_var(const char *s, int idx, t_minishell *minishell) i = 0; while (expander_character_valid(s[idx + i])) i++; - name = ft_substr(s, idx, i); + name = ft_substr_safe(minishell, s, idx, i); if (!name || !*name) return (NULL); env = environment_get(minishell, name); diff --git a/src/parser/parser_get_commands.c b/src/parser/parser_get_commands.c index 724db81..34a77e7 100644 --- a/src/parser/parser_get_commands.c +++ b/src/parser/parser_get_commands.c @@ -1,46 +1,63 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* parser_get_commands.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: qmennen +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2025/02/11 14:06:02 by qmennen #+# #+# */ -/* Updated: 2025/02/18 20:36:01 by qmennen ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "minishell.h" - -static int is_command_token(t_token *token) -{ - return (token->type < 3 || redirect_token_type(token)); -} - -t_list *parser_get_commands(t_minishell *minishell) -{ - t_list *command_list; - t_list *current; - t_command *command; - t_token *token; - - command_list = NULL; - if (!minishell->tokens) - return (NULL); - current = minishell->tokens; - while (current) - { - token = (t_token *) current->content; - command = parser_command_new(minishell, ft_strdup_safe(minishell, token->value)); - command->args = parser_get_arguments(current, minishell); - command->redirect_in = redirect_get_inputs(minishell, current); - command->redirect_out = redirect_get_outputs(minishell, current); - ft_lstadd_back(&command_list, ft_lstnew_safe(minishell, command)); - while (current && is_command_token((t_token *)current->content)) - current = current->next; - if (current && ((t_token *)current->content)->type >= 3) - current = current->next; - } - ft_lstiter(command_list, print_commands); - return (command_list); -} +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parser_get_commands.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/11 14:06:02 by qmennen #+# #+# */ +/* Updated: 2025/02/18 20:36:01 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" +#include "utils.h" + +static int is_command_token(t_token *token) +{ + return (token->type < 3 || redirect_token_type(token)); +} + +/* +static int validate_redirects(t_list *lst) +{ + t_list *token; + + token = lst; + while (token) + { + if (((t_token *)token)->type == T_ERROR) + return (0); + token = token->next; + } + return (1); +} +*/ + +t_list *parser_get_commands(t_minishell *minishell) +{ + t_list *command_list; + t_list *current; + t_command *command; + t_token *token; + + command_list = NULL; + if (!minishell->tokens) + return (NULL); + current = minishell->tokens; + while (current) + { + token = (t_token *) current->content; + command = parser_command_new(minishell, ft_strdup_safe(minishell, token->value)); + command->args = parser_get_arguments(current, minishell); + command->redirect_in = redirect_get_inputs(minishell, current); + command->redirect_out = redirect_get_outputs(minishell, current); + ft_lstadd_back(&command_list, ft_lstnew_safe(minishell, command)); + while (current && is_command_token((t_token *)current->content)) + current = current->next; + if (current && ((t_token *)current->content)->type >= 3) + current = current->next; + } + ft_lstiter(command_list, print_commands); + return (command_list); +} diff --git a/src/redirect/redirect_get_inputs.c b/src/redirect/redirect_get_inputs.c index f68d9af..68aed2c 100644 --- a/src/redirect/redirect_get_inputs.c +++ b/src/redirect/redirect_get_inputs.c @@ -1,76 +1,93 @@ -/* ************************************************************************** */ -/* */ -/* :::::::: */ -/* redirect_get_inputs.c :+: :+: */ -/* +:+ */ -/* By: Quinten +#+ */ -/* +#+ */ -/* Created: 2025/02/23 12:29:05 by Quinten #+# #+# */ -/* Updated: 2025/02/23 12:29:05 by Quinten ######## odam.nl */ -/* */ -/* ************************************************************************** */ - -#include "redirect.h" - -static void process_heredoc(t_minishell *ms, t_token *heredoc, t_token *delim) -{ - char *line; - int fd; - - fd = open(".ms_heredoc", O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd < 0) //TODO: Will this work? - return ; - - while (TRUE) - { - line = readline(">"); - if ((*line && ft_strcmp(line, delim->value) == 0) || !line) //TODO: What if not line? - break ; - if (!*line) - ft_putendl_fd("", fd); - else - ft_putendl_fd(line, fd); - } - close(fd); - heredoc->type = T_REDIRECT_IN; - delim->value = ft_strdup_safe(ms, ".ms_heredoc"); -} - -t_list *redirect_get_inputs(t_minishell *minishell, t_list *list) -{ - t_list *current; - t_list *redirects; - t_token *token; - - redirects = NULL; - current = list; - while (current) - { - token = (t_token *)current->content; - if (redirect_is_delimiter(token)) - break ; - if (token->type != T_REDIRECT_IN && token->type != T_HEREDOC) - { - current = current->next; - continue ; - } - if (token->type == T_HEREDOC && redirect_is_valid(current, token)) - process_heredoc(minishell, token, current->next->content); - if (redirect_is_valid(current, token)) - { - ft_lstadd_back(&redirects, ft_lstnew_safe(minishell, - redirect_new(minishell, token->type, - ft_strdup_safe(minishell, - ((t_token *)current->next->content)->value)))); - current = current->next; - continue ; - } - else - { - ft_lstadd_front(&redirects, ft_lstnew_safe(minishell, redirect_new(minishell, T_ERROR, NULL))); - break ; - } - current = current->next; - } - return (redirects); -} +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* redirect_get_inputs.c :+: :+: */ +/* +:+ */ +/* By: Quinten +#+ */ +/* +#+ */ +/* Created: 2025/02/23 12:29:05 by Quinten #+# #+# */ +/* Updated: 2025/02/23 12:29:05 by Quinten ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "redirect.h" + +static int process_heredoc(t_minishell *msh, t_token *heredoc, t_token *delim) +{ + char *line; + char *expand; + int fd; + + fd = open(".ms_heredoc", O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd < 0) // TODO: Will this work? + { + error_msg("heredoc", "unable to write to temp file"); + return (fd); + } + + while (TRUE && fd > 0) + { + line = readline(">"); + if ((*line && ft_strcmp(line, delim->value) == 0) || !line) // TODO: What if not line? + break; + if (!*line) + ft_putendl_fd("", fd); + else + { + expand = expander_parse_string(line, msh); + ft_putendl_fd(expand, fd); + free_safe(msh, (void **)&expand); + } + free(line); + } + close(fd); + free(line); + heredoc->type = T_REDIRECT_IN; + delim->value = ft_strdup_safe(msh, ".ms_heredoc"); + return (1); +} + +t_list *redirect_get_inputs(t_minishell *minishell, t_list *list) +{ + t_list *current; + t_list *redirects; + t_token *token; + int result; + + redirects = NULL; + current = list; + result = 1; + while (current && result) + { + token = (t_token *)current->content; + if (redirect_is_delimiter(token)) + break ; + if (token->type != T_REDIRECT_IN && token->type != T_HEREDOC) + { + current = current->next; + continue ; + } + if (token->type == T_HEREDOC && redirect_is_valid(current, token, F_OK | W_OK)) + result = process_heredoc(minishell, token, current->next->content); + if (redirect_is_valid(current, token, F_OK | R_OK)) + { + ft_lstadd_back(&redirects, ft_lstnew_safe(minishell, + redirect_new(minishell, token->type, + ft_strdup_safe(minishell, + ((t_token *)current->next->content)->value)))); + current = current->next; + continue; + } + else + { + ft_lstadd_front(&redirects, ft_lstnew_safe(minishell, redirect_new(minishell, T_ERROR, NULL))); + break; + } + current = current->next; + } + if (result < 0) + { + ft_lstadd_front(&redirects, ft_lstnew_safe(minishell, redirect_new(minishell, T_ERROR, NULL))); + } + return (redirects); +} diff --git a/src/redirect/redirect_get_outputs.c b/src/redirect/redirect_get_outputs.c index f1f884c..813d39b 100644 --- a/src/redirect/redirect_get_outputs.c +++ b/src/redirect/redirect_get_outputs.c @@ -30,7 +30,7 @@ t_list *redirect_get_outputs(t_minishell *minishell, t_list *list) current = current->next; continue ; } - if (redirect_is_valid(current, token)) + if (redirect_is_valid(current, token, F_OK | W_OK)) { ft_lstadd_front(&redirects, ft_lstnew_safe(minishell, redirect_new(minishell, token->type, ft_strdup_safe(minishell, ((t_token *)current->next->content)->value)))); diff --git a/src/redirect/redirect_valid_type.c b/src/redirect/redirect_valid_type.c index 2554d32..493aff3 100644 --- a/src/redirect/redirect_valid_type.c +++ b/src/redirect/redirect_valid_type.c @@ -1,37 +1,41 @@ -/* ************************************************************************** */ -/* */ -/* :::::::: */ -/* redirect_valid_type.c :+: :+: */ -/* +:+ */ -/* By: Quinten +#+ */ -/* +#+ */ -/* Created: 2025/02/23 12:30:18 by Quinten #+# #+# */ -/* Updated: 2025/02/23 12:30:18 by Quinten ######## odam.nl */ -/* */ -/* ************************************************************************** */ - -#include "minishell.h" - -int redirect_token_type(t_token *token) -{ - return (token->type == T_REDIRECT_IN || token->type == T_HEREDOC || - token->type == T_REDIRECT_OUT || token->type == T_APPEND_OUT); -} - -int redirect_is_valid(t_list *lst, t_token *token) -{ - t_token *next; - - if (!lst->next) - return (0); - next = (t_token *)lst->next->content; - if (!next) - return (0); - return (redirect_token_type(token) && next->type < 3); -} - -int redirect_is_delimiter(t_token *token) -{ - return (token->type == T_PIPE || token->type == T_AND || - token->type == T_OR || token->type == T_EOF || token->type == T_ERROR); -} \ No newline at end of file +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* redirect_valid_type.c :+: :+: */ +/* +:+ */ +/* By: Quinten +#+ */ +/* +#+ */ +/* Created: 2025/02/23 12:30:18 by Quinten #+# #+# */ +/* Updated: 2025/02/23 12:30:18 by Quinten ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int redirect_token_type(t_token *token) +{ + return (token->type == T_REDIRECT_IN || token->type == T_HEREDOC || + token->type == T_REDIRECT_OUT || token->type == T_APPEND_OUT); +} + +int redirect_is_valid(t_list *lst, t_token *token, int mode) +{ + t_token *next; + + if (!lst->next) + return (0); + next = (t_token *)lst->next->content; + if (!next) + { + return (0); + } + if (!access(next->value, mode)) + return (0); + return (redirect_token_type(token) && next->type < 3); +} + +int redirect_is_delimiter(t_token *token) +{ + return (token->type == T_PIPE || token->type == T_AND || + token->type == T_OR || token->type == T_EOF || token->type == T_ERROR); +} diff --git a/src/utils/free_minishell_line.c b/src/utils/free_minishell_line.c index 693b953..c7a6102 100644 --- a/src/utils/free_minishell_line.c +++ b/src/utils/free_minishell_line.c @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ -/* :::::::: */ -/* free_minishell_line.c :+: :+: */ -/* +:+ */ -/* By: whaffman +#+ */ -/* +#+ */ -/* Created: 2025/02/05 16:01:44 by whaffman #+# #+# */ -/* Updated: 2025/02/25 17:40:32 by whaffman ######## odam.nl */ +/* ::: :::::::: */ +/* free_minishell_line.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/05 16:01:44 by whaffman #+# #+# */ +/* Updated: 2025/02/26 14:24:20 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/src/utils/ft_substr_safe.c b/src/utils/ft_substr_safe.c new file mode 100644 index 0000000..2c50548 --- /dev/null +++ b/src/utils/ft_substr_safe.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* ft_strdup_safe.c :+: :+: */ +/* +:+ */ +/* By: whaffman +#+ */ +/* +#+ */ +/* Created: 2025/02/20 18:01:27 by whaffman #+# #+# */ +/* Updated: 2025/02/20 18:04:53 by whaffman ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +char *ft_substr_safe(t_minishell *minishell, const char *str, + unsigned int start, size_t len) +{ + char *new_str; + + new_str = ft_substr(str, start, len); + check_malloc(minishell, new_str); + return (new_str); +}