This commit is contained in:
2024-02-16 21:53:38 +01:00
parent 2a2ef1d63c
commit 79f99ce489
14 changed files with 29 additions and 46 deletions

36
srcs/debug.c Normal file
View File

@ -0,0 +1,36 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* debug.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/15 14:16:47 by tomoron #+# #+# */
/* Updated: 2024/02/16 16:34:53 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
void print_parsed_cmd(t_cmd *cmd)
{
while (cmd)
{
printf("[");
if (cmd->type == ARG)
printf("ARG : %s", cmd->token);
else if (cmd->type == PIPE)
printf("PIPE");
else if (cmd->type == RED_O)
printf("RED_O");
else if (cmd->type == RED_O_APP)
printf("RED_O_APP");
else if(cmd->type == RED_I)
printf("RED_I");
else if(cmd->type == HERE_DOC)
printf("HERE_DOC");
printf("] ");
cmd = cmd->next;
}
printf("\n");
}

35
srcs/echo.c Executable file
View File

@ -0,0 +1,35 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* echo.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/07 15:30:37 by tomoron #+# #+# */
/* Updated: 2024/02/14 12:36:02 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int echo(t_cmd *args)
{
int put_nl;
put_nl = 1;
while (args && !strcmp(args->token, "-n"))
{
put_nl = 0;
args = args->next;
}
while (args && args->type == ARG)
{
ft_putstr_fd(args->token, STDOUT_FILENO);
if (args->next)
ft_putchar_fd(' ', STDOUT_FILENO);
args = args->next;
}
if (put_nl)
ft_putchar_fd('\n', STDOUT_FILENO);
return (0);
}

45
srcs/env_to_char_tab.c Normal file
View File

@ -0,0 +1,45 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* env_to_char_tab.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/16 13:30:18 by tomoron #+# #+# */
/* Updated: 2024/02/16 15:08:53 by marde-vr ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int get_env_len(t_env *env)
{
int res;
res = 0;
while (env)
{
res++;
env = env->next;
}
return (res);
}
char **env_to_char_tab(t_env *env)
{
char **res;
int i;
char *tmp;
res = ft_calloc(get_env_len(env) + 1, sizeof(char *));
i = 0;
while (res && env)
{
tmp = ft_strjoin(env->name, "=");
tmp = ft_strjoin_free(tmp, env->value, 1);
res[i] = tmp;
i++;
env = env->next;
}
return (res);
}

172
srcs/exec.c Executable file
View File

@ -0,0 +1,172 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* exec.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/07 14:12:49 by tomoron #+# #+# */
/* Updated: 2024/02/16 21:52:02 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int exec_builtin(t_cmd *parsed_cmd, t_env *env)
{
if (!ft_strcmp(parsed_cmd->token, "echo"))
g_return_code = echo(parsed_cmd->next);
else if (!ft_strcmp(parsed_cmd->token, "ret"))
g_return_code = ft_atoi(parsed_cmd->next->token);
else if (!ft_strcmp(parsed_cmd->token, "env"))
g_return_code = print_env(env);
else if (!ft_strcmp(parsed_cmd->token, "exit"))
exit_bt(parsed_cmd, env);
else if (!ft_strcmp(parsed_cmd->token, "pwd"))
g_return_code = pwd();
else
return (STDIN_FILENO);
return (STDOUT_FILENO);
}
void ft_exit(t_cmd *parsed_cmd, t_env *env, int exit_code)
{
free_cmd(parsed_cmd);
free_env(env);
exit(exit_code);
}
int get_args_count(t_cmd *parsed_cmd)
{
int count;
t_cmd *cur_cmd;
count = 0;
cur_cmd = parsed_cmd;
while (cur_cmd->next != 0 && cur_cmd->type == ARG)
{
cur_cmd = cur_cmd->next;
count++;
}
if (cur_cmd->type == ARG)
count++;
return (count);
}
char **split_paths_from_env(t_env *env)
{
t_env *cur_env_var;
int path_in_envp;
path_in_envp = 0;
cur_env_var = env;
while (cur_env_var->next != 0)
{
if (!ft_strcmp(cur_env_var->name, "PATH"))
{
path_in_envp = 1;
break ;
}
cur_env_var = cur_env_var->next;
}
if (!path_in_envp)
{
ft_printf_fd(2, "pipex: error: PATH not found\n");
return (0);
}
return (ft_split(cur_env_var->value, ':'));
}
void find_cmd_path(t_cmd *cmd, t_env *env, char **paths, int *found)
{
char *tmp;
char *path;
int i;
i = 0;
while (paths[i])
{
path = paths[i];
tmp = ft_strjoin(path, "/");
if (!tmp)
ft_exit(cmd, env, 1);
path = ft_strjoin(tmp, cmd->token);
if (!path)
ft_exit(cmd, env, 1);
free(tmp);
if (access(path, X_OK) != -1)
{
*found = 1;
free(cmd->token);
cmd->token = path;
break ;
}
free(path);
i++;
}
}
void get_cmd_path(t_cmd *cmd, t_env *env)
{
char **paths;
int found;
found = 0;
if (ft_strchr(cmd->token, '/') && access(cmd->token, X_OK) != -1)
found = 1;
else
{
paths = split_paths_from_env(env);
if (!paths)
ft_exit(cmd, env, 1);
find_cmd_path(cmd, env, paths, &found);
}
if (!found)
{
ft_printf_fd(2, "%s: command not found\n", cmd->token);
free(cmd->token);
cmd->token = 0;
}
}
void exec_command(t_cmd *parsed_cmd, t_env *env)
{
t_cmd *cur_cmd;
int args_count;
char **cmd_args;
int i;
if (!parsed_cmd || exec_builtin(parsed_cmd, env))
return ;
cur_cmd = parsed_cmd;
args_count = get_args_count(parsed_cmd);
cmd_args = calloc(args_count, sizeof(char *));
if (!cmd_args)
ft_exit(parsed_cmd, env, 1);
i = 0;
get_cmd_path(parsed_cmd, env);
while (i < args_count)
{
cmd_args[i] = cur_cmd->token;
cur_cmd = cur_cmd->next;
i++;
}
cmd_args[i] = 0;
pid_t pid;
pid = fork();
if (pid == -1)
{
perror("fork");
ft_exit(parsed_cmd, env, 1);
}
if (pid == 0)
execve(parsed_cmd->token, cmd_args, env_to_char_tab(env));
else
rl_redisplay();
if (waitpid(pid, 0, 0) < 0)
ft_exit(parsed_cmd, env, 1);
//if (cur_cmd->type == PIPE)
// exec_command(cur_cmd->next, env);
}

47
srcs/exit.c Executable file
View File

@ -0,0 +1,47 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* exit.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/07 16:04:11 by tomoron #+# #+# */
/* Updated: 2024/02/16 13:07:01 by marde-vr ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
void print_numeric_arg_err(char *arg)
{
ft_putstr_fd("minishell: exit: ", 2);
ft_putstr_fd(arg, 2);
ft_putstr_fd(": numeric argument required\n", 2);
}
void exit_bt(t_cmd *args, t_env *env)
{
t_cmd *start;
int exit_code;
start = args;
args = args->next;
ft_printf("exit\n");
if (args && args->next && args->next->type == ARG
&& ft_strisnbr(args->token))
ft_putstr_fd("minishell: exit: too many arguments\n", 2);
else
{
if (args && args->type == ARG && !ft_strisnbr(args->token))
print_numeric_arg_err(args->token);
if (args && args->type == ARG)
exit_code = (unsigned char)ft_atoi(args->token);
else if (args && args->type == ARG && !ft_strisnbr(args->token))
exit_code = 2;
else
exit_code = g_return_code;
free_cmd(start);
free_env(env);
exit(exit_code);
}
}

41
srcs/lst_cmd.c Executable file
View File

@ -0,0 +1,41 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* lst_cmd.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/06 20:46:19 by tomoron #+# #+# */
/* Updated: 2024/02/13 16:13:01 by marde-vr ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
t_cmd *cmd_add_back(t_cmd *cmd, char *token, t_token_type type)
{
t_cmd *res;
t_cmd *current;
res = ft_calloc(1, sizeof(t_cmd));
if (!res)
return (cmd);
res->token = token;
res->type = type;
if (!cmd)
return (res);
current = cmd;
while (current->next)
current = current->next;
current->next = res;
return (cmd);
}
void free_cmd(t_cmd *cmd)
{
if (cmd && cmd->next)
free_cmd(cmd->next);
if (cmd)
free(cmd->token);
free(cmd);
}

77
srcs/lst_env.c Executable file
View File

@ -0,0 +1,77 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* lst_env.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/06 20:46:19 by tomoron #+# #+# */
/* Updated: 2024/02/13 16:21:41 by marde-vr ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
t_env *env_add_back(t_env *env, char *name, char *value)
{
t_env *res;
t_env *current;
res = ft_calloc(1, sizeof(t_env));
if (!res)
return (env);
res->name = name;
res->value = value;
if (!env)
return (res);
current = env;
while (current->next)
current = current->next;
current->next = res;
return (env);
}
void free_env(t_env *env)
{
if (env && env->next)
free_env(env->next);
if (env)
{
free(env->name);
free(env->value);
}
free(env);
}
int print_env(t_env *env)
{
while (env)
{
ft_printf("%s=%s\n", env->name, env->value);
env = env->next;
}
return (0);
}
char *ft_get_env(t_env *env, char *name)
{
while (env)
{
if (!ft_strcmp(env->name, name))
return (env->value);
env = env->next;
}
return (0);
}
int get_var_name_len(char *command)
{
int res;
res = 0;
if (command[res] == '?')
return (1);
while (ft_isalnum(command[res]) || command[res] == '_')
res++;
return (res);
}

93
srcs/main.c Executable file
View File

@ -0,0 +1,93 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* main.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/02 21:59:20 by tomoron #+# #+# */
/* Updated: 2024/02/16 21:29:05 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int g_return_code = 0;
char *get_prompt(void)
{
char *res;
char cwd_buffer[100];
res = ft_strjoin_free("\001", ft_get_color(10, 255, 80), 2);
res = ft_strjoin_free(res, "\002", 1);
res = ft_strjoin_free(res, getenv("USER"), 1);
res = ft_strjoin_free(res, "@", 1);
res = ft_strjoin_free(res, "minishell\001\033[0m\002:\001", 1);
res = ft_strjoin_free(res, ft_get_color(80, 80, 255), 3);
res = ft_strjoin_free(res, "\002", 1);
res = ft_strjoin_free(res, getcwd(cwd_buffer, 99), 1);
res = ft_strjoin_free(res, "\001\033[0m\002$ ", 1);
return (res);
}
t_env *get_env(char **envp)
{
t_env *env;
char *name;
char *value;
int i;
int j;
env = 0;
while (*envp)
{
i = 0;
j = 0;
while ((*envp)[i] && (*envp)[i] != '=')
i++;
while ((*envp)[i + 1 + j])
j++;
name = ft_substr(*envp, 0, i);
value = ft_substr(*envp, i + 1, j);
env = env_add_back(env, name, value);
if (!name || !value)
free_env(env);
if (!name || !value)
return (0);
envp++;
}
return (env);
}
int main(int argc, char **argv, char **envp)
{
char *command;
t_cmd *parsed_cmd;
t_env *env;
char *prompt;
command = (char *)STDOUT_FILENO;
(void)argc;
(void)argv;
env = get_env(envp);
if (env)
handle_minishellrc(env);
while (env && command)
{
prompt = get_prompt();
if (!prompt)
exit(STDIN_FILENO);
command = readline(prompt);
free(prompt);
add_history(command);
parsed_cmd = parse_command(command, env);
free(command);
//print_parsed_cmd(parsed_cmd);//debug
exec_command(parsed_cmd, env);
free_cmd(parsed_cmd);
}
rl_clear_history();
free_env(env);
return (g_return_code);
}

70
srcs/minishell.h Executable file
View File

@ -0,0 +1,70 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* minishell.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/04 17:31:38 by tomoron #+# #+# */
/* Updated: 2024/02/16 21:51:37 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef MINISHELL_H
# define MINISHELL_H
# include <readline/readline.h>
# include <readline/history.h>
# include <limits.h>
# include <stdio.h>//debug
# include <sys/wait.h>
# include "../libft/libft.h"
# include "fcntl.h"
typedef enum e_token_type
{
ARG,
PIPE,
RED_O,
RED_O_APP,
RED_I,
HERE_DOC,
} t_token_type;
typedef struct s_cmd
{
t_token_type type;
char *token;
struct s_cmd *next;
} t_cmd;
typedef struct s_env
{
char *name;
char *value;
struct s_env *next;
} t_env;
extern int g_return_code;
t_cmd *cmd_add_back(t_cmd *res, char *token, t_token_type type);
void free_cmd(t_cmd *cmd);
void exec_command(t_cmd *cmd, t_env *env);
int echo(t_cmd *args);
void exit_bt(t_cmd *args, t_env *env);
t_env *env_add_back(t_env *env, char *name, char *value);
void free_env(t_env *env);
int print_env(t_env *env);
t_cmd *parse_command(char *command, t_env *env);
int get_token_len(char *cmd, t_env *env);
int add_var_to_str(char *res, char **command, t_env *env);
int get_var_name_len(char *command);
char *ft_get_env(t_env *env, char *var_name);
int pwd(void);
int is_cmd_char(char c);
void print_parsed_cmd(t_cmd *cmd);//debug
void ft_exit(t_cmd *cmd, t_env *env, int error_code);
char **env_to_char_tab(t_env *env);
void handle_minishellrc(t_env *env);
#endif

46
srcs/minishellrc.c Normal file
View File

@ -0,0 +1,46 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* minishellrc.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/16 17:40:16 by marde-vr #+# #+# */
/* Updated: 2024/02/16 18:25:56 by marde-vr ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
void handle_minishellrc(t_env *env)
{
char *home;
char *rc_path;
int fd;
char *line;
t_cmd *parsed_cmd;
home = ft_get_env(env, "HOME");
rc_path = ft_strjoin(home, "/.minishellrc");
if (access(rc_path, R_OK) != -1)
{
fd = open(rc_path, O_RDONLY);
if (fd == -1)
{
free(env);
perror("open");
return ;
}
line = get_next_line(fd);
while (line)
{
parsed_cmd = parse_command(line, env);
exec_command(parsed_cmd, env);
free(parsed_cmd);
free(line);
line = get_next_line(fd);
}
close(fd);
}
free(rc_path);
}

101
srcs/parsing.c Executable file
View File

@ -0,0 +1,101 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* parsing.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/09 15:26:01 by tomoron #+# #+# */
/* Updated: 2024/02/16 16:34:13 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int is_cmd_char(char c)
{
return (!ft_isspace(c) && c != '|' && c != '&' && c != '<' && c != '>');
}
char *get_token(char **cmd, int *in_quote, int *in_dquote, t_env *env)
{
char *res;
int i;
i = 0;
while (ft_isspace(**cmd))
(*cmd)++;
res = ft_calloc(get_token_len(*cmd, env) + 1, 1);
while (res && **cmd && (is_cmd_char(**cmd) || *in_quote || *in_dquote))
{
if (**cmd == '"' && !*in_quote)
*in_dquote = !*in_dquote;
if (**cmd == '\'' && !*in_dquote)
*in_quote = !*in_quote;
if (**cmd == '$' && !*in_quote)
{
(*cmd) += EXIT_FAILURE;
i += add_var_to_str(res + i, cmd, env);
}
else if (((**cmd == '\'' && *in_dquote) || (**cmd == '"' && *in_quote))
|| (**cmd != '\'' && **cmd != '"'))
res[i++] = **cmd;
(*cmd)++;
}
return (res);
}
t_token_type get_token_type(char **command)
{
t_token_type res;
while (ft_isspace(**command))
(*command)++;
if ((*command)[0] == '>' && (*command)[1] == '>')
res = RED_O_APP;
else if ((*command)[0] == '<' && (*command)[1] == '<')
res = HERE_DOC;
else if ((*command)[0] == '>')
res = RED_O;
else if ((*command)[0] == '<')
res = RED_I;
else if ((*command)[0] == '|')
res = PIPE;
else
res = ARG;
if (res == RED_O_APP || res == HERE_DOC)
(*command) += 2;
if (res == RED_O || res == RED_I || res == PIPE)
(*command)++;
return (res);
}
t_cmd *parse_command(char *command, t_env *env)
{
int in_quote;
int in_dquote;
t_cmd *res;
char *token;
t_token_type type;
in_quote = EXIT_SUCCESS;
in_dquote = STDIN_FILENO;
res = 0;
while (command && *command)
{
type = get_token_type(&command);
if (type == ARG)
token = get_token(&command, &in_quote, &in_dquote, env);
else
token = 0;
res = cmd_add_back(res, token, type);
while (ft_isspace(*command))
command++;
}
if (command && (in_quote || in_dquote))
{
free_cmd(res);
ft_putstr_fd("minishell: syntax error\n", 2);
return (0);
}
return (res);
}

112
srcs/parsing_var.c Executable file
View File

@ -0,0 +1,112 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* parsing_var.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/09 15:24:36 by tomoron #+# #+# */
/* Updated: 2024/02/13 16:25:37 by marde-vr ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
char *get_var_name(char *command)
{
char *res;
int len;
len = get_var_name_len(command);
res = ft_substr(command, 0, len);
return (res);
}
int get_var_len(char **command, t_env *env)
{
char *var_name;
char *env_var;
(*command)++;
if (!ft_isalnum(**command) && **command != '_' && **command != '?')
return (2);
if (**command == '?')
return (get_number_len(g_return_code));
var_name = get_var_name(*command);
env_var = ft_get_env(env, var_name);
free(var_name);
if (!env_var)
return (0);
*command += get_var_name_len(*command) - 1;
return (ft_strlen(env_var));
}
int get_token_len(char *command, t_env *env)
{
int in_quote;
int in_dquote;
int res;
in_quote = 0;
in_dquote = 0;
res = 0;
while (*command && (is_cmd_char(*command) || in_quote || in_dquote))
{
if (*command == '"' && !in_quote)
in_dquote = !in_dquote;
if (*command == '\'' && !in_dquote)
in_quote = !in_quote;
if (*command == '$' && !in_quote)
res += get_var_len(&command, env);
else if (*command != '\'' && *command != '"')
res++;
else if ((*command == '\'' && in_dquote)
|| (*command == '"' && in_quote))
res++;
command++;
}
return (res);
}
int add_return_code_to_str(char *res)
{
char *var;
int i;
i = 0;
var = ft_itoa(g_return_code);
while (var && var[i])
{
res[i] = var[i];
i++;
}
free(var);
return (i);
}
int add_var_to_str(char *res, char **command, t_env *env)
{
char *var_name;
char *var;
int i;
i = 0;
if (!ft_isalnum(**command) && **command != '_' && **command != '?')
{
res[0] = '$';
res[1] = **command;
return (2);
}
if (**command == '?')
return (add_return_code_to_str(res));
var_name = get_var_name(*command);
var = ft_get_env(env, var_name);
free(var_name);
while (var && var[i])
{
res[i] = var[i];
i++;
}
*command += get_var_name_len(*command) - 1;
return (i);
}

24
srcs/pwd.c Executable file
View File

@ -0,0 +1,24 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* pwd.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/09 18:31:21 by tomoron #+# #+# */
/* Updated: 2024/02/16 21:19:30 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int pwd(void)
{
char *buffer;
buffer = getcwd(NULL, 0);
if(!buffer)
return(1);
ft_printf("%s\n", buffer);
free(buffer);
return (0);
}