This commit was generated by cvs2svn to track changes on a CVS vendor
[unix-history] / usr.sbin / sendmail / src / arpadate.c
CommitLineData
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 36static 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
67char *
68arpadate(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}