sources-request@panda.UUCP (05/19/86)
Mod.sources: Volume 5, Issue 4 Submitted by: seismo!s3sun!gould9!joel (Joel West @ CACI) retouch(1) is like touch(1), except it uses the sccs id instead of the current time. It also contains a nifty subroutine that can be used as the inverse of localtime(3) or gmtime(3), to convert a date to the UNIX time format. The algorithm is brute force, but deterministic, and involves no UNIX proprietary source code. Joel West (619) 457-9681 CACI, Inc. Federal, 3344 N. Torrey Pines Ct., La Jolla, CA 92037 {cbosgd, ihnp4, sdcsvax, ucla-cs} !gould9!joel joel%gould9.uucp@NOSC.ARPA #!/bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #!/bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # README # Makefile # retouch.c # This archive created: Tue May 13 21:52:48 1986 export PATH; PATH=/bin:$PATH echo shar: extracting "'README'" '(1001 characters)' if test -f 'README' then echo shar: over-writing existing file "'README'" fi sed 's/^X//' << \SHAR_EOF > 'README' Xretouch is a command that can be used to "correct" last changed Xdates, such as when by 'make' or 'ls -l -t'. These dates Xcan be inaccurate after a cp, or uucp, or kermit to create a new Xcopy of an existing file, or to import it from another system. X Xretouch looks for an sccs string of the form X @(#) anything at all mm/dd/yy X @(#) anything at all yy/mm/dd Xto get the date. It is intended for use on source files, and Xassumes there is no such string if it's not in the top 10 lines. X XIt has the following options: X -v verbose X -g assume the date is GMT rather than local time X -d date set the last change date to "date". X XIt has defs for BSD and USG, although it's been tested only Xunder BSD. It was intended as a one-time hack, and may not Xbe as clean as it should be, but it has proven versatile and Xnecessary over the past 6 months. X XI'd appreciate any suggestions or changes. X X Joel West CACI, Inc. Federal, La Jolla X {cbosgd, ihnp4, sdcsvax, ucla-cs} !gould9!joel X joel%gould9.uucp@NOSC.ARPA SHAR_EOF if test 1001 -ne "`wc -c 'README'`" then echo shar: error transmitting "'README'" '(should have been 1001 characters)' fi echo shar: extracting "'Makefile'" '(50 characters)' if test -f 'Makefile' then echo shar: over-writing existing file "'Makefile'" fi sed 's/^X//' << \SHAR_EOF > 'Makefile' Xretouch: retouch.c X cc -DBSD -o retouch retouch.c SHAR_EOF if test 50 -ne "`wc -c 'Makefile'`" then echo shar: error transmitting "'Makefile'" '(should have been 50 characters)' fi echo shar: extracting "'retouch.c'" '(6231 characters)' if test -f 'retouch.c' then echo shar: over-writing existing file "'retouch.c'" fi sed 's/^X//' << \SHAR_EOF > 'retouch.c' X/* @(#) retouch.c 1.0 10/25/85 X*/ X/* retouch.c: set update time to match SCCS id X X Copyright (c) 1985, Joel West (ihnp4!gould9!joel) X License for non-commercial use freely granted as long X as this notice is retained. X X The id should be of the form X @(#) xxxxxxx 10/23/85 X or @(#) xxxxxxx 85/10/23 X it assumes date is the last non-blank thing on the line X and this program will only work between 1970 and 2000, inclusive X X works best if only one id (ignores others) and if id is at the X top of the file. X X Does not retouch if not found in first 10 lines; should be X an optionable parameter. A line is a newline or a null, X so this just might work on a binary file. X X*/ X X#include <sys/types.h> Xtypedef struct { X time_t actime; X time_t modtime; X} utimbuf; X X#include <sys/stat.h> X#include <errno.h> X#ifdef BSD Xextern int errno; X#endif X X#include <stdio.h> X#define ungetchar(c) ungetc(c,stdin) X X#ifdef BSD X# include <strings.h> X# include <sys/time.h> X#else X# include <string.h> X# include <time.h> X#endif X#ifdef USG X# define index(s,c) strchr(s,c) X#endif X X#ifndef TRUE X# define TRUE (1) X# define FALSE (0) X#endif X X/* below are hour and minute at local time that should be X time-stamped; default 00:00:00. No user control over seconds */ X#define STDHR 00 X#define STDMIN 00 X X#define SCCSKEY "@(#)" X#define SCCSCHR '@' X X#define EOL '\n' X#define EOS '\0' X Xint optg = 0, optd = 0, optv = 0; Xlong stddate; X Xmain(argc,argv) Xint argc; Xchar **argv; X{ int depthlim,line,i,sccslen,touched; X char *p,*filenam,buff[1024]; X int c,errind; X X depthlim = 10; X sccslen = strlen(SCCSKEY); X errind = 0; X X for (i = 1; i<argc && errind == 0; i++) X { if (*argv[i] != '-') X break; X p = argv[i]; X while (*(++p)) X switch(*p) X { case 'g': X optg++; X break; X case 'v': X optv++; X break; X case 'd': X if (optd) X errind++; X else X { optd++; X stddate = dateatol(argv[++i]); X if (stddate < 0) X { fprintf(stderr,"%s: invalid date format\n",argv[i]); X exit (0); X } X } X break; X default: X errind++; X } X } X X if (errind || i >= argc) X { fprintf(stderr, X "usage: %s [-v ] [-g] [-d date] file1 [file2 ... ]\n", X argv[0]); X exit (0); X } X X for (; i<argc; i++) X { filenam = argv[i]; X if (freopen(filenam, "r", stdin) == NULL) X { perror(filenam); X exit(errno); X } X touched = 0; X if (optd) /* one date for all */ X { setupdtime(filenam, stddate); X touched++; X goto settouch; X } X X for (line = 1; line <= depthlim; line++) X { while ( 1 ) X { c = getchar(); X if (c == EOF) X goto settouch; X if (c == EOS || c == EOL) X break; X if (c == SCCSCHR) X { X ungetchar(c); X gets(buff); /* won't work on binary */ X if (strncmp(buff, SCCSKEY, sccslen) == 0) X { p = buff+strlen(buff); /* use last nonblank */ X while (*(--p) == ' ') /* field in string */ X ; X while (*p != ' ' && *p != '\t') X --p; X if ( setupdtime(filenam, dateatol(++p)) ) X touched++; X goto settouch; X } X } X } /* within line */ X } /* end of line */ Xsettouch: X if (touched==0) X fprintf(stderr, "%s: not retouched\n", filenam); X else X if (optv) X fprintf(stderr, "%s: retouched\n", filenam); X } /* end of file */ X} X X/* Reset the file's update time to the specified date. If the date is dubious, X don't reset it at all X*/ Xint setupdtime(fname, mtime) Xchar *fname; Xlong mtime; X{ utimbuf timep; X struct stat statbuf; X X stat(fname, &statbuf); X timep.actime = statbuf.st_atime; /* copy current accessed time */ X X if (mtime > 0) /* valid date */ X { timep.modtime = mtime; X utime(fname, &timep); X return (TRUE); X } X return (FALSE); X} X X#define NSECYR 31536000 X/* 365*24*60*60 */ X#define NSECDA 86400 X#define APPROXT(yr,mo,da) (((yr-70)*NSECYR) + ((mo*30)+da)*NSECDA) X#define INVDATE (-1) Xlong dateatol(string) Xchar *string; X{ char *p,*q; X int mdy[3],mo,da,yr,i,num; X struct tm *tmptr; X long timsec,approxsec,deltasec,lasttimsec,maxdelta,mindelta; X int deltasign; X static char *numstr = "0123456789"; X X p = string; X while (*p == ' ') /* skip leading blanks */ X p++; X for (i = 0 ; i<3; i++) X { num = 0; X q = NULL; /* watch for null field */ X while (*p != EOS && *p != '/' && *p != ' ') X { q = index(numstr,*p++); X if (q == NULL) /* invalid digit */ X break; X num = num*10 +(q-numstr); X } X if (q) X mdy[i] = num; X else X return (INVDATE); /* invalid or null field */ X p++; /* skip delimiter */ X } X --p; X while (*p++ == ' ') X ; X if (*--p != EOS) /* not end of string */ X return (INVDATE); X X if (mdy[0] > 11) X { yr = mdy[0]; /* assume YY/MM/DD */ X mo = mdy[1] - 1; /* months 0..11 not 1..12 */ X da = mdy[2]; X } X else X { mo = mdy[0] - 1; /* assume MM/DD/YY */ X da = mdy[1]; X yr = mdy[2]; X } X X if (yr > 1900) X yr = yr - 1900; X X approxsec = APPROXT(yr,mo,da); X timsec = approxsec; X lasttimsec = 0; X mindelta = NSECDA; X maxdelta = NSECYR; X while (1) X { tmptr = (optg ? gmtime(&timsec) : localtime(&timsec)) ; X/* decode absolute time into local or gmt */ X if (yr == tmptr->tm_year && X mo == tmptr->tm_mon && X da == tmptr->tm_mday) X { X/* the date is right, set the time to midnight local time; this Xmay behave strangely on daylight savings time changeover days */ X if (STDHR == tmptr->tm_hour && X STDMIN == tmptr->tm_min && X 0 == tmptr->tm_sec) X break; /* exactly right */ X else X { timsec -= (tmptr->tm_hour - STDHR) * 3600 + X (tmptr->tm_min - STDMIN) * 60 + X tmptr->tm_sec; X maxdelta = mindelta; X mindelta = 1; X } X } X else X { deltasec = APPROXT(tmptr->tm_year,tmptr->tm_mon,tmptr->tm_mday) X - approxsec; X deltasign = (deltasec < 0) ? -1 : 1; X/* approximately the difference in the number of seconds between X the guessed date and the actual date */ X if (abs(deltasec) > abs(timsec-lasttimsec)) X deltasec = timsec-lasttimsec; X deltasec = abs(deltasec); X deltasec = (deltasec > maxdelta) ? deltasec / 2 : X ((deltasec >= mindelta) ? (deltasec-1) : mindelta); X lasttimsec = timsec; X timsec -= deltasec * deltasign; /* binary convergence */ X } X } X X return (timsec); X} SHAR_EOF if test 6231 -ne "`wc -c 'retouch.c'`" then echo shar: error transmitting "'retouch.c'" '(should have been 6231 characters)' fi # End of shell archive exit 0