1 # include "conf.h"
2 # include <time.h>
3 # ifndef V6
4 # include <sys/types.h>
5 # include <sys/timeb.h>
6 # endif
7 
8 static char SccsId[] = "@(#)arpadate.c	3.6.1.1	09/23/81";
9 
10 /*
11 **  ARPADATE -- Create date in ARPANET format
12 **
13 **	Parameters:
14 **		ud -- unix style date string.  if NULL, one is created.
15 **
16 **	Returns:
17 **		pointer to an ARPANET date field
18 **
19 **	Side Effects:
20 **		none
21 **
22 **	WARNING:
23 **		date is stored in a local buffer -- subsequent
24 **		calls will overwrite.
25 **
26 **	Bugs:
27 **		Timezone is computed from local time, rather than
28 **		from whereever (and whenever) the message was sent.
29 **		To do better is very hard.
30 **
31 **		Some sites are now inserting the timezone into the
32 **		local date.  This routine should figure out what
33 **		the format is and work appropriately.
34 */
35 
36 # define NULL		0
37 
38 struct cvttab
39 {
40 	char	*old;
41 	char	*new;
42 };
43 
44 struct cvttab	DowTab[] =
45 {
46 	"Sun",		"Sunday",
47 	"Mon",		"Monday",
48 	"Tue",		"Tuesday",
49 	"Wed",		"Wednesday",
50 	"Thu",		"Thursday",
51 	"Fri",		"Friday",
52 	"Sat",		"Saturday",
53 	NULL,		NULL
54 };
55 
56 struct cvttab	MonthTab[] =
57 {
58 	"Jan",		"January",
59 	"Feb",		"February",
60 	"Mar",		"March",
61 	"Apr",		"April",
62 	"May",		"May",
63 	"Jun",		"June",
64 	"Jul",		"July",
65 	"Aug",		"August",
66 	"Sep",		"September",
67 	"Oct",		"October",
68 	"Nov",		"November",
69 	"Dec",		"December",
70 	NULL,		NULL
71 };
72 
73 char *
74 arpadate(ud)
75 	register char *ud;
76 {
77 	register char *p;
78 	register char *q;
79 	static char b[40];
80 	extern char *ctime();
81 	register int i;
82 	struct cvttab *c;
83 	extern struct tm *localtime();
84 # ifdef V6
85 	long t;
86 	extern char *StdTimezone, *DstTimezone;
87 	extern long time();
88 # else
89 	struct timeb t;
90 	extern struct timeb *ftime();
91 	extern char *timezone();
92 # endif
93 
94 	/*
95 	**  Get current time.
96 	**	This will be used if a null argument is passed and
97 	**	to resolve the timezone.
98 	*/
99 
100 # ifdef V6
101 	(void) time(&t);
102 	if (ud == NULL)
103 		ud = ctime(&t);
104 # else
105 	ftime(&t);
106 	if (ud == NULL)
107 		ud = ctime(&t.time);
108 # endif
109 
110 	/*
111 	**  Crack the UNIX date line in a singularly unoriginal way.
112 	*/
113 
114 	q = b;
115 
116 	p = &ud[8];		/* 16 */
117 	if (*p == ' ')
118 		p++;
119 	else
120 		*q++ = *p++;
121 	*q++ = *p++;
122 	*q++ = ' ';
123 
124 	p = NULL;		/* Sep */
125 	for (c = MonthTab; c->old != NULL; c++)
126 	{
127 		if (strncmp(&ud[4], c->old, 3) == 0)
128 		{
129 			p = c->new;
130 			break;
131 		}
132 	}
133 	if (p != NULL)
134 	{
135 		while (*p != '\0')
136 			*q++ = *p++;
137 	}
138 	else
139 	{
140 		p = &ud[4];
141 		*q++ = *p++;
142 		*q++ = *p++;
143 		*q++ = *p++;
144 	}
145 	*q++ = ' ';
146 
147 	p = &ud[20];		/* 1979 */
148 	for (i = 4; i > 0; i--)
149 		*q++ = *p++;
150 	*q++ = ' ';
151 
152 	p = &ud[11];		/* 01:03:52 */
153 	for (i = 5; i > 0; i--)
154 		*q++ = *p++;
155 
156 				/* -PST or -PDT */
157 # ifdef V6
158 	if (localtime(&t)->tm_isdst)
159 		p = DstTimezone;
160 	else
161 		p = StdTimezone;
162 # else
163 	p = timezone(t.timezone, localtime(&t.time)->tm_isdst);
164 # endif V6
165 	if (p[3] != '\0')
166 	{
167 		/* hours from GMT */
168 		p += 3;
169 		*q++ = *p++;
170 		if (p[1] == ':')
171 			*q++ = '0';
172 		else
173 			*q++ = *p++;
174 		*q++ = *p++;
175 		p++;		/* skip ``:'' */
176 		*q++ = *p++;
177 		*q++ = *p++;
178 	}
179 	else
180 	{
181 		*q++ = '-';
182 		*q++ = *p++;
183 		*q++ = *p++;
184 		*q++ = *p++;
185 	}
186 
187 	p = NULL;		/* Mon */
188 	for (c = DowTab; c->old != NULL; c++)
189 	{
190 		if (strncmp(&ud[0], c->old, 3) == 0)
191 		{
192 			p = c->new;
193 			break;
194 		}
195 	}
196 	if (p != NULL)
197 	{
198 		*q++ = ' ';
199 		*q++ = '(';
200 		while (*p != '\0')
201 			*q++ = *p++;
202 		*q++ = ')';
203 	}
204 
205 	*q = '\0';
206 
207 	return (b);
208 }
209