1 # include <time.h>
2 # ifndef V6
3 # include <sys/types.h>
4 # include <sys/timeb.h>
5 # endif
6 # include "useful.h"
7 
8 static char SccsId[] = "@(#)arpadate.c	3.7	09/24/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 struct cvttab
37 {
38 	char	*old;
39 	char	*new;
40 };
41 
42 struct cvttab	DowTab[] =
43 {
44 	"Sun",		"Sunday",
45 	"Mon",		"Monday",
46 	"Tue",		"Tuesday",
47 	"Wed",		"Wednesday",
48 	"Thu",		"Thursday",
49 	"Fri",		"Friday",
50 	"Sat",		"Saturday",
51 	NULL,		NULL
52 };
53 
54 struct cvttab	MonthTab[] =
55 {
56 	"Jan",		"January",
57 	"Feb",		"February",
58 	"Mar",		"March",
59 	"Apr",		"April",
60 	"May",		"May",
61 	"Jun",		"June",
62 	"Jul",		"July",
63 	"Aug",		"August",
64 	"Sep",		"September",
65 	"Oct",		"October",
66 	"Nov",		"November",
67 	"Dec",		"December",
68 	NULL,		NULL
69 };
70 
71 char *
72 arpadate(ud)
73 	register char *ud;
74 {
75 	register char *p;
76 	register char *q;
77 	static char b[40];
78 	extern char *ctime();
79 	register int i;
80 	struct cvttab *c;
81 	extern struct tm *localtime();
82 # ifdef V6
83 	long t;
84 	extern char *StdTimezone, *DstTimezone;
85 	extern long time();
86 # else
87 	struct timeb t;
88 	extern struct timeb *ftime();
89 	extern char *timezone();
90 # endif
91 
92 	/*
93 	**  Get current time.
94 	**	This will be used if a null argument is passed and
95 	**	to resolve the timezone.
96 	*/
97 
98 # ifdef V6
99 	(void) time(&t);
100 	if (ud == NULL)
101 		ud = ctime(&t);
102 # else
103 	ftime(&t);
104 	if (ud == NULL)
105 		ud = ctime(&t.time);
106 # endif
107 
108 	/*
109 	**  Crack the UNIX date line in a singularly unoriginal way.
110 	*/
111 
112 	q = b;
113 
114 	p = &ud[8];		/* 16 */
115 	if (*p == ' ')
116 		p++;
117 	else
118 		*q++ = *p++;
119 	*q++ = *p++;
120 	*q++ = ' ';
121 
122 	p = NULL;		/* Sep */
123 	for (c = MonthTab; c->old != NULL; c++)
124 	{
125 		if (strncmp(&ud[4], c->old, 3) == 0)
126 		{
127 			p = c->new;
128 			break;
129 		}
130 	}
131 	if (p != NULL)
132 	{
133 		while (*p != '\0')
134 			*q++ = *p++;
135 	}
136 	else
137 	{
138 		p = &ud[4];
139 		*q++ = *p++;
140 		*q++ = *p++;
141 		*q++ = *p++;
142 	}
143 	*q++ = ' ';
144 
145 	p = &ud[20];		/* 1979 */
146 	for (i = 4; i > 0; i--)
147 		*q++ = *p++;
148 	*q++ = ' ';
149 
150 	p = &ud[11];		/* 01:03:52 */
151 	for (i = 5; i > 0; i--)
152 		*q++ = *p++;
153 
154 				/* -PST or -PDT */
155 # ifdef V6
156 	if (localtime(&t)->tm_isdst)
157 		p = DstTimezone;
158 	else
159 		p = StdTimezone;
160 # else
161 	p = timezone(t.timezone, localtime(&t.time)->tm_isdst);
162 # endif V6
163 	if (p[3] != '\0')
164 	{
165 		/* hours from GMT */
166 		p += 3;
167 		*q++ = *p++;
168 		if (p[1] == ':')
169 			*q++ = '0';
170 		else
171 			*q++ = *p++;
172 		*q++ = *p++;
173 		p++;		/* skip ``:'' */
174 		*q++ = *p++;
175 		*q++ = *p++;
176 	}
177 	else
178 	{
179 		*q++ = '-';
180 		*q++ = *p++;
181 		*q++ = *p++;
182 		*q++ = *p++;
183 	}
184 
185 	p = NULL;		/* Mon */
186 	for (c = DowTab; c->old != NULL; c++)
187 	{
188 		if (strncmp(&ud[0], c->old, 3) == 0)
189 		{
190 			p = c->new;
191 			break;
192 		}
193 	}
194 	if (p != NULL)
195 	{
196 		*q++ = ' ';
197 		*q++ = '(';
198 		while (*p != '\0')
199 			*q++ = *p++;
200 		*q++ = ')';
201 	}
202 
203 	*q = '\0';
204 
205 	return (b);
206 }
207