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