arpadate.c revision 42575
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 14static char sccsid[] = "@(#)arpadate.c 8.12 (Berkeley) 5/19/1998"; 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 56char * 57arpadate(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 (void) time(&t); 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 tz = tzname[lt->tm_isdst]; 160 } 161#endif 162#if TZ_TYPE == TZ_TIMEZONE 163 { 164 extern char *timezone(); 165 166 tz = timezone(off, lt->tm_isdst); 167 } 168#endif 169 if (off < 0) 170 { 171 off = -off; 172 *q++ = '-'; 173 } 174 else 175 *q++ = '+'; 176 177 if (off >= 24*60) /* should be impossible */ 178 off = 23*60+59; /* if not, insert silly value */ 179 180 *q++ = (off / 600) + '0'; 181 *q++ = (off / 60) % 10 + '0'; 182 off %= 60; 183 *q++ = (off / 10) + '0'; 184 *q++ = (off % 10) + '0'; 185 if (tz != NULL && *tz != '\0') 186 { 187 *q++ = ' '; 188 *q++ = '('; 189 while (*tz != '\0' && q < &b[sizeof b - 3]) 190 *q++ = *tz++; 191 *q++ = ')'; 192 } 193 } 194 *q = '\0'; 195 196 return (b); 197} 198