taylor@limbo.Intuitive.Com (Dave Taylor) (07/01/90)
Timestamp is a handy utility I recently whipped up for some local administrative needs that lists the subset of files given on the command line that are older (or newer) than the specified timestamp delta. Timestamp can be included in shell scripts where the resolution of the 'last modified' check of the "find" utility doesn't offer sufficiently high resolution. Specifically, "timestamp" can be used to check for files that are older than "any" time, from seconds to days. Further, with the use of the optional '-r' flag (to reverse the meaning of the command) "timestamp" can be used to find files newer than the specified time too. (indeed, in conjunction, you could find all files that were created during an specific 'slice' of time, even weeks ago). Enjoy! -- Dave Taylor Intuitive Systems Mountain View, California taylor@limbo.intuitive.com or {uunet!}{decwrl,apple}!limbo!taylor -- Shell archive: # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by Dave Taylor <taylor@intuitive.com> on Sat Jun 30 12:38:08 1990 # # This archive contains: # timestamp.1 timestamp.c # # Error checking via wc(1) will be performed. # Error checking via sum(1) will be performed. LANG=""; export LANG PATH=/bin:/usr/bin:$PATH; export PATH if sum -r </dev/null >/dev/null 2>&1 then sumopt='-r' else sumopt='' fi echo x - timestamp.1 cat >timestamp.1 <<'@EOF' .TH TIMESTAMP 1L "" "" .SH NAME timestamp \- check file modification times .SH SYNOPSIS .B timestamp [ .I \-q ] [ .I delta ] .I filelist .sp .B timestamp [ .I \-q ] [ .I \-r ] [ .I delta ] .I filelist .SH DESCRIPTION .I Timestamp is a utility that lists the subset of files given on the command line that are older (or newer) than the specified timestamp delta. .PP This simple application is designed to be included in shell scripts where the resolution of the 'last modified' check of the .I find utility doesn't offer sufficiently high resolution. Specifically, .I timestamp can be used to check for files that are older than .I any time, from seconds to days. Further, with the use of the optional .I \-r flag (to reverse the meaning of the command) .I timestamp can be used to find files .I newer than the specified time. .SH OPTIONS The .I timestamp program has the following set of options available: .TP .B "-d N" Add the specified number of days to the timestamp delta. .TP .B "-h N" Add the specified number of hours to the timestamp delta. .TP .B "-m N" Add the specified number of minutes to the timestamp delta. .TP .B "-s N" Add the specified number of seconds to the timestamp delta. .TP .B "-q" Quiet: don't complain about files that we can't open. .TP .B "-r" Reverse the logic of the program; this will cause it to show all files newer than the specified timestamp delta, rather than older. .SH EXAMPLES Consider the case when you want to remove spurious lock files from the .I sendmail queue: we don't want to wait until they're a day or more old to remove them (because that'd be a pretty slow delivery time for email), so instead: .nf .in +0.5i timestamp -q -m 30 /usr/spool/mqueue/l* .in -0.5i .fi which would output the lock files that are at least 30 minutes old in the spool directory. .PP By the same token, if we had our machine broken into, we could find out which files in .I /tmp had been modified in the past few minutes with: .nf .in +0.5i timestamp -r -m 5 /tmp/* .in -0.5i .fi as appropriate. .SH SEE ALSO find(1) .SH AUTHOR Dave Taylor, Intuitive Systems .br <taylor@limbo.Intuitive.Com> .SH NOTES This command checks the last modified time of the files, not the created or last accessed times. It's possible that we've choosen the wrong option in this case. .PP The .I \-q option might well be something that should be there as a default value too... @EOF set `sum $sumopt <timestamp.1`; if test $1 -ne 15993 then echo ERROR: timestamp.1 checksum is $1 should be 15993 fi set `wc -lwc <timestamp.1` if test $1$2$3 != 1084372406 then echo ERROR: wc results of timestamp.1 are $* should be 108 437 2406 fi chmod 644 timestamp.1 echo x - timestamp.c cat >timestamp.c <<'@EOF' /** timestamp.c **/ /** This program prints the names of all files in the argument list that are at least as old as the time specified (with no default) (C) Copyright 1990 Dave Taylor <taylor@intuitive.com> (C) Copyright 1990 Intuitive Systems You may do whatever you want with this program so long as the copyright notice above remains intact. **/ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/time.h> #ifndef TRUE # define TRUE 1 # define FALSE 0 #endif #define SLEN 128 #define SECONDS_PER_MINUTE 60 #define SECONDS_PER_HOUR 3600 /* 60 * 60 */ #define SECONDS_PER_DAY 86400 /* 60 * 60 * 24 */ #define compare_times(ft,ct,test) (test ? ft <= ct : ft > ct) int getopt(); char *ctime(); main(argc, argv) char **argv; { extern int optind; extern char *optarg; int c, older = TRUE, quiet = FALSE; long hours = 0L, minutes = 0L, seconds = 0L, days = 0L; long current_time, comparator; char buffer[SLEN]; struct stat statbuf; while ((c = getopt(argc, argv, "d:h:m:qrs:")) != EOF) { switch (c) { case 'd' : days = atoi(optarg); break; case 'h' : hours = atoi(optarg); break; case 'm' : minutes = atoi(optarg); break; case 'q' : quiet = TRUE; break; case 'r' : older = FALSE; break; case 's' : seconds = atoi(optarg); break; default : usage(); } } /** now compute our offset from the current time **/ current_time = time(0); comparator = current_time - (days * SECONDS_PER_DAY) - (hours * SECONDS_PER_HOUR) - (minutes * SECONDS_PER_MINUTE) - seconds; while (optind < argc) { if ((stat(argv[optind], &statbuf) < 0) && (! quiet)) { sprintf(buffer, "Failed trying to stat file '%s'", argv[optind]); perror(buffer); } if (compare_times(statbuf.st_mtime, comparator, older)) printf("%s\n", argv[optind]); optind++; } exit(0); } usage() { fprintf(stderr, "Usage: timestamp [delta] [-q] [-r] filenames\n"); fprintf(stderr, "\nWhere delta can be any combination of:\n"); fprintf(stderr, "\t-d N \tOlder than N days in the past\n"); fprintf(stderr, "\t-h N \tOlder than N hours in the past\n"); fprintf(stderr, "\t-m N \tOlder than N minutes in the past\n"); fprintf(stderr, "\t-q \tQuiet: don't complain about nonexistent files\n"); fprintf(stderr, "\t-r \tReverse logic: show newer, rather than older\n"); fprintf(stderr, "\t-s N \tOlder than N seconds in the past\n"); exit(1); } @EOF set `sum $sumopt <timestamp.c`; if test $1 -ne 39407 then echo ERROR: timestamp.c checksum is $1 should be 39407 fi set `wc -lwc <timestamp.c` if test $1$2$3 != 963562510 then echo ERROR: wc results of timestamp.c are $* should be 96 356 2510 fi chmod 644 timestamp.c exit 0