|
@@ -9,6 +9,9 @@
|
|
|
#include <stdlib.h>
|
|
|
#include <unistd.h>
|
|
|
#include <errno.h>
|
|
|
+#include <sys/types.h>
|
|
|
+#include <sys/stat.h>
|
|
|
+#include <fcntl.h>
|
|
|
#include "parser.h"
|
|
|
|
|
|
/* --- Fonctions privées --- */
|
|
@@ -109,6 +112,9 @@ int get_command(Command* c, char* line){
|
|
|
c->input = STDIN;
|
|
|
c->output = STDOUT;
|
|
|
c->error = STDERR;
|
|
|
+ c->erase[0] = false;
|
|
|
+ c->erase[1] = false;
|
|
|
+ c->bck = false;
|
|
|
//Trim et supprime l'ancienne chaine
|
|
|
old = c->cmd;
|
|
|
c->cmd = rtrim(c->cmd, ' ');
|
|
@@ -117,38 +123,89 @@ int get_command(Command* c, char* line){
|
|
|
return length + separator;
|
|
|
}
|
|
|
|
|
|
-/* --- Fonctions publiques --- */
|
|
|
-int parse_line(CommandTab* ct, char* line){
|
|
|
+int set_io(Command* c, char* filename, int redir){
|
|
|
//Declaration variable
|
|
|
- int compteur, tmp;
|
|
|
- //Nettoyage ligne
|
|
|
- line = trim(mtrim(line, '\n'));
|
|
|
- //Compte le nombre de commande dans la ligne
|
|
|
- compteur = nb_commands(line);
|
|
|
- if(compteur == SHELL_ERR){
|
|
|
+ int file;
|
|
|
+ //Ouverture du fichier
|
|
|
+ file = open(filename, O_CREAT | O_RDWR, S_IRWXU);
|
|
|
+ if(file == ERR){
|
|
|
+ perror("Erreur lors de l'ouverture du fichier pour la redirection : ");
|
|
|
return SHELL_ERR;
|
|
|
}
|
|
|
- //Initialisation structure
|
|
|
- ct->cmd = malloc(sizeof(Command*) * compteur);
|
|
|
- ct->length = compteur;
|
|
|
- //Recupération de chaque commande
|
|
|
- for(int i = 0; i < compteur; i++){
|
|
|
- ct->cmd[i] = malloc(sizeof(Command));
|
|
|
- tmp = get_command(ct->cmd[i], line);
|
|
|
- line += tmp;
|
|
|
- //Si pas dernière commande on trim
|
|
|
- if(i + 1 < compteur){
|
|
|
- line = ltrim(line, ' ');
|
|
|
- }
|
|
|
+ //Analyse dans quel descripteur il doit etre mis
|
|
|
+ switch(redir){
|
|
|
+ case SHELLR_IN:
|
|
|
+ //Si un fichier deja ouvert
|
|
|
+ if(c->input != STDIN){
|
|
|
+ //On le ferme
|
|
|
+ if(close(c->input) == -1){
|
|
|
+ perror("Erreur lors de la fermeture de l'ancien fichier de redirection : ");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //Set nouveau fichier
|
|
|
+ c->input = file;
|
|
|
+ break;
|
|
|
+ case SHELLR_OUT:
|
|
|
+ case SHELLRE_OUT:
|
|
|
+ //Si un fichier deja ouvert
|
|
|
+ if(c->output != STDOUT){
|
|
|
+ //On le ferme
|
|
|
+ if(close(c->output) == -1){
|
|
|
+ perror("Erreur lors de la fermeture de l'ancien fichier de redirection : ");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ c->output = file;
|
|
|
+ if(redir == SHELLRE_OUT){
|
|
|
+ c->erase[STDOUT - 1] = true;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case SHELLR_ERR:
|
|
|
+ case SHELLRE_ERR:
|
|
|
+ //Si un fichier deja ouvert
|
|
|
+ if(c->error != STDERR){
|
|
|
+ //On le ferme
|
|
|
+ if(close(c->error) == -1){
|
|
|
+ perror("Erreur lors de la fermeture de l'ancien fichier de redirection : ");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ c->error = file;
|
|
|
+ if(redir == SHELLRE_ERR){
|
|
|
+ c->erase[STDERR - 1] = true;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case SHELLR_ALL:
|
|
|
+ case SHELLRE_ALL:
|
|
|
+ //Si un fichier deja ouvert
|
|
|
+ if(c->output != STDOUT){
|
|
|
+ //On le ferme
|
|
|
+ if(close(c->output) == -1){
|
|
|
+ perror("Erreur lors de la fermeture de l'ancien fichier de redirection : ");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(c->error != STDERR){
|
|
|
+ //On le ferme
|
|
|
+ if(close(c->error) == -1){
|
|
|
+ perror("Erreur lors de la fermeture de l'ancien fichier de redirection : ");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ c->output = file;
|
|
|
+ c->error = file;
|
|
|
+ if(redir == SHELLRE_ALL){
|
|
|
+ c->erase[STDOUT - 1] = true;
|
|
|
+ c->erase[STDERR - 1] = true;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default :
|
|
|
+ return SHELL_ERR;
|
|
|
}
|
|
|
- //Retour
|
|
|
+ //Si on arrive ici tous est ok
|
|
|
return SHELL_OK;
|
|
|
}
|
|
|
|
|
|
-int parse_command(Command* c){
|
|
|
- boolean guillemet = false;
|
|
|
+int set_redirection(Command* c){
|
|
|
+ boolean first = true, guillemet = false;
|
|
|
char* deb, * file, * buffer = c->cmd + 1;
|
|
|
- int redir = 0, compteur;
|
|
|
+ int redir = -1, compteur, finCmd = 0;
|
|
|
//Parcours chaine
|
|
|
while(*buffer){
|
|
|
//Repere redirection
|
|
@@ -233,13 +290,24 @@ int parse_command(Command* c){
|
|
|
break;
|
|
|
}
|
|
|
buffer++;
|
|
|
+ //On incremente pour trouver la fin de la commande
|
|
|
+ if(first){
|
|
|
+ finCmd++;
|
|
|
+ }
|
|
|
}
|
|
|
+ //Apres ce n'est que des redirection
|
|
|
+ first = false;
|
|
|
//On passe les espaces
|
|
|
while(*buffer == ' '){
|
|
|
buffer++;
|
|
|
}
|
|
|
//Si on est à la fin de la chaine
|
|
|
if(*buffer == '\0'){
|
|
|
+ if(redir == -1){
|
|
|
+ //Aucune redirection
|
|
|
+ return finCmd + 1;
|
|
|
+ }
|
|
|
+ //Sinon on est dans un redirection non terminée
|
|
|
return SHELL_ERR;
|
|
|
}
|
|
|
//Regarde si le nom du fichier est entre ""
|
|
@@ -273,15 +341,68 @@ int parse_command(Command* c){
|
|
|
//Allocation file et copie nom fichier
|
|
|
file = malloc(sizeof(char) * compteur);
|
|
|
strncpy(file, deb, compteur);
|
|
|
- printf("%s %d %d\n", file, redir, guillemet);
|
|
|
+ //Redirection
|
|
|
+ if(set_io(c, file, redir) == SHELL_ERR){
|
|
|
+ free(file);
|
|
|
+ return SHELL_ERR;
|
|
|
+ }
|
|
|
free(file);
|
|
|
//Passe les espaces
|
|
|
while(*buffer == ' '){
|
|
|
buffer++;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- return 1;
|
|
|
+ //Si on arrive ici tous est ok
|
|
|
+ return finCmd;
|
|
|
+}
|
|
|
+
|
|
|
+/* --- Fonctions publiques --- */
|
|
|
+int parse_line(CommandTab* ct, char* line){
|
|
|
+ //Declaration variable
|
|
|
+ int compteur, tmp;
|
|
|
+ //Nettoyage ligne
|
|
|
+ line = trim(mtrim(line, '\n'));
|
|
|
+ //Compte le nombre de commande dans la ligne
|
|
|
+ compteur = nb_commands(line);
|
|
|
+ if(compteur == SHELL_ERR){
|
|
|
+ return SHELL_ERR;
|
|
|
+ }
|
|
|
+ //Initialisation structure
|
|
|
+ ct->cmd = malloc(sizeof(Command*) * compteur);
|
|
|
+ ct->length = compteur;
|
|
|
+ //Recupération de chaque commande
|
|
|
+ for(int i = 0; i < compteur; i++){
|
|
|
+ ct->cmd[i] = malloc(sizeof(Command));
|
|
|
+ tmp = get_command(ct->cmd[i], line);
|
|
|
+ line += tmp;
|
|
|
+ //Si pas dernière commande on trim
|
|
|
+ if(i + 1 < compteur){
|
|
|
+ line = ltrim(line, ' ');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //Retour
|
|
|
+ return SHELL_OK;
|
|
|
+}
|
|
|
+
|
|
|
+int parse_command(Command* c){
|
|
|
+ //Declaration variable
|
|
|
+ int length;
|
|
|
+ char* cmd;
|
|
|
+ //Parse les redirections
|
|
|
+ length = set_redirection(c);
|
|
|
+ if(length == SHELL_ERR){
|
|
|
+ return SHELL_ERR;
|
|
|
+ }
|
|
|
+ //Recup la commande (sans redirection)
|
|
|
+ cmd = malloc(length);
|
|
|
+ strncpy(cmd, c->cmd, length);
|
|
|
+ //Split en un tableau
|
|
|
+ c->argv = str_split(cmd, ' ', &c->argc); //ToDo changer par un methode de split qui prend en compte les " " et les \espaces
|
|
|
+ c->name = c->argv[0];
|
|
|
+ //Analyse wildcard
|
|
|
+ /* Todo */
|
|
|
+ //Ici tous est ok
|
|
|
+ return SHELL_OK;
|
|
|
}
|
|
|
|
|
|
int parse_all_command(CommandTab* ct){
|