Consultas, desarrollo de programas y petición de presupuestos:

jueves, 12 de julio de 2012

examen 5 solucion compi. Antonio

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