[comp.unix.ultrix] changing the date of a file

mbm75@leah.Albany.EDU (Michael B Meyer) (09/26/88)

Reply-to: mbm75@leah.Albany.EDU (Michael B Meyer)


Does anyone know of an easy way (perhaps an existing utility?) for the 
owner of a file to change the time (date) of last modification to that
file?

Thanks for any insights.  Reply directly to: mbm@halfog.albany.edu

avolio@decuac.dec.com (Frederick M. Avolio) (11/05/88)

Reply-to: avolio@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@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