allbery@ncoast.UUCP (07/09/87)
I wrote this one day trying to solve the problem of the file modification
dates of restored files. Someone in comp.unix.questions wanted something
like this, so here it is.
Bugs - doesn't know about DST, and barely knows how to get the hours
in the first place. No manual page, this program works kind of like the
settime command that I remember from Version 7 days. Also, the inode
changed time will always be set to the time you changed the file times.
Enjoy!
John. (jfh@killer.UUCP)
------------------------ cut somewheres near here ----------------------
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
/*
* settime - change the access and modification dates of files
*
* This is mine. You steal, and you die. Ha, Ha.
*/
static char sccsid[] = "@(#)settime.c 1.0 John F. Haugh 08/05/86";
#define SECPERMIN 60
#define MINPERHR 60
#define HRPERDAY 24
#define SECPERHR (MINPERHR*SECPERMIN)
#define SECPERDAY (HRPERDAY*MINPERHR*SECPERMIN)
#define YEAR(y) (y & 03 ? 365:366)
#define MONTH(m,y) (m != 2 ? months[(m - 1)]:(y & 03 ? 28:29))
extern long timezone;
int months[12] = {
31, 28, 31, 30,
31, 30, 31, 31,
30, 31, 30, 31
};
conversion ()
{
fprintf (stderr, "settime: conversion error\n");
exit (1);
}
usage ()
{
fprintf (stderr, "usage: settime [ mmddHHMMyy | -f file ] name ...\n");
exit (1);
}
twodigits (s)
char *s;
{
if (s[0] == 0 || s[1] == 0) {
fprintf (stderr, "settime: bad date string\n");
exit (1);
}
return ((s[0] - '0') * 10 + s[1] - '0');
}
month (m, y)
int m,
y;
{
int i;
int days = 0;
for (i = 1; i < m;i++)
days += MONTH (i, y);
return (SECPERDAY * days);
}
year (y)
int y;
{
int i;
int days = 0;
for (i = 70;i < y;i++)
days += YEAR (i);
return (days * SECPERDAY);
}
time_t date (ds)
char *ds;
{
time_t seconds = 0;
int len;
int mm,
dd,
HH,
MM,
yy;
len = strlen (ds);
if (len & 01) {
mm = ds[0] - '0';
ds++;
}
else {
mm = twodigits (ds);
ds += 2;
}
dd = twodigits (ds);
ds += 2;
HH = twodigits (ds);
ds += 2;
MM = twodigits (ds);
ds += 2;
yy = twodigits (ds);
if (MM > 59)
conversion ();
if (mm > 12 || mm == 0)
conversion ();
if (HH > 23)
conversion ();
if (yy < 70)
conversion ();
if (dd > MONTH (mm, yy) || dd == 0)
conversion ();
seconds = year (yy) + month (mm, yy) + (SECPERDAY * (dd - 1)) + (SECPERHR * HH) + (SECPERMIN * MM) + timezone;
return (seconds);
}
main (argc, argv)
int argc;
char **argv;
{
struct utimbuf {
time_t actime;
time_t modtime;
} utimbuf;
struct stat statbuf;
int i;
if (argc < 3)
usage ();
tzset ();
if (argv[1][0] == '-') {
if (argv[1][1] != 'f')
usage ();
if (stat (argv[2], &statbuf) != 0) {
perror (argv[2]);
exit (2);
}
utimbuf.actime = statbuf.st_atime;
utimbuf.modtime = statbuf.st_mtime;
i = 3;
}
else {
utimbuf.actime = utimbuf.modtime = date (argv[1]);
i = 2;
}
for (;argv[i] != (char *) 0;i++)
if (utime (argv[i], &utimbuf) != 0)
perror (argv[i]);
}