Import sendmail 8.13.4 into a new contrib directory as the first step
[dragonfly.git] / contrib / sendmail-8.13.4 / sendmail / arpadate.c
blob16082cd259af77d42c70b13b23f02fff2a643f02
1 /*
2 * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
3 * All rights reserved.
4 * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
5 * Copyright (c) 1988, 1993
6 * The Regents of the University of California. All rights reserved.
8 * By using this file, you agree to the terms and conditions set
9 * forth in the LICENSE file which can be found at the top level of
10 * the sendmail distribution.
14 #include <sendmail.h>
16 SM_RCSID("@(#)$Id: arpadate.c,v 8.30 2001/09/11 04:05:12 gshapiro Exp $")
19 ** ARPADATE -- Create date in ARPANET format
21 ** Parameters:
22 ** ud -- unix style date string. if NULL, one is created.
24 ** Returns:
25 ** pointer to an ARPANET date field
27 ** Side Effects:
28 ** none
30 ** WARNING:
31 ** date is stored in a local buffer -- subsequent
32 ** calls will overwrite.
34 ** Bugs:
35 ** Timezone is computed from local time, rather than
36 ** from wherever (and whenever) the message was sent.
37 ** To do better is very hard.
39 ** Some sites are now inserting the timezone into the
40 ** local date. This routine should figure out what
41 ** the format is and work appropriately.
44 #ifndef TZNAME_MAX
45 # define TZNAME_MAX 50 /* max size of timezone */
46 #endif /* ! TZNAME_MAX */
48 /* values for TZ_TYPE */
49 #define TZ_NONE 0 /* no character timezone support */
50 #define TZ_TM_NAME 1 /* use tm->tm_name */
51 #define TZ_TM_ZONE 2 /* use tm->tm_zone */
52 #define TZ_TZNAME 3 /* use tzname[] */
53 #define TZ_TIMEZONE 4 /* use timezone() */
55 char *
56 arpadate(ud)
57 register char *ud;
59 register char *p;
60 register char *q;
61 register int off;
62 register int i;
63 register struct tm *lt;
64 time_t t;
65 struct tm gmt;
66 char *tz;
67 static char b[43 + TZNAME_MAX];
70 ** Get current time.
71 ** This will be used if a null argument is passed and
72 ** to resolve the timezone.
75 /* SM_REQUIRE(ud == NULL || strlen(ud) >= 23); */
76 t = curtime();
77 if (ud == NULL)
78 ud = ctime(&t);
81 ** Crack the UNIX date line in a singularly unoriginal way.
84 q = b;
86 p = &ud[0]; /* Mon */
87 *q++ = *p++;
88 *q++ = *p++;
89 *q++ = *p++;
90 *q++ = ',';
91 *q++ = ' ';
93 p = &ud[8]; /* 16 */
94 if (*p == ' ')
95 p++;
96 else
97 *q++ = *p++;
98 *q++ = *p++;
99 *q++ = ' ';
101 p = &ud[4]; /* Sep */
102 *q++ = *p++;
103 *q++ = *p++;
104 *q++ = *p++;
105 *q++ = ' ';
107 p = &ud[20]; /* 1979 */
108 *q++ = *p++;
109 *q++ = *p++;
110 *q++ = *p++;
111 *q++ = *p++;
112 *q++ = ' ';
114 p = &ud[11]; /* 01:03:52 */
115 for (i = 8; i > 0; i--)
116 *q++ = *p++;
119 ** should really get the timezone from the time in "ud" (which
120 ** is only different if a non-null arg was passed which is different
121 ** from the current time), but for all practical purposes, returning
122 ** the current local zone will do (its all that is ever needed).
125 gmt = *gmtime(&t);
126 lt = localtime(&t);
128 off = (lt->tm_hour - gmt.tm_hour) * 60 + lt->tm_min - gmt.tm_min;
130 /* assume that offset isn't more than a day ... */
131 if (lt->tm_year < gmt.tm_year)
132 off -= 24 * 60;
133 else if (lt->tm_year > gmt.tm_year)
134 off += 24 * 60;
135 else if (lt->tm_yday < gmt.tm_yday)
136 off -= 24 * 60;
137 else if (lt->tm_yday > gmt.tm_yday)
138 off += 24 * 60;
140 *q++ = ' ';
141 if (off == 0)
143 *q++ = 'G';
144 *q++ = 'M';
145 *q++ = 'T';
147 else
149 tz = NULL;
150 #if TZ_TYPE == TZ_TM_NAME
151 tz = lt->tm_name;
152 #endif /* TZ_TYPE == TZ_TM_NAME */
153 #if TZ_TYPE == TZ_TM_ZONE
154 tz = lt->tm_zone;
155 #endif /* TZ_TYPE == TZ_TM_ZONE */
156 #if TZ_TYPE == TZ_TZNAME
158 extern char *tzname[];
160 if (lt->tm_isdst > 0)
161 tz = tzname[1];
162 else if (lt->tm_isdst == 0)
163 tz = tzname[0];
164 else
165 tz = NULL;
167 #endif /* TZ_TYPE == TZ_TZNAME */
168 #if TZ_TYPE == TZ_TIMEZONE
170 extern char *timezone();
172 tz = timezone(off, lt->tm_isdst);
174 #endif /* TZ_TYPE == TZ_TIMEZONE */
175 if (off < 0)
177 off = -off;
178 *q++ = '-';
180 else
181 *q++ = '+';
183 if (off >= 24*60) /* should be impossible */
184 off = 23*60+59; /* if not, insert silly value */
186 *q++ = (off / 600) + '0';
187 *q++ = (off / 60) % 10 + '0';
188 off %= 60;
189 *q++ = (off / 10) + '0';
190 *q++ = (off % 10) + '0';
191 if (tz != NULL && *tz != '\0')
193 *q++ = ' ';
194 *q++ = '(';
195 while (*tz != '\0' && q < &b[sizeof b - 3])
196 *q++ = *tz++;
197 *q++ = ')';
200 *q = '\0';
202 return b;