Bladeren bron

Merge pull request #11 from Loquicom/myls

Loquicom 6 jaren geleden
bovenliggende
commit
c1f52a62bb
12 gewijzigde bestanden met toevoegingen van 384 en 33 verwijderingen
  1. 3 1
      .gitignore
  2. 56 2
      README.md
  3. 7 0
      color.h
  4. 7 8
      command.c
  5. 5 0
      command.h
  6. 6 5
      makefile
  7. 265 0
      myls.c
  8. 23 0
      myls.h
  9. 7 8
      mysh.c
  10. 2 5
      mysh.h
  11. 2 3
      parser.c
  12. 1 1
      subdiv.c

+ 3 - 1
.gitignore

@@ -55,4 +55,6 @@ dkms.conf
 /mysh
 /mysh.log
 *.log
-/bug.txt
+/bug.txt
+/myls
+

+ 56 - 2
README.md

@@ -1,2 +1,56 @@
-# SEC
-Projet final SEC Master 1 Informatique Artois
+# Projet SEC (MySh) Master 1 Artois 2018-2019
+### Brandao Arthur (75%) & Maxence Bacquet (25%)
+
+
+
+## Utilisation
+
+La compilation du programme s'effectue avec le commande make dans le dossier du projet. Il est possible de recréer les dépendances avec la commande made depend, et de supprimer les logs avec make rm-log. Pour lancer le programme il suffit d'exécuter le fichier ./mysh.
+
+Les commandes externes (myls et myps) sont exécutable sans passer par le programme mysh, mais sont aussi utilisable comme des commandes internes de ce dernier. Il suffit juste de taper le nom de la commande dans un terminal mysh pour l'exécuter.
+
+
+
+## Fonctionalités
+
+Présentes :
+
+- Exécution de commandes
+- Séquencement
+- Wildcards
+- Changement de répertoire
+- Sortie du shell (commande exit et Ctrl+C)
+- Code de retoure d'un processus (commande status)
+- Lister le contenue d'un répertoire (commande myls)
+- Les tubes
+- Les redirections d'entrées et de sorties vers des fichiers
+- Premier et arrière plans
+- Commande myjobs
+- Variables locales et d'environnements
+
+Absentes :
+
+- Commandes myfg, mybg et gestion du Ctrl+Z
+
+Partiels :
+
+- Etat des processus en cours (commande myps) : La commande liste les processus en cours d'exécution avec leur PID, le nom de la commande et l'utilisateur qui l'a lancé.
+
+
+
+## Bug
+
+Aucun bug pour le moment
+
+
+
+## Blagounette
+
+Qu'est-ce qu'un canife ?
+
+Un petit fien.
+
+
+
+
+

+ 7 - 0
color.h

@@ -0,0 +1,7 @@
+#define RED     "\x1b[31m"
+#define GREEN   "\x1b[32m"
+#define YELLOW  "\x1b[33m"
+#define BLUE    "\x1b[34m"
+#define MAGENTA "\x1b[35m"
+#define CYAN    "\x1b[36m"
+#define RESET   "\x1b[0m"

+ 7 - 8
command.c

@@ -9,22 +9,21 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include "command.h"
 #include "error.h"
 #include "str.h"
 #include "parser.h"
 #include "execute.h"
 #include "ipc.h"
 #include "variable.h"
-#include "command.h"
-#include "mysh.h"
 
 /* --- Extern --- */
 extern Error error;
 extern pid_t last;
-extern int status_cmd;
-extern int result_cmd;
-extern char base_path[];
-extern pid_list pidlist;
+int status_cmd = -1;
+int result_cmd = -1;
+char base_path[BUFFER_SIZE];
+pid_list pidlist;
 char* cmdlist[] = {
     "cd",
     "exit",
@@ -367,8 +366,8 @@ int myls(int argc, char** argv){
     path[length + 3] = 'l';
     path[length + 4] = 's';
     //Execution
-    //return exec_file(path, argv);
-    return 0;
+    return exec_file(path, argv);
+    //return 0;
 }
 
 int myps(int argc, char** argv){

+ 5 - 0
command.h

@@ -11,6 +11,7 @@
 /* --- Include --- */
 #include <sys/types.h>
 #include "constante.h"
+#include "parser.h"
 
 /* --- Structure --- */
 typedef struct pid_node pid_node;
@@ -29,6 +30,10 @@ typedef struct{
 /* --- Extern --- */
 extern char* cmdlist[];
 extern boolean exitsh;
+extern int status_cmd;
+extern int result_cmd;
+extern char base_path[];
+extern pid_list pidlist;
 
 /* --- Fonctions --- */
 /**

+ 6 - 5
makefile

@@ -2,7 +2,7 @@
 # CONFIGURATION GENERALE
 #
 
-EXEC = mysh
+EXEC = mysh myls
 OBJETS = error.o str.o parser.o wildcard.o command.o execute.o sem.o shm.o subdiv.o ipc.o expreg.o variable.o
 NOM_PROJET = mini-shell
 
@@ -103,8 +103,8 @@ str.o: str.c str.h
 parser.o: parser.c error.h str.h wildcard.h constante.h ipc.h sem.h shm.h \
  subdiv.h variable.h parser.h
 wildcard.o: wildcard.c error.h wildcard.h constante.h
-command.o: command.c error.h str.h parser.h constante.h execute.h ipc.h \
- sem.h shm.h subdiv.h variable.h command.h mysh.h
+command.o: command.c command.h constante.h parser.h error.h str.h \
+ execute.h ipc.h sem.h shm.h subdiv.h variable.h
 execute.o: execute.c error.h execute.h constante.h
 sem.o: sem.c error.h sem.h constante.h
 shm.o: shm.c error.h shm.h constante.h
@@ -112,5 +112,6 @@ subdiv.o: subdiv.c subdiv.h constante.h
 ipc.o: ipc.c ipc.h constante.h sem.h shm.h subdiv.h variable.h
 expreg.o: expreg.c expreg.h constante.h
 variable.o: variable.c str.h expreg.h constante.h variable.h subdiv.h
-mysh.o: mysh.c error.h str.h parser.h constante.h command.h execute.h \
- ipc.h sem.h shm.h subdiv.h mysh.h
+mysh.o: mysh.c error.h str.h parser.h constante.h mysh.h command.h ipc.h \
+ sem.h shm.h subdiv.h execute.h
+myls.o: myls.c error.h color.h myls.h constante.h

+ 265 - 0
myls.c

@@ -0,0 +1,265 @@
+#define _POSIX_C_SOURCE 200809L
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <grp.h>
+#include <pwd.h>
+#include "error.h"
+#include "color.h"
+#include "myls.h"
+
+void printls(char* path, char* filename){
+        int length;
+        char* completePath;
+        char permission[11];
+        char mois[5];
+        struct stat info;
+        struct group* grp;
+        struct passwd* user;
+        struct tm* date;
+        //Si le nom est en 2 partie
+        if(filename != NULL){
+            //Création chemin vers le fichier
+            length = strlen(path) + strlen(filename) + 2;
+            completePath = malloc(sizeof(char) * length);
+            memset(completePath, 0, length);
+            if(path[strlen(path)-1] != '/'){
+                snprintf(completePath, length, "%s/%s", path, filename);
+            } else {
+                 snprintf(completePath, length, "%s%s", path, filename);
+            }
+        } else {
+            filename = path;
+            completePath = path;
+            path = NULL;
+        }
+        
+        //Recup info fichier
+        if(stat(completePath, &info) == ERR){
+            addperror("Erreur stat");
+            return;
+        }
+        if(path != NULL){
+            free(completePath);
+        }
+
+        //Calcul permission
+        memset(permission, 0, 11);
+        if(S_ISDIR(info.st_mode)){
+            permission[0] = 'd';
+        }
+        else if(S_ISBLK(info.st_mode)){
+            permission[0] = 'b';
+        }
+        else if(S_ISCHR(info.st_mode)){
+            permission[0] = 'c';
+        }
+#ifdef S_ISFIFO
+        else if(S_ISFIFO(info.st_mode)){
+            permission[0] = 'p';
+        }
+#endif
+#ifdef S_ISLINK
+        else if(S_ISLINK(info.st_mode)){
+            permission[0] = 'l';
+        }
+#endif
+#ifdef S_ISSOCK
+        else if(S_ISSOCK(info.st_mode)){
+            permission[0] = 's';
+        }
+#endif
+        else
+            permission[0] = '-';
+        info.st_mode & S_IRUSR ? (permission[1] = 'r') : (permission[1] = '-');
+        info.st_mode & S_IWUSR ? (permission[2] = 'w') : (permission[2] = '-');
+        info.st_mode & S_IXUSR ? (permission[3] = 'x') : (permission[3] = '-');
+        info.st_mode & S_IRGRP ? (permission[4] = 'r') : (permission[4] = '-');
+        info.st_mode & S_IWGRP ? (permission[5] = 'w') : (permission[5] = '-');
+        info.st_mode & S_IXGRP ? (permission[6] = 'x') : (permission[6] = '-');
+        info.st_mode & S_IROTH ? (permission[7] = 'r') : (permission[7] = '-');
+        info.st_mode & S_IWOTH ? (permission[8] = 'w') : (permission[8] = '-');
+        info.st_mode & S_IXOTH ? (permission[9] = 'x') : (permission[9] = '-');
+
+        //Recup le groupe et l'utilisateur
+        grp = getgrgid(info.st_gid);
+        user = getpwuid(info.st_uid);
+
+        //Recup la date
+        memset(mois, 0, 5);
+        date = gmtime(&info.st_mtime);
+        switch(date->tm_mon){
+            case 0:
+                strcpy(mois, "jan.");
+                break;
+            case 1:
+                strcpy(mois, "fev.");
+                break;
+            case 2:
+                strcpy(mois, "mar.");
+                break;
+            case 3:
+                strcpy(mois, "avr.");
+                break;
+            case 4:
+                strcpy(mois, "mai.");
+                break;
+            case 5:
+                strcpy(mois, "jui.");
+                break;
+            case 6:
+                strcpy(mois, "jul.");
+                break;
+            case 7:
+                strcpy(mois, "aou.");
+                break;
+            case 8:
+                strcpy(mois, "sep.");
+                break;
+            case 9:
+                strcpy(mois, "oct.");
+                break;
+            case 10:
+                strcpy(mois, "nov.");
+                break;
+            case 11:
+                strcpy(mois, "dec.");
+                break;
+        }
+
+        //Affiche
+        printf("%s X %s %s %ld %s  %d %d:%d ", permission, user->pw_name, grp->gr_name, info.st_size, mois, date->tm_mday, date->tm_hour, date->tm_min);
+
+        //color the name
+        if(permission[0] == 'd'){
+            printf(BLUE "%s\n" RESET, filename);
+        }
+        else if(permission[3] == 'x'){
+            printf(GREEN "%s\n" RESET, filename);
+        }
+        else{
+            printf("%s\n", filename);
+        }
+}
+
+void printdir(char* path, boolean subdir, boolean hidden){
+    struct dirent** contentsDir;
+    int nbFile;
+    int j = 0;
+    //Recup info
+    if((nbFile = scandir(path, &contentsDir, 0, alphasort)) == ERR){
+        addperror("Erreur scandir()");
+        return;
+    }
+    //Si sous dossier on affiche le dossier d'origine
+    if(subdir){
+        printf("%s :\n", path);
+    }
+    //Si besoins passe les fichiers cachés
+    while(j < nbFile && !hidden && *contentsDir[j]->d_name == '.') j++;
+    //Parcours les fichiers du dossier
+    while(j < nbFile){
+        printls(path, contentsDir[j]->d_name);
+        j++;
+    }
+    //Si on affiche les sous dossiers on parcours le contenue pour les trouver
+    if(subdir){
+        char* completePath;
+        int length;
+        struct stat info;
+        j = 0;
+        //Si besoins passe les fichiers cachés
+        while(j < nbFile && !hidden && *contentsDir[j]->d_name == '.') j++;
+        //Cherche les sous dossiers
+        while(j < nbFile){
+            length = strlen(contentsDir[j]->d_name);
+            if(strncmp(contentsDir[j]->d_name, ".", length) == 0 || strncmp(contentsDir[j]->d_name, "..", length) == 0){
+                j++;
+                continue;
+            }
+            //Création chemin vers le dossier
+            length += strlen(path) + 2;
+            completePath = malloc(sizeof(char) * length);
+            memset(completePath, 0, length);
+            if(path[strlen(path)-1] != '/'){
+                snprintf(completePath, length, "%s/%s", path, contentsDir[j]->d_name);
+            } else {
+                 snprintf(completePath, length, "%s%s", path, contentsDir[j]->d_name);
+            }
+            //Recup info fichier
+            if(stat(completePath, &info) == ERR){
+                addperror("Erreur stat");
+                free(completePath);
+                j++;
+                continue;
+            }
+            //Si c'est un dossier
+            if(S_ISDIR(info.st_mode)){
+                //On l'affiche
+                printf("\n");
+                printdir(completePath, subdir, hidden);
+            }
+            //Tour suivant
+            free(completePath);
+            j++;
+        }
+    }
+    //Nettoyage
+    while (nbFile--) {
+        free(contentsDir[nbFile]);
+    }
+    free(contentsDir);
+}
+
+int main(int argc, char* argv[]){
+    struct stat info;
+    int i = 1, displayed = 0, opt;
+    boolean hiddenFile = false;
+    boolean displaySubDir = false;
+
+    //Gestion des options
+    while((opt = getopt(argc, argv, "aR")) != ERR){
+        switch(opt){
+            case 'a' : 
+                hiddenFile = true;
+                break;
+            case 'R' : 
+                displaySubDir = true;
+                break;
+            default:
+                addperror("getotp error");
+        }
+    }
+
+    //Time to display
+    for(i = 1; i < argc; i++){
+        if(argv[i][0] != '-'){
+            if(stat(argv[i], &info) == ERR){
+                addperror("Erreur stat");
+                return EXIT_FAILURE;
+            }
+            if(S_ISDIR(info.st_mode)){
+                //Affiche le dossier
+                printdir(argv[i], displaySubDir, hiddenFile);
+                displayed = true;
+            }
+            else{
+                printls(argv[i], NULL);
+                displayed = true;
+            }
+        }
+    }
+
+    //Si aucun dossier ou fichier en argument
+    if(!displayed){
+        //On affiche le dossier courrant
+        printdir(".", displaySubDir, hiddenFile);
+    }
+
+    return EXIT_SUCCESS;
+}

+ 23 - 0
myls.h

@@ -0,0 +1,23 @@
+#ifndef MYLS_H
+#define MYLS_H
+
+/* --- Include --- */
+#include "constante.h"
+
+/* --- Fonctions --- */
+/**
+ * Affiche sous la forme ls -l les infos d'un fichier/dossier
+ * @param char* Le chemin vers le fichier (avec ou sans le nom du fichier)
+ * @param char* Le nom du fichier ou NULL si il est déjà dans le chemin
+ */
+void printls(char*, char*);
+
+/**
+ * Affiche tous le contenu d'un dossier
+ * @param char* Le chemin vers le dossier
+ * @param boolean Affiche ou non les sous dossiers
+ * @param boolean Affiche ou non les fichiers/dossiers cachés
+ */
+void printdir(char*, boolean, boolean);
+
+#endif /* MYLS_H */

+ 7 - 8
mysh.c

@@ -17,19 +17,18 @@
 #include "error.h"
 #include "str.h"
 #include "parser.h"
-#include "command.h"
-#include "execute.h"
-#include "ipc.h"
 #include "mysh.h"
+#include "ipc.h"
+#include "execute.h"
 
 /* --- Extern --- */
 extern Error error;
 extern boolean exitsh;
 extern pid_t active;
-int status_cmd = -1;
-int result_cmd = -1;
-char base_path[BUFFER_SIZE];
-pid_list pidlist;
+extern int status_cmd;
+extern int result_cmd;
+extern char base_path[];
+extern pid_list pidlist;
 
 /* --- Globale --- */
 int job = 1;
@@ -82,7 +81,7 @@ int main(int argc, char* argv[], char* envp[]) {
     error_init();
     ini_pid_list(&pidlist);
     //Recup chemain de base de l'application
-    if (getcwd(base_path, sizeof (base_path)) == NULL) {
+    if (getcwd(base_path, sizeof (char) * BUFFER_SIZE) == NULL) {
         addperror("Impossible de récuperer le chemin actuel");
         error.print("Erreur pendant l'initialisation\n");
         clean_pid(&pidlist);

+ 2 - 5
mysh.h

@@ -8,11 +8,8 @@
 #ifndef MYSH_H
 #define MYSH_H
 
-/* --- Extern --- */
-extern int status_cmd;
-extern int result_cmd;
-extern char base_path[];
-extern pid_list pidlist;
+/* --- Include --- */
+#include "command.h"
 
 /* --- Fonctions --- */
 /**

+ 2 - 3
parser.c

@@ -149,7 +149,6 @@ int get_command(Command* c, char* line){
  * @return int SHELL_OK si réussite, SHELL_ERR sinon
  */
 int set_io(Command* c, char* filename, int redir){
-    printf("Redir : %d\n", redir);
     //Declaration variable
     int file;
     //Si fichier existe et on supprime
@@ -387,8 +386,8 @@ int set_redirection(Command* c){
             buffer++;
         }
         //Allocation file et copie nom fichier
-        file = malloc(sizeof(char) * compteur);
-        memset(file, 0, compteur);
+        file = malloc(sizeof(char) * (compteur + 1));
+        memset(file, 0, compteur + 1);
         strncpy(file, deb, compteur);
         //Redirection
         if(set_io(c, file, redir) == SHELL_ERR){

+ 1 - 1
subdiv.c

@@ -50,7 +50,7 @@ node* find_key(subdiv* sd, char* mem, char* key) {
 }
 
 /**
- * Récupère la valeur d'un noeid
+ * Récupère la valeur d'un noeud
  * @param node* La noeud
  * @param char* La mémoire
  */