/* * Recréation de la commande LS * TP/TP de Système * alex, DUT Année Spéciale, IUT NANCY Charlemagne (2006) */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <dirent.h> #include <sys/stat.h> #include <pwd.h> #include <time.h> #include <grp.h> int main ( int argc , char ** argv ) { // Déclarations DIR * rep_courant ; struct dirent * entree ; char * nom ; char modeFichier = '-' ; char modeFinFichier = ' ' ; char chemin [ 256 ] ; char esc = 27 ; char couleur [ 7 ] ; char rst [ ] = "[0m" ; struct stat statinfo ; int sommeBlocs ; int tailleBloc ; char * droits [ ] = { "---" , "--x" , "-w-" , "-wx" , "r--" , "r-x" , "rw-" , "rwx" } ; int b ; // Lecture des paramètres passés sur la ligne de commande if ( argc < 2 ) strcpy ( chemin , "." ) ; else strcpy ( chemin , argv [ 1 ] ) ; // Ouvre le répertoire courant if ( ( rep_courant = opendir ( chemin ) ) == NULL ) { // Si il n'a pas été possible de l'ouvrir, on sort sur une erreur printf ( "Impossible d'ouvrir le répertoire %s\n" , argv [ 1 ] ) ; exit ( 2 ) ; } sommeBlocs = 0 ; tailleBloc = 0 ; // Parcoure la liste des entrées figurant dans ce répertoire while ( entree = readdir ( rep_courant ) ) { //Récupère le nom du fichier nom = entree -> d_name ; //S'il ne commence pas par un point (fichiers cachés sous unix) if ( nom [ 0 ] != '.' ) { //Regarde les informations sur le fichier b = lstat ( nom , & statinfo ) ; //Détermine le mode du fichier //un fichier ordinaire ? if ( S_ISREG ( statinfo . st_mode ) ) { modeFichier = '-' ; //Fichier exécutable ? if ( ( statinfo . st_mode & S_IXUSR ) || ( statinfo . st_mode & S_IXGRP ) || ( statinfo . st_mode & S_IXOTH ) ) { modeFinFichier = '*' ; strcpy ( couleur , "[1;32m" ) ; } else { modeFinFichier = ' ' ; strcpy ( couleur , "[0m" ) ; } } //un répertoire ? if ( S_ISDIR ( statinfo . st_mode ) ) { modeFichier = 'd' ; modeFinFichier = '/' ; strcpy ( couleur , "[1;34m" ) ; } //un périphérique en mode caractère ? if ( S_ISCHR ( statinfo . st_mode ) ) { modeFichier = 'c' ; modeFinFichier = '/' ; strcpy ( couleur , "[33m" ) ; } //un périphérique en mode bloc ? if ( S_ISBLK ( statinfo . st_mode ) ) { modeFichier = 'b' ; modeFinFichier = ' ' ; strcpy ( couleur , "[33m" ) ; } //FIFO (tube nommé) ? if ( S_ISFIFO ( statinfo . st_mode ) ) { modeFichier = 'p' ; modeFinFichier = '|' ; strcpy ( couleur , "[1;35m" ) ; } //un lien symbolique ? if ( S_ISLNK ( statinfo . st_mode ) ) { modeFichier = 'l' ; modeFinFichier = '@' ; strcpy ( couleur , "[1;36m" ) ; } //une socket ? if ( S_ISSOCK ( statinfo . st_mode ) ) { modeFichier = 's' ; modeFinFichier = '=' ; strcpy ( couleur , "[1;35m" ) ; } sommeBlocs += statinfo . st_blocks ; if ( tailleBloc == 0 ) tailleBloc = statinfo . st_blksize ; //Affiche les infos sur le fichier (format long de la commande ls) printf ( "%c%s%s%s %d %s %s %-4d\t%d-%02d-%02d %02d:%02d %c%s%s%c%s%c\n" , modeFichier , //Mode de fichier (répertoire, lien, régulier, ...) droits [ ( statinfo . st_mode ) >> 6 & 7 ] , //Droits de l'utilisateur droits [ ( statinfo . st_mode ) >> 3 & 7 ] , //Droits du groupe droits [ ( statinfo . st_mode ) >> 0 & 7 ] , //Droits du reste du monde statinfo . st_nlink , //Nombre de liens matériels ( getpwuid ( statinfo . st_uid ) ) -> pw_name , //Nom (en clair) de l'utilisateur ( getgrgid ( statinfo . st_gid ) ) -> gr_name , //Nom (en clair) du groupe statinfo . st_size , //Taille du fichier 1900 + ( localtime ( & ( statinfo . st_mtime ) ) ) -> tm_year , //Année de dernière modification 1 + ( localtime ( & ( statinfo . st_mtime ) ) ) -> tm_mon , //Mois de dernière modification ( localtime ( & ( statinfo . st_mtime ) ) ) -> tm_mday , //Jour de dernière modification ( localtime ( & ( statinfo . st_mtime ) ) ) -> tm_hour , //Heure de dernière modification ( localtime ( & ( statinfo . st_mtime ) ) ) -> tm_min , //Minutes de dernière modification esc, couleur, //La séquence d'échappement suivi de la couleur pour le fichier nom , //Nom du fichier esc, rst , //La séquence d'échappement de réinitialisation des couleurs modeFinFichier //Le caractère ajouté à la fin du fichier ) ; } //Fin if } //Fin while closedir ( rep_courant ) ; //Ferme le répertoire printf ( "Total : %d\ntaille bloc : %d\n" , sommeBlocs , tailleBloc ) ; return 0 ; }