changing the date of a file
Frederick M. Avolio
avolio at decuac.dec.com
Sat Nov 5 06:46:21 AEST 1988
Reply-to: avolio at decuac.dec.com (Frederick M. Avolio)
No guarantees. Don't call me if you have questions. You get what you
pay for, etc.
Fred
---------------------
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of shell archive."
# Contents: chtim.c chtim.1
# Wrapped by avolio at gildor.dec.com on Tue Sep 27 13:28:06 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f chtim.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"chtim.c\"
else
echo shar: Extracting \"chtim.c\" \(6985 characters\)
sed "s/^X//" >chtim.c <<'END_OF_chtim.c'
X#ifndef lint
Xstatic char *sccsid = "@(#)chtim.c 1.2 (Don Gworek) 8/10/85";
X#endif
X
X/*
X * chtim [-sR] [-p proto-file] [-am "date" or seconds] files ...
X *
X * Change or report file time stamps
X *
X * -s report in shell script/archive format
X * -R recursive for directories
X * -p put the proto-file's time stamps on the following files
X * -a set access time stamp
X * -m set modification time stamp
X *
X * Default: report time stamps for the files
X *
X * unctime() routines borrowed from Berkeley dump(8)
X * Recusion based on Berkeley 4.3 chmod(1) and ls(1)
X *
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/time.h>
X#include <ctype.h>
X#include <sys/stat.h>
X#include <sys/dir.h>
X
X#define TRUE 1
X#define FALSE 0
X#define ARGVAL() (*++(*argv) || (--argc && *++argv))
X
Xint scriptf = FALSE;
Xint Recursf = FALSE;
Xint protof = FALSE;
Xint accessf = FALSE;
Xint modif = FALSE;
X
Xint status = 0;
Xint argc;
Xchar **argv;
Xlong now;
Xchar nowyear[5];
Xchar command[1024];
X
Xstruct tm *localtime ();
Xstruct timeval newtime[2];
Xstruct stat stbuf;
X
Xstatic char months[12][4] = {
X "jan", "feb", "mar", "apr", "may", "jun",
X "jul", "aug", "sep", "oct", "nov", "dec"
X};
X
Xmain (ARGC, ARGV)
Xint ARGC;
Xchar *ARGV[];
X{
X char *s;
X argc = ARGC;
X argv = ARGV;
X (void) strcpy (command, *argv);
X (void) time (&now);
X s = (char *) ctime (&now);
X (void) sprintf (nowyear, "%.4s", (s + 20));
X newtime[0].tv_sec = newtime[1].tv_sec = 0;
X getoptions ();
X if (argc <= 0)
X usage ();
X for (; --argc >= 0; argv++)
X chtim (*argv);
X exit (status);
X}
X
Xgetoptions () {
X while (--argc > 0)
X if (**(++argv) != '-')
X return;
X else
X switch (*++(*argv)) {
X case '\0':
X return;
X case 'p':
X if (!ARGVAL ())
X usage ();
X if (stat (*argv, &stbuf) == -1) {
X perror (*argv);
X exit (1);
X }
X newtime[0].tv_sec = stbuf.st_atime;
X newtime[1].tv_sec = stbuf.st_mtime;
X protof = TRUE;
X break;
X case 'a':
X extract_time (0);
X break;
X case 'm':
X extract_time (1);
X break;
X default:
X for (; **argv != '\0'; *(*argv)++)
X switch (**argv) {
X case 's':
X scriptf = TRUE;
X break;
X case 'R':
X Recursf = TRUE;
X break;
X default:
X usage ();
X }
X }
X}
X
Xextract_time (option)
Xint option;
X{
X int a, m;
X a = m = FALSE;
X for (;; *++(*argv))
X switch (**argv) {
X case '\0':
X if (--argc && *++argv)
X goto set;
X else
X usage ();
X break;
X case 'a':
X a = accessf = TRUE;
X break;
X case 'm':
X m = modif = TRUE;
X break;
X default:
X goto set;
X }
Xset:
X if (!isdigit (**argv)) {
X if ((newtime[option].tv_sec = unctime (*argv)) < 0)
X usage ();
X }
X else
X newtime[option].tv_sec = atol (*argv);
X if (a)
X newtime[0].tv_sec = newtime[option].tv_sec;
X if (m)
X newtime[1].tv_sec = newtime[option].tv_sec;
X}
X
Xchtim (fname)
Xchar *fname;
X{
X struct stat stb;
X if (stat (fname, &stb) == -1) {
X perror (fname);
X status++;
X return;
X }
X if (Recursf && stb.st_mode & S_IFDIR)
X status += chtimr (fname);
X if (newtime[0].tv_sec || newtime[1].tv_sec) {
X if (accessf && !modif)
X newtime[1].tv_sec = stb.st_mtime;/* preserve m value */
X else
X if (modif && !accessf)
X newtime[0].tv_sec = stb.st_atime;/* preserve a value */
X
X if (utimes (fname, newtime) != 0) {
X status++;
X perror (fname);
X }
X }
X else
X if (scriptf) {
X if (stb.st_atime == stb.st_mtime)
X printf ("%s -am %d", command, stb.st_atime);
X else
X printf ("%s -a %d -m %d", command, stb.st_atime, stb.st_mtime);
X printf (" %s\n", fname);
X }
X else {
X printf ("%s\n", fname);
X print_time ("a", stb.st_atime);
X print_time ("m", stb.st_mtime);
X print_time ("c", stb.st_ctime);
X }
X}
X
Xchtimr (dir)
Xchar *dir;
X{
X register DIR * dirp;
X register struct direct *dp;
X char dirfile[1024];
X if ((dirp = opendir (dir)) == NULL) {
X perror (dir);
X return (1);
X }
X dp = readdir (dirp);
X dp = readdir (dirp); /* read "." and ".." */
X for (dp = readdir (dirp); dp != NULL; dp = readdir (dirp)) {
X (void) sprintf (dirfile, "%s/%s", dir, dp -> d_name);
X chtim (dirfile);
X }
X closedir (dirp);
X return (0);
X}
X
Xprint_time (label, t)
Xchar *label;
Xlong t;
X{
X char *s;
X s = (char *) ctime (&t);
X if (strncmp ((s + 20), nowyear, 4))
X printf ("\t%s %-13.12s%-5.4s(%d)\n", label, (s + 4), (s + 20), t);
X else
X printf ("\t%s %-18.15s(%d)\n", label, (s + 4), t);
X}
X
Xchar *
X substring (str, substr)
Xchar *str, *substr;
X{
X while (isspace (*str) && (*str != '\0'))
X str++;
X while (!isspace (*str) && (*str != '\0'))
X *substr++ = *str++;
X *substr = '\0';
X return (str);
X}
X
X/*
X * Convert a date to seconds since Jan 1, 1970. If an error, return -1.
X */
Xtime_t
Xunctime (str)
Xchar *str;
X{
X struct tm tm;
X time_t emitl ();
X char *s, word[30], *substring ();
X if (strlen (str) >= 30)
X return (-1);
X
X str = substring (str, word);/* extract month number */
X if ((tm.tm_mon = get_month (word)) < 0)
X return (-1);
X
X str = substring (str, word);/* extract day */
X tm.tm_mday = atoi (word);
X
X str = substring (str, word);/* extract time */
X tm.tm_hour = atoi (word);
X for (s = word; (*s != '\0') && (*s != ':'); s++);
X if (*s == ':')
X tm.tm_min = atoi (++s);
X else
X return (-1); /* mistake in format */
X for (; (*s != '\0') && (*s != ':'); s++);
X if (*s == ':')
X tm.tm_sec = atoi (++s);
X else
X tm.tm_sec = 0; /* assume zero */
X
X str = substring (str, word);/* if no year given, */
X if (*word) /* assume this year. */
X tm.tm_year = atoi (word) - 1900;
X else
X tm.tm_year = atoi (nowyear) - 1900;
X
X return (emitl (&tm));
X}
X
Xget_month (str)
Xchar *str;
X{
X int i;
X char *strp;
X int uclc_diff = 'a' - 'A';
X for (strp = str; !isspace (*strp) && *strp != '\0'; strp++)
X if (isupper (*strp))
X *strp += uclc_diff;
X for (i = 0; i < 12; i++)
X if (!strncmp (months[i], str, 3))
X return (i);
X return (-1);
X}
X
X/*
X * Routine to convert a localtime(3) format date back into
X * a system format date.
X *
X * Use a binary search.
X */
Xtime_t
Xemitl (dp)
Xstruct tm *dp;
X{
X time_t conv;
X register int i, bit;
X struct tm dcopy;
X
X dcopy = *dp;
X dp = &dcopy;
X conv = 0;
X for (i = 30; i >= 0; i--) {
X bit = 1 << i;
X conv |= bit;
X if (dcmp (localtime (&conv), dp) > 0)
X conv &= ~bit;
X }
X return (conv);
X}
X
X/*
X * Compare two localtime dates, return result.
X */
X#define DECIDE(a) \
Xif (dp -> a > dp2 -> a) \
X return (1); \
Xif (dp -> a < dp2 -> a) \
X return (-1)
X
Xstatic
Xdcmp (dp, dp2)
Xregister struct tm *dp, *dp2;
X{
X DECIDE (tm_year);
X DECIDE (tm_mon);
X DECIDE (tm_mday);
X DECIDE (tm_hour);
X DECIDE (tm_min);
X DECIDE (tm_sec);
X return (0);
X}
X
Xusage () {
X fprintf (stderr, "Usage: %s [-sR] [-p proto-file]", command);
X fprintf (stderr, " [-am \"date\" or seconds] files ...\n");
X exit (1);
X}
END_OF_chtim.c
if test 6985 -ne `wc -c <chtim.c`; then
echo shar: \"chtim.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f chtim.1 -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"chtim.1\"
else
echo shar: Extracting \"chtim.1\" \(1685 characters\)
sed "s/^X//" >chtim.1 <<'END_OF_chtim.1'
X
X
X
X CHTIM(l)
X
X
X
XNAME
X chtim - change time stamps
X
XSYNOPSIS
X chtim [ -sR ] [ -p proto-file ] [ -am time ] files ...
X
XDESCRIPTION
X The -a and -m flags mean to reset the access and modifica-
X tion times, respectively, to the following time. The time
X can be in seconds since Jan 1, 1970; or in a conventional
X month, day, time, year, format (Example: "Aug 10 14:34:12
X 1985"). The user must use quotes for the date form. If the
X user leaves out the year, chtim will assume the user means
X the current year. If the user leaves out the seconds field,
X chtim assumes 00 seconds. The month may be in lower-case,
X upper-case, or capitalized.
X
X The -p flag means that the time stamps on the proto-file are
X to be used to reset the access and modification times on the
X files.
X
X With a -s flag chtim makes a report in shell script format.
X If the user redirects this output to a file, and later
X sources that file, the original access and modification
X times of the files will be restored.
X
X The -R flag says chtim should change or report time stamps
X recursively on subdirectories. Parent directories are
X changed after the child files so that the new access and
X modification times on the parent are not immediately reset
X to the current time.
X
X By default, chtim only reports the time stamps of the files.
X
XBUG
X Utimes sets the creation time to the current time.
X
XSEE ALSO
X utimes(2), stat(2), ls(1)
X
XAUTHOR
X Don Gworek (3 functions borrowed from Berkeley dump(8))
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
END_OF_chtim.1
if test 1685 -ne `wc -c <chtim.1`; then
echo shar: \"chtim.1\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0
More information about the Comp.unix.ultrix
mailing list