123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- #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;
- }
|