1
0
mirror of https://frontier.innolan.net/rainlance/amiga-tz.git synced 2025-11-23 01:53:02 +00:00

conversion logic pushed to end

SCCS-file: date.c
SCCS-SID: 3.10
This commit is contained in:
Arthur David Olson
1989-03-10 22:58:42 -05:00
committed by Paul Eggert
parent ffe1c98e4d
commit 7ab37a1fb3

227
date.c
View File

@ -167,16 +167,17 @@ static time_t now;
static int retval = EXIT_SUCCESS; static int retval = EXIT_SUCCESS;
static void ambiguous(); static void checkfinal();
static int comptm();
static void display(); static void display();
static void errensure(); static void errensure();
static void finalcheck(); static void iffy();
#ifdef TSP_SETDATE #ifdef TSP_SETDATE
int netsettime(); int netsettime();
#endif /* defined TSP_SETDATE */ #endif /* defined TSP_SETDATE */
static char * nondigit(); static char * nondigit();
static void oops(); static void oops();
static time_t parse(); static time_t convert();
static void timeout(); static void timeout();
static void usage(); static void usage();
static void wildinput(); static void wildinput();
@ -195,6 +196,7 @@ char * argv[];
register char * cp; register char * cp;
register char * username; register char * username;
register int ch; register int ch;
register int convtype;
time_t t; time_t t;
#ifdef DST_NONE #ifdef DST_NONE
static struct timeval tv; /* static so tv_usec is 0 */ static struct timeval tv; /* static so tv_usec is 0 */
@ -357,9 +359,20 @@ char * argv[];
} }
} }
if (value != NULL) { if (value != NULL) {
t = parse(value, -1); t = convert(value, (convtype = 0), now);
#ifdef USG_INPUT
if (t == -1) if (t == -1)
usage(); t = convert(value, (convtype = 1), now);
#endif /* defined USG_INPUT */
if (t == -1) {
/*
** Better diagnosis needed here.
** Utterly nonsensical time,
** or time that falls in a DST transition hole?
*/
wildinput("time", value,
"can't be converted to time_t");
}
} }
/* /*
** Entire command line has now been checked. ** Entire command line has now been checked.
@ -405,12 +418,14 @@ char * argv[];
if (nflag || !netsettime(tv)) if (nflag || !netsettime(tv))
#endif /* defined TSP_SETDATE */ #endif /* defined TSP_SETDATE */
{ {
#ifndef EBUG
logwtmp(OTIME_MSG, TIME_USER, ""); logwtmp(OTIME_MSG, TIME_USER, "");
if (settimeofday(&tv, (struct timezone *) NULL) == 0) { if (settimeofday(&tv, (struct timezone *) NULL) == 0) {
logwtmp(NTIME_MSG, TIME_USER, ""); logwtmp(NTIME_MSG, TIME_USER, "");
syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", syslog(LOG_AUTH | LOG_NOTICE, "date set by %s",
username); username);
} else oops("date: error: settimeofday"); } else oops("date: error: settimeofday");
#endif /* !defined EBUG */
} }
#else /* !defined DST_NONE */ #else /* !defined DST_NONE */
logwtmp(OTIME_MSG, TIME_USER, ""); logwtmp(OTIME_MSG, TIME_USER, "");
@ -419,9 +434,10 @@ char * argv[];
else oops("date: error: stime"); else oops("date: error: stime");
#endif /* !defined DST_NONE */ #endif /* !defined DST_NONE */
finalcheck(t); checkfinal(value, convtype, t);
display(format); display(format);
/* gcc -Wall pacifier */
for ( ; ; ) for ( ; ; )
; ;
} }
@ -471,18 +487,15 @@ char * string;
} }
static void static void
ambiguous(thist, thatt, was_set) iffy(thist, thatt)
time_t thist; time_t thist;
time_t thatt; time_t thatt;
int was_set;
{ {
struct tm tm; struct tm tm;
(void) fprintf(stderr, "date: error: ambiguous time. "); (void) fprintf(stderr, "date: error: ambiguous time. ");
tm = *gmtime(&thist); tm = *gmtime(&thist);
if (was_set) (void) fprintf(stderr, "Time was set as if you used\n");
(void) fprintf(stderr, "Time was set as if you used\n");
else (void) fprintf(stderr, "Use\n");
/* /*
** Avoid running afoul of SCCS! ** Avoid running afoul of SCCS!
*/ */
@ -493,9 +506,7 @@ int was_set;
timeout(stderr, "to get %c", &tm); timeout(stderr, "to get %c", &tm);
(void) fprintf(stderr, " (%s time)", (void) fprintf(stderr, " (%s time)",
tm.tm_isdst ? "summer" : "standard"); tm.tm_isdst ? "summer" : "standard");
if (was_set) (void) fprintf(stderr, ". Use\n");
(void) fprintf(stderr, ". Use\n");
else (void) fprintf(stderr, ", or\n");
tm = *gmtime(&thatt); tm = *gmtime(&thatt);
timeout(stderr, "\tdate -u %Y", &tm); timeout(stderr, "\tdate -u %Y", &tm);
timeout(stderr, "%m%d%H", &tm); timeout(stderr, "%m%d%H", &tm);
@ -720,33 +731,75 @@ struct tm * tmp;
#endif /* !defined USE_STRFTIME */ #endif /* !defined USE_STRFTIME */
static int
comptm(atmp, btmp)
register struct tm * atmp;
register struct tm * btmp;
{
register int result;
if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
(result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
(result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
(result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
(result = (atmp->tm_min - btmp->tm_min)) == 0)
result = atmp->tm_sec - btmp->tm_sec;
return result;
}
/* /*
** Check for iffy input.
*/
#ifndef USG_INPUT
/*ARGSUSED*/
#endif /* defined USG_INPUT */
static void
checkfinal(value, convtype, t)
char * value;
int convtype;
time_t t;
{
time_t othert;
struct tm tm;
struct tm othertm;
register int pass;
register long offset;
#ifdef USG_INPUT
/*
** If USG_INPUT is defined, check for USG/BSD ambiguity.
*/
othert = convert(value, !convtype, t);
if (othert != -1 && othert != t)
iffy(t, othert);
#endif /* defined USG_INPUT */
/*
** See if there's both a DST and a STD version.
*/
tm = *localtime(&t);
othertm = tm;
othertm.tm_isdst = !tm.tm_isdst;
othert = mktime(&tm);
if (othert != -1 && comptm(&tm, &othertm))
iffy(t, othert);
/*
** Final check.
**
** If a jurisdiction shifts time *without* shifting whether time is ** If a jurisdiction shifts time *without* shifting whether time is
** summer or standard (as Hawaii, the United Kingdom, and Saudi Arabia ** summer or standard (as Hawaii, the United Kingdom, and Saudi Arabia
** have done), routine checks for ambiguous times may not work. ** have done), routine checks for iffy times may not work.
** So we perform this final check, deferring it until after the time has ** So we perform this final check, deferring it until after the time has
** been set--it may take a while, and we don't want to introduce an unnecessary ** been set--it may take a while, and we don't want to introduce an unnecessary
** lag between the time the user enters their command and the time that ** lag between the time the user enters their command and the time that
** stime/settimeofday is called. ** stime/settimeofday is called.
** **
** We just check nearby times to see if any of them have the same representation ** We just check nearby times to see if any of them have the same representation
** as the time that parse returned. We work our way out from the center ** as the time that convert returned. We work our way out from the center
** for quick response in solar time situations. We only handle common cases-- ** for quick response in solar time situations. We only handle common cases--
** offsets of at most a minute, and offsets of exact numbers of minutes ** offsets of at most a minute, and offsets of exact numbers of minutes
** and at most an hour. ** and at most an hour.
*/ */
static void
finalcheck(t)
time_t t;
{
struct tm tm;
register int pass;
register long offset;
time_t othert;
struct tm othertm;
tm = *localtime(&t);
for (offset = 1; offset <= 60; ++offset) for (offset = 1; offset <= 60; ++offset)
for (pass = 1; pass <= 4; ++pass) { for (pass = 1; pass <= 4; ++pass) {
if (pass == 1) if (pass == 1)
@ -757,18 +810,13 @@ time_t t;
othert = t + 60 * offset; othert = t + 60 * offset;
else othert = t - 60 * offset; else othert = t - 60 * offset;
othertm = *localtime(&othert); othertm = *localtime(&othert);
if (tm.tm_year == othertm.tm_year && if (comptm(&tm, &othertm) == 0)
tm.tm_mon == othertm.tm_mon && iffy(t, othert);
tm.tm_hour == othertm.tm_hour &&
tm.tm_min == othertm.tm_min &&
tm.tm_sec == othertm.tm_sec &&
tm.tm_isdst == othertm.tm_isdst)
ambiguous(t, othert, 1);
} }
} }
/* /*
** parse -- ** convert --
** convert user's input into a time_t. ** convert user's input into a time_t.
*/ */
@ -781,50 +829,25 @@ register char * cp;
return (cp[0] - '0') * 10 + cp[1] - '0'; return (cp[0] - '0') * 10 + cp[1] - '0';
} }
#ifndef USG_INPUT
/*ARGSUSED*/
#endif /* !defined USG_INPUT */
static time_t static time_t
xtime(intmp) convert(format, dousg, t)
register struct tm * intmp; register char * format;
{ int dousg;
struct tm outtm; time_t t;
time_t outt;
outtm = *intmp;
outt = mktime(&outtm);
return (outtm.tm_isdst == intmp->tm_isdst &&
outtm.tm_sec == intmp->tm_sec &&
outtm.tm_min == intmp->tm_min &&
outtm.tm_hour == intmp->tm_hour &&
outtm.tm_mday == intmp->tm_mday &&
outtm.tm_mon == intmp->tm_mon &&
outtm.tm_year == intmp->tm_year) ?
outt : -1;
}
static time_t
parse(cp, isdst)
register char * cp;
int isdst;
{ {
register char * cp;
register int i; register int i;
register int year; register int year;
struct tm tm; struct tm tm, outtm;
time_t outt;
int pairs[6]; int pairs[6];
time_t thist;
time_t thatt;
if (isdst < 0) { cp = format;
thist = parse(cp, 0); tm = *localtime(&t);
thatt = parse(cp, 1); tm.tm_isdst = -1;
if (thist == -1)
if (thatt == -1)
return -1;
else return thatt;
else if (thatt == -1)
return thist;
else ambiguous(thist, thatt, 0);
}
tm = *localtime(&now);
tm.tm_isdst = isdst;
tm.tm_sec = 0; tm.tm_sec = 0;
for (i = 0; ; ++i) { for (i = 0; ; ++i) {
if (*cp == '\0') if (*cp == '\0')
@ -847,24 +870,39 @@ int isdst;
} }
switch (i) { switch (i) {
default: default:
break; return -1;
case 2: /* hhmm */ case 2: /* hhmm */
tm.tm_hour = pairs[0]; tm.tm_hour = pairs[0];
tm.tm_min = pairs[1]; tm.tm_min = pairs[1];
return xtime(&tm); break;
case 3: /* ddhhmm */ case 3: /* ddhhmm */
tm.tm_mday = pairs[0]; tm.tm_mday = pairs[0];
tm.tm_hour = pairs[1]; tm.tm_hour = pairs[1];
tm.tm_min = pairs[2]; tm.tm_min = pairs[2];
return xtime(&tm); break;
case 4: /* mmddhhmm */ case 4: /* mmddhhmm */
tm.tm_mon = pairs[0] - 1; tm.tm_mon = pairs[0] - 1;
tm.tm_mday = pairs[1]; tm.tm_mday = pairs[1];
tm.tm_hour = pairs[2]; tm.tm_hour = pairs[2];
tm.tm_min = pairs[3]; tm.tm_min = pairs[3];
return xtime(&tm); break;
case 5: /* Ulp! yymmddhhmm or mmddhhmmyy */ case 5: /* Ulp! yymmddhhmm or mmddhhmmyy */
#ifdef USG_INPUT
if (dousg) {
tm.tm_mon = pairs[0] - 1;
tm.tm_mday = pairs[1];
tm.tm_hour = pairs[2];
tm.tm_min = pairs[3];
year = tm.tm_year + TM_YEAR_BASE;
year -= year % 100;
year = year + pairs[4];
tm.tm_year = year - TM_YEAR_BASE;
break;
}
#endif /* defined USG_INPUT */
year = tm.tm_year + TM_YEAR_BASE; year = tm.tm_year + TM_YEAR_BASE;
year -= year % 100; year -= year % 100;
year = year + pairs[0]; year = year + pairs[0];
@ -875,32 +913,7 @@ int isdst;
tm.tm_hour = pairs[3]; tm.tm_hour = pairs[3];
tm.tm_min = pairs[4]; tm.tm_min = pairs[4];
thist = xtime(&tm); break;
#ifndef USG_INPUT
return thist;
#else /* defined USG_INPUT */
tm.tm_mon = pairs[0] - 1;
tm.tm_mday = pairs[1];
tm.tm_hour = pairs[2];
tm.tm_min = pairs[3];
year = tm.tm_year + TM_YEAR_BASE;
year -= year % 100;
year = year + pairs[4];
tm.tm_year = year - TM_YEAR_BASE;
thatt = xtime(&tm);
if (thist == -1)
if (thatt == -1)
break;
else return thatt;
else if (thatt == -1)
return thist;
else ambiguous(thist, thatt, 0);
#endif /* defined USG_INPUT */
case 6: /* yyyymmddhhmm--BSD finally wins in the 21st century */ case 6: /* yyyymmddhhmm--BSD finally wins in the 21st century */
year = pairs[0] * 100 + pairs[1]; year = pairs[0] * 100 + pairs[1];
tm.tm_year = year - TM_YEAR_BASE; tm.tm_year = year - TM_YEAR_BASE;
@ -908,9 +921,11 @@ int isdst;
tm.tm_mday = pairs[3]; tm.tm_mday = pairs[3];
tm.tm_hour = pairs[4]; tm.tm_hour = pairs[4];
tm.tm_min = pairs[5]; tm.tm_min = pairs[5];
return xtime(&tm); break;
} }
return -1; outtm = tm;
outt = mktime(&outtm);
return (comptm(&tm, &outtm) == 0) ? outt : -1;
} }
#ifdef TSP_SETDATE #ifdef TSP_SETDATE