retouch(1): force changed date
sources-request at panda.UUCP
sources-request at panda.UUCP
Mon May 19 07:48:56 AEST 1986
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 at 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 at 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
More information about the Mod.sources
mailing list