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.