mirror of
https://github.com/zoriya/ash.git
synced 2026-06-09 12:52:11 +00:00
Merge branch 'master' into builtin_source
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
name: Push to epitech
|
||||
|
||||
on: [push]
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -12,7 +15,7 @@ jobs:
|
||||
- name: Push
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
echo -ne $SSH_PRIVATE_KEY >> ~/.ssh/blih
|
||||
echo -ne $SSH_PRIVATE_KEY > ~/.ssh/blih
|
||||
chmod 400 ~/.ssh/blih
|
||||
find . -regex '.*\/\.git.*' -delete
|
||||
echo -ne "Host git.epitech.eu\n\tHostname git.epitech.eu\n\tUser git\n\tIdentityFile $(readlink -f ~/.ssh/blih)\n" >> ~/.ssh/config
|
||||
@@ -22,7 +25,6 @@ jobs:
|
||||
echo "Clonning as ${USER}@epitech.eu from git@git.epitech.eu:/${USER}@epitech.eu/${REPO}"
|
||||
cat ~/.ssh/blih | wc
|
||||
git clone git@git.epitech.eu:/${USER}@epitech.eu/${REPO} /tmp/blihRepo
|
||||
echo "Clone done"
|
||||
export REPOVAR=`pwd`
|
||||
cd /tmp/blihRepo
|
||||
find . -not -path "./.git*" -delete
|
||||
|
||||
@@ -14,6 +14,8 @@ SRC = src/shell.c \
|
||||
src/redirections/redirection_validator.c \
|
||||
src/env.c \
|
||||
src/args.c \
|
||||
src/builtin/builtin_history.c \
|
||||
src/builtin/builtin_history_two.c \
|
||||
src/builtin/builtin_manager.c \
|
||||
src/builtin/builtin_env.c \
|
||||
src/builtin/builtin_source.c \
|
||||
@@ -26,8 +28,10 @@ SRC = src/shell.c \
|
||||
src/utility/envvar_is_valid.c \
|
||||
src/utility/to_array.c \
|
||||
src/utility/catpath.c \
|
||||
src/utility/split_str.c \
|
||||
src/utility/split_str.c
|
||||
src/utility/envpath.c \
|
||||
src/utility/fusion.c \
|
||||
src/utility/split_commands.c \
|
||||
|
||||
OBJ = $(SRC:%.c=%.o)
|
||||
OBJ += src/main.o
|
||||
|
||||
+10
-1
@@ -25,9 +25,18 @@ int builtin_exit(char **argv, env_t *env);
|
||||
int builtin_which(char **argv, env_t *env);
|
||||
int builtin_where(char **argv, env_t *env);
|
||||
int builtin_source(char **argv, env_t *env);
|
||||
int builtin_history(char **args, env_t *env);
|
||||
//utility
|
||||
bool find_path_in_builtins(char *cmd);
|
||||
char **get_envpath(env_t *env);
|
||||
char *check_executable(char *cmd, char *folder);
|
||||
char **get_paths_from_envpath(char *cmd, char **envpath);
|
||||
char **get_envpath(env_t *env);
|
||||
char **get_envpath(env_t *env);
|
||||
//history
|
||||
int add_to_history(char *cmd, env_t *env);
|
||||
int show_history(env_t *env);
|
||||
int clear_history(env_t *env);
|
||||
int execute_from_history(char **args, env_t *env);
|
||||
void remove_duplicate_history(env_t *env);
|
||||
int execute_command_history(history_t *old, history_t *new,
|
||||
char **args, env_t *env);
|
||||
@@ -10,10 +10,21 @@ typedef struct redirection redirection;
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct history_s
|
||||
{
|
||||
int index;
|
||||
char *command;
|
||||
int hour;
|
||||
int minute;
|
||||
int print;
|
||||
struct history_s *next;
|
||||
} history_t;
|
||||
|
||||
typedef struct env_s
|
||||
{
|
||||
char **env;
|
||||
char **vars;
|
||||
history_t *history;
|
||||
} env_t;
|
||||
|
||||
void start_shell(env_t *env);
|
||||
@@ -31,6 +42,7 @@ char **get_argv(char *cmd);
|
||||
int get_argc(char **argv);
|
||||
void exec_error(char *path, char *cmd);
|
||||
|
||||
int get_return(char *ret);
|
||||
int env_get_length(char **env);
|
||||
char *my_getenv(char **env, char *name);
|
||||
char **my_setenv(char **env, char *name, char *value);
|
||||
|
||||
@@ -18,3 +18,6 @@ int count_str(char *str, char *delim);
|
||||
char **split_str(char *str, char delim);
|
||||
char *same_var(char *str, const char *to_find);
|
||||
void destroy_str_arr(char **arr);
|
||||
char *fusion(char *command, char **args);
|
||||
char **split_commands(char *cmd);
|
||||
int *get_return_separator(char *cmd);
|
||||
|
||||
@@ -25,12 +25,15 @@ int builtin_setenv(char **argv, env_t *env)
|
||||
{
|
||||
if (!argv[1])
|
||||
return (builtin_env(argv, env));
|
||||
if ('a' <= argv[1][0] && argv[1][0] <= 'z') {
|
||||
if ((!('a' <= argv[1][0] && argv[1][0] <= 'z'))
|
||||
&& (!('A' <= argv[1][0] && argv[1][0] <= 'Z'))) {
|
||||
write(2, "setenv: Variable name must begin with a letter.\n", 49);
|
||||
my_setenv(env->vars, "?", "1");
|
||||
return (0);
|
||||
}
|
||||
if (!envvar_is_valid(argv[1])) {
|
||||
write(2, INVALID_ENV_VAR, strlen(INVALID_ENV_VAR));
|
||||
my_setenv(env->vars, "?", "1");
|
||||
return (0);
|
||||
}
|
||||
env->env = my_setenv(env->env, argv[1], argv[2]);
|
||||
@@ -42,6 +45,7 @@ int builtin_unsetenv(char **argv, env_t *env)
|
||||
{
|
||||
if (!argv[1]) {
|
||||
write(2, "unsetenv: Too few arguments.\n", 29);
|
||||
my_setenv(env->vars, "?", "1");
|
||||
free(argv);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
** EPITECH PROJECT, 2020
|
||||
** PSU_minishell1_2019
|
||||
** File description:
|
||||
** builtin
|
||||
*/
|
||||
|
||||
#include "shell.h"
|
||||
#include "builtin.h"
|
||||
#include "redirections.h"
|
||||
#include "time.h"
|
||||
#include "utility.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int builtin_history(char **args, env_t *env)
|
||||
{
|
||||
if (**args == '!')
|
||||
return (execute_from_history(args, env));
|
||||
if (!args[1])
|
||||
return (show_history(env));
|
||||
if (args[1]) {
|
||||
if (!strcmp(args[1], "-c"))
|
||||
return (clear_history(env));
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
int add_to_history(char *cmd, env_t *env)
|
||||
{
|
||||
time_t time_struct;
|
||||
struct tm *curr_time = 0;
|
||||
history_t *log = malloc(sizeof(history_t));
|
||||
history_t *tmp = env->history;
|
||||
char *command = cmd;
|
||||
|
||||
for (; *command && (*command == ' ' || *command == '\t'); command++);
|
||||
if (!strlen(command))
|
||||
return (0);
|
||||
if (!log)
|
||||
return (-1);
|
||||
for (tmp = env->history; tmp && tmp->next; tmp = tmp->next);
|
||||
time(&time_struct);
|
||||
curr_time = localtime(&time_struct);
|
||||
*log = (history_t){tmp ? tmp->index + 1 : 1, strdup(command),
|
||||
curr_time->tm_hour, curr_time->tm_min, 1, NULL};
|
||||
(env->history) ? (tmp->next = log) : (env->history = log);
|
||||
remove_duplicate_history(env);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int list_len(history_t *list)
|
||||
{
|
||||
int len = 0;
|
||||
history_t *tmp = NULL;
|
||||
|
||||
for (tmp = list; tmp; tmp = tmp->next)
|
||||
len++;
|
||||
return (len);
|
||||
}
|
||||
|
||||
int execute_from_history(char **args, env_t *env)
|
||||
{
|
||||
int len = list_len(env->history);
|
||||
history_t *tmp = NULL;
|
||||
history_t *last = NULL;
|
||||
|
||||
for (tmp = env->history; tmp; tmp = tmp->next)
|
||||
if (!tmp->next)
|
||||
last = tmp;
|
||||
for (int i = 0; i < len; i++) {
|
||||
tmp = env->history;
|
||||
for (int m = 0; m < len - i - 1; m++)
|
||||
tmp = tmp->next;
|
||||
if (tmp->print && strncmp(&args[0][1], tmp->command,
|
||||
strlen(args[0]) - 1) == 0)
|
||||
return (execute_command_history(tmp, last, args, env));
|
||||
}
|
||||
printf("%s: Event not found.\n", &args[0][1]);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int execute_command_history(history_t *old, history_t *new,
|
||||
char **args, env_t *env)
|
||||
{
|
||||
old->print = 0;
|
||||
new->command = fusion(old->command, args);
|
||||
if (!new->command)
|
||||
return (-1);
|
||||
printf("%s\n", new->command);
|
||||
return (eval_raw_cmd(new->command, env));
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
** EPITECH PROJECT, 2020
|
||||
** PSU_minishell1_2019
|
||||
** File description:
|
||||
** builtin
|
||||
*/
|
||||
|
||||
#include "shell.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void remove_duplicate_history(env_t *env)
|
||||
{
|
||||
char *last_command = NULL;
|
||||
history_t *tmp = env->history;
|
||||
|
||||
if (!tmp->next)
|
||||
return;
|
||||
for (;tmp->next; tmp = tmp->next);
|
||||
last_command = tmp->command;
|
||||
for (tmp = env->history; tmp->next; tmp = tmp->next) {
|
||||
if (!strcmp(last_command, tmp->command))
|
||||
tmp->print = 0;
|
||||
if (!tmp)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int show_history(env_t *env)
|
||||
{
|
||||
for (history_t *tmp = env->history; tmp; tmp = tmp->next) {
|
||||
if (tmp->print)
|
||||
printf("%6d\t%d:%02d\t%s\n", tmp->index, tmp->hour,
|
||||
tmp->minute, tmp->command);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int clear_history(env_t *env)
|
||||
{
|
||||
history_t *tmp = NULL;
|
||||
|
||||
for (tmp = env->history; tmp; tmp = tmp->next)
|
||||
tmp->print = 0;
|
||||
return (0);
|
||||
}
|
||||
@@ -31,6 +31,7 @@ int main(int argc, char **argv, char **env)
|
||||
envcp[env_get_length(env)] = NULL;
|
||||
envt->env = envcp;
|
||||
envt->vars = NULL;
|
||||
envt->history = NULL;
|
||||
start_shell(envt);
|
||||
ret = get_return(my_getenv(envt->vars, "?"));
|
||||
(void)argc;
|
||||
|
||||
@@ -23,6 +23,7 @@ const builtin builtins[] = {
|
||||
{"which", &builtin_which},
|
||||
{"where", &builtin_where},
|
||||
{"source", &builtin_source},
|
||||
{"history", &builtin_history},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
@@ -36,6 +37,8 @@ int prompt_run(char *cmd, redirection *inout[2], env_t *env)
|
||||
}
|
||||
if (!argv[0])
|
||||
return (0);
|
||||
if (**argv == '!' && argv[0][1] && argv[0][1] != ' ')
|
||||
return (run_builtin(&builtins[5], argv, inout, env));
|
||||
for (int i = 0; builtins[i].name; i++)
|
||||
if (!strcmp(argv[0], builtins[i].name))
|
||||
return (run_builtin(&builtins[i], argv, inout, env));
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <sys/wait.h>
|
||||
#include <string.h>
|
||||
#include "utility.h"
|
||||
#include "builtin.h"
|
||||
|
||||
const redirection_map redirections[] = {
|
||||
{"|", &get_pipe_fd, &handle_pipe, OUTPUT | PIPE | EX_PIPE},
|
||||
@@ -79,17 +80,25 @@ int run_with_redirections(char *cmd, env_t *env, redirection *input)
|
||||
|
||||
int eval_raw_cmd(char *cmd, env_t *env)
|
||||
{
|
||||
char **cmds = split_str(cmd, ';');
|
||||
int *return_values = get_return_separator(cmd);
|
||||
char **cmds = split_commands(cmd);
|
||||
int ret = 0;
|
||||
|
||||
if (!cmds)
|
||||
return (-1);
|
||||
for (int i = 0; cmds[i]; i++) {
|
||||
if (redirections_are_invalid(cmds[i])) {
|
||||
my_setenv(env->vars, "?", "1");
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
for (int i = 0; cmds[i]; i++)
|
||||
for (int i = 0; cmds[i]; i++) {
|
||||
if (return_values[i] == 0 && get_return(my_getenv(env->vars, "?")))
|
||||
break;
|
||||
if (return_values[i] == 1 && !get_return(my_getenv(env->vars, "?")))
|
||||
break;
|
||||
if (run_with_redirections(cmds[i], env, NULL))
|
||||
ret = -1;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include "shell.h"
|
||||
#include "builtin.h"
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
@@ -24,6 +25,7 @@ void start_shell(env_t *env)
|
||||
p = strchr(cmd, '\n');
|
||||
if (p)
|
||||
*p = '\0';
|
||||
add_to_history(cmd, env);
|
||||
if (eval_raw_cmd(cmd, env) < 0)
|
||||
should_close = true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
** EPITECH PROJECT, 2020
|
||||
** fusion.c
|
||||
** File description:
|
||||
** fusion
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
char *fusion(char *command, char **args)
|
||||
{
|
||||
char *str = NULL;
|
||||
int len = strlen(command) + 1;
|
||||
int pos = 0;
|
||||
if (!args[1])
|
||||
return (command);
|
||||
for (int i = 1; args[i]; i++)
|
||||
len += strlen(args[i]) + 1;
|
||||
str = malloc(sizeof(char) * (len + 1));
|
||||
if (!str)
|
||||
return (NULL);
|
||||
strcpy(str, command);
|
||||
pos += strlen(command);
|
||||
str[pos++] = ' ';
|
||||
for (int i = 1; args[i]; i++) {
|
||||
strcpy(str + pos, args[i]);
|
||||
pos += strlen(args[i]);
|
||||
str[pos++] = ' ';
|
||||
}
|
||||
str[pos] = 0;
|
||||
return (str);
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
** EPITECH PROJECT, 2020
|
||||
** PSU_minishell2_2019
|
||||
** File description:
|
||||
** split_commands
|
||||
*/
|
||||
|
||||
#include <malloc.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
int get_command_len(char *str)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
for (int i = 0; str[i]; i++) {
|
||||
if (str[i] == ';' || (str[i] == '&' && str[i + 1] == '&')
|
||||
|| (str[i] == '|' && str[i + 1] == '|'))
|
||||
break;
|
||||
len++;
|
||||
}
|
||||
return (len);
|
||||
}
|
||||
|
||||
int get_nb_commands(char *cmd)
|
||||
{
|
||||
int len = 1;
|
||||
for (int i = 0; cmd[i]; i++) {
|
||||
len += (cmd[i] == ';') ? 1 : 0;
|
||||
len += (cmd[i] == '&' && cmd[i + 1] == '&') ? 1 : 0;
|
||||
len += (cmd[i] == '|' && cmd[i + 1] == '|') ? 1 : 0;
|
||||
}
|
||||
return (len);
|
||||
}
|
||||
|
||||
int *get_return_separator(char *cmd)
|
||||
{
|
||||
int len = get_nb_commands(cmd);
|
||||
int *array = malloc(sizeof(int) * len);
|
||||
int pos = 1;
|
||||
|
||||
if (!array)
|
||||
return (NULL);
|
||||
array[0] = -1;
|
||||
for (int i = 0; cmd[i + 1]; i++) {
|
||||
if (cmd[i] == ';')
|
||||
array[pos] = -1;
|
||||
if (cmd[i] == '&' && cmd[i + 1] == '&')
|
||||
array[pos] = 0;
|
||||
if (cmd[i] == '|' && cmd[i + 1] == '|')
|
||||
array[pos] = 1;
|
||||
if ((cmd[i] == '|' && cmd[i + 1] == '|') || (cmd[i] == '&'
|
||||
&& cmd[i + 1] == '&') || (cmd[i] == ';'))
|
||||
pos++;
|
||||
}
|
||||
return (array);
|
||||
}
|
||||
|
||||
char **split_commands(char *cmd)
|
||||
{
|
||||
int len = get_nb_commands(cmd);
|
||||
char **array = malloc(sizeof(char *) * (len + 1));
|
||||
int pos = 0;
|
||||
|
||||
array[len] = NULL;
|
||||
for (int i = 0; i < len; i++) {
|
||||
for (; *cmd && (*cmd == ' ' || *cmd == '\t'); cmd++);
|
||||
pos = get_command_len(cmd);
|
||||
array[i] = malloc(sizeof(char) * (pos + 1));
|
||||
strncpy(array[i], cmd, pos);
|
||||
array[i][pos] = 0;
|
||||
cmd += pos;
|
||||
if (*cmd == ';')
|
||||
cmd++;
|
||||
else if ((*cmd == '|') || (*cmd == '&'))
|
||||
cmd += 2;
|
||||
}
|
||||
return (array);
|
||||
}
|
||||
Reference in New Issue
Block a user