#define _POSIX_C_SOURCE 200809L #include #include #include #include #include #include #include #include #include #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; }