Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!decvax!bellcore!ulysses!allegra!mit-eddie!genrad!panda!sources-request From: sources-request@panda.UUCP Newsgroups: mod.sources Subject: retouch(1): force changed date Message-ID: <1886@panda.UUCP> Date: Sun, 18-May-86 17:48:56 EDT Article-I.D.: panda.1886 Posted: Sun May 18 17:48:56 1986 Date-Received: Mon, 19-May-86 19:09:48 EDT Sender: jpn@panda.UUCP Organization: CACI, Inc. -- La Jolla (home of SIMSCRIPT II.5) Lines: 366 Keywords: touch, sccs, ls Approved: jpn@panda.UUCP 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 Xtypedef struct { X time_t actime; X time_t modtime; X} utimbuf; X X#include X#include X#ifdef BSD Xextern int errno; X#endif X X#include X#define ungetchar(c) ungetc(c,stdin) X X#ifdef BSD X# include X# include X#else X# include X# include 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) X { fprintf(stderr, X "usage: %s [-v ] [-g] [-d date] file1 [file2 ... ]\n", X argv[0]); X exit (0); X } X X for (; i 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