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);
}
}
}
Suscribirse a:
Enviar comentarios (Atom)
No hay comentarios:
Publicar un comentario