Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | ** EPITECH PROJECT, 2024 | ||
3 | ** 42sh | ||
4 | ** File description: | ||
5 | ** The file containing the command functions | ||
6 | */ | ||
7 | /** | ||
8 | * @file command.c | ||
9 | * @brief The file containing the command functions | ||
10 | */ | ||
11 | |||
12 | #include "../include/myshell.h" | ||
13 | |||
14 | /** | ||
15 | * @brief Get the builtin command | ||
16 | * @param index The index of the command | ||
17 | * @return <b>builtin_t *</b> The builtin command selected | ||
18 | */ | ||
19 | 34619 | builtin_t *get_builtin_command(int index) | |
20 | { | ||
21 | static builtin_t commands[] = { | ||
22 | {"about", &exec_about}, {"alias", &exec_alias}, | ||
23 | {"cd", &exec_cd}, {"echo", &exec_echo}, | ||
24 | {"else", &exec_else}, {"end", &exec_end}, {"endif", &exec_endif}, | ||
25 | {"env", &exec_env}, {"exit", &exec_exit}, {"foreach", &exec_foreach}, | ||
26 | {"help", &exec_help}, {"history", &exec_history}, {"if", &exec_if}, | ||
27 | {"repeat", &exec_repeat}, {"set", &exec_set}, {"setenv", &exec_setenv}, | ||
28 | {"source", &exec_source}, {"unalias", &exec_unalias}, | ||
29 | {"unset", &exec_unset}, {"unsetenv", &exec_unsetenv}, | ||
30 | {"where", &exec_where}, {"which", &exec_which}, {NULL, &exec_command} | ||
31 | }; | ||
32 | |||
33 | 34619 | return &commands[index]; | |
34 | } | ||
35 | |||
36 | /** | ||
37 | * @brief Get the path of the command | ||
38 | * @param command The command | ||
39 | * @param env The env | ||
40 | * @return <b>char *</b> The path of the command | ||
41 | */ | ||
42 | 435 | static char *get_command_path(char *command, char **env) | |
43 | { | ||
44 | 435 | char *path = NULL; | |
45 | 435 | char **path_tab = my_str_to_word_array_select( | |
46 | 435 | get_env_var(env, "PATH"), ":"); | |
47 | |||
48 |
2/2✓ Branch 0 taken 496 times.
✓ Branch 1 taken 70 times.
|
566 | for (int index = 0; path_tab[index] != NULL; index++) { |
49 | 496 | path = my_malloc(sizeof(char) * (my_strlen(path_tab[index]) + | |
50 | 496 | my_strlen(command) + 4), 1); | |
51 | 496 | path[0] = '\0'; | |
52 | 496 | my_strcat(path, path_tab[index]); | |
53 | 496 | my_strcat(path, "/"); | |
54 | 496 | my_strcat(path, command); | |
55 |
2/2✓ Branch 1 taken 365 times.
✓ Branch 2 taken 131 times.
|
496 | if (access(path, X_OK) == 0) { |
56 | 365 | FREE_WORD_ARRAY(path_tab); | |
57 | 365 | return path; | |
58 | } | ||
59 | } | ||
60 | 70 | FREE_WORD_ARRAY(path_tab); | |
61 | 70 | return NULL; | |
62 | } | ||
63 | |||
64 | /** | ||
65 | * @brief Display the error message | ||
66 | * @param mysh The shell structure | ||
67 | * @param command The command | ||
68 | * @return <b>int</b> <u>1</u> if the command is invalid, | ||
69 | * <u>0</u> otherwise | ||
70 | */ | ||
71 | 25 | static int display_error(mysh_t *mysh, char *command) | |
72 | { | ||
73 | struct stat file_info; | ||
74 | |||
75 |
2/2✓ Branch 1 taken 11 times.
✓ Branch 2 taken 14 times.
|
25 | if (access(mysh->args[0], F_OK) != 0) { |
76 | 11 | my_fprintf(2, "%s: Command not found.\n", mysh->args[0]); | |
77 | 11 | return 1; | |
78 | } | ||
79 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
|
14 | if (stat(mysh->args[0], &file_info) == -1) { |
80 | ✗ | my_fprintf(2, "%s: %s.\n", mysh->args[0], strerror(errno)); | |
81 | ✗ | return 1; | |
82 | } | ||
83 |
3/4✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 11 times.
|
14 | if (S_ISREG(file_info.st_mode) == 0 || access(mysh->args[0], X_OK) != 0) { |
84 | 3 | my_fprintf(2, "%s: Permission denied.\n", mysh->args[0]); | |
85 | 3 | return 1; | |
86 | } | ||
87 | 11 | return 0; | |
88 | } | ||
89 | |||
90 | /** | ||
91 | * @brief Check if the command exists | ||
92 | * @param mysh The shell structure | ||
93 | * @param command The command | ||
94 | * @return <b>char *</b> The path of the command if it exists, | ||
95 | * <u>NULL</u> otherwise | ||
96 | */ | ||
97 | 460 | char *check_command_exist(mysh_t *mysh, char *command) | |
98 | { | ||
99 | 460 | char *path = NULL; | |
100 | |||
101 |
2/2✓ Branch 1 taken 435 times.
✓ Branch 2 taken 25 times.
|
460 | if (my_str_contains(mysh->args[0], "/") == 0) |
102 | 435 | path = get_command_path(mysh->args[0], mysh->env); | |
103 |
2/2✓ Branch 0 taken 95 times.
✓ Branch 1 taken 365 times.
|
460 | if (path == NULL) { |
104 |
2/2✓ Branch 1 taken 70 times.
✓ Branch 2 taken 25 times.
|
95 | if (my_str_contains(mysh->args[0], "/") == 0) { |
105 | 70 | my_fprintf(2, "%s: Command not found.\n", mysh->args[0]); | |
106 | 70 | return NULL; | |
107 | } | ||
108 |
3/4✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
✓ Branch 4 taken 11 times.
|
50 | if (my_str_contains(mysh->args[0], "/") && |
109 | 25 | display_error(mysh, mysh->args[0])) | |
110 | 14 | return NULL; | |
111 | 11 | path = mysh->args[0]; | |
112 | } | ||
113 | 376 | return path; | |
114 | } | ||
115 | |||
116 | /** | ||
117 | * @brief Select the command to execute | ||
118 | * @param mysh The shell structure | ||
119 | * @return <b>void</b> | ||
120 | */ | ||
121 | 1092 | void analyse_command(mysh_t *mysh) | |
122 | { | ||
123 | 1092 | char **tmp = NULL; | |
124 | |||
125 | 1092 | tmp = replace_alias_in_line( | |
126 | replace_history(mysh->args), &mysh->alias_list); | ||
127 |
2/4✓ Branch 0 taken 1092 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1092 times.
|
1092 | if (tmp == NULL || tmp[0] == NULL) |
128 | ✗ | return; | |
129 | 1092 | mysh->args = my_malloc_strdup_word_array(tmp); | |
130 | 1092 | FREE(tmp); | |
131 |
2/4✓ Branch 0 taken 1092 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1092 times.
|
1092 | if (mysh->args == NULL || mysh->args[0] == NULL) |
132 | ✗ | return; | |
133 |
2/2✓ Branch 1 taken 16633 times.
✓ Branch 2 taken 446 times.
|
17079 | for (int index = 0; get_builtin_command(index)->name != NULL; index++) { |
134 |
2/2✓ Branch 2 taken 646 times.
✓ Branch 3 taken 15987 times.
|
16633 | if (my_strcmp(mysh->args[0], get_builtin_command(index)->name) == 0) { |
135 | 279 | mysh->exit_status = | |
136 | 646 | get_builtin_command(index)->builtin_function(mysh); | |
137 | 279 | return; | |
138 | } | ||
139 | } | ||
140 | 446 | mysh->exit_status = exec_command(mysh); | |
141 | } | ||
142 | |||
143 | /** | ||
144 | * @brief Execute the command | ||
145 | * @param mysh The shell structure | ||
146 | * @param input The input command | ||
147 | * @return <b>void</b> | ||
148 | */ | ||
149 | 1109 | void command(mysh_t *mysh, input_command_t *input) | |
150 | { | ||
151 | 1109 | mysh->args = input->args; | |
152 |
3/4✓ Branch 0 taken 1109 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 1092 times.
|
1109 | if (mysh->args == NULL || mysh->args[0] == NULL) { |
153 |
3/4✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 15 times.
|
17 | if (input->left_type != 0 || input->right_type != 0) { |
154 | 2 | mysh->exit_status = 1; | |
155 | 2 | my_putstr_error("Invalid null command.\n"); | |
156 | } | ||
157 |
2/4✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 17 times.
|
34 | if (my_strstr(input->command, "\"\"") != NULL || |
158 | 17 | my_strstr(input->command, "''") != NULL) { | |
159 | ✗ | mysh->exit_status = 1; | |
160 | ✗ | my_putstr_error(": Command not found.\n"); | |
161 | } | ||
162 | 17 | return; | |
163 | } | ||
164 | 1092 | analyse_command(mysh); | |
165 | } | ||
166 |