Antonio, es otro alumno del curso, que ha resuelto el problema de otra
forma (aunque no resuelve el caso de que le demos un fichero). Pero como
siempre es interesante ver las distintas formas resolver el problema,
aqui os lo dejo:
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>
#define FALSE 0
#define TRUE !0
void
VerResultado(char *, struct stat *,int ,int); //Función que te
muestra los resultados de lsl dependiendo de los argumentos.
void
permisos (char *, struct stat *); //Función que nos
compara st_mode con sus banderas y nos escribe las letras en la cadena
perm.
int main(int argc, char **argv) {
DIR *pdir; // declaramos un puntero de tipo DIR que permite manejar directorios.
char nomcomp[255];
struct stat st; // variable st de tipo strut stat.
struct dirent *dp; // puntero dp de tipo struct dirent.
int c=1;
int argumento_a=0;
int argumento_c=0;
while(c<argc) { // Mientras c sea menor que el número de palabras introducidas, sigue comprobando.
if(strcmp(argv[c],"-a")==0) {
argumento_a=TRUE;
} else {
if(strcmp(argv[c],"-c")==0) {
argumento_c=TRUE;
} else {
if(strcmp(argv[c],"-ac")==0 || (strcmp(argv[c],"-ca")==0 )) {
argumento_c=TRUE;
argumento_a=TRUE;
} else {
if(argumento_c==TRUE && argumento_a==TRUE) { //Si ya tiene los 2 argumentos, se sale del bucle.
c=argc;
} else {
pdir = opendir(argv[c]); //si el
argumento no es válido intentamos abrir (argv[c]) como directorio.
if (pdir == NULL) { // si no se
puede abrir ese directorio nos dara error y se saldra del programa.
perror(argv[0]); // nos devuelve el mensaje de error actual de tu programa (perror)
exit(-1);
}
}
}
}
}
c++; //Aseguramos la salida sumando 1 a c.
}
pdir = opendir(argv[argc-1]); // abrimos un directorio que
lo recibimos en argv[argc-1] y lo pasamos al puntero pdir (opendir)
if (pdir == NULL) {
pdir = opendir("."); //si no se puede abrir
argv[argc-1](se supone que es el directorio),abriremos el
actual(significará que se ha escrito solo lsl porque si nos falla por un
argumento inválido ya lo tenemos controlado anteriormente)
if (pdir == NULL) { // si no se puede abrir ese directorio nos dara error y se saldra del programa.
perror(argv[0]); // nos devuelve el mensaje de error actual de tu programa (perror)
exit(-1);
}
strcpy(argv[argc-1],"."); // Si consigue abrir el
directorio actual, le decimos que el actual es "." que si es el
directorio válido.
}
dp = readdir(pdir);
// si la linea 24 ha funcionado, leemos una entrada del directorio
(readdir) y la pasamos a dp
while (dp != NULL) { // mientras haya directorios que leer.
sprintf(nomcomp, "%s/%s", argv[argc-1], dp->d_name); //
como dp es un puntero ponemos dp->d_name(sino fuera puntero dp.d_name
que seria igual que la que teniamos en otro programa donde poniamos
tablaRecords.nombre)
if (stat(nomcomp, &st) < 0) {
// stat te devuelve un valor numerico y obtiene informacion de un
fichero y me la guarda en &st(que hace referencia a la direccion de
memoria donde se almacena esa variable)
perror(nomcomp);
} else {
VerResultado(dp->d_name,
&st,argumento_a,argumento_c); // si obtiene la informacion y la
ha podido guardar en st le pasamos a la funcion VerResultado el nombre
fichero y la direccion de memoria donde esta almacenada su información.
}
dp = readdir(pdir); // leo el siguiente nombre de
archivo que haya en el directorio hasta que devuelva un NULL al puntero
dp
}
closedir(pdir);
return 0;
}
// Funcion que muestra el nombre de fichero o directorio y la informacion detallada.
void
VerResultado(char *nomfich, struct stat *st,int argumento_a,int
argumento_c) { // recifimos un puntero llamado nomfich y un puntero a
la variable st de tipo struct stat
struct tm *t; // creamos una structura del tipo tm y la manejamos por medio del puntero t
struct passwd *pwu; // creamos otras 2 estructuras para el id de grupo y se usuario.
struct group *pwg;
char perm[10];
t = gmtime(&st->st_mtime); // a t le
pasamos la funcion gmtime(coge el numero q te da st_mtime y lo desglosa
en horas,minutos,segundos,etc) le indicamos el trozo de memoria de st
,mtime
pwu = getpwuid(st->st_uid); // a
pwu y pwg le pasamos los nombres de usuario y grupo respectivamente.
pwg = getgrgid(st->st_gid);
permisos(perm,st); // declaramos la
función permisos, que nos devuelve la variable perm con los permisos en
letras.
if(argumento_a==TRUE && argumento_c==FALSE) {
printf("%s %3d %s %s %8ld bytes %02d/%02d/%4d %02d:%02d:%02d %-20s\n",
perm,
st->st_nlink,
pwu->pw_name,
pwg->gr_name,
st->st_size,
t->tm_mday,
t->tm_mon + 1,
t->tm_year + 1900,
t->tm_hour,
t->tm_min,
t->tm_sec,
nomfich);
} else {
if(argumento_a==TRUE && argumento_c ==TRUE) {
printf("%20s\n",nomfich); //Nos muestra directorios y ficheros y además ocultos cada uno en una línea.
} else {
if(nomfich[0]!='.') { //Si el argumento a es FALSE(no muestra los ocultos),imprime los directorios visibles.
if(argumento_a==FALSE && argumento_c==TRUE) {
printf("%20s\n",nomfich);
} else {
if(argumento_a==FALSE && argumento_c==FALSE) { //Si no se especifica ningun argumento.
printf("%s %3d %s %s %8ld bytes %02d/%02d/%4d %02d:%02d:%02d %-20s\n",
perm, //variable que contiene una cadena de caracteres con los permisos.
st->st_nlink,
pwu->pw_name,
pwg->gr_name,
st->st_size,
t->tm_mday,
t->tm_mon + 1,
t->tm_year + 1900,
t->tm_hour,
t->tm_min,
t->tm_sec,
nomfich);
}
}
}
}
}
}
// Procedimiento que te escribe los permisos en letras.
void permisos (char *perm, struct stat *st) { //comparamos st_mode con sus banderas para escribir los permisos en perm.
if (S_ISDIR(st->st_mode)) { //es un directorio?
perm[0] = 'd';
} else if(S_ISLNK(st->st_mode)) { //es un enlace?
perm[0] = 'l';
} else { //es un fichero?
perm[0]= '-';
}
if (st->st_mode & S_IRUSR) { //tiene permiso de lectura el usuario?
perm[1] = 'r';
} else {
perm[1] = '-';
}
if (st->st_mode & S_IWUSR) { //tiene permiso de escritura el usuario?
perm[2] = 'w';
} else {
perm[2] = '-';
}
if (st->st_mode & S_IXUSR) {
perm[3] = 'x';
} else {
perm[3] = '-';
}
if (st->st_mode & S_IRGRP) {
perm[4] = 'r';
} else {
perm[4] = '-';
}
if (st->st_mode & S_IWGRP) {
perm[5] = 'w';
} else {
perm[5] = '-';
}
if (st->st_mode & S_IXGRP) {
perm[6] = 'x';
} else {
perm[6] = '-';
}
if (st->st_mode & S_IROTH) {
perm[7] = 'r';
} else {
perm[7] = '-';
}
if (st->st_mode & S_IWOTH) {
perm[8] = 'w';
} else {
perm[8] = '-';
}
if (st->st_mode & S_IXOTH) {
perm[9] = 'x';
} else {
perm[9] = '-';
}
}
No hay comentarios:
Publicar un comentario