· 5 years ago · Oct 01, 2020, 02:56 PM
1/*
2 Fichier : shell_cp_executetocomplete.c
3*/
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7#include <unistd.h>
8#include <sys/types.h>
9#include <sys/wait.h>
10#include <signal.h>
11#include <assert.h>
12#include <errno.h>
13
14
15/*---------------------------------------------*/
16
17char *sh_read_line(FILE *f) {
18 char *line = NULL;
19 ssize_t bufsize = 0; // donc getline realise l'allocation
20 getline(&line, &bufsize,
21 f); // Extracts characters from is and stores them into str until the delimitation character delim is found (or the newline character, '\n', for (2)).
22 return line;
23}
24
25/*---------------------------------------------*/
26
27#define LSH_TOK_BUFSIZE 64
28#define LSH_TOK_DELIM " \t\n"
29
30char **sh_split_line(char *line) { // Fonction qui split les arguments en token
31 int bufsize = LSH_TOK_BUFSIZE, position = 0;
32 char **tokens = malloc(bufsize * sizeof(char *));
33 char *token;
34
35 if (!tokens) {
36 fprintf(stderr, "lsh: allocation error\n");
37 exit(EXIT_FAILURE);
38 }
39
40 token = strtok(line, LSH_TOK_DELIM);
41
42 while (token != NULL) {
43 tokens[position] = token;
44 position++;
45
46 if (position >= bufsize) {
47 bufsize += LSH_TOK_BUFSIZE;
48 tokens = realloc(tokens, bufsize * sizeof(char *));
49 if (!tokens) {
50 fprintf(stderr, "lsh: allocation error\n");
51 exit(EXIT_FAILURE);
52 }
53 }
54 token = strtok(NULL, LSH_TOK_DELIM);
55 }
56 tokens[position] = NULL;
57 return tokens;
58}
59
60/*---------------------------------------------*/
61
62int sh_execute(char **args) { // TODO: Traitement des erreurs
63 pid_t pid = fork();
64 if (pid == 0) {
65 // Child
66 int errno;
67 if (execvp(args[0], args) == -1) {
68 // Erreur d'exécution
69 }
70 exit(errno);
71 } else if (pid > 0) {
72 //Parent
73 int status = 0;
74
75 wait(&status);
76 while(!WIFEXITED(status));
77 status = WEXITSTATUS(status);
78
79 return status;
80 } else {
81 //fork error
82 }
83}
84
85/*---------------------------------------------*/
86char *LCSubStr(char *X, char *Y) {
87 size_t m = strlen(X);
88 size_t n = strlen(Y);
89
90 // Create a table to store lengths of longest common
91 // suffixes of substrings. Note that LCSuff[i][j]
92 // contains length of longest common suffix of X[0..i-1]
93 // and Y[0..j-1]. The first row and first column entries
94 // have no logical meaning, they are used only for
95 // simplicity of program
96 int LCSuff[m + 1][n + 1];
97
98 // To store length of the longest common substring
99 int len = 0;
100
101 // To store the index of the cell which contains the
102 // maximum value. This cell's index helps in building
103 // up the longest common substring from right to left.
104 int row, col;
105
106 /* Following steps build LCSuff[m+1][n+1] in bottom
107 up fashion. */
108 for (int i = 0; i <= m; i++) {
109 for (int j = 0; j <= n; j++) {
110 if (i == 0 || j == 0)
111 LCSuff[i][j] = 0;
112
113 else if (X[i - 1] == Y[j - 1]) {
114 LCSuff[i][j] = LCSuff[i - 1][j - 1] + 1;
115 if (len < LCSuff[i][j]) {
116 len = LCSuff[i][j];
117 row = i;
118 col = j;
119 }
120 } else
121 LCSuff[i][j] = 0;
122 }
123 }
124
125 // if true, then no common substring exists
126 if (len) {
127 // allocate space for the longest common substring
128 char *resultStr = (char *) malloc((len + 1) * sizeof(char));
129
130 // traverse up diagonally form the (row, col) cell
131 // until LCSuff[row][col] != 0
132 while (LCSuff[row][col] != 0) {
133 resultStr[--len] = X[row - 1]; // or Y[col-1]
134
135 // move diagonally up to previous cell
136 row--;
137 col--;
138 }
139 return resultStr;
140 } else {
141 return NULL;
142 }
143}
144
145char is_forbidden(char **args, char *f_env) {
146 char *buffer;
147 char *token;
148 char *lcss;
149 for (int i = 0; args[i] != NULL; i++) {
150 // f_env = "test:mp3"
151 lcss = LCSubStr(f_env, args[i]);
152 if (lcss) {
153 buffer = strdup(f_env);
154 token = strtok(buffer, ":");
155 while (token) {
156 if (!strcmp(token, lcss)) {
157 return 1;
158 }
159 token = strtok(NULL, ":");
160 }
161 }
162 }
163 return 0;
164}
165
166/*---------------------------------------------*/
167
168void sh_loop(char *f_env) {
169 char *prompt = "l3miage shell > ";
170 char *line;
171 char **args;
172 char *buffer;
173 int status;
174
175 do {
176 printf("%s", prompt);
177 fflush(stdout);
178
179 line = sh_read_line(stdin);
180 args = sh_split_line(line);
181
182 if (args[0] == NULL) {
183 continue;
184 } else if (!strcmp(args[0], "exit")) {
185 exit(0); // TODO : end instructions
186 } else if (!strcmp(args[0], "newf")) {
187 // Ajout dans les variables d'environnement
188 if (*f_env) {
189 buffer = (char *) malloc(sizeof(char) * (strlen(f_env) + strlen(args[1]) + (size_t) 2));
190 strcpy(buffer, f_env);
191 strcat(buffer, ":");
192 strcat(buffer, args[1]);
193 } else {
194 buffer = (char *) malloc(sizeof(char) * (strlen(f_env) + strlen(args[1]) + (size_t) 1));
195 strcpy(buffer, args[1]);
196 }
197
198 setenv("FORBIDDEN", buffer, 1);
199
200 free(buffer);
201 buffer = NULL;
202
203 free(f_env);
204 f_env = strdup(getenv("FORBIDDEN"));
205 } else if (!strcmp(args[0], "rmf")) {
206 if (is_forbidden(args, f_env)) {
207 char *substr = strstr(f_env, args[1]);
208
209 size_t len_substr = strlen(args[1]) + 1; // +1 pour le ':'
210 size_t len_before_substr = substr - f_env;
211 size_t len_after_substr = strlen(substr + len_substr);
212
213 //assert(len_before_substr+len_after_substr+len_substr == strlen(f_env));
214
215 if (len_before_substr == 0) {
216 buffer = (char *) malloc(sizeof(char) * (len_after_substr) + (size_t) 1);
217 strncpy(buffer, f_env + len_substr, len_after_substr);
218 } else if (len_after_substr == 0) {
219 buffer = (char *) malloc(sizeof(char) * (len_before_substr));
220 strncpy(buffer, f_env, len_before_substr - 1);
221 } else {
222 buffer = (char *) malloc(sizeof(char) * (len_before_substr + len_after_substr) + (size_t) 1);
223 strncpy(buffer, f_env, len_before_substr);
224 strncat(buffer, substr + len_substr, len_after_substr);
225 }
226
227 setenv("FORBIDDEN", buffer, 1);
228
229 free(buffer);
230 buffer = NULL;
231
232 free(f_env);
233 f_env = strdup(getenv("FORBIDDEN"));
234 } else {
235 printf("%s is not a forbidden element\n", args[1]);
236 }
237 } else if (is_forbidden(args, f_env)) {
238 printf("Travaille au lieu de jouer !\n");
239 } else {
240 status = sh_execute(args);
241 if (status == 1) {
242 printf("Syntaxe incorrecte\nStatus code : %d\n", status);
243 fflush(stdout);
244 } else if (status == 2){
245 printf("Commande inexistante\nStatus code : %d\n", status);
246 fflush(stdout);
247 }
248 }
249
250 /*sh_free(line); */
251 /*sh_free(args); */
252 } while (1); //TODO: modif to status
253}
254
255/*==============================================*/
256
257void handler(int signum) {
258 printf("\nIl faut taper \"exit\" pour quitter le terminal !\n");
259 fflush(stdout);
260}
261
262int main(int argc, char *argv[]) {
263
264 // Init : Load config files, if any
265 signal(SIGINT, handler);
266 if (getenv("FORBIDDEN")) {
267 char *f_env = strdup(getenv("FORBIDDEN"));
268 sh_loop(f_env);
269 } else {
270 char *f_env = (char *) malloc(sizeof(char));
271 sh_loop(f_env);
272 }
273
274 // Termin : Perform any shutdown / cleanup
275
276 return EXIT_SUCCESS;
277}
278
279