1 /*
2 **  Sendmail
3 **  Copyright (c) 1983  Eric P. Allman
4 **  Berkeley, California
5 **
6 **  Copyright (c) 1983 Regents of the University of California.
7 **  All rights reserved.  The Berkeley software License Agreement
8 **  specifies the terms and conditions for redistribution.
9 */
10 
11 #ifndef lint
12 static char	SccsId[] = "@(#)arpadate.c	5.1 (Berkeley) 06/07/85";
13 #endif not lint
14 
15 # include "conf.h"
16 # ifdef USG
17 # include <time.h>
18 # else
19 # include <sys/time.h>
20 # ifndef V6
21 # include <sys/types.h>
22 # include <sys/timeb.h>
23 # endif V6
24 # endif USG
25 # include "useful.h"
26 
27 SCCSID(@(#)arpadate.c	5.1		06/07/85);
28 
29 # ifdef V6
30 # define OLDTIME
31 # endif V6
32 # ifdef USG
33 # define OLDTIME
34 # endif USG
35 
36 /*
37 **  ARPADATE -- Create date in ARPANET format
38 **
39 **	Parameters:
40 **		ud -- unix style date string.  if NULL, one is created.
41 **
42 **	Returns:
43 **		pointer to an ARPANET date field
44 **
45 **	Side Effects:
46 **		none
47 **
48 **	WARNING:
49 **		date is stored in a local buffer -- subsequent
50 **		calls will overwrite.
51 **
52 **	Bugs:
53 **		Timezone is computed from local time, rather than
54 **		from whereever (and whenever) the message was sent.
55 **		To do better is very hard.
56 **
57 **		Some sites are now inserting the timezone into the
58 **		local date.  This routine should figure out what
59 **		the format is and work appropriately.
60 */
61 
62 char *
63 arpadate(ud)
64 	register char *ud;
65 {
66 	register char *p;
67 	register char *q;
68 	static char b[40];
69 	extern char *ctime();
70 	register int i;
71 	extern struct tm *localtime();
72 	extern bool fconvert();
73 # ifdef OLDTIME
74 	long t;
75 	extern long time();
76 # else OLDTIME
77 	struct timeb t;
78 	extern struct timeb *ftime();
79 	extern char *timezone();
80 # endif OLDTIME
81 # ifdef V6
82 	extern char *StdTimezone, *DstTimezone;
83 # endif V6
84 # ifdef USG
85 	extern char *tzname[2];
86 # endif USG
87 
88 	/*
89 	**  Get current time.
90 	**	This will be used if a null argument is passed and
91 	**	to resolve the timezone.
92 	*/
93 
94 # ifdef OLDTIME
95 	(void) time(&t);
96 	if (ud == NULL)
97 		ud = ctime(&t);
98 # else
99 	ftime(&t);
100 	if (ud == NULL)
101 		ud = ctime(&t.time);
102 # endif OLDTIME
103 
104 	/*
105 	**  Crack the UNIX date line in a singularly unoriginal way.
106 	*/
107 
108 	q = b;
109 
110 	p = &ud[0];		/* Mon */
111 	*q++ = *p++;
112 	*q++ = *p++;
113 	*q++ = *p++;
114 	*q++ = ',';
115 	*q++ = ' ';
116 
117 	p = &ud[8];		/* 16 */
118 	if (*p == ' ')
119 		p++;
120 	else
121 		*q++ = *p++;
122 	*q++ = *p++;
123 	*q++ = ' ';
124 
125 	p = &ud[4];		/* Sep */
126 	*q++ = *p++;
127 	*q++ = *p++;
128 	*q++ = *p++;
129 	*q++ = ' ';
130 
131 	p = &ud[22];		/* 79 */
132 	*q++ = *p++;
133 	*q++ = *p++;
134 	*q++ = ' ';
135 
136 	p = &ud[11];		/* 01:03:52 */
137 	for (i = 8; i > 0; i--)
138 		*q++ = *p++;
139 
140 				/* -PST or -PDT */
141 # ifdef V6
142 	if (localtime(&t)->tm_isdst)
143 		p = DstTimezone;
144 	else
145 		p = StdTimezone;
146 # else
147 # ifdef USG
148 	if (localtime(&t)->tm_isdst)
149 		p = tzname[1];
150 	else
151 		p = tzname[0];
152 # else
153 	p = timezone(t.timezone, localtime(&t.time)->tm_isdst);
154 # endif USG
155 # endif V6
156 	if ((strncmp(p, "GMT", 3) == 0 || strncmp(p, "gmt", 3) == 0) &&
157 	    p[3] != '\0')
158 	{
159 		/* hours from GMT */
160 		p += 3;
161 		*q++ = *p++;
162 		if (p[1] == ':')
163 			*q++ = '0';
164 		else
165 			*q++ = *p++;
166 		*q++ = *p++;
167 		p++;		/* skip ``:'' */
168 		*q++ = *p++;
169 		*q++ = *p++;
170 		*q = '\0';
171 	}
172 	else if (!fconvert(p, q))
173 	{
174 		*q++ = ' ';
175 		*q++ = *p++;
176 		*q++ = *p++;
177 		*q++ = *p++;
178 		*q = '\0';
179 	}
180 
181 	return (b);
182 }
183 /*
184 **  FCONVERT -- convert foreign timezones to ARPA timezones
185 **
186 **	This routine is essentially from Teus Hagen.
187 **
188 **	Parameters:
189 **		a -- timezone as returned from UNIX.
190 **		b -- place to put ARPA-style timezone.
191 **
192 **	Returns:
193 **		TRUE -- if a conversion was made (and b was filled in).
194 **		FALSE -- if this is not a recognized local time.
195 **
196 **	Side Effects:
197 **		none.
198 */
199 
200 /* UNIX to arpa conversion table */
201 struct foreign
202 {
203 	char *f_from;
204 	char *f_to;
205 };
206 
207 static struct foreign Foreign[] =
208 {
209 	{ "EET",	" -0200" },	/* eastern europe */
210 	{ "MET",	" -0100" },	/* middle europe */
211 	{ "WET",	" GMT"   },	/* western europe */
212 	{ "EET DST",	" -0300" },	/* daylight saving times */
213 	{ "MET DST",	" -0200" },
214 	{ "WET DST",	" -0100" },
215 	{ NULL,		NULL	 }
216 };
217 
218 bool
219 fconvert(a, b)
220 	register char *a;
221 	char *b;
222 {
223 	register struct foreign *euptr;
224 	register char *p;
225 
226 	for (euptr = Foreign; euptr->f_from != NULL; euptr++)
227 	{
228 		if (sameword(euptr->f_from, a))
229 		{
230 			p = euptr->f_to;
231 			while (*p)
232 				*b++ = *p++;
233 			*b = '\0';
234 			return (TRUE);
235 		}
236 	}
237 	return (FALSE);
238 }
239