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

jueves, 12 de julio de 2012

examen 5: solucion alumno (usando colores)







// Paginas web de referencia:
// tomado del: https://sites.google.com/site/fpoprogramadorsistemas/analisis-de-argumentos-2
// https://sites.google.com/site/fpoprogramadorsistemas/soluciones-profe-del-cat
#include <stdio.h>
#include <limits.h>
#include <string.h>

// https://sites.google.com/site/fpoprogramadorsistemas/c-trabajar-con-directorios
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <time.h>

// para datos del usuario: man getpwuid
#include <pwd.h>

//http://www.fismat.umich.mx/mn1/manual/node19.html
#include <unistd.h> // leer la ruta actual donde este el programa

#include <grp.h> // datos del grupo




void VerResultadoA(char *, struct stat *); //lsl -a: ocultos y visibles mas datos.
void escribedatos(char *, struct stat *);
void VerResultadoAC(char *, struct stat *); //lsl -aca: ocultos y visibles sin datos
void VerResultadoC(char *, struct stat *); //lsl -c: solo nombre de visibles
void VerResultadoLSL(char *, struct stat *); //lsl: de visibles mas datos
int comprobar_Directorio_o_Fichero(char *); // lsl comprobar directorio o fichero


int procesarArgumentos(int, char **);

DIR *pdir;
char *nomfich;
char nomcomp[255];
struct stat st;
struct dirent *dp;
FILE *pf;

char cadena[125]; // aqui guarda el directorio actual si solo ejecuto LSL


// procesa todos los argumentos que reciba, y devuelve un numero
// positivo= la suma de los valores de los argumentos
// negativo =hay argumentos pero no son validos
// cero= no hay ningun argumento

int argumento(char *); // procesa   cada argumento de forma

int esArgumento(char *); // comprueba que es un argumento

int main(int argc, char **argv)
{
    int resul;
    int numero_de_argumentos=0; // contador de argumentos
    int uno=0;
    int dos=0;

    int archivo=0;
    int valor=0;

// caso de lsl solo
// comprobacion si: es un archivo o directorio, y si existen....
    if (argc==1) {
        printf("Se trata del comando lsl solo.\n");
        // se trata de solo la orden lsl
        pdir = opendir(".");
        dp = readdir(pdir);
        while (dp != NULL) {
            sprintf(nomcomp, "%s/%s", ".", dp->d_name);
            nomfich = dp->d_name;

            if (stat(nomcomp, &st) < 0) {
                perror(nomcomp);
            } else {
                VerResultadoLSL(nomfich, &st);
            }
            dp = readdir(pdir);
        }
        closedir(pdir);
        return 0; //  termino el programa aqui

    }




// hay mas de 1 arguento......

// PROCESAR ARGUMENTOS......
    resul = procesarArgumentos(argc, argv);
    printf("Trabajo realizar: \n");
    if (resul > 0) { //
        if (resul & 1) { // Enmascaramiento Binario: pregunto por los numero &(=y logico a nivel de bits). (no es lo mismo que  &&) posicion 1, vease final
            printf("Usado argumento \"a\"\n");
            numero_de_argumentos++;
            uno=1;
        }
        if (resul & 2) {
            printf("Usado argumento \"c\"\n");
            dos=1;
            if (uno!=1) {
                // para que no sume cuando la a esta tambien...
                numero_de_argumentos++;
            }
        }

    }

//***********************************************************************************
// dos= 1 ,numero de agumento =1
// uno=1, numero de agumento =1
// uno=1 y dos=1, numero de argumentos=2
//***********************************************************************************



// caso de lsl y directorio/fichero
    if (uno==0 && dos==0 && argc==2) {
// ver si es un archivo o un directorio y listar como si fuera lsl solo

        valor=comprobar_Directorio_o_Fichero(argv[1]);
// devuelve 1 si es directorio.
// devuelve 2 si es fichero.
        if (valor==1) {
            pdir = opendir(argv[1]);
            dp = readdir(pdir);
            while (dp != NULL) {
                sprintf(nomcomp, "%s/%s", argv[1], dp->d_name);
                nomfich = dp->d_name;

                if (stat(nomcomp, &st) < 0) {
                    perror(nomcomp);
                } else {
                    VerResultadoLSL(nomfich, &st);
                }
                dp = readdir(pdir);
            }
            closedir(pdir);
            return 0; //  termino el programa aqui

        }
        if (valor==2) {
            if((pf = fopen(argv[1], "r")) != NULL) {
                // es un archivo... lo que nos han pasado
                archivo=1;
                //Importante: cargo con la funcio stat los datos del fichero a st
                if (stat(argv[1], &st) < 0) {
                    perror(argv[1]);
                } else {

                    VerResultadoLSL(argv[1], &st);
                }
                fclose(pf);
            } else {
                printf("Error: no encuentro el fichero");
            }

            return 0;
        }
    }




// caso de lsl un argumento y sin nada: caso a al directorio actual
    if (uno==1 && dos==0 && argc==2) {
        // ver si es un archivo o un directorio y listar como si fuera lsl solo
        pdir = opendir(".");
        dp = readdir(pdir);
        while (dp != NULL) {
            sprintf(nomcomp, "%s/%s", ".", dp->d_name);
            nomfich = dp->d_name;

            if (stat(nomcomp, &st) < 0) {
                perror(nomcomp);
            } else {
                VerResultadoA(nomfich, &st);
            }
            dp = readdir(pdir);
        }
        closedir(pdir);
        return 0; //  termino el programa aqui

    }


// caso de lsl un argumento y sin nada: caso c

    if (uno==0 && dos==1 && argc==2) {
        // ver si es un archivo o un directorio y listar como si fuera lsl solo


        pdir = opendir(".");
        dp = readdir(pdir);
        while (dp != NULL) {
            sprintf(nomcomp, "%s/%s", ".", dp->d_name);
            nomfich = dp->d_name;

            if (stat(nomcomp, &st) < 0) {
                perror(nomcomp);
            } else {
                VerResultadoC(nomfich, &st);
            }
            dp = readdir(pdir);
        }
        closedir(pdir);
        return 0; //  termino el programa aqui

    }


// caso de lsl un argmento y con directorio/fichero: caso a
    if (uno==1 && dos==0 && argc==3) {

        valor=comprobar_Directorio_o_Fichero(argv[3-1]);
// devuelve 1 si es directorio.
// devuelve 2 si es fichero.
        if (valor==1) {
            pdir = opendir(argv[3-1]);
            dp = readdir(pdir);
            while (dp != NULL) {
                sprintf(nomcomp, "%s/%s",argv[3-1] , dp->d_name);
                nomfich = dp->d_name;
                if (stat(nomcomp, &st) < 0) {
                    perror(nomcomp);
                } else {
                    VerResultadoA(nomfich, &st);
                }
                dp = readdir(pdir);
            }
            closedir(pdir);
            return 0; //  termino el programa aqui

        }
        if (valor==2) {
            if((pf = fopen(argv[3-1], "r")) != NULL) {
                // es un archivo... lo que nos han pasado
                archivo=1;

                if (stat(argv[3-1], &st) < 0) {
                    perror(argv[3-1]);
                } else {

                    VerResultadoA(argv[3-1], &st);
                }
                fclose(pf);

            }
            return 0;
        }

    }


// caso de lsl un argmento y con directorio/fichero: caso c
    if (uno==0 && dos==1 && argc==3) {
        valor=comprobar_Directorio_o_Fichero(argv[3-1]);

// devuelve 1 si es directorio.
// devuelve 2 si es fichero.
        if (valor==1) {
            pdir = opendir(argv[3-1]);
            dp = readdir(pdir);
            while (dp != NULL) {
                sprintf(nomcomp, "%s/%s",argv[3-1] , dp->d_name);
                nomfich = dp->d_name;
                if (stat(nomcomp, &st) < 0) {
                    perror(nomcomp);
                } else {
                    VerResultadoC(nomfich, &st);
                }
                dp = readdir(pdir);
            }
            closedir(pdir);
            return 0; //  termino el programa aqui

        }
        if (valor==2) {
            if((pf = fopen(argv[3-1], "r")) != NULL) {
                // es un archivo... lo que nos han pasado
                archivo=1;


                if (stat(argv[3-1], &st) < 0) {
                    perror(argv[3-1]);
                } else {
                    VerResultadoC(argv[3-1], &st);
                    fclose(pf);
                }
                return 0;
            }

        }
    }

// caso de lsl dos argumentos y sin nada: lsl -a -c ó es -a-c
    if (uno==1 && dos==1 &&  argc==2) {
        pdir = opendir(".");
        dp = readdir(pdir);
        while (dp != NULL) {
            sprintf(nomcomp, "%s/%s","." , dp->d_name);
            nomfich = dp->d_name;

            if (stat(nomcomp, &st) < 0) {
                perror(nomcomp);
            } else {
                VerResultadoAC(nomfich, &st);
            }
            dp = readdir(pdir);
        }
        closedir(pdir);
        return 0; //  termino el programa aqui

    }


// caso de lsl dos argumentos con fichero: lsl -a -c ó es -ac ó es -ca + fichero
    if (uno==1 && dos==1 &&  argc==3) {
        valor=comprobar_Directorio_o_Fichero(argv[3-1]);
// devuelve 1 si es directorio.
// devuelve 2 si es fichero.
        if (valor==1) {
            pdir = opendir(argv[3-1]);
            dp = readdir(pdir);
            while (dp != NULL) {
                sprintf(nomcomp, "%s/%s",argv[3-1], dp->d_name);
                nomfich = dp->d_name;

                if (stat(nomcomp, &st) < 0) {
                    perror(nomcomp);
                } else {
                    VerResultadoAC(nomfich, &st);
                }
                dp = readdir(pdir);
            }
            closedir(pdir);
            return 0; //  termino el programa aqui
        }

        if (valor==2) {
            if((pf = fopen(argv[3-1], "r")) != NULL) {
                // es un archivo... lo que nos han pasado
                archivo=1;

                if (stat(argv[3-1], &st) < 0) {
                    perror(argv[3-1]);
                } else {

                    VerResultadoC(argv[3-1], &st);
                    fclose(pf);
                }
                return 0;
            }
        }
    }

// caso de lsl dos argumentos y con directorio o fichero
    if (uno==1 && dos==1 && argc==4) {
        valor=comprobar_Directorio_o_Fichero(argv[4-1]);
// devuelve 1 si es directorio.
// devuelve 2 si es fichero.
        if (valor==1) {
            pdir = opendir(argv[4-1]);
            dp = readdir(pdir);
            while (dp != NULL) {
                sprintf(nomcomp, "%s/%s",argv[4-1] , dp->d_name);
                nomfich = dp->d_name;
                if (stat(nomcomp, &st) < 0) {
                    perror(nomcomp);
                } else {
                    VerResultadoAC(nomfich, &st);
                }
                dp = readdir(pdir);
            }
            closedir(pdir);
            return 0; //  termino el programa aqui

        }
        if (valor==2) {
            if((pf = fopen(argv[4-1], "r")) != NULL) {
                // es un archivo... lo que nos han pasado
                archivo=1;


                if (stat(argv[4-1], &st) < 0) {
                    perror(argv[4-1]);
                } else {
                    VerResultadoAC(argv[4-1], &st);
                    fclose(pf);
                }
                return 0;
            }

        }





    }
    return 0;

}


//-------------------------------------------------------------------------------
// FIN DEL MAIN
//-------------------------------------------------------------------------------


//-------------------------------------------------------------------------------
// OTRAS FUNCIONES
//-------------------------------------------------------------------------------

// Procesa la lista de argumentos.
// Devuelve un nº positivo indicando la suma de los argumentos empleados
// Negativo si alguna letra no es válida

int procesarArgumentos(int argc, char **argv)
{
    char usados[100] = "";
    int c = 0;
    int suma = 0;
    char *argu; // para procesar la lista de argumentos

    int valor;
    char *posUsados;
// para buscar en la tabla de usados
// el argumento 0 no lo proceso ya que  es el nombre del programa, y empieza por el c=1
    for (c = 1; c < argc; c++) {
        argu = argv[c];


        if(esArgumento(argu)) {
            //sumo al puntero 1 posicion, me desplazo a la derecha una posicion
            //(salto al signo menos que no me interesa analizar ahora dentro de la cadena)

            argu++;

            //*argu=conenido a lo que apuntaba argu: la letra "a" en asci no vale cero,
            // por lo tanto cumple la condicion de que sea distinto de cero
            // cuando encuentre \0, el valor numerico es 0, con lo cual parará el while.
            while (*argu) {
                valor = argumento(argu);

                // 0 es cuando no tenga signo menos, y negativo cuendo no lo encuentra en la tabla
                if (valor > 0) {
                    posUsados = strchr(usados, *argu);
                    // si el usuario pone varias veces el mismo argumento, solo lo cuenta una vez

                    //si no lo he encontrado lo meto en la tabla
                    if (posUsados == NULL) {
                        usados[strlen(usados)] = *argu;
                    } else {
                        // si la he encontrado, es porque ha repetido el valor
                        valor = 0;
                    }
                }
                // calculo la suma de todos los arguemntos
                suma += valor;
                //me desplazo al siguiente argumento
                argu++;
            }
        }
    }
    return suma;
}


// Procesa un argumento de forma individual
// Devuelve INT_MIN si no es válido y positivo si lo es (2 ^ posicion)


int argumento(char *argu)
{

// los argumentos validos van a ser: a,c
// el comando -l ya lo doy visto

    char valen[] = { "ac" };

    // tabla sin tamaño definido([]), el compilador cuenta los elementos "abcdef",
    // y lo dimensiona automaticamente, tambien valdria: char valen[6]={ "abcdef" }

    char *pos;
    int dif; // es la diferencia....

    if ((pos = strchr(valen, argu[0]))) {
        // la asignación pos=strchr. La función strchr te busca un caracter en una cadena:
        // si lo encuentra lo que hace es que pos apunte al caracter,
        // y la expresion (pos=strchr(valen, *argu[0])) la evalua el if.
        // si strchr() devuelve una posicion, pos = esa posicion, con lo cual es correcto(verdadero)
        // si strchr() no devuelve nada (NULL), no lo ha encontrado, pos=NULL, con lo cual el falso

        dif = (pos - valen); // se pueden hacer operaciones aritmeticas con los puntero,
        // se estan restando las posiciones.
        // por ejemplo si pos marcaria 12034, y si valen marcaria 12035, dif=1

        return (1 << dif); // << operador binario que trabaja con bits, y hace desplazamiento a la izquierda
    } else {
        return INT_MIN; //
    }
}

int esArgumento(char *argu)
{
// en el puntero *argu, (guarda la posicion donde esta apuntando)
//...y nos puede mostrar  el contenido a donde apunta:

    if (*argu == '-') {
        // si el primer carater es '-' es un argumento.
        return 1; // verdadero
    }
    return 0; // falso
}

//------------------------------------------------------------------------------------------
void VerResultadoA(char *nomfich, struct stat *st)
{
    escribedatos(nomfich,st); // todos, incluidos los ocultos
}


void VerResultadoAC(char *nomfich, struct stat *st)
{
    // voy a colorear segun sea fichero,directorio,o enlace

    struct tm *t;
    struct passwd *p;
    struct group *p2;
    struct stat atributos;
    char permiso[13];
    t = gmtime(&st->st_mtime);
    int ejecutable=0;
    int directorio=0;
    int enlace=0;
    int fichero=0;
   
   
    lstat(nomfich,&atributos); // leo todos los atributos de nomfich
   
   
    if((atributos.st_mode & S_IXUSR)!=0) {
       
        ejecutable=1;
    } else {
       
    }
   
   
    if( S_ISDIR(st->st_mode )) {

        directorio=1;
    } else {
        if(( S_ISREG(st->st_mode ))) {
            //ES UN FICHERO

            fichero=1;
        } else {
            if((S_ISLNK(st->st_mode ))) {
                // es un enlace Simbolico
           
                enlace=1;
            }
        }
    }
   
   
if (ejecutable==1 && fichero==1 ) {
        // lo pongo en verde
        printf("\033[0;32m %-20s \033[m\n",  nomfich);
    }

    if (directorio==1) {
        // lo pongo en azul
        printf("\033[0;34m %-20s \033[m\n",  nomfich);
    } else {
        if (fichero==1 && ejecutable==0) {
            // lo pongo en gris claro
            printf("\033[1;30m %-20s \033[m\n",  nomfich);
        }
    }
}

void VerResultadoC(char *nomfich, struct stat *st)
{
    if (nomfich[0]!='.') {
        // se trata visible
        VerResultadoAC(nomfich,st);
    }

}



void VerResultadoLSL(char *nomfich, struct stat *st)
{

// muestro todos los archivos (incluido los ocultos)

    escribedatos(nomfich,st);


}

//-----------------------------------------------------------------------------------------------
// Funcion para saber si lo me pasan es un directorio o un fichero
//----------------------------------------------------------------------------------------------
// intento abrirlo con opendir(),
//             si me da error no es un directorio en caso contrario es un directorio y devuelve 1
// si ha dado error en opendir(), intento abrirlo como un fichero fopen(), si no da error es un fichero y
//             devuelve 2, en caso contrario devuelve 0

// devuelve 1 si es directorio.
// devuelve 2 si es fichero.


int comprobar_Directorio_o_Fichero(char *argumento)
{

    pdir = opendir(argumento);
    if (pdir != NULL) {
        // es un directorio.... lo que nos han dado
        //directorio=1;
        printf("directorio: %s\n",argumento);
        closedir(pdir);
        return 1;
    } else {
        if((pf = fopen(argumento, "r")) != NULL) {
            // es un archivo... lo que nos han pasado
            //    archivo=1;
            printf("Fichero: %s\n",argumento);
            fclose(pf);
            return 2;
        }
    }
    return 0;
}

void escribedatos(char *nomfich, struct stat *st)
{
    struct tm *t;
    struct passwd *p;
    struct group *p2;
    struct stat atributos;
    char permiso[13];
    t = gmtime(&st->st_mtime);
    p=getpwuid(st->st_uid);
    p2=getgrgid(st->st_gid);
    int ejecutable=0;
    int directorio=0;
    int fichero=0;
    int enlace=0;
    // http://www.juntadeandalucia.es/averroes/iesbajoguadalquivir/inf/dfsi/lstat.c
    lstat(nomfich,&atributos);
    //    printf("\nPermisos:\n");


//  p=passwd(&);
    printf("%8ld bytes %02d/%02d/%4d %02d:%02d:%02d  %-10s %-10s ",
           st->st_size,
           t->tm_mday,
           t->tm_mon + 1,
           t->tm_year + 1900,
           t->tm_hour,
           t->tm_min,
           t->tm_sec,

           // ------------------
           //  t->tm_nlink ,

           p->pw_name,
           p2->gr_name);
    //-------------------

    // es un directorio
    if( S_ISDIR(st->st_mode )) {
        printf(" D ");
        directorio=1;
    } else {
        if(( S_ISREG(st->st_mode ))) {
            //ES UN FICHERO
            printf(" F ");
            fichero=1;
        } else {
            if((S_ISLNK(st->st_mode ))) {
                // es un enlace Simbolico
                printf(" E ");
                enlace=1;
            }
        }
    }


    if((atributos.st_mode & S_IRUSR)!=0) {
        printf("r");
    } else {
        printf("-");
    }
    if((atributos.st_mode & S_IWUSR)!=0) {
        printf("w");
    } else {
        printf("-");
    }

    if((atributos.st_mode & S_IXUSR)!=0) {
        printf("x");
        ejecutable=1;
    } else {
        printf("-");
    }

    if((atributos.st_mode & S_IRGRP)!=0) {
        printf("r");
    } else {
        printf("-");
    }

    if((atributos.st_mode & S_IWGRP)!=0) {
        printf("w");
    } else {
        printf("-");
    }

    if((atributos.st_mode & S_IXGRP)!=0) {
        printf("x");
    } else {
        printf("-");
    }

    if((atributos.st_mode & S_IROTH)!=0) {
        printf("r");
    } else {
        printf("-");
    }

    if((atributos.st_mode & S_IWOTH)!=0) {
        printf("w");
    } else {
        printf("-");
    }

    if((atributos.st_mode & S_IXOTH)!=0) {
        printf("x");
    } else {
        printf("-");
    }


    if((atributos.st_mode & S_ISUID)!=0) {
        printf("1");
    } else {
        printf("-");
    }

    if((atributos.st_mode & S_ISGID)!=0) {
        printf("2");
    } else {
        printf("-");
    }

    if((atributos.st_mode & S_ISVTX)!=0) {
        printf("t");
    } else {
        printf("-");
    }

    if (ejecutable==1 && fichero==1 ) {
        // lo pongo en verde
        printf("\033[0;32m %-20s \033[m\n",  nomfich);
    }

    if (directorio==1) {
        // lo pongo en azul
        printf("\033[0;34m %-20s \033[m\n",  nomfich);
    } else {
        if (fichero==1 && ejecutable==0) {
            // lo pongo en gris claro
            printf("\033[1;30m %-20s \033[m\n",  nomfich);
        }
    }

}

No hay comentarios:

Publicar un comentario