home *** CD-ROM | disk | FTP | other *** search
- From: warren@pluto.UUCP (Warren Burstein)
- Newsgroups: comp.sources.misc
- Subject: utility to find changed files
- Message-ID: <4123@ncoast.UUCP>
- Date: 13 Aug 87 00:09:20 GMT
- Sender: allbery@ncoast.UUCP
- Organization: Industrial Automation Systems - New York, NY
- Lines: 265
- Approved: allbery@ncoast.UUCP
- X-Archive: comp.sources.misc/8708/12
-
- changed searches for files underneath specified directories that have
- changed after a given date. It does not check subdirectories on
- other filesystems. I use it to find out what files have changed
- on my root and /usr filesystems without seeing everything under /.
-
- Usage: changed mmddyy directories
-
- The code that parses mmddyy and produces the number of seconds
- since Jan 1, 1970 should be useful in other places, too.
-
- Warren Burstein (pluto!warren) 8/11/87
-
- No doubt I could have done it in find(1) but it took less time
- to write this than to figure it out.
- -----------cut somewhere else, why don't you?-----------------
-
- # This is a shell archive. Remove anything before this line, then
- # unpack it by saving it in a file and typing "sh file". (Files
- # unpacked will be owned by you and have default permissions.)
- #
- # This archive contains:
- # Read.me Makefile changed.c
-
- echo x - Read.me
- cat > "Read.me" << '//E*O*F Read.me//'
- This directory makes the "changed" program.
-
- It searches for files underneath specified directories that have
- changed after a given date. It does not check subdirectories on
- other filesystems. I use it to find out what files have changed
- on my root and /usr filesystems without seeing everything under /.
-
- Usage: changed mmddyy directories
-
- The code that parses mmddyy and produces the number of seconds
- since Jan 1, 1970 should be useful in other places, too.
-
- Warren Burstein (pluto!warren) 8/11/87
- //E*O*F Read.me//
-
- echo x - Makefile
- cat > "Makefile" << '//E*O*F Makefile//'
- changed: changed.c
- cc changed.c -o changed
-
- lint:
- lint changed.c
-
- shar:
- shar Read.me Makefile changed.c > shar
-
- clean:
- -rm -f *.o core a.out changed
- //E*O*F Makefile//
-
- echo x - changed.c
- cat > "changed.c" << '//E*O*F changed.c//'
- /*
- * This program expects args mmddyy dir1 dir2 ....
- *
- * For each directory named, all files under that directory recusively
- * that are newer than the specified date will be listed on stdout, but
- * it does not check subdirectories that are not on the same device as
- * their parent directory.
- *
- * It should be useful if you want to find out what files on your
- * root and usr devices have been changed since your last upgrade without
- * listing every user file, unless you keep users on /usr.
- *
- * Warren Burstein (pluto!warren) 7/22/87
- */
-
- #include <stdio.h>
- #include <time.h>
- #include <sys/types.h>
- #include <sys/dir.h>
- #include <sys/stat.h>
- #include <sys/param.h>
-
- char *progname;
-
- main(argc, argv)
- char **argv;
- {
- int arg;
- long date, parse_date();
- char cwd[MAXPATHLEN];
-
- progname = argv[0];
-
- if (argc < 3) {
- fprintf(stderr, "usage: %s mmddyy dir...\n", progname);
- exit(1);
- }
-
- date = parse_date(argv[1]);
-
- getwd(cwd);
- for (arg = 2; arg < argc; arg++) {
- /*
- * look_at may change working directory, so come back
- * to where we started if this directory arg doesn't start
- * at /. Don't bother if this is the first time thru here.
- */
- if (arg != 2 && *argv[arg] != '/' && chdir(cwd) < 0) {
- fprintf(stderr, "%s: cannot return to %s: ", progname, cwd);
- perror("");
- exit(1);
- }
- look_at(argv[arg], date);
- }
-
- exit(0);
- }
-
- /*
- * Turn a string that looks like mmddyy into a date in the format
- * returned by time(2), seconds since 00:00:00 GMT Jan 1, 1970.
- */
-
- static int months[13] = {
- 0, /* let January be 1, not zero */
- 31, 28, 31, 30, 31, 30,
- 31, 31, 30, 31, 30, 31
- };
-
- long parse_date(mmddyy)
- char *mmddyy;
- {
- int month, day, year;
- int m;
- long date;
- struct timeval tv;
- struct timezone tz;
-
- (void) gettimeofday(&tv, &tz);
-
- if (sscanf(mmddyy, "%2d%2d%2d", &month, &day, &year) != 3) {
- fprintf(stderr, "%s: date must be in mmddyy format\n", progname);
- exit(1);
- }
-
- if (year < 70) {
- fprintf(stderr, "%s: the world was created in 1970!\n", progname);
- exit(1);
- }
-
- /*
- * Adjust February
- */
- months[2] = is_leap(year + 1900) ? 29 : 28;
-
- if (month < 1 || month > 12) {
- fprintf(stderr, "%s: month must be between 1 and 12\n", progname);
- exit(1);
- }
-
- if (day < 1 || day > months[month]) {
- fprintf(stderr, "%s: day must be between 1 and %d\n",
- progname, months[month]);
- exit(1);
- }
-
- /*
- * Find days between Jan 1, 1970 and Jan 1 of year (ignore Julian
- * corrections here), add days in months and day in month.
- */
- date = (year - 70) * 365 + year / 4 - 70 / 4;
- for (m = 1; m < month; m++)
- date += months[m];
- date += day - 1;
-
- /*
- * Turn into seconds, correct for longitude and daylight savings time.
- */
- date *= 24 * 60 *60;
- date += tz.tz_minuteswest * 60;
- if (localtime(&date)->tm_isdst)
- date -= 60 * 60;
-
- return date;
- }
-
- /*
- * Return true if year is a leap year.
- */
- int is_leap(year) {
- return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
- }
-
- /*
- * List all entries in dir that are newer than date. Recurse on
- * subdirectories that are on the same device as dir. Treat symbolic
- * links like regular files - list them if the link is new, not the file
- * referenced.
- *
- * Exit on any error since it's a pain to figure out what the current
- * directory is afterwards.
- */
-
- look_at(dir, date)
- char *dir;
- long date;
- {
- DIR *dirp;
- struct direct *dp;
- struct stat st;
- dev_t dev;
-
- if (stat(dir, &st) < 0) {
- fprintf(stderr, "%s: cannot stat directory %s\n", progname, dir);
- exit(1);
- }
- dev = st.st_dev;
-
- if ( (dirp = opendir(dir)) == NULL) {
- fprintf(stderr, "%s: cannot open directory %s\n", progname, dir);
- exit(1);
- }
-
- if (chdir(dir) < 0) {
- fprintf(stderr, "%s: cannot chdir to %s\n", progname, dir);
- exit(1);
- }
-
- while ( (dp = readdir(dirp)) != NULL) {
- /*
- * Skip self and parent
- */
- if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
- continue;
-
- /*
- * Use lstat, so as not to follow symbolic links.
- */
- if (lstat(dp->d_name, &st) < 0) {
- fprintf(stderr, "cannot stat file %s/%s\n", dir, dp->d_name);
- continue;
- }
-
- if ((st.st_mode & S_IFMT) == S_IFDIR) {
- if (st.st_dev == dev) {
- char dirname[MAXPATHLEN];
-
- /*
- * look_at chdir's to a subdirectory, go back up
- * when done.
- */
- (void) sprintf(dirname, "%s/%s", dir, dp->d_name);
- look_at(dirname, date);
- (void) chdir("..");
- }
- } else if (st.st_mtime > date)
- printf("%s/%s\n", dir, dp->d_name);
- }
- (void) closedir(dirp);
- }
- //E*O*F changed.c//
-
- exit 0
- --
- /|/~\~~\ The entire world Warren Burstein
- |__/__/_/ is a very strange carrot.
- | But the farmer philabs!tg!pluto!warren
- / is not afraid at all. Why doesn't life come with subtitles?
-