[47] in pc-kerberos

home help back first fref pref prev next nref lref last post

Re: stupid Microsoft epoch

daemon@ATHENA.MIT.EDU (John Gilmore)
Sat Sep 17 23:40:35 1994

To: Jim.Rees@umich.edu
Cc: pc-kerberos@MIT.EDU, Andy Adamson <andros@citi.umich.edu>, gnu@cygnus.com
In-Reply-To: Your message of "Thu, 08 Sep 1994 11:09:48 EDT."
             <9409081510.AA02408@MIT.EDU> 
Date: Sat, 17 Sep 1994 20:34:17 -0700
From: John Gilmore <gnu@cygnus.com>

> We're compiling the the DOS clients using Microsoft C 7.0, and one of the
> things we had to change was gettimofday().  It seems that the Microsoft
> time() uses the wrong epoch.  This is apparently a feature, not a bug, since
> it's in the documentation.

The Cygnus code accomodates this; it'll handle any epoch, by using
mktime to determine the local epoch.  We had to do this for both this
Microsoft brain-death (which they fixed in MSC 7.01) and for Mac support.

Here's relevant chunks of code.  Our code differs greatly from the MIT
release, since we made it all portable, while they just made it work
on DOS & Windows.  So you may want to plug it in differently.

	John Gilmore
	Cygnus Support

==> lib/krb/stime.c <==
/*
 * stime.c
 *
 * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
 * of Technology.
 *
 * For copying and distribution information, please see the file
 * <mit-copyright.h>.
 */

#include "mit-copyright.h"
#define	DEFINE_SOCKADDR
#define NEED_TIME_H
#include "krb.h"
#include <stdio.h>                      /* for sprintf() */

/*
 * Given a pointer to a long containing the number of seconds
 * since the beginning of time (midnight 1 Jan 1970 GMT), return
 * a string containing the local time in the form:
 *
 * "25-Jan-88 10:17:56"
 */

char *krb_stime(t)
    long *t;
{
    static char st[40];
    static time_t adjusted_time;
    struct tm *tm;
    char *month_sname();

    adjusted_time = *t - CONVERT_TIME_EPOCH;
    tm = localtime(&adjusted_time);
    (void) sprintf(st,"%2d-%s-%02d %02d:%02d:%02d",tm->tm_mday,
                   month_sname(tm->tm_mon + 1),tm->tm_year,
                   tm->tm_hour, tm->tm_min, tm->tm_sec);
    return st;
}


==> include/c-windows.h <==
/*
 * c-windows.h
 *
 * Machine-type definitions: PC running Windows.
 */

...
/*
 * TIME_GMT_UNIXSEC returns the current time of day, in Greenwich Mean Time,
 * as its unsigned KRB_INT32 result.  The result is in seconds since 
 * January 1, 1970, as used in Unix.
 *
 * TIME_GMT_UNIXSEC_US does the above, and also returns the number of
 * microseconds that have passed in the current second, through 
 * the argument pointer *usecptr, which points to an unsigned KRB_INT32.
 */
 
/* Unfortunately, KRB_INT32 isn't defined here yet.  Push the declaration
   into a macro, which krb.h will expand as needed at an appropriate point.  */
#define	DECL_THAT_NEEDS_KRB_INT32	\
	extern	unsigned KRB_INT32	win_time_gmt_unixsec \
					PROTOTYPE ((unsigned KRB_INT32 *));

#define	TIME_GMT_UNIXSEC	win_time_gmt_unixsec((unsigned KRB_INT32 *)0)
#define	TIME_GMT_UNIXSEC_US(us)	win_time_gmt_unixsec((us))

/* 
 * The long value which is the difference between the current time
 * as handled by the system time conversion utilities, and the 
 * current time as transmitted by Kerberos (seconds since 1/1/70).
 *
 * E.g. the result of   (tickettime) - CONVERT_TIME_EPOCH   is suitable
 * to pass to localtime() or ctime().
 */
#define	CONVERT_TIME_EPOCH	win_time_get_epoch()
extern long win_time_get_epoch();

==> lib/des/win_time.c <==
/*
 * win_time.c
 * 
 * Glue code for pasting Kerberos into the Windows environment.
 *
 * Originally written by John Gilmore, Cygnus Support, May '94.
 * Public Domain.
 */

#define	DEFINE_SOCKADDR
#include "krb.h"

#include <sys/types.h>
#include <time.h>
#include <sys/timeb.h>
#include <stdio.h>
#include <windows.h>

/* Time handling.  Translate Unix time calls into Kerberos internal 
   procedure calls.  See ../../include/c-win.h.  */

unsigned KRB_INT32
win_time_gmt_unixsec (usecptr)
	unsigned KRB_INT32	*usecptr;
{
	static struct _timeb	now_stat;
	struct _timeb now;

	_ftime (&now_stat);	/* Time into static storage (DLL craziness) */
	now = now_stat;		/* Grab it into non-shared storage */
	if (usecptr)
		*usecptr = now.millitm * 1000;
	return now.time + CONVERT_TIME_EPOCH;
}


/*
 * This routine figures out the current time epoch and returns the
 * conversion factor.  It exists because 
 * Microloss screwed the pooch on the time() and _ftime() calls in
 * its release 7.0 libraries.  They changed the epoch to Dec 31, 1899!
 * Idiots...   We try to cope.
 */

static struct tm jan_1_70 = {0, 0, 0, 1, 0, 70};
static long epoch = 0;
static int epoch_set = 0;

long
win_time_get_epoch()
{

	if (!epoch_set) {
		epoch = - mktime (&jan_1_70);	/* Seconds til 1970 localtime */
		epoch += timezone;		/* Seconds til 1970 GMT */
		epoch_set = 1;
	}
	return epoch;
}

home help back first fref pref prev next nref lref last post