source: trunk/third/sendmail/sendmail/arpadate.c @ 19204

Revision 19204, 4.1 KB checked in by zacheiss, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r19203, which included commits to RCS files with non-trunk default branches.
RevLine 
[19203]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.
7 *
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.
11 *
12 */
13
14#include <sendmail.h>
15
16SM_RCSID("@(#)$Id: arpadate.c,v 1.1.1.1 2003-04-08 15:06:09 zacheiss Exp $")
17
18/*
19**  ARPADATE -- Create date in ARPANET format
20**
21**      Parameters:
22**              ud -- unix style date string.  if NULL, one is created.
23**
24**      Returns:
25**              pointer to an ARPANET date field
26**
27**      Side Effects:
28**              none
29**
30**      WARNING:
31**              date is stored in a local buffer -- subsequent
32**              calls will overwrite.
33**
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.
38**
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.
42*/
43
44#ifndef TZNAME_MAX
45# define TZNAME_MAX     50      /* max size of timezone */
46#endif /* ! TZNAME_MAX */
47
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() */
54
55char *
56arpadate(ud)
57        register char *ud;
58{
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];
68
69        /*
70        **  Get current time.
71        **      This will be used if a null argument is passed and
72        **      to resolve the timezone.
73        */
74
75        /* SM_REQUIRE(ud == NULL || strlen(ud) >= 23); */
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
125        gmt = *gmtime(&t);
126        lt = localtime(&t);
127
128        off = (lt->tm_hour - gmt.tm_hour) * 60 + lt->tm_min - gmt.tm_min;
129
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;
139
140        *q++ = ' ';
141        if (off == 0)
142        {
143                *q++ = 'G';
144                *q++ = 'M';
145                *q++ = 'T';
146        }
147        else
148        {
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
157                {
158                        extern char *tzname[];
159
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;
166                }
167#endif /* TZ_TYPE == TZ_TZNAME */
168#if TZ_TYPE == TZ_TIMEZONE
169                {
170                        extern char *timezone();
171
172                        tz = timezone(off, lt->tm_isdst);
173                }
174#endif /* TZ_TYPE == TZ_TIMEZONE */
175                if (off < 0)
176                {
177                        off = -off;
178                        *q++ = '-';
179                }
180                else
181                        *q++ = '+';
182
183                if (off >= 24*60)               /* should be impossible */
184                        off = 23*60+59;         /* if not, insert silly value */
185
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')
192                {
193                        *q++ = ' ';
194                        *q++ = '(';
195                        while (*tz != '\0' && q < &b[sizeof b - 3])
196                                *q++ = *tz++;
197                        *q++ = ')';
198                }
199        }
200        *q = '\0';
201
202        return b;
203}
Note: See TracBrowser for help on using the repository browser.