ENUNCIADO

El programa que hay que realizar no admite ningun argumento por la línea de órdenes de la shell. El programa listará el nombre de todos los ficheros del directorio actual en los que haya trascurrido más de una semana desde que fueron modificados la última vez hasta que fueron accedidos por última vez. Hacer una comprobación no paranoica de errores.

COMENTARIOS

En esta ocasión, la solución era bastante fácil si nos fijamos en la versión para HPUX. Casi todas las prácticas enviadas están muy bien, pero los que primero la enviaron correctamente fueron Matrix y Neo, a los que les corresponde 0.25. Aprovecho la ocasión para desearles suerte en la segunda parte de la película y que no se cumpla lo de "Nunca segundas partes fueron buenas".
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/dirent.h>


int main(int argc,char *argv[])
   {int fd, fin;
    char etiqueta[80];
    struct dirent *buffer;
    struct stat estado;
    long tamano;
    struct dirent *sdp;
    float diferencia;


    if (argc!=1)
       {fprintf(stderr,"%s no admite ningun argumento\n",argv[0]);
        return 1;}

    /* Una vez más os recuerdo que estas construcciones en el if son propensas a errores */
    if ((fd=open(".",O_RDONLY))==-1)
       {sprintf(etiqueta,"%s:open",argv[0]); perror(etiqueta);
        return 1;}

    if (stat(".",&estado)==-1)
       {sprintf(etiqueta,"%s:stat",argv[0]); perror(etiqueta);
        close(fd);
        return 1;}

    tamano=estado.st_blksize;
    buffer=(struct dirent *)malloc(tamano*5);

    for(;;) /* Salida del for: (a) No hay más entradas (getdents=0) 
                               (b) Hay error           (getdents=-1) */
       {
        if ( (fin=getdents(fd,buffer,tamano*5) ) ==-1 )
           {sprintf(etiqueta,"%s:getdents",argv[0]); perror(etiqueta);
            free(buffer);
            close(fd);
            return 1;}

        if (fin==0) {free(buffer); close(fd); return 0;}

        /* Hemos leído un bloque de entradas de directorio. */
        /* Vamos a procesarlas. */
        sdp=(struct dirent *)buffer;
        while (fin > 0)
           {
            if(lstat(sdp->d_name,&estado)==-1)
               {sprintf(etiqueta,"%s:stat:%s",argv[0],sdp->d_name);
                perror(etiqueta);
                /* No interrumpimos el programa porque lo consideramos*/
                /* un error menor.                                    */
                /* ¡¡BIEN!! Aunque no podamos acceder a un fichero, al resto puede que sí. */
                }

            /* 604800 = numero de segundos en una semana */
            diferencia= (estado.st_atime - estado.st_mtime) / (float)604800;
            if(diferencia > 1 || diferencia < -1) 
                 printf("%s\n", sdp->d_name);  
                 /* Entra si hay más de una semana entre las dos fechas */
                 /* No es esto lo que decía exactamente el enunciado, pero puede valer. */
                 /* Lo más estrictamente conrrecto sería dejar sólo la condición >. */

            fin-=sdp->d_reclen;
            sdp=(struct dirent *)((char *)sdp+sdp->d_reclen);
            }
        }
   }
   

© 2003 Guillermo González Talaván.