[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 | |
---|
| 16 | SM_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 | |
---|
| 55 | char * |
---|
| 56 | arpadate(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 | } |
---|