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