[78] in Info-AFS_Redistribution
file access times
daemon@ATHENA.MIT.EDU (daemon@ATHENA.MIT.EDU)
Tue Feb 12 14:19:55 1991
Date: Tue, 12 Feb 1991 13:13:26 -0500 (EST)
From: Robert Dodson <RDODSON@ibm.com>
To: info-afs@transarc.com
Hi folks,
The current discussion about file permissions reminded me of a
bug that I found a while ago but never reported.
It seems that file access times are not updated correctly in AFS.
Three times are stored with a file:
last access
last modification
last status change
It looks like in AFS that file modification (or creation) is the only
thing that
affects the time, and it affects all the times, which it should
not. Normally different actions change only certain times. For example:
$ date > tt # all times are set to create time
$ cat tt # only last access time should change
$ date >> tt # last modification and status should change
$ chmod +x tt # only status should change
On AFS, modification changes all the times, and a read (access), or
status change (chmod for example), do not change any times.
This problem does affect some programs that need the time info.
I encountered all this on AIX221 and AIX31 running AFS3.1 and AFS3.1.
Included below is a program for others to test this problem on their systems.
It is a C program that will print out all the file times from the stat
structure associated with the file. (It may require modification for
non-AIX systems).
Rob
/// Robert A. Dodson, rdodson@ibm.com, RAD at WATSON, (914) 784-7334 ///
-------------------------CUT HERE-------------------------------------------
/* print out file stat info */
#include <pwd.h>
#include <grp.h>
#include <sys/stat.h>
int
main(argc,argv)
int argc;
char **argv;
{
int i;
struct stat s;
void do_stat( /* struct stat *s */ );
if (argc < 2)
{
printf("Usage: %s file [ ... ]\n",argv[0]);
exit(1);
}
for(i=1;i<argc;i++)
{
if (argc > 2)
{
printf("\n");
printf("%s\n",argv[i]);
printf("------------------------------\n");
}
if ((stat(argv[i],&s)) == -1)
{
printf("stat failed.\n");
perror(argv[i]);
if (i == argc - 1)
exit(1);
else
continue;
}
do_stat(&s);
}
exit(0);
}
void
do_stat(s)
struct stat *s;
{
struct passwd *pw,*getpwuid();
struct group *gr,*getgrgid();
printf("Device ID : %d\n",s->st_dev);
printf("File serial number : %d\n",s->st_ino);
printf("File mode : 0%o\n",s->st_mode);
printf("File type : ");
switch(s->st_mode & S_IFMT)
{
case S_IFDIR:
printf("directory\n");
break;
case S_IFCHR:
printf("character special\n");
printf("special device ID : %d\n",s->st_rdev);
break;
case S_IFBLK:
printf("block special\n");
printf("special device ID : %d\n",s->st_rdev);
break;
case S_IFREG:
printf("regular\n");
break;
case S_IFIFO:
printf("fifo\n");
break;
case S_IFLNK:
printf("symbolic link\n");
break;
default:
printf("unknown\n");
break;
}
printf("Set user id on execution? : %s\n",s->st_mode & S_ISUID ?
"yes" : "no");
printf("Set group id on execution? : %s\n",s->st_mode & S_ISGID ?
"yes" : "no");
printf("Sticky bit? : %s\n",s->st_mode & S_ISVTX ?
"yes" : "no");
printf("Number of links : %d\n",s->st_nlink);
pw = getpwuid(s->st_uid);
printf("Owner : %d (%s)\n",s->st_uid,pw !=
0?pw->pw_name:"unknown");
gr = getgrgid(s->st_gid);
printf("Group : %d (%s)\n",s->st_gid,gr !=
0?gr->gr_name:"unknown");
printf("File size in bytes : %d\n",s->st_size);
printf("Time of last access : %s",ctime(&s->st_atime));
printf("Time of last data modification : %s",ctime(&s->st_mtime));
printf("Time of last status change : %s",ctime(&s->st_ctime));
}