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