|
@@ -1,33 +1,71 @@
|
|
|
-#define _DEFAULT_SOURCE
|
|
|
+#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 "parser.h"
|
|
|
+#include <grp.h>
|
|
|
+#include <pwd.h>
|
|
|
#include "error.h"
|
|
|
#include "color.h"
|
|
|
-#include "constante.h"
|
|
|
+#include "myls.h"
|
|
|
|
|
|
-int printDir(struct dirent** contentsDir, char* path, int nbFile,
|
|
|
- boolean hiddenFile){
|
|
|
-
|
|
|
- struct stat info;
|
|
|
- char permission[11] = "---------";
|
|
|
- char completePath[1024];
|
|
|
- int j = 0;
|
|
|
-
|
|
|
- //enleve les fichiers caches
|
|
|
- while(j < nbFile && !hiddenFile && *contentsDir[j]->d_name == '.') j++;
|
|
|
-
|
|
|
- //Affiche les fichiers
|
|
|
- while(j < nbFile){
|
|
|
- path[strlen(path)-1] != '/' ? sprintf(completePath, "%s/%s", path, contentsDir[j]->d_name) : sprintf(completePath, "%s%s", path, contentsDir[j]->d_name);
|
|
|
+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;
|
|
|
+ //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);
|
|
|
+ }
|
|
|
+
|
|
|
+ //Recup info fichier
|
|
|
if(stat(completePath, &info) == ERR){
|
|
|
addperror("Erreur stat");
|
|
|
- return -1;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ //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] = '-');
|
|
@@ -37,19 +75,142 @@ int printDir(struct dirent** contentsDir, char* path, int nbFile,
|
|
|
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] = '-');
|
|
|
- printf("%s %ld %s\n", permission, info.st_size, contentsDir[j]->d_name);
|
|
|
+
|
|
|
+ //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 1 %s %s %s %d %d:%d %ld ", permission, user->pw_name, grp->gr_name, mois, date->tm_mday, date->tm_hour, date->tm_min, info.st_size);
|
|
|
+
|
|
|
+ //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++;
|
|
|
}
|
|
|
- printf("\n");
|
|
|
- return 1;
|
|
|
+ //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);
|
|
|
}
|
|
|
|
|
|
-void ls(int argc, char* argv[]){
|
|
|
- struct dirent** contentsDir;
|
|
|
+int main(int argc, char* argv[]){
|
|
|
struct stat info;
|
|
|
- int i = 1, displayed = 0, nbFile, opt;
|
|
|
+ int i = 1, displayed = 0, opt;
|
|
|
boolean hiddenFile = false;
|
|
|
- boolean checksubDir = false;
|
|
|
+ boolean displaySubDir = false;
|
|
|
|
|
|
//Gestion des options
|
|
|
while((opt = getopt(argc, argv, "aR")) != ERR){
|
|
@@ -58,7 +219,7 @@ void ls(int argc, char* argv[]){
|
|
|
hiddenFile = true;
|
|
|
break;
|
|
|
case 'R' :
|
|
|
- checksubDir = true;
|
|
|
+ displaySubDir = true;
|
|
|
break;
|
|
|
default:
|
|
|
addperror("getotp error");
|
|
@@ -70,39 +231,25 @@ void ls(int argc, char* argv[]){
|
|
|
if(argv[i][0] != '-'){
|
|
|
if(stat(argv[i], &info) == ERR){
|
|
|
addperror("Erreur stat");
|
|
|
- return;
|
|
|
+ return EXIT_FAILURE;
|
|
|
}
|
|
|
if(S_ISDIR(info.st_mode)){
|
|
|
- if((nbFile = scandir(argv[i], &contentsDir, 0, alphasort)) == ERR){
|
|
|
- addperror("Erreur scandir()");
|
|
|
- return;
|
|
|
- }
|
|
|
- printf("%s : \n\n", argv[i]);
|
|
|
- displayed = printDir(contentsDir, argv[i], nbFile, hiddenFile);
|
|
|
+ //Affiche le dossier
|
|
|
+ printdir(argv[i], displaySubDir, hiddenFile);
|
|
|
+ displayed = true;
|
|
|
}
|
|
|
else{
|
|
|
- printf("%d %ld %s\n", info.st_mode, info.st_size, argv[i]);
|
|
|
- displayed = 1;
|
|
|
+ //printls(argv[i]);
|
|
|
+ displayed = true;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ //Si aucun dossier ou fichier en argument
|
|
|
if(!displayed){
|
|
|
- nbFile = scandir(".", &contentsDir, 0, alphasort);
|
|
|
- if (nbFile < 0) {
|
|
|
- addperror("Erreur scandir()");
|
|
|
- return;
|
|
|
- }
|
|
|
- displayed = printDir(contentsDir, ".", nbFile, hiddenFile);
|
|
|
+ //On affiche le dossier courrant
|
|
|
+ printdir(".", displaySubDir, hiddenFile);
|
|
|
}
|
|
|
|
|
|
- printf("%d %d\n", hiddenFile, checksubDir);
|
|
|
-
|
|
|
- return;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-int main(int argc, char* argv[]){
|
|
|
- ls(argc, argv);
|
|
|
- printf(RESET);
|
|
|
+ return EXIT_SUCCESS;
|
|
|
}
|