19152Seric # include "conf.h"
2*16895Seric # ifdef USG
3*16895Seric # include <time.h>
4*16895Seric # else
513587Swnj # include <sys/time.h>
62897Seric # ifndef V6
72897Seric # include <sys/types.h>
82897Seric # include <sys/timeb.h>
9*16895Seric # endif V6
10*16895Seric # endif USG
114437Seric # include "useful.h"
12293Seric 
13*16895Seric SCCSID(@(#)arpadate.c	4.4		08/11/84);
14403Seric 
15*16895Seric # ifdef V6
16*16895Seric # define OLDTIME
17*16895Seric # endif V6
18*16895Seric # ifdef USG
19*16895Seric # define OLDTIME
20*16895Seric # endif USG
21*16895Seric 
22293Seric /*
23293Seric **  ARPADATE -- Create date in ARPANET format
24293Seric **
25293Seric **	Parameters:
262897Seric **		ud -- unix style date string.  if NULL, one is created.
27293Seric **
28293Seric **	Returns:
29293Seric **		pointer to an ARPANET date field
30293Seric **
31293Seric **	Side Effects:
32293Seric **		none
33293Seric **
34293Seric **	WARNING:
35293Seric **		date is stored in a local buffer -- subsequent
36293Seric **		calls will overwrite.
373185Seric **
383185Seric **	Bugs:
393185Seric **		Timezone is computed from local time, rather than
403185Seric **		from whereever (and whenever) the message was sent.
413185Seric **		To do better is very hard.
424315Seric **
434315Seric **		Some sites are now inserting the timezone into the
444315Seric **		local date.  This routine should figure out what
454315Seric **		the format is and work appropriately.
46293Seric */
47293Seric 
481586Seric char *
492897Seric arpadate(ud)
502897Seric 	register char *ud;
51293Seric {
52293Seric 	register char *p;
532897Seric 	register char *q;
54293Seric 	static char b[40];
551586Seric 	extern char *ctime();
562897Seric 	register int i;
572897Seric 	extern struct tm *localtime();
5815137Seric 	extern bool fconvert();
59*16895Seric # ifdef OLDTIME
602897Seric 	long t;
614315Seric 	extern long time();
62*16895Seric # else OLDTIME
632897Seric 	struct timeb t;
642897Seric 	extern struct timeb *ftime();
652897Seric 	extern char *timezone();
66*16895Seric # endif OLDTIME
67*16895Seric # ifdef V6
68*16895Seric 	extern char *StdTimezone, *DstTimezone;
69*16895Seric # endif V6
70*16895Seric # ifdef USG
71*16895Seric 	extern char *tzname[2];
72*16895Seric # endif USG
73293Seric 
744315Seric 	/*
754315Seric 	**  Get current time.
764315Seric 	**	This will be used if a null argument is passed and
774315Seric 	**	to resolve the timezone.
784315Seric 	*/
794315Seric 
80*16895Seric # ifdef OLDTIME
814315Seric 	(void) time(&t);
822897Seric 	if (ud == NULL)
832897Seric 		ud = ctime(&t);
842897Seric # else
852897Seric 	ftime(&t);
862897Seric 	if (ud == NULL)
872897Seric 		ud = ctime(&t.time);
88*16895Seric # endif OLDTIME
89293Seric 
904315Seric 	/*
914315Seric 	**  Crack the UNIX date line in a singularly unoriginal way.
924315Seric 	*/
934315Seric 
942897Seric 	q = b;
952897Seric 
9613932Seric 	p = &ud[0];		/* Mon */
9713932Seric 	*q++ = *p++;
9813932Seric 	*q++ = *p++;
9913932Seric 	*q++ = *p++;
10013932Seric 	*q++ = ',';
10113932Seric 	*q++ = ' ';
10213932Seric 
103293Seric 	p = &ud[8];		/* 16 */
104293Seric 	if (*p == ' ')
105293Seric 		p++;
1062897Seric 	else
1072897Seric 		*q++ = *p++;
1082897Seric 	*q++ = *p++;
10910251Seric 	*q++ = ' ';
1102897Seric 
1115184Seric 	p = &ud[4];		/* Sep */
1125184Seric 	*q++ = *p++;
1135184Seric 	*q++ = *p++;
1145184Seric 	*q++ = *p++;
11510251Seric 	*q++ = ' ';
1162897Seric 
11713932Seric 	p = &ud[22];		/* 79 */
1185184Seric 	*q++ = *p++;
1195184Seric 	*q++ = *p++;
1202897Seric 	*q++ = ' ';
1212897Seric 
1222897Seric 	p = &ud[11];		/* 01:03:52 */
1235184Seric 	for (i = 8; i > 0; i--)
1242897Seric 		*q++ = *p++;
1252897Seric 
1262897Seric 				/* -PST or -PDT */
1272897Seric # ifdef V6
128293Seric 	if (localtime(&t)->tm_isdst)
1294315Seric 		p = DstTimezone;
130293Seric 	else
1314315Seric 		p = StdTimezone;
1322897Seric # else
133*16895Seric # ifdef USG
134*16895Seric 	if (localtime(&t)->tm_isdst)
135*16895Seric 		p = tzname[1];
136*16895Seric 	else
137*16895Seric 		p = tzname[0];
138*16895Seric # else
1392897Seric 	p = timezone(t.timezone, localtime(&t.time)->tm_isdst);
140*16895Seric # endif USG
1412897Seric # endif V6
14215137Seric 	if ((strncmp(p, "GMT", 3) == 0 || strncmp(p, "gmt", 3) == 0) &&
14315137Seric 	    p[3] != '\0')
1442897Seric 	{
1452897Seric 		/* hours from GMT */
1462897Seric 		p += 3;
1472897Seric 		*q++ = *p++;
1482897Seric 		if (p[1] == ':')
1492897Seric 			*q++ = '0';
1502897Seric 		else
1512897Seric 			*q++ = *p++;
1522897Seric 		*q++ = *p++;
1532897Seric 		p++;		/* skip ``:'' */
1542897Seric 		*q++ = *p++;
1552897Seric 		*q++ = *p++;
15615109Skarels 		*q = '\0';
1572897Seric 	}
15815137Seric 	else if (!fconvert(p, q))
1592897Seric 	{
16010251Seric 		*q++ = ' ';
1612897Seric 		*q++ = *p++;
1622897Seric 		*q++ = *p++;
1632897Seric 		*q++ = *p++;
16415109Skarels 		*q = '\0';
1652897Seric 	}
1662897Seric 
167293Seric 	return (b);
168293Seric }
16915137Seric /*
17015137Seric **  FCONVERT -- convert foreign timezones to ARPA timezones
17115137Seric **
17215137Seric **	This routine is essentially from Teus Hagen.
17315137Seric **
17415137Seric **	Parameters:
17515137Seric **		a -- timezone as returned from UNIX.
17615137Seric **		b -- place to put ARPA-style timezone.
17715137Seric **
17815137Seric **	Returns:
17915137Seric **		TRUE -- if a conversion was made (and b was filled in).
18015137Seric **		FALSE -- if this is not a recognized local time.
18115137Seric **
18215137Seric **	Side Effects:
18315137Seric **		none.
18415137Seric */
18515109Skarels 
18615137Seric /* UNIX to arpa conversion table */
18715137Seric struct foreign
18815137Seric {
18915109Skarels 	char *f_from;
19015109Skarels 	char *f_to;
19115109Skarels };
19215109Skarels 
19315137Seric static struct foreign Foreign[] =
19415137Seric {
195*16895Seric 	{ "EET",	" -0200" },	/* eastern europe */
196*16895Seric 	{ "MET",	" -0100" },	/* middle europe */
197*16895Seric 	{ "WET",	" GMT"   },	/* western europe */
198*16895Seric 	{ "EET DST",	" -0300" },	/* daylight saving times */
199*16895Seric 	{ "MET DST",	" -0200" },
200*16895Seric 	{ "WET DST",	" -0100" },
20115137Seric 	{ NULL,		NULL	 }
20215137Seric };
20315109Skarels 
20415137Seric bool
20515137Seric fconvert(a, b)
20615137Seric 	register char *a;
20715137Seric 	char *b;
20815137Seric {
20915137Seric 	register struct foreign *euptr;
21015137Seric 	register char *p;
21115137Seric 
21215137Seric 	for (euptr = Foreign; euptr->f_from != NULL; euptr++)
21315137Seric 	{
214*16895Seric 		if (sameword(euptr->f_from, a))
21515137Seric 		{
21615137Seric 			p = euptr->f_to;
21715137Seric 			while (*p)
21815137Seric 				*b++ = *p++;
21915109Skarels 			*b = '\0';
22015137Seric 			return (TRUE);
22115109Skarels 		}
22215137Seric 	}
22315137Seric 	return (FALSE);
22415109Skarels }
225