commit aee974b462691bf0c67a2f471c1266fc9b361038 Author: Xamora Date: Tue Aug 27 17:41:29 2024 +0200 Push project diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8488d99 --- /dev/null +++ b/Makefile @@ -0,0 +1,61 @@ +UTILS_SRC = utils/ft_is_in_quote.c utils/ft_strncpy.c utils/ft_strreplace.c utils/ft_strnchr.c utils/ft_split_charset_quoted.c utils/ft_strshift.c utils/ft_quote_remover.c utils/ft_str_is_empty.c utils/ft_atoi_check.c ./utils/ft_get_executable.c ./utils/fd.c + +BUILTINS_SRC = builtins/pwd.c \ + builtins/export.c \ + builtins/env.c \ + builtins/cd.c \ + builtins/exit.c \ + builtins/unset.c \ + builtins/echo.c + +SRCS = ${BUILTINS_SRC} \ + ${UTILS_SRC} \ + main.c \ + ./cmd/cmd.c \ + ./env/env1.c \ + ./env/env2.c \ + ./env/env3.c \ + ./env/env_fill.c \ + ./data/data.c \ + ./execution/execution.c \ + ./syntax/syntax.c \ + ./format/format.c \ + ./redirection/heredoc.c \ + ./redirection/file.c \ + ./redirection/redirection.c \ + ./redirection/check.c \ + ./parse/parse.c \ + ./signal/signal.c + +OBJS = ${SRCS:.c=.o} + +NAME = minishell + +CC = clang + +CFLAGS = -Werror -Wextra -Wall -g + +LIBS = libftx/libftx.a + +%.o: %.c + ${CC} ${CFLAGS} -c -o $@ $< + +all: ${NAME} + +${NAME}: ${OBJS} + make -C libftx all + ${CC} ${OBJS} -o ${NAME} ${LIBS} -lreadline + +clean: + make -C libftx clean + rm -f ${OBJS} + +fclean: clean + make -C libftx fclean + rm -f ${NAME} + +re: fclean + make all + +.PHONY: all clean fclean re + diff --git a/bozoshell.h b/bozoshell.h new file mode 100644 index 0000000..85bde9e --- /dev/null +++ b/bozoshell.h @@ -0,0 +1,34 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* bozoshell.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet +# include +# include +# include +# include +# include + +#endif diff --git a/builtins/.nfs000000000ab804b60000004a b/builtins/.nfs000000000ab804b60000004a new file mode 100644 index 0000000..ca45be8 Binary files /dev/null and b/builtins/.nfs000000000ab804b60000004a differ diff --git a/builtins/builtins.h b/builtins/builtins.h new file mode 100644 index 0000000..8b7679a --- /dev/null +++ b/builtins/builtins.h @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* builtins.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet +# include "../libftx/libftx.h" +# include "../env/env.h" +# include "../utils/utils.h" + +char *get_pwd(void); + +#endif diff --git a/builtins/cd.c b/builtins/cd.c new file mode 100644 index 0000000..45249ce --- /dev/null +++ b/builtins/cd.c @@ -0,0 +1,62 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* cd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: erey-bet +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/02/20 14:27:36 by erey-bet #+# #+# */ +/* Updated: 2023/04/18 13:22:22 by erey-bet ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "./builtins_private.h" + +int make_move(char *path, t_list **env) +{ + char *join; + char *old; + + join = ft_strjoin("/", path); + join = ft_strfjoin(get_pwd(), join); + old = get_pwd(); + if (chdir(join) == 0) + { + set_value_by_key("OLDPWD", old, env); + set_value_by_key("PWD", get_pwd(), env); + free(join); + return (0); + } + free(old); + free(join); + write(2, "cd: No such file or directory\n", 30); + return (1); +} + +int move_folder(char **args, t_list **env) +{ + char *path; + char *old; + + if (args[0] == NULL || args[1] != NULL) + { + write(2, "cd: Wrong number's argument\n", 28); + return (1); + } + path = args[0]; + if (path[0] == '/' || ft_strncmp(path, "..", ft_strlen(path)) == 0) + { + old = get_pwd(); + if (chdir(path) == 0) + { + set_value_by_key("OLDPWD", old, env); + set_value_by_key("PWD", get_pwd(), env); + return (0); + } + free(old); + write(2, "cd: No such file or directory\n", 30); + return (1); + } + else + return (make_move(path, env)); +} diff --git a/builtins/echo.c b/builtins/echo.c new file mode 100644 index 0000000..c381f45 --- /dev/null +++ b/builtins/echo.c @@ -0,0 +1,63 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* echo.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: erey-bet +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/02/17 13:09:08 by erey-bet #+# #+# */ +/* Updated: 2023/04/11 14:57:00 by erey-bet ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "./builtins_private.h" + +int is_space(char c) +{ + return (c == ' ' || c == '\f' || c == '\v' || c == '\t' + || c == '\r' || c == '\n'); +} + +int check_argument(char *str, int *check_backslash_n) +{ + int i; + + i = -1; + while (str[++i]) + if (str[i] != '-' && str[i] != 'n') + return (1); + if (ft_strnstr(str, "n", ft_strlen(str)) && str[0] == '-') + *check_backslash_n = 1; + else + return (1); + return (0); +} + +int echo(int fd, char **strs) +{ + int check_backslash_n; + int check_start_write; + int i; + int y; + + check_backslash_n = 0; + check_start_write = 0; + i = -1; + while (strs[++i]) + { + y = -1; + while (is_space(strs[i][++y])) + ; + if (check_start_write == 1 + || check_argument(strs[i], &check_backslash_n)) + { + check_start_write = 1; + ft_putstr_fd(strs[i], fd); + if (strs[i + 1] != NULL) + write(fd, " ", 1); + } + } + if (!check_backslash_n) + write(fd, "\n", 1); + return (0); +} diff --git a/builtins/env.c b/builtins/env.c new file mode 100644 index 0000000..6b3c038 --- /dev/null +++ b/builtins/env.c @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* env.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet next != NULL) + { + if (((t_env *)(current->content))->value) + { + ft_putstr_fd(((t_env *)(current->content))->key, fd); + ft_putstr_fd("=", fd); + ft_putstr_fd(((t_env *)(current->content))->value, fd); + write(fd, "\n", 1); + } + current = current->next; + } + return (0); +} diff --git a/builtins/exit.c b/builtins/exit.c new file mode 100644 index 0000000..043b883 --- /dev/null +++ b/builtins/exit.c @@ -0,0 +1,43 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* exit.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: erey-bet +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/02/24 10:17:59 by erey-bet #+# #+# */ +/* Updated: 2023/04/05 12:30:46 by erey-bet ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "./builtins_private.h" + +static int error(int err, char *reason, char *problem) +{ + ft_putstr_fd("bozoshell: bozo_exit ", 2); + if (problem != NULL) + { + ft_putstr_fd(problem, 2); + write(2, ": ", 3); + } + ft_putstr_fd(reason, 2); + return (err); +} + +int ft_exit(char **args, int err) +{ + if (args[0] == NULL) + { + write(1, "bozo_exit\n", 10); + return (err); + } + err = ft_atoi_check(args[0]); + if (err == 1) + return (error(err, "bozo_exit: numeric argument required\n", args[0])); + if (args[1] != NULL) + return (error(-1, "bozo_exit: too many arguments\n", NULL)); + if (err > 0) + return (error(err, "bozo_exit: numeric argument required\n", args[0])); + write(1, "exit\n", 6); + return ((ft_atoi(args[0]) % 256 + 256) % 256); +} diff --git a/builtins/export.c b/builtins/export.c new file mode 100644 index 0000000..293f3d3 --- /dev/null +++ b/builtins/export.c @@ -0,0 +1,114 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* export.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet next != NULL) + { + if (ft_strcmp(((t_env *)(current->content))->key, "_")) + { + write(fd, "declare -x ", 11); + ft_putstr_fd(((t_env *)(current->content))->key, fd); + if (((t_env *)(current->content))->value != NULL) + { + ft_putstr_fd("=", fd); + write(fd, "\"", 1); + ft_putstr_fd(((t_env *)(current->content))->value, fd); + write(fd, "\"\n", 2); + } + else + write(fd, "\n", 2); + } + current = current->next; + } +} + +int set_key_value_export(t_list **env, char *args, char **key, char **value) +{ + *key = ft_strndup(args, ft_strnchr(args, '=')); + if (*key == NULL) + return (1); + if (ft_strlen(*key) == 0) + return (1); + if (possible_key(*key) == 2) + { + (*key)[ft_strlen(*key) - 1] = '\0'; + if (get_value_by_key(*key, env) == NULL) + *value = ft_strdup(ft_strchr(args, '=') + 1); + else + *value = ft_strjoin(get_value_by_key(*key, env), + ft_strchr(args, '=') + 1); + } + else + *value = ft_strdup(ft_strchr(args, '=') + 1); + return (0); +} + +int add_export(t_list **env, char *args) +{ + char *key; + char *value; + + if (ft_strchr(args, '=') != NULL) + { + if (set_key_value_export(env, args, &key, &value)) + return (error(args, key, NULL)); + } + else + { + key = ft_strdup(args); + value = get_value_by_key(key, env); + if (value != NULL) + value = ft_strdup(value); + if (possible_key(key) == 2) + return (error(key, key, value)); + } + if (!possible_key(key)) + return (error(args, key, value)); + create_value_by_key(key, value, env); + return (0); +} + +int ft_export(t_list **env, char **args, int fd) +{ + int err; + int i; + + err = 0; + if (args[0] == NULL) + print_export(env, fd); + else + { + i = -1; + while (args[++i]) + if (add_export(env, args[i]) == 1) + err = 1; + } + return (err); +} diff --git a/builtins/pwd.c b/builtins/pwd.c new file mode 100644 index 0000000..ae096bd --- /dev/null +++ b/builtins/pwd.c @@ -0,0 +1,41 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pwd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: erey-bet +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/02/17 16:09:11 by erey-bet #+# #+# */ +/* Updated: 2023/04/18 12:59:25 by erey-bet ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "./builtins_private.h" + +int pwd(int fd) +{ + char path[PATH_MAX]; + + if (getcwd(path, sizeof(path)) != NULL) + ft_putendl_fd(path, fd); + else + { + ft_putendl_fd("Error getcwd", 2); + return (1); + } + return (0); +} + +char *get_pwd(void) +{ + char *str; + + str = ft_calloc(PATH_MAX, sizeof(char *)); + if (getcwd(str, PATH_MAX) != NULL) + return (str); + else + { + ft_putendl_fd("Error getcwd", 2); + return (NULL); + } +} diff --git a/builtins/unset.c b/builtins/unset.c new file mode 100644 index 0000000..1b04514 --- /dev/null +++ b/builtins/unset.c @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* unset.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: erey-bet +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/02/22 13:28:27 by erey-bet #+# #+# */ +/* Updated: 2023/04/07 12:46:28 by erey-bet ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "./builtins_private.h" + +int error(char *str, int fd) +{ + write(fd, "bozoshell: unset: `", 19); + write(fd, str, ft_strlen(str)); + write(fd, "': not a valid identifier\n", 26); + return (1); +} + +int unset(t_list **env, char **args, int fd) +{ + int i; + int err; + + i = -1; + err = 0; + while (args[++i]) + if (delete_by_key(args[i], env)) + if (!possible_key(args[i])) + err = error(args[i], fd); + return (err); +} diff --git a/cmd/cmd.c b/cmd/cmd.c new file mode 100644 index 0000000..3b834ec --- /dev/null +++ b/cmd/cmd.c @@ -0,0 +1,73 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* cmd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet + +void ft_cmddel(void *ptr) +{ + t_cmd *content; + + content = (t_cmd *) ptr; + if (content->args != NULL) + ft_freer_tab_ultimate(1, content->args); + if (content->own_cmd == false && content->executable != NULL) + free(content->executable); + if (content->fd_in[0] > 2) + close(content->fd_in[0]); + if (content->fd_out[0] > 2) + close(content->fd_out[0]); + if (content->fd_in[1] > 2) + close(content->fd_in[1]); + if (content->fd_out[1] > 2) + close(content->fd_out[1]); + free(content); +} + +void ft_cmdcloser(void *ptr) +{ + t_cmd *cmd; + + cmd = ptr; + ft_closer(cmd->fd_in); + ft_closer(cmd->fd_out); +} + +void ft_cmdwaiter(void *ptr) +{ + t_cmd *cmd; + int exit_status; + + cmd = ptr; + if (cmd->executable != NULL && cmd->own_cmd == 0 + && cmd->pid != -1 && cmd->fd_in[0] != -2 && cmd->fd_out[0] != -2) + { + waitpid(cmd->pid, &exit_status, 0); + if (WIFSIGNALED(exit_status)) + { + if (exit_status == 131) + { + ft_printf("Quit (core dumped)"); + *ft_get_exit_code() = 131; + } + else + *ft_get_exit_code() = 130; + ft_printf("\n"); + } + else + *ft_get_exit_code() = WEXITSTATUS(exit_status); + } + signal(SIGINT, ft_ctrlc); + signal(SIGQUIT, SIG_IGN); +} diff --git a/cmd/cmd.h b/cmd/cmd.h new file mode 100644 index 0000000..ae87162 --- /dev/null +++ b/cmd/cmd.h @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* cmd.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet +# include "../data/data.h" + +typedef struct s_cmd +{ + int fd_in[2]; + int fd_out[2]; + int pid; + char *executable; + char **args; + bool own_cmd; +} t_cmd; + +void ft_cmddel(void *content); +void ft_cmdwaiter(void *content); +void ft_cmdcloser(void *ptr); + +#endif diff --git a/cmd/cmd_private.h b/cmd/cmd_private.h new file mode 100644 index 0000000..cd7cd0e --- /dev/null +++ b/cmd/cmd_private.h @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* cmd_private.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet +# include +# include "./cmd.h" +# include "../libftx/libftx.h" +# include "../data/data.h" +# include "../utils/utils.h" +#endif diff --git a/data/data.c b/data/data.c new file mode 100644 index 0000000..79a9bd7 --- /dev/null +++ b/data/data.c @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* data.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet +# include "../libftx/libft/list.h" +# include "../data/data.h" + +typedef struct s_env +{ + char *key; + char *value; +} t_env; + +char *ft_env_filler(t_data *data, const char *str); +void env_del(void *content); +t_list **init_env(char **env); +char **env_to_strs(t_list **head); +int create_value_by_key(char *key, char *value, t_list **head); +int create_value_by_key_dup(char *key, char *value, t_list **head); +int set_value_by_key(char *key, char *value, t_list **head); +char *get_value_by_key(char *key, t_list **head); +void env_del(void *ptr); +int delete_by_key(char *key, t_list **head); +int possible_key(char *key); + +#endif diff --git a/env/env1.c b/env/env1.c new file mode 100644 index 0000000..e47bf0e --- /dev/null +++ b/env/env1.c @@ -0,0 +1,120 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* env1.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: erey-bet +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/02/02 14:39:56 by erey-bet #+# #+# */ +/* Updated: 2023/04/18 13:57:38 by erey-bet ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "env_private.h" + +void add_sort(t_list **head, t_env *var) +{ + t_list *current; + t_env *last; + + current = *head; + while (current->next != NULL + && ft_strcmp(var->key, ((t_env *)(current->content))->key) > 0) + current = current->next; + if (current->content == NULL) + current->content = var; + else + { + last = NULL; + swap_env_3((void **)&last, ¤t->content, (void **)&var); + while (current->next != NULL) + { + current = current->next; + swap_env(¤t->content, (void **)&last); + } + } + if (current->next == NULL) + { + current->next = ft_calloc(1, sizeof(t_list)); + if (!current->next) + return ; + } +} + +char *get_value_by_key(char *key, t_list **head) +{ + t_list *current; + + current = *head; + while (current->next != NULL) + { + if (ft_strcmp(((t_env *)current->content)->key, key) == 0) + return (((t_env *)current->content)->value); + current = current->next; + } + return (NULL); +} + +int set_value_by_key(char *key, char *value, t_list **head) +{ + t_list *current; + + current = *head; + while (current->next != NULL) + { + if (ft_strcmp(((t_env *)current->content)->key, key) == 0) + { + free(((t_env *)current->content)->value); + ((t_env *)current->content)->value = value; + return (0); + } + current = current->next; + } + return (1); +} + +int create_value_by_key(char *key, char *value, t_list **head) +{ + t_env *content; + + if (set_value_by_key(key, value, head) == 0) + { + free(key); + return (0); + } + content = ft_calloc(1, sizeof(t_env)); + if (content == NULL) + return (1); + content->key = key; + content->value = value; + add_sort(head, content); + return (0); +} + +t_list **init_env(char **env) +{ + t_list **head; + int i; + t_env *var; + + head = ft_calloc(1, sizeof(t_list *)); + if (head == NULL) + return (NULL); + *head = ft_calloc(1, sizeof(t_list)); + if (*head == NULL) + { + free(head); + return (NULL); + } + i = -1; + while (env[++i]) + { + var = ft_calloc(1, sizeof(t_env)); + if (var == NULL) + return (NULL); + var->key = get_key(env[i]); + var->value = get_value(env[i]); + add_sort(head, var); + } + return (head); +} diff --git a/env/env2.c b/env/env2.c new file mode 100644 index 0000000..4b425c2 --- /dev/null +++ b/env/env2.c @@ -0,0 +1,77 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* env2.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: erey-bet +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/03/09 19:59:03 by erey-bet #+# #+# */ +/* Updated: 2023/04/18 13:26:31 by erey-bet ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "env_private.h" + +int get_index(char *s, char c) +{ + int i; + + i = -1; + while (s[++i]) + if (s[i] == c) + return (i); + return (-1); +} + +void swap_env_3(void **a, void **b, void **c) +{ + void *d; + + d = *a; + *a = *b; + *b = *c; + *c = d; +} + +void swap_env(void **a, void **b) +{ + void *c; + + c = *a; + *a = *b; + *b = c; +} + +void env_del(void *ptr) +{ + t_env *content; + + if (ptr == NULL) + return ; + content = ptr; + if (content->key != NULL) + free(content->key); + if (content->key != NULL) + free(content->value); + if (content != NULL) + free(content); +} + +char **env_to_strs(t_list **head) +{ + t_list *current; + t_env *content; + char **env; + int i; + + current = *head; + env = ft_calloc(ft_lstsize(*head), sizeof(char *)); + i = 0; + while (current->content) + { + content = current->content; + env[i++] = ft_strmerger(3, content->key, "=", content->value); + current = current->next; + } + return (env); +} diff --git a/env/env3.c b/env/env3.c new file mode 100644 index 0000000..38462f2 --- /dev/null +++ b/env/env3.c @@ -0,0 +1,109 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* env3.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: erey-bet +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/02/17 17:25:09 by erey-bet #+# #+# */ +/* Updated: 2023/04/07 13:21:54 by erey-bet ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "env_private.h" + +char *get_value(char *str) +{ + char *s; + int i; + int start; + + s = ft_calloc(ft_strlen(str), sizeof(char)); + start = get_index(str, '='); + i = start; + while (str[++i]) + s[i - start - 1] = str[i]; + return (s); +} + +char *get_key(char *str) +{ + char *s; + int i; + + s = ft_calloc(ft_strlen(str), sizeof(char)); + i = -1; + while (str[++i] != '=') + s[i] = str[i]; + return (s); +} + +int create_value_by_key_dup(char *key, char *value, t_list **env) +{ + char *key_dup; + char *value_dup; + + if (set_value_by_key(key, value, env) == 0) + return (0); + key_dup = ft_strdup(key); + if (key_dup == NULL) + return (1); + if (value != NULL) + { + value_dup = ft_strdup(value); + if (value_dup == NULL) + { + free(key); + return (1); + } + } + else + value_dup = value; + if (create_value_by_key(key_dup, value_dup, env)) + return (1); + return (0); +} + +int delete_by_key(char *key, t_list **head) +{ + t_list *last; + t_list *current; + + current = *head; + last = NULL; + while (current->next != NULL) + { + if (ft_strcmp(((t_env *)current->content)->key, key) == 0) + { + free(((t_env *)current->content)->key); + free(((t_env *)current->content)->value); + free(current->content); + if (last && last->next) + last->next = current->next; + else + *head = current->next; + free(current); + return (0); + } + last = current; + current = current->next; + } + return (1); +} + +int possible_key(char *key) +{ + int i; + + i = -1; + if (ft_isdigit(key[i + 1])) + return (0); + while (key[++i + 1]) + if (!ft_isalnum(key[i]) && key[i] != '_') + return (0); + if (key[i] == '+') + return (2); + else if (!ft_isalnum(key[i]) && key[i] != '_') + return (0); + return (1); +} diff --git a/env/env_fill.c b/env/env_fill.c new file mode 100644 index 0000000..34182cb --- /dev/null +++ b/env/env_fill.c @@ -0,0 +1,117 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* env_fill.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet exit_code); + else if (ft_strcmp(key, "$") == 0) + value = ft_strdup("PID"); + else if (key[0] == '\0') + value = ft_strdup("$"); + else + { + value = get_value_by_key(key, data->env); + if (value == NULL) + value = ft_strdup(""); + else + value = ft_strdup(value); + } + if (value == NULL) + ft_eprintf("bozoshell: malloc failed\n"); + return (value); +} + +static char *ft_getvalue_by_str(t_data *data, const char *str, + size_t *key_len) +{ + char *key; + char *value; + + key = ft_getkey(str); + if (key == NULL) + return (NULL); + *key_len = ft_strlen(key) + 1; + value = ft_getvalue(data, key); + free(key); + return (value); +} + +char *ft_str_formator(t_data *data, char *str, size_t *i) +{ + char *value; + size_t key_len; + char *out; + + value = ft_getvalue_by_str(data, str + *i, &key_len); + if (value == NULL) + return (NULL); + out = ft_strreplace(str, value, *i, key_len + *i); + *i = *i + ft_strlen(value); + free(value); + return (out); +} + +char *ft_env_filler(t_data *data, const char *str) +{ + char *out; + char *temp; + size_t i; + + out = ft_strdup(str); + if (out == NULL) + return (NULL); + i = 0; + while (out[i] != '\0') + { + while (ft_is_in_quote(out, i) == 1) + i++; + while (out[i] == '$') + { + temp = ft_str_formator(data, out, &i); + if (temp == NULL) + return (NULL); + free(out); + out = temp; + } + if (out[i] != '\0') + i++; + } + return (out); +} diff --git a/env/env_private.h b/env/env_private.h new file mode 100644 index 0000000..e735d71 --- /dev/null +++ b/env/env_private.h @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* env_private.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet executable, "pwd") == 0) + return_code = pwd(cmd->fd_out[0]); + else if (ft_strcmp(cmd->executable, "env") == 0) + return_code = print_env(data->env, cmd->fd_out[0]); + else if (ft_strcmp(cmd->executable, "export") == 0) + return_code = ft_export(data->env, cmd->args + 1, cmd->fd_out[0]); + else if (ft_strcmp(cmd->executable, "cd") == 0) + return_code = (move_folder(cmd->args + 1, data->env, cmd->fd_out[0])); + else if (ft_strcmp(cmd->executable, "unset") == 0) + return_code = (unset(data->env, cmd->args, cmd->fd_out[0])); + else if (ft_strcmp(cmd->executable, "echo") == 0) + return_code = (echo(cmd->fd_out[0], cmd->args + 1)); + else + { + return_code = ft_exit(cmd->args + 1, *data->exit_code); + if (return_code >= 0) + { + *data->exit_code = return_code; + return (-2); + } + } + *data->exit_code = return_code; + return (return_code); +} + +static bool ft_executor(t_data *data, t_cmd *cmd, char **env) +{ + if (cmd->fd_in[0] == -1 || cmd->fd_out[0] == -1 || cmd->executable == NULL) + return (0); + cmd->pid = fork(); + if (cmd->pid == -1) + return (1); + if (cmd->pid == 0) + { + signal(SIGQUIT, SIG_DFL); + signal(SIGINT, SIG_DFL); + dup2(cmd->fd_in[0], 0); + dup2(cmd->fd_out[0], 1); + ft_lstiter(*data->cmds, ft_cmdcloser); + execve(cmd->executable, cmd->args, env); + return (1); + } + signal(SIGQUIT, SIG_IGN); + signal(SIGINT, SIG_IGN); + return (0); +} + +static int ft_cmd_executor(t_data *data, t_cmd *cmd) +{ + int exit_code; + char **env; + + if (cmd->own_cmd == 1) + { + exit_code = ft_execute_own_cmd(data, cmd); + ft_closer(cmd->fd_in); + ft_closer(cmd->fd_out); + if (exit_code == -2) + return (1); + } + else + { + env = env_to_strs(data->env); + if (env == NULL) + return (1); + exit_code = ft_executor(data, cmd, env); + ft_closer(cmd->fd_in); + ft_closer(cmd->fd_out); + ft_freer_tab_ultimate(1, env); + if (exit_code == 1) + return (1); + } + return (0); +} + +int ft_cmds_executor(t_data *data) +{ + int fds[2]; + t_list *current; + t_cmd *content; + + current = *data->cmds; + while (current != NULL) + { + content = current->content; + fds[0] = -1; + if (current->next != NULL) + { + if (pipe(fds) == -1) + return (1); + ft_add_fd(content->fd_out, fds[1]); + ft_add_fd(((t_cmd *)(current->next->content))->fd_in, fds[0]); + } + if (content->fd_in[0] == -2 || content->fd_out[0] == -2) + ft_mega_closer(content->fd_in, content->fd_out); + else if (ft_cmd_executor(data, content)) + return (1); + current = current->next; + } + return (0); +} diff --git a/execution/execution.h b/execution/execution.h new file mode 100644 index 0000000..822c59b --- /dev/null +++ b/execution/execution.h @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* execution.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet +# include "../signal/signal.h" +# include "../data/data.h" +# include "../libftx/libftx.h" +# include "../cmd/cmd.h" +# include "../env/env.h" +# include "../builtins/builtins.h" +# include "../utils/utils.h" + +#endif diff --git a/format/format.c b/format/format.c new file mode 100644 index 0000000..9d688d9 --- /dev/null +++ b/format/format.c @@ -0,0 +1,130 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* format.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet <|", out[i - 1])) + { + while (out[i] == out[i - 1]) + i++; + if (ft_replace(&out, i)) + return (NULL); + } + if (out[i] != '\0') + i++; + } + return (out); +} + +static char *ft_spacer_before(const char *str) +{ + char *out; + ssize_t i; + + out = ft_strdup(str); + if (out == NULL) + return (NULL); + i = -1; + while (out[++i] != '\0') + { + while (ft_is_in_quote(out, i + 1)) + i++; + if (out[i] == '\0') + break ; + if (ft_is_in("><|", out[i + 1])) + { + while (out[i] == ' ') + i++; + while (out[i] == out[i + 1]) + i++; + if (ft_replace(&out, i + 1)) + return (NULL); + } + } + return (out); +} + +static void ft_space_simplifier(char *str) +{ + size_t i; + size_t y; + + i = 0; + while (str[i] != '\0') + { + if (ft_is_in_quote(str, i)) + i++; + if (str[i] != '\0') + break ; + y = 0; + while (str[y + i] == ' ') + y++; + if (y > 1) + { + ft_strshift(str + i, -y + 1); + y--; + } + i++; + } +} + +char *ft_formater(t_data *data, const char *str) +{ + char *out; + char *temp; + + if (ft_str_is_empty(str)) + return (ft_strdup(" ")); + temp = ft_spacer_after(str); + if (temp == NULL) + return (NULL); + out = ft_spacer_before(temp); + free(temp); + if (out == NULL) + return (NULL); + ft_space_simplifier(out); + if (out[ft_strlen(out) - 1] == ' ') + out[ft_strlen(out) - 1] = '\0'; + temp = ft_env_filler(data, out); + free(out); + return (temp); +} diff --git a/format/format.h b/format/format.h new file mode 100644 index 0000000..022ec63 --- /dev/null +++ b/format/format.h @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* format.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet +# include +# include +# include +# include "../libft/libft.h" + +char *ft_ultoa_base(unsigned long long n, char *base); +char *get_next_line(int fd); +size_t ft_random_generator(size_t start, size_t stop); +void ft_freer_tab_ultimate(size_t len, ...); +void ft_freer_ultimate(size_t len, ...); +char *ft_strgen(char c, size_t len); +char *ft_strfjoin(char *s1, char *s2); +char *ft_strmerger(size_t arg_len, ...); +int ft_is_in(char *str, char c); +char **ft_tabrealloc(char **tab, size_t current_size, size_t new_size); +char *ft_strndup(const char *src, size_t n); +ssize_t ft_strchri(char *str, char c); +int ft_contain_only_str(char *str, char *to_find); +int ft_contain_only(char *str, char c); +int ft_strcmp(char *s1, char *s2); +void ft_swap(void *a, void *b); +void ft_swap_int(int *a, int *b); +void ft_swap_char(char *a, char *b); + +#endif diff --git a/libftx/extra/ft_contain_only.c b/libftx/extra/ft_contain_only.c new file mode 100644 index 0000000..4844e79 --- /dev/null +++ b/libftx/extra/ft_contain_only.c @@ -0,0 +1,41 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_contain_only.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet 2) + { + temp = ft_strjoin(out, va_arg(va, char *)); + free(out); + if (temp == NULL) + return (NULL); + out = temp; + arg_len--; + } + return (out); +} diff --git a/libftx/extra/ft_strndup.c b/libftx/extra/ft_strndup.c new file mode 100644 index 0000000..c289878 --- /dev/null +++ b/libftx/extra/ft_strndup.c @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strndup.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet +# include +# ifndef BUFFER_SIZE +# define BUFFER_SIZE 42 +# endif +# include "../libft/libft.h" +# include "../extra/extra.h" + +char *get_next_line(int fd); + +#endif diff --git a/libftx/libft/Makefile b/libftx/libft/Makefile new file mode 100644 index 0000000..0102a19 --- /dev/null +++ b/libftx/libft/Makefile @@ -0,0 +1,81 @@ +:# **************************************************************************** # +# # +# ::: :::::::: # +# Makefile :+: :+: :+: # +# +:+ +:+ +:+ # +# By: cchauvet = c && c >= '0') + || ('z' >= c && c >= 'a') + || ('Z' >= c && c >= 'A')) + return (1); + return (0); +} diff --git a/libftx/libft/ft_isalpha.c b/libftx/libft/ft_isalpha.c new file mode 100644 index 0000000..9573931 --- /dev/null +++ b/libftx/libft/ft_isalpha.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_isalpha.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet = c && c >= 'a') || ('Z' >= c && c >= 'A')) + return (1); + return (0); +} diff --git a/libftx/libft/ft_isascii.c b/libftx/libft/ft_isascii.c new file mode 100644 index 0000000..5706106 --- /dev/null +++ b/libftx/libft/ft_isascii.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_isascii.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet = 0 && 127 >= c) + return (1); + return (0); +} diff --git a/libftx/libft/ft_isdigit.c b/libftx/libft/ft_isdigit.c new file mode 100644 index 0000000..0db99f6 --- /dev/null +++ b/libftx/libft/ft_isdigit.c @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_isdigit.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet = c && c >= '0') + return (1); + return (0); +} diff --git a/libftx/libft/ft_isprint.c b/libftx/libft/ft_isprint.c new file mode 100644 index 0000000..fd6d523 --- /dev/null +++ b/libftx/libft/ft_isprint.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_isprint.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet next = new; +} diff --git a/libftx/libft/ft_lstadd_front.c b/libftx/libft/ft_lstadd_front.c new file mode 100644 index 0000000..b17cc46 --- /dev/null +++ b/libftx/libft/ft_lstadd_front.c @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstadd_front.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet next = *lst; + *lst = new; +} diff --git a/libftx/libft/ft_lstclear.c b/libftx/libft/ft_lstclear.c new file mode 100644 index 0000000..e29060a --- /dev/null +++ b/libftx/libft/ft_lstclear.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstclear.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet next; + ft_lstdelone(*lst, del); + *lst = next; + } +} diff --git a/libftx/libft/ft_lstdelone.c b/libftx/libft/ft_lstdelone.c new file mode 100644 index 0000000..73ac454 --- /dev/null +++ b/libftx/libft/ft_lstdelone.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstdelone.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet content != NULL) + del(lst->content); + free(lst); + } +} diff --git a/libftx/libft/ft_lstiter.c b/libftx/libft/ft_lstiter.c new file mode 100644 index 0000000..1baa94d --- /dev/null +++ b/libftx/libft/ft_lstiter.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstiter.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet content); + lst = lst->next; + } +} diff --git a/libftx/libft/ft_lstlast.c b/libftx/libft/ft_lstlast.c new file mode 100644 index 0000000..ba0d9d7 --- /dev/null +++ b/libftx/libft/ft_lstlast.c @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstlast.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet next != NULL) + lst = lst->next; + return (lst); +} diff --git a/libftx/libft/ft_lstmap.c b/libftx/libft/ft_lstmap.c new file mode 100644 index 0000000..ed99c7c --- /dev/null +++ b/libftx/libft/ft_lstmap.c @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstmap.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet content)); + if (root == NULL) + return (NULL); + last = root; + lst = lst->next; + while (lst != NULL) + { + last->next = ft_lstnew(f(lst->content)); + if (last->next == NULL) + { + ft_lstclear(&root, del); + return (NULL); + } + lst = lst->next; + last = last->next; + } + return (root); +} diff --git a/libftx/libft/ft_lstnew.c b/libftx/libft/ft_lstnew.c new file mode 100644 index 0000000..705733e --- /dev/null +++ b/libftx/libft/ft_lstnew.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstnew.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet next = NULL; + new->content = content; + return (new); +} diff --git a/libftx/libft/ft_lstsize.c b/libftx/libft/ft_lstsize.c new file mode 100644 index 0000000..fa39de9 --- /dev/null +++ b/libftx/libft/ft_lstsize.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lstsize.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet next; + } + return (count); +} diff --git a/libftx/libft/ft_memchr.c b/libftx/libft/ft_memchr.c new file mode 100644 index 0000000..28f3775 --- /dev/null +++ b/libftx/libft/ft_memchr.c @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_memchr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet 9) + { + ft_putnbr_fd(n / 10, fd); + ft_putnbr_fd(n % 10, fd); + } + else + ft_putchar_fd(n + 48, fd); +} diff --git a/libftx/libft/ft_putstr_fd.c b/libftx/libft/ft_putstr_fd.c new file mode 100644 index 0000000..d8c87d2 --- /dev/null +++ b/libftx/libft/ft_putstr_fd.c @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_putstr_fd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet = size) + return (ft_strlen(src) + (size)); + return (len_dest + ft_strlcpy(dest + len_dest, src, size - len_dest)); +} diff --git a/libftx/libft/ft_strlcpy.c b/libftx/libft/ft_strlcpy.c new file mode 100644 index 0000000..677264b --- /dev/null +++ b/libftx/libft/ft_strlcpy.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strlcpy.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet 0) + if (s[i] == (char) c) + return ((char *) s + i); + return (NULL); +} diff --git a/libftx/libft/ft_strtrim.c b/libftx/libft/ft_strtrim.c new file mode 100644 index 0000000..229cb81 --- /dev/null +++ b/libftx/libft/ft_strtrim.c @@ -0,0 +1,44 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strtrim.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet len) + size = len; + ptr = malloc((size + 1) * sizeof(char)); + if (ptr == NULL) + return (NULL); + ptr[size] = '\0'; + while (size-- > 0) + ptr[size] = s[start + size]; + return (ptr); +} diff --git a/libftx/libft/ft_tolower.c b/libftx/libft/ft_tolower.c new file mode 100644 index 0000000..14d83da --- /dev/null +++ b/libftx/libft/ft_tolower.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_tolower.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet = 'A' && 'Z' >= c)); +} diff --git a/libftx/libft/ft_toupper.c b/libftx/libft/ft_toupper.c new file mode 100644 index 0000000..3775f6d --- /dev/null +++ b/libftx/libft/ft_toupper.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_toupper.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet = 'a' && 'z' >= c)); +} diff --git a/libftx/libft/libft.h b/libftx/libft/libft.h new file mode 100644 index 0000000..be70f59 --- /dev/null +++ b/libftx/libft/libft.h @@ -0,0 +1,56 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* libft.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet +# include +# include "./list.h" + +void *ft_cancel(void **tab, size_t len); +int ft_atoi(const char *nptr); +void ft_bzero(void *s, size_t n); +void *ft_calloc(size_t nmemb, size_t size); +int ft_isalnum(int c); +int ft_isalpha(int c); +int ft_isascii(int c); +int ft_isdigit(int c); +int ft_isprint(int c); +void *ft_memchr(const void *s, int c, size_t n); +int ft_memcmp(const void *s1, const void *s2, size_t n); +void *ft_memcpy(void *dest, const void *src, size_t n); +void *ft_memmove(void *dest, const void *src, size_t n); +void *ft_memset(void *s, int c, size_t n); +char *ft_strchr(const char *s, int c); +char *ft_strdup(const char *s); +size_t ft_strlcat(char *dst, const char *src, size_t size); +size_t ft_strlcpy(char *dst, const char *src, size_t size); +size_t ft_strlen(const char *s); +int ft_strncmp(const char *s1, const char *s2, size_t n); +char *ft_strnstr(const char *big, const char *little, size_t len); +char *ft_strrchr(const char *s, int c); +int ft_tolower(int c); +int ft_toupper(int c); + +char *ft_substr(char const *s, unsigned int start, size_t len); +char *ft_strjoin(char const *s1, char const *s2); +char *ft_strtrim(char const *s1, char const *set); +char **ft_split(char const *s, char c); +char *ft_itoa(int n); +char *ft_strmapi(char const *s, char (*f)(unsigned int, char)); +void ft_striteri(char *s, void (*f)(unsigned int, char*)); +void ft_putchar_fd(char c, int fd); +void ft_putstr_fd(char *s, int fd); +void ft_putendl_fd(char *s, int fd); +void ft_putnbr_fd(int n, int fd); + +#endif diff --git a/libftx/libft/list.h b/libftx/libft/list.h new file mode 100644 index 0000000..1e09214 --- /dev/null +++ b/libftx/libft/list.h @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* list.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet +# include +# include +# include "./libft/libft.h" + +char *ft_ultoa_base(unsigned long long n, char *base); +int ft_printf(const char *format, ...); +int ft_eprintf(const char *format, ...); +int ft_dprintf(int fd, const char *format, ...); +int ft_dprintf(int fd, const char *format, ...); +char *get_next_line(int fd); +size_t ft_random_generator(size_t start, size_t stop); +void ft_freer_tab_ultimate(size_t len, ...); +void ft_freer_ultimate(size_t len, ...); +char *ft_strgen(char c, size_t len); +int ft_is_in(char *str, char c); +char **ft_tabrealloc(char **tab, size_t current_size, size_t new_size); +int ft_contain_only_str(char *str, char *to_find); +int ft_contain_only(char *str, char c); +char *ft_strfjoin(char *s1, char *s2); +char *ft_strmerger(size_t arg_len, ...); +int ft_strcmp(char *s1, char *s2); +ssize_t ft_strchri(char *str, char c); +char *ft_strndup(const char *src, size_t n); +void ft_swap(void *a, void *b); +void ft_swap_int(int *a, int *b); +void ft_swap_char(char *a, char *b); + +/* void *ft_cancel(void **tab, size_t len); */ +/* int ft_atoi(const char *nptr); */ +/* void ft_bzero(void *s, size_t n); */ +/* void *ft_calloc(size_t nmemb, size_t size); */ +/* int ft_isalnum(int c); */ +/* int ft_isalpha(int c); */ +/* int ft_isascii(int c); */ +/* int ft_isdigit(int c); */ +/* int ft_isprint(int c); */ +/* void *ft_memchr(const void *s, int c, size_t n); */ +/* int ft_memcmp(const void *s1, const void *s2, size_t n); */ +/* void *ft_memcpy(void *dest, const void *src, size_t n); */ +/* void *ft_memmove(void *dest, const void *src, size_t n); */ +/* void *ft_memset(void *s, int c, size_t n); */ +/* char *ft_strchr(const char *s, int c); */ +/* char *ft_strdup(const char *s); */ +/* size_t ft_strlcat(char *dst, const char *src, size_t size); */ +/* size_t ft_strlcpy(char *dst, const char *src, size_t size); */ +/* size_t ft_strlen(const char *s); */ +/* int ft_strncmp(const char *s1, const char *s2, size_t n); */ +/* char *ft_strnstr(const char *big, const char *little, size_t len); */ +/* char *ft_strrchr(const char *s, int c); */ +/* int ft_tolower(int c); */ +/* int ft_toupper(int c); */ + +/* char *ft_substr(char const *s, unsigned int start, size_t len); */ +/* char *ft_strjoin(char const *s1, char const *s2); */ +/* char *ft_strtrim(char const *s1, char const *set); */ +/* char **ft_split(char const *s, char c); */ +/* char *ft_itoa(int n); */ +/* char *ft_strmapi(char const *s, char (*f)(unsigned int, char)); */ +/* void ft_striteri(char *s, void (*f)(unsigned int, char*)); */ +/* void ft_putchar_fd(char c, int fd); */ +/* void ft_putstr_fd(char *s, int fd); */ +/* void ft_putendl_fd(char *s, int fd); */ +/* void ft_putnbr_fd(int n, int fd); */ + +#endif diff --git a/libftx/printf/Makefile b/libftx/printf/Makefile new file mode 100644 index 0000000..da6a158 --- /dev/null +++ b/libftx/printf/Makefile @@ -0,0 +1,39 @@ +# **************************************************************************** # +# # +# ::: :::::::: # +# Makefile :+: :+: :+: # +# +:+ +:+ +:+ # +# By: cchauvet base_size - 1) + { + ft_dprintul_base(fd, n / base_size, base); + ft_putchar_fd_p(fd, base[n % base_size]); + } + else + ft_putchar_fd_p(fd, base[n]); + return (str_size - 1); +} diff --git a/libftx/printf/ft_dprintx.c b/libftx/printf/ft_dprintx.c new file mode 100644 index 0000000..6d6de6e --- /dev/null +++ b/libftx/printf/ft_dprintx.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_dprintx.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet = '0') + return (1); + return (0); +} diff --git a/libftx/printf/ft_printf.c b/libftx/printf/ft_printf.c new file mode 100644 index 0000000..2ad2382 --- /dev/null +++ b/libftx/printf/ft_printf.c @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_printf.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet +# include + +size_t ft_strlen(const char *s); +char *ft_strchr(const char *s, int c); +int ft_isdigit(int c); +int ft_skipflag(const char *str); +int ft_isarg(int c); + +int ft_dprintptr(int fd, void *ptr); +int ft_dprintl_base(int fd, long long n, char *base); +int ft_dprintul_base(int fd, unsigned long long n, char *base); +int ft_dprintul(int fd, unsigned long long n); +int ft_dprintx(int fd, unsigned int n); +int ft_dprint_upperx(int fd, unsigned int n); +int ft_dprintflag(int fd, const char *flag, va_list va); +int ft_dprintarg(int fd, int c, va_list va); +int ft_dprintstrtab(int fd, char **tab); + +int ft_printf(const char *format, ...); +int ft_dprintf(int fd, const char *format, ...); +int ft_eprintf(const char *format, ...); + +int ft_vdprintf(int fd, const char *format, va_list va); + +int ft_putchar_fd_p(int fd, char c); +int ft_putstr_fd_p(int fd, char *str); + +#endif diff --git a/libftx/printf/ft_putchar_fd.c b/libftx/printf/ft_putchar_fd.c new file mode 100644 index 0000000..7604043 --- /dev/null +++ b/libftx/printf/ft_putchar_fd.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_putchar_fd.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet + +static char *ft_get_user_input(void) +{ + char *line; + char *prompt; + char *pwd; + + pwd = get_pwd(); + if (pwd == NULL) + return (NULL); + prompt = ft_strmerger(2, pwd, "$ "); + free(pwd); + if (prompt == NULL) + { + ft_eprintf("bozoshell: malloc failed\n"); + return (NULL); + } + line = readline(prompt); + if (line != NULL && ft_strcmp(line, "") != 0) + add_history(line); + free(prompt); + if (line == NULL) + ft_printf("exit\n"); + return (line); +} + +static int ft_minishell(t_data *data, char *line) +{ + char *line_clean; + + if (ft_syntax_verif(data, line)) + return (0); + line_clean = ft_formater(data, line); + if (line_clean == NULL || line_clean[0] == '\0') + return (0); + if (ft_cmds_parser(data, line_clean)) + { + free(line_clean); + return (0); + } + free(line_clean); + if (ft_cmds_executor(data) == 1) + return (1); + ft_lstiter(*data->cmds, ft_cmdwaiter); + ft_lstclear(data->cmds, ft_cmddel); + return (0); +} + +int ft_init_data(t_data *data, char **env) +{ + data->exit_code = ft_get_exit_code(); + data->cmds = malloc(sizeof(t_cmd *)); + if (data->cmds == NULL) + { + ft_eprintf("bozoshell: malloc failed\n"); + return (1); + } + *data->cmds = NULL; + data->env = init_env(env); + if (data->env == NULL) + { + ft_eprintf("bozoshell: malloc failed\n"); + free(data->cmds); + return (1); + } + return (0); +} + +int main(int ac, char **av, char **env) +{ + t_data data; + char *line; + + (void) ac; + (void) av; + signal(SIGINT, ft_ctrlc); + signal(SIGQUIT, SIG_IGN); + if (ft_init_data(&data, env)) + return (1); + line = ft_get_user_input(); + while (line != NULL) + { + if (ft_minishell(&data, line) == 1) + break ; + free(line); + line = ft_get_user_input(); + if (line == NULL) + break ; + } + ft_lstclear(data.cmds, ft_cmddel); + free(data.cmds); + ft_lstclear(data.env, env_del); + free(data.env); + return (*data.exit_code); +} diff --git a/parse/parse.c b/parse/parse.c new file mode 100644 index 0000000..a1242fe --- /dev/null +++ b/parse/parse.c @@ -0,0 +1,127 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parse.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet args = tab; + return (0); +} + +static int ft_executable_parse(t_data *data, t_cmd *cmd) +{ + bool own; + char *path; + + path = cmd->args[0]; + own = 0; + if (cmd->args[0] == NULL) + { + ft_closer(cmd->fd_in); + ft_closer(cmd->fd_out); + } + else if (ft_strcmp(cmd->args[0], "env") == 0 || (ft_strcmp(cmd->args[0], + "export") == 0) || (ft_strcmp(cmd->args[0], "echo") == 0) + || (ft_strcmp(cmd->args[0], "unset") == 0) || (ft_strcmp(cmd->args[0], + "exit") == 0) || (ft_strcmp(cmd->args[0], "pwd") == 0) + || (ft_strcmp(cmd->args[0], "cd") == 0)) + own = 1; + else + { + path = ft_get_executable(data, cmd->args[0]); + if (path == NULL) + return (1); + } + cmd->own_cmd = own; + cmd->executable = path; + return (0); +} + +int ft_cmd_adder(t_data *data, t_cmd *cmd) +{ + t_list *element; + + element = ft_lstnew(cmd); + if (element == NULL) + { + ft_cmddel(cmd); + return (1); + } + ft_lstadd_back(data->cmds, element); + return (0); +} + +int ft_cmd_parser(t_data *data, char *cmd_str) +{ + t_cmd *cmd; + + cmd = ft_calloc(sizeof(t_cmd), 1); + if (cmd == NULL) + { + ft_eprintf("bozoshell: malloc failed\n"); + return (1); + } + if (ft_redirection(data, cmd, cmd_str)) + { + ft_cmddel(cmd); + return (1); + } + if (ft_args_parse(cmd_str, cmd)) + { + ft_cmddel(cmd); + return (1); + } + ft_executable_parse(data, cmd); + return (ft_cmd_adder(data, cmd)); +} + +int ft_cmds_parser(t_data *data, const char *line) +{ + char **tab; + ssize_t i; + + tab = ft_split_charset_quoted(line, "|"); + if (tab == NULL) + { + ft_eprintf("bozoshell: malloc failed\n"); + return (1); + } + i = -1; + while (tab[++i] != NULL) + { + if (ft_cmd_parser(data, tab[i])) + { + ft_freer_tab_ultimate(1, tab); + return (1); + } + } + if (*data->cmds != NULL) + { + ft_add_fd(((t_cmd *)(*data->cmds)->content)->fd_in, 0); + ft_add_fd(((t_cmd *)(ft_lstlast(*data->cmds))->content)->fd_out, 1); + } + ft_freer_tab_ultimate(1, tab); + return (0); +} diff --git a/parse/parse.h b/parse/parse.h new file mode 100644 index 0000000..cdaa9d3 --- /dev/null +++ b/parse/parse.h @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parse.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet +#include "../signal/signal.h" +#include + +static bool ft_check_heredoc(t_data *data, t_cmd *cmd, + char *redirection_identifier, char *redirection) +{ + int fd; + + if (ft_strcmp(redirection_identifier, "<<") == 0) + { + if (cmd->fd_in[0] == -2) + return (0); + signal(SIGINT, ft_ctrlc_heredoc); + fd = ft_heredoc(data, redirection); + signal(SIGINT, ft_ctrlc); + if (fd == -2) + return (1); + else + { + if (cmd->fd_in[0] > 2) + close(cmd->fd_in[0]); + cmd->fd_in[0] = fd; + } + } + return (0); +} + +static bool ft_check_infile(t_data *data, t_cmd *cmd, + char *redirection_identifier, char *redirection) +{ + int fd; + + if (ft_strcmp(redirection_identifier, "<") == 0) + { + if (cmd->fd_in[0] == -2) + return (0); + if (ft_file_is_readable(data, redirection)) + { + fd = open(redirection, O_RDONLY); + if (cmd->fd_in[0] > 2) + close(cmd->fd_in[0]); + cmd->fd_in[0] = fd; + } + else + { + if (cmd->fd_in[0] > 2) + close(cmd->fd_in[0]); + cmd->fd_in[0] = -2; + return (0); + } + } + return (0); +} + +static bool ft_check_outfile(t_data *data, t_cmd *cmd, + char *redirection_identifier, char *redirection) +{ + int fd; + + if (ft_strcmp(redirection_identifier, ">") == 0) + { + if (cmd->fd_out[0] == -2) + return (0); + if (ft_file_is_writable(data, redirection)) + { + fd = open(redirection, + O_WRONLY | O_TRUNC | O_CREAT, 0644); + if (cmd->fd_out[0] > 2) + close(cmd->fd_out[0]); + cmd->fd_out[0] = fd; + } + else + { + if (cmd->fd_out[0] > 2) + close(cmd->fd_out[0]); + cmd->fd_out[0] = -2; + return (0); + } + } + return (0); +} + +static bool ft_check_outfile_append(t_data *data, t_cmd *cmd, + char *redirection_identifier, char *redirection) +{ + int fd; + + if (ft_strcmp(redirection_identifier, ">>") == 0) + { + if (cmd->fd_out[0] == -2) + return (0); + if (ft_file_is_appendable(data, redirection)) + { + fd = open(redirection, + O_WRONLY | O_APPEND | O_CREAT, 0644); + if (cmd->fd_out[0] > 2) + close(cmd->fd_out[0]); + cmd->fd_out[0] = fd; + } + else + { + if (cmd->fd_out[0] > 2) + close(cmd->fd_out[0]); + cmd->fd_out[0] = -2; + } + } + return (0); +} + +bool ft_check_redirection(t_data *data, t_cmd *cmd, + char *redirection_identifier, char *redirection) +{ + char *str; + bool out; + + if (ft_is_in("<>", redirection_identifier[0]) + && ft_is_in("<>", redirection[0])) + { + ft_eprintf("bozoshell: %s: invalid redirection file\n", redirection); + return (1); + } + str = ft_strdup(redirection); + if (str == NULL) + { + ft_eprintf("bozoshell: malloc failed\n"); + return (1); + } + ft_quote_remover(str); + out = 0; + if (ft_check_heredoc(data, cmd, redirection_identifier, str) + || ft_check_infile(data, cmd, redirection_identifier, str) + || ft_check_outfile(data, cmd, redirection_identifier, str) + || ft_check_outfile_append(data, cmd, redirection_identifier, str)) + out = 1; + free(str); + return (out); +} diff --git a/redirection/file.c b/redirection/file.c new file mode 100644 index 0000000..9a93bc4 --- /dev/null +++ b/redirection/file.c @@ -0,0 +1,82 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* file.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet exit_code = 1; + ft_eprintf("bozoshell: %s: No such file or directory\n", path); + return (0); + } + readable = read(fd, "", 0); + if (readable == -1) + { + *data->exit_code = 1; + ft_eprintf("bozoshell: %s: Permission denied\n", path); + return (0); + } + close(fd); + return (1); +} + +int ft_file_is_writable(t_data *data, const char *path) +{ + int writeable; + int fd; + + fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0644); + if (fd == -1) + { + *data->exit_code = 1; + ft_eprintf("bozoshell: %s: Permission denied\n", path); + return (0); + } + writeable = write(fd, "", 0); + if (writeable == -1) + { + *data->exit_code = 1; + ft_eprintf("bozoshell: %s: Permission denied\n", path); + return (0); + } + close(fd); + return (1); +} + +int ft_file_is_appendable(t_data *data, const char *path) +{ + int writeable; + int fd; + + fd = open(path, O_WRONLY | O_APPEND | O_CREAT, 0644); + if (fd == -1) + { + *data->exit_code = 1; + ft_eprintf("bozoshell: %s: Permission denied\n", path); + return (0); + } + writeable = write(fd, "", 0); + if (writeable == -1) + { + *data->exit_code = 1; + ft_eprintf("bozoshell: %s: Permission denied\n", path); + return (0); + } + close(fd); + return (1); +} diff --git a/redirection/heredoc.c b/redirection/heredoc.c new file mode 100644 index 0000000..7b9fbef --- /dev/null +++ b/redirection/heredoc.c @@ -0,0 +1,93 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* heredoc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet +#include + +static bool ft_fd_is_closed(int fd) +{ + int fd2; + + fd2 = dup(fd); + if (fd2 == -1) + return (1); + close(fd2); + return (0); +} + +static int ft_format_and_write(t_data *data, const char *str, int fd) +{ + char *line_clean; + + line_clean = ft_env_filler(data, str); + if (line_clean == NULL) + return (1); + ft_putendl_fd(line_clean, fd); + free(line_clean); + return (0); +} + +int ft_heredoc2(t_data *data, char *line, char *stop, int fds[2]) +{ + if (line == NULL) + { + if (ft_fd_is_closed(0)) + { + close(fds[0]); + fds[0] = -2; + return (1); + } + else + { + ft_eprintf("\nbozoshell: warning: here-document at line 1%s", + "delimited by end-of-file (wanted `adfsd')\n"); + return (1); + } + } + if (ft_strcmp(line, stop) == 0) + return (1); + if (ft_format_and_write(data, line, fds[1])) + { + close(fds[0]); + fds[0] = -2; + return (1); + } + return (0); +} + +int ft_heredoc(t_data *data, char *stop) +{ + int fds[2]; + int stdin_bak; + char *line; + + stdin_bak = dup(0); + if (stdin_bak == -1) + return (1); + if (pipe(fds)) + { + close(stdin_bak); + return (1); + } + line = readline("> "); + while (ft_heredoc2(data, line, stop, fds) == 0) + { + free(line); + line = readline("> "); + } + free(line); + close(fds[1]); + dup2(stdin_bak, 0); + close(stdin_bak); + return (fds[0]); +} diff --git a/redirection/redirection.c b/redirection/redirection.c new file mode 100644 index 0000000..279e0af --- /dev/null +++ b/redirection/redirection.c @@ -0,0 +1,115 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redirection.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet ", tab[i][0])) + { + i++; + redirection = ft_env_filler(data, tab[i]); + if (redirection == NULL) + return (1); + free(tab[i]); + tab[i] = redirection; + ft_quote_remover(tab[i]); + } + i++; + } + return (0); +} + +static void ft_skip(char *str, size_t *i, ssize_t *start) +{ + while (str[*i] == str[*start]) + (*i)++; + while (str[*i] == ' ') + (*i)++; + while (str[*i] != '\0' && (str[*i] != ' ' + || ft_is_in_quote(str, *i))) + (*i)++; +} + +static void ft_remove_redirection(char *cmd_str) +{ + size_t i; + ssize_t start; + + i = 0; + while (cmd_str[i] != '\0') + { + start = -1; + while ((ft_is_in_quote(cmd_str, i) || !ft_is_in("<>", cmd_str[i])) + && cmd_str[i] != '\0') + i++; + if (ft_is_in("<>", cmd_str[i])) + start = i; + else + continue ; + ft_skip(cmd_str, &i, &start); + if (start != -1) + { + ft_strshift(cmd_str + start, -1 * (i - start)); + i = start; + } + } +} + +int ft_set_redirection(t_data *data, t_cmd *cmd, char **tab) +{ + size_t i; + + i = 0; + while (tab[i + 1] != NULL) + { + if (ft_check_redirection(data, cmd, tab[i], tab[i + 1])) + return (1); + i++; + } + if (ft_is_in("<>", tab[i][0])) + { + ft_eprintf("bozoshell: %s: must be followed by a file\n", tab[i]); + return (1); + } + return (0); +} + +int ft_redirection(t_data *data, t_cmd *cmd, char *cmd_str) +{ + char **tab; + + cmd->fd_in[0] = -1; + cmd->fd_in[1] = -1; + cmd->fd_out[0] = -1; + cmd->fd_out[1] = -1; + tab = ft_split_charset_quoted(cmd_str, " \t"); + if (tab == NULL) + { + ft_eprintf("bozoshell: malloc failed\n"); + return (1); + } + ft_remove_redirection(cmd_str); + if (ft_set_redirection(data, cmd, tab)) + { + ft_freer_tab_ultimate(1, tab); + return (1); + } + ft_freer_tab_ultimate(1, tab); + return (0); +} diff --git a/redirection/redirection.h b/redirection/redirection.h new file mode 100644 index 0000000..c745c90 --- /dev/null +++ b/redirection/redirection.h @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redirection.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet +# include +# include +# include +# include "../libftx/libftx.h" +# include "../data/data.h" +# include "../env/env.h" +# include "../utils/utils.h" +# include "../cmd/cmd.h" + +int ft_file_is_readable(t_data *data, const char *path); +int ft_file_is_writable(t_data *data, const char *path); +bool ft_check_redirection(t_data *data, t_cmd *cmd, + char *redirection_identifier, char *redirection); +int ft_file_is_appendable(t_data *data, const char *path); +int ft_heredoc(t_data *data, char *stop); + +#endif diff --git a/signal/signal.c b/signal/signal.c new file mode 100644 index 0000000..2aff3fa --- /dev/null +++ b/signal/signal.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* signal.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet +# include +# include +# include +# include "../libftx/libftx.h" +# include "../data/data.h" +# include "../redirection/redirection.h" +#endif diff --git a/syntax/syntax.c b/syntax/syntax.c new file mode 100644 index 0000000..f8e88ad --- /dev/null +++ b/syntax/syntax.c @@ -0,0 +1,106 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* syntax.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet ", str[i])) + { + y = 0; + while (str[i] == str[i + y]) + y++; + if ((y > 2 && (str[i] == '>' || str[i] == '<')) + || (y > 1 && str[i] == '|')) + { + ft_eprintf("bozoshell: too many %s in a row\n", str); + return (1); + } + i = i + y; + } + else if (str[i] != '\0') + i++; + } + return (0); +} + +static int ft_empty_verif(const char *str) +{ + size_t i; + + i = 0; + while (str[i] == ' ' || str[i] == '\t') + i++; + return (str[i] == '\0'); +} + +int ft_syntax_verif(t_data *data, const char *str) +{ + if (ft_empty_verif(str)) + return (1); + if (ft_quote_verif(str) + || ft_pipe_is_alone(str) + || ft_special_char_dub(str)) + { + *data->exit_code = 2; + return (1); + } + return (0); +} diff --git a/syntax/syntax.h b/syntax/syntax.h new file mode 100644 index 0000000..5b064ac --- /dev/null +++ b/syntax/syntax.h @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* syntax.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet + +void ft_closer(int fds[2]) +{ + if (fds[0] > 2) + { + close(fds[0]); + } + if (fds[1] > 2) + { + close(fds[1]); + } +} + +void ft_mega_closer(int fds1[2], int fds2[2]) +{ + ft_closer(fds1); + ft_closer(fds2); +} + +void ft_add_fd(int fds[2], int fd) +{ + if (fds[0] == -1) + fds[0] = fd; + else + fds[1] = fd; +} diff --git a/utils/ft_atoi_check.c b/utils/ft_atoi_check.c new file mode 100644 index 0000000..db21024 --- /dev/null +++ b/utils/ft_atoi_check.c @@ -0,0 +1,50 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_atoi_check.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: erey-bet +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2022/07/21 08:21:05 by erey-bet #+# #+# */ +/* Updated: 2023/04/04 13:40:43 by erey-bet ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "utils.h" + +static int ft_isspace(char c) +{ + if (c == ' ' || c == '\f' + ||c == '\n' || c == '\r' || c == '\t' || c == '\v') + return (1); + return (0); +} + +int ft_atoi_check(const char *nptr) +{ + int64_t result; + int sign; + + while (ft_isspace(*nptr)) + nptr++; + sign = 1; + if (*nptr == '+' || *nptr == '-') + { + if (*nptr == '-') + sign = -1; + nptr++; + } + result = 0; + while (*nptr >= '0' && *nptr <= '9') + { + result = result * 10 + (*nptr++ - '0') * sign; + if ((result < 0 && sign == 1) + || (result > 0 && sign == -1)) + return (2); + } + if (*nptr--) + return (1); + if (*nptr == '-' || *nptr == '+') + return (1); + return (0); +} diff --git a/utils/ft_change_exit_code.c b/utils/ft_change_exit_code.c new file mode 100644 index 0000000..a209856 --- /dev/null +++ b/utils/ft_change_exit_code.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_change_exit_code.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet exit_code = new_value; + exit_code_str = ft_itoa(new_value); + if (exit_code_str == NULL) + { + ft_eprintf("bozoshell: malloc failed\n"); + return (1); + } + return (0); +} diff --git a/utils/ft_get_executable.c b/utils/ft_get_executable.c new file mode 100644 index 0000000..3878d41 --- /dev/null +++ b/utils/ft_get_executable.c @@ -0,0 +1,115 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_get_executable.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet + +char *ft_get_executable_with_path(t_data *data, const char *name) +{ + char *path; + + if (access(name, F_OK) != 0) + { + *data->exit_code = 127; + ft_eprintf("bozoshell: %s: No such file or directery\n", name); + return (NULL); + } + if (access(name, X_OK) != 0) + { + *data->exit_code = 126; + ft_eprintf("bozoshell: %s: permission denied\n", name); + return (NULL); + } + path = ft_strdup(name); + if (path == NULL) + { + ft_eprintf("bozoshell: malloc failed\n"); + return (NULL); + } + return (path); +} + +static char **ft_get_paths(t_data *data, const char *name) +{ + char *paths; + char **tab; + + paths = get_value_by_key("PATH", data->env); + if (paths == NULL) + { + *data->exit_code = 127; + ft_eprintf("bozoshell: %s: command not found\n", name); + return (NULL); + } + tab = ft_split(paths, ':'); + if (tab == NULL) + { + ft_eprintf("bozoshell: malloc failed\n"); + return (NULL); + } + return (tab); +} + +static char *ft_file_is_executable(const char *path, const char *name) +{ + char *out; + + out = ft_strmerger(3, path, "/", name); + if (out == NULL) + { + ft_eprintf("bozoshell: malloc failed\n"); + free(out); + return (NULL); + } + if (access(out, X_OK) == 0) + return (out); + free(out); + return (NULL); +} + +static char *ft_get_executable_without_path(t_data *data, const char *name) +{ + char **paths; + char *path; + size_t i; + + paths = ft_get_paths(data, name); + if (paths == NULL) + return (NULL); + path = NULL; + i = 0; + while (paths[i] != NULL) + { + path = ft_file_is_executable(paths[i], name); + if (path != NULL) + break ; + i++; + } + ft_freer_tab_ultimate(1, paths); + if (path == NULL) + { + *data->exit_code = 127; + ft_eprintf("bozoshell: %s: command not found\n", name); + } + return (path); +} + +char *ft_get_executable(t_data *data, const char *name) +{ + char *path; + + if (name[0] == '.' || name[0] == '/') + path = ft_get_executable_with_path(data, name); + else + path = ft_get_executable_without_path(data, name); + return (path); +} diff --git a/utils/ft_is_in_quote.c b/utils/ft_is_in_quote.c new file mode 100644 index 0000000..795f29e --- /dev/null +++ b/utils/ft_is_in_quote.c @@ -0,0 +1,40 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_is_in_quote.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/04/11 14:50:26 by erey-bet #+# #+# */ +/* Updated: 2023/04/14 15:53:49 by erey-bet ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "utils.h" + +int new_strs(char ***strs, const char *to_split, int *i, int *j) +{ + if (ft_strlen((*strs)[(*i)]) <= 0) + return (0); + (*i)++; + (*j) = 0; + (*strs)[(*i)] = ft_calloc(sizeof(char), + (ft_strlen(to_split) + 1)); + if (!(*strs)[(*i)]) + return (1); + return (0); +} + +int get_strs(const char *to_split, const char *charset, char ***strs, int *i) +{ + int j; + int x; + int y; + int check; + + x = -1; + j = 0; + while (to_split[++x]) + { + y = -1; + check = 1; + while (charset[++y]) + { + if (to_split[x] == charset[y] && !ft_is_in_quote(to_split, x)) + { + check = 0; + if (new_strs(strs, to_split, i, &j)) + return (1); + } + } + if (check) + (*strs)[(*i)][j++] = to_split[x]; + } + return (0); +} + +void free_set_null(char ***strs, int i) +{ + if (ft_strlen((*strs)[i]) == 0) + { + free((*strs)[i]); + (*strs)[i] = NULL; + } +} + +char **ft_split_charset_quoted(const char *to_split, const char *charset) +{ + char **strs; + int i; + + strs = ft_calloc(sizeof(char *), (ft_strlen(to_split) + 1)); + if (!strs) + return (NULL); + i = 0; + strs[0] = ft_calloc(sizeof(char), (ft_strlen(to_split) + 1)); + if (!strs[0]) + { + free(strs); + return (NULL); + } + if (get_strs(to_split, charset, &strs, &i)) + { + i = -1; + while (strs[++i]) + free(strs[i]); + free(strs); + return (NULL); + } + free_set_null(&strs, i); + return (strs); +} diff --git a/utils/ft_str_is_empty.c b/utils/ft_str_is_empty.c new file mode 100644 index 0000000..f647b75 --- /dev/null +++ b/utils/ft_str_is_empty.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_str_is_empty.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet 0) + return ; + else + { + i = 0; + while (str[i - shift - 1] != '\0') + { + str[i] = str[i - shift]; + i++; + } + } +} diff --git a/utils/utils.h b/utils/utils.h new file mode 100644 index 0000000..88088b0 --- /dev/null +++ b/utils/utils.h @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* utils.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cchauvet +# include "../libftx/libftx.h" +# include "../data/data.h" +# include "../env/env.h" + +size_t ft_strncpy(char *dst, const char *src, size_t n); +int ft_is_in_quote(const char *str, size_t n); +char *ft_strreplace(const char *str, const char *fill, + size_t start, size_t stop); +ssize_t ft_strnchr(const char *str, char c); +char *ft_getstr(const char *str, size_t n); +int ft_str_is_empty(const char *str); +char **ft_split_charset_quoted(const char *s, const char *charset); +void ft_strshift(char *str, int shift); +char *ft_quote_remover(char *str); +int ft_atoi_check(const char *nptr); +char *ft_get_executable(t_data *data, const char *name); +void ft_closer(int fds[2]); +void ft_mega_closer(int fds1[2], int fds2[2]); +void ft_add_fd(int fds[2], int fd); + +#endif