]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/sendmail/src/arpadate.c
This commit was generated by cvs2svn to compensate for changes in r53024,
[FreeBSD/FreeBSD.git] / contrib / sendmail / src / arpadate.c
1 /*
2  * Copyright (c) 1998 Sendmail, Inc.  All rights reserved.
3  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
4  * Copyright (c) 1988, 1993
5  *      The Regents of the University of California.  All rights reserved.
6  *
7  * By using this file, you agree to the terms and conditions set
8  * forth in the LICENSE file which can be found at the top level of
9  * the sendmail distribution.
10  *
11  */
12
13 #ifndef lint
14 static char sccsid[] = "@(#)arpadate.c  8.14 (Berkeley) 2/2/1999";
15 #endif /* not lint */
16
17 # include "sendmail.h"
18
19 /*
20 **  ARPADATE -- Create date in ARPANET format
21 **
22 **      Parameters:
23 **              ud -- unix style date string.  if NULL, one is created.
24 **
25 **      Returns:
26 **              pointer to an ARPANET date field
27 **
28 **      Side Effects:
29 **              none
30 **
31 **      WARNING:
32 **              date is stored in a local buffer -- subsequent
33 **              calls will overwrite.
34 **
35 **      Bugs:
36 **              Timezone is computed from local time, rather than
37 **              from whereever (and whenever) the message was sent.
38 **              To do better is very hard.
39 **
40 **              Some sites are now inserting the timezone into the
41 **              local date.  This routine should figure out what
42 **              the format is and work appropriately.
43 */
44
45 #ifndef TZNAME_MAX
46 # define TZNAME_MAX     50      /* max size of timezone */
47 #endif
48
49 /* values for TZ_TYPE */
50 #define TZ_NONE         0       /* no character timezone support */
51 #define TZ_TM_NAME      1       /* use tm->tm_name */
52 #define TZ_TM_ZONE      2       /* use tm->tm_zone */
53 #define TZ_TZNAME       3       /* use tzname[] */
54 #define TZ_TIMEZONE     4       /* use timezone() */
55
56 char *
57 arpadate(ud)
58         register char *ud;
59 {
60         register char *p;
61         register char *q;
62         register int off;
63         register int i;
64         register struct tm *lt;
65         time_t t;
66         struct tm gmt;
67         char *tz;
68         static char b[43 + TZNAME_MAX];
69
70         /*
71         **  Get current time.
72         **      This will be used if a null argument is passed and
73         **      to resolve the timezone.
74         */
75
76         t = curtime();
77         if (ud == NULL)
78                 ud = ctime(&t);
79
80         /*
81         **  Crack the UNIX date line in a singularly unoriginal way.
82         */
83
84         q = b;
85
86         p = &ud[0];             /* Mon */
87         *q++ = *p++;
88         *q++ = *p++;
89         *q++ = *p++;
90         *q++ = ',';
91         *q++ = ' ';
92
93         p = &ud[8];             /* 16 */
94         if (*p == ' ')
95                 p++;
96         else
97                 *q++ = *p++;
98         *q++ = *p++;
99         *q++ = ' ';
100
101         p = &ud[4];             /* Sep */
102         *q++ = *p++;
103         *q++ = *p++;
104         *q++ = *p++;
105         *q++ = ' ';
106
107         p = &ud[20];            /* 1979 */
108         *q++ = *p++;
109         *q++ = *p++;
110         *q++ = *p++;
111         *q++ = *p++;
112         *q++ = ' ';
113
114         p = &ud[11];            /* 01:03:52 */
115         for (i = 8; i > 0; i--)
116                 *q++ = *p++;
117
118         /*
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).
123          */
124         gmt = *gmtime(&t);
125         lt = localtime(&t);
126
127         off = (lt->tm_hour - gmt.tm_hour) * 60 + lt->tm_min - gmt.tm_min;
128
129         /* assume that offset isn't more than a day ... */
130         if (lt->tm_year < gmt.tm_year)
131                 off -= 24 * 60;
132         else if (lt->tm_year > gmt.tm_year)
133                 off += 24 * 60;
134         else if (lt->tm_yday < gmt.tm_yday)
135                 off -= 24 * 60;
136         else if (lt->tm_yday > gmt.tm_yday)
137                 off += 24 * 60;
138
139         *q++ = ' ';
140         if (off == 0)
141         {
142                 *q++ = 'G';
143                 *q++ = 'M';
144                 *q++ = 'T';
145         }
146         else
147         {
148                 tz = NULL;
149 #if TZ_TYPE == TZ_TM_NAME
150                 tz = lt->tm_name;
151 #endif
152 #if TZ_TYPE == TZ_TM_ZONE
153                 tz = lt->tm_zone;
154 #endif
155 #if TZ_TYPE == TZ_TZNAME
156                 {
157                         extern char *tzname[];
158
159                         if (lt->tm_isdst > 0)
160                                 tz = tzname[1];
161                         else if (lt->tm_isdst == 0)
162                                 tz = tzname[0];
163                         else
164                                 tz = NULL;
165                 }
166 #endif
167 #if TZ_TYPE == TZ_TIMEZONE
168                 {
169                         extern char *timezone();
170
171                         tz = timezone(off, lt->tm_isdst);
172                 }
173 #endif
174                 if (off < 0)
175                 {
176                         off = -off;
177                         *q++ = '-';
178                 }
179                 else
180                         *q++ = '+';
181
182                 if (off >= 24*60)               /* should be impossible */
183                         off = 23*60+59;         /* if not, insert silly value */
184
185                 *q++ = (off / 600) + '0';
186                 *q++ = (off / 60) % 10 + '0';
187                 off %= 60;
188                 *q++ = (off / 10) + '0';
189                 *q++ = (off % 10) + '0';
190                 if (tz != NULL && *tz != '\0')
191                 {
192                         *q++ = ' ';
193                         *q++ = '(';
194                         while (*tz != '\0' && q < &b[sizeof b - 3])
195                                 *q++ = *tz++;
196                         *q++ = ')';
197                 }
198         }
199         *q = '\0';
200
201         return (b);
202 }