Commit | Line | Data |
---|---|---|
15637ed4 RG |
1 | /* |
2 | * Copyright (c) 1983 Eric P. Allman | |
6f14531a RG |
3 | * Copyright (c) 1988, 1993 |
4 | * The Regents of the University of California. All rights reserved. | |
15637ed4 RG |
5 | * |
6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | |
9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | |
11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | |
14 | * 3. All advertising materials mentioning features or use of this software | |
15 | * must display the following acknowledgement: | |
16 | * This product includes software developed by the University of | |
17 | * California, Berkeley and its contributors. | |
18 | * 4. Neither the name of the University nor the names of its contributors | |
19 | * may be used to endorse or promote products derived from this software | |
20 | * without specific prior written permission. | |
21 | * | |
22 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
32 | * SUCH DAMAGE. | |
33 | */ | |
34 | ||
35 | #ifndef lint | |
6f14531a | 36 | static char sccsid[] = "@(#)arpadate.c 8.1 (Berkeley) 6/7/93"; |
15637ed4 RG |
37 | #endif /* not lint */ |
38 | ||
6f14531a | 39 | # include "sendmail.h" |
15637ed4 RG |
40 | |
41 | /* | |
42 | ** ARPADATE -- Create date in ARPANET format | |
43 | ** | |
44 | ** Parameters: | |
45 | ** ud -- unix style date string. if NULL, one is created. | |
46 | ** | |
47 | ** Returns: | |
48 | ** pointer to an ARPANET date field | |
49 | ** | |
50 | ** Side Effects: | |
51 | ** none | |
52 | ** | |
53 | ** WARNING: | |
54 | ** date is stored in a local buffer -- subsequent | |
55 | ** calls will overwrite. | |
56 | ** | |
57 | ** Bugs: | |
58 | ** Timezone is computed from local time, rather than | |
59 | ** from whereever (and whenever) the message was sent. | |
60 | ** To do better is very hard. | |
61 | ** | |
62 | ** Some sites are now inserting the timezone into the | |
63 | ** local date. This routine should figure out what | |
64 | ** the format is and work appropriately. | |
65 | */ | |
66 | ||
67 | char * | |
68 | arpadate(ud) | |
69 | register char *ud; | |
70 | { | |
71 | register char *p; | |
72 | register char *q; | |
73 | register int off; | |
74 | register int i; | |
75 | register struct tm *lt; | |
76 | time_t t; | |
77 | struct tm gmt; | |
78 | static char b[40]; | |
15637ed4 RG |
79 | |
80 | /* | |
81 | ** Get current time. | |
82 | ** This will be used if a null argument is passed and | |
83 | ** to resolve the timezone. | |
84 | */ | |
85 | ||
86 | (void) time(&t); | |
87 | if (ud == NULL) | |
88 | ud = ctime(&t); | |
89 | ||
90 | /* | |
91 | ** Crack the UNIX date line in a singularly unoriginal way. | |
92 | */ | |
93 | ||
94 | q = b; | |
95 | ||
96 | p = &ud[0]; /* Mon */ | |
97 | *q++ = *p++; | |
98 | *q++ = *p++; | |
99 | *q++ = *p++; | |
100 | *q++ = ','; | |
101 | *q++ = ' '; | |
102 | ||
103 | p = &ud[8]; /* 16 */ | |
104 | if (*p == ' ') | |
105 | p++; | |
106 | else | |
107 | *q++ = *p++; | |
108 | *q++ = *p++; | |
109 | *q++ = ' '; | |
110 | ||
111 | p = &ud[4]; /* Sep */ | |
112 | *q++ = *p++; | |
113 | *q++ = *p++; | |
114 | *q++ = *p++; | |
115 | *q++ = ' '; | |
116 | ||
6f14531a RG |
117 | p = &ud[20]; /* 1979 */ |
118 | *q++ = *p++; | |
119 | *q++ = *p++; | |
15637ed4 RG |
120 | *q++ = *p++; |
121 | *q++ = *p++; | |
122 | *q++ = ' '; | |
123 | ||
124 | p = &ud[11]; /* 01:03:52 */ | |
125 | for (i = 8; i > 0; i--) | |
126 | *q++ = *p++; | |
127 | ||
128 | /* | |
129 | * should really get the timezone from the time in "ud" (which | |
130 | * is only different if a non-null arg was passed which is different | |
131 | * from the current time), but for all practical purposes, returning | |
132 | * the current local zone will do (its all that is ever needed). | |
133 | */ | |
134 | gmt = *gmtime(&t); | |
135 | lt = localtime(&t); | |
136 | ||
137 | off = (lt->tm_hour - gmt.tm_hour) * 60 + lt->tm_min - gmt.tm_min; | |
138 | ||
139 | /* assume that offset isn't more than a day ... */ | |
140 | if (lt->tm_year < gmt.tm_year) | |
141 | off -= 24 * 60; | |
142 | else if (lt->tm_year > gmt.tm_year) | |
143 | off += 24 * 60; | |
144 | else if (lt->tm_yday < gmt.tm_yday) | |
145 | off -= 24 * 60; | |
146 | else if (lt->tm_yday > gmt.tm_yday) | |
147 | off += 24 * 60; | |
148 | ||
149 | *q++ = ' '; | |
150 | if (off == 0) { | |
151 | *q++ = 'G'; | |
152 | *q++ = 'M'; | |
153 | *q++ = 'T'; | |
154 | } else { | |
155 | if (off < 0) { | |
156 | off = -off; | |
157 | *q++ = '-'; | |
158 | } else | |
159 | *q++ = '+'; | |
160 | ||
161 | if (off >= 24*60) /* should be impossible */ | |
162 | off = 23*60+59; /* if not, insert silly value */ | |
163 | ||
164 | *q++ = (off / 600) + '0'; | |
165 | *q++ = (off / 60) % 10 + '0'; | |
166 | off %= 60; | |
167 | *q++ = (off / 10) + '0'; | |
168 | *q++ = (off % 10) + '0'; | |
169 | } | |
170 | *q = '\0'; | |
171 | ||
172 | return (b); | |
173 | } |