/*
* 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 ;
}