1 /* 2 * Copyright (c) 1983, 1995 Eric P. Allman 3 * Copyright (c) 1988, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * %sccs.include.redist.c% 7 */ 8 9 #ifndef lint 10 static char sccsid[] = "@(#)arpadate.c 8.4 (Berkeley) 04/21/95"; 11 #endif /* not lint */ 12 13 # include "sendmail.h" 14 15 /* 16 ** ARPADATE -- Create date in ARPANET format 17 ** 18 ** Parameters: 19 ** ud -- unix style date string. if NULL, one is created. 20 ** 21 ** Returns: 22 ** pointer to an ARPANET date field 23 ** 24 ** Side Effects: 25 ** none 26 ** 27 ** WARNING: 28 ** date is stored in a local buffer -- subsequent 29 ** calls will overwrite. 30 ** 31 ** Bugs: 32 ** Timezone is computed from local time, rather than 33 ** from whereever (and whenever) the message was sent. 34 ** To do better is very hard. 35 ** 36 ** Some sites are now inserting the timezone into the 37 ** local date. This routine should figure out what 38 ** the format is and work appropriately. 39 */ 40 41 #ifndef TZNAME_MAX 42 # define TZNAME_MAX 50 /* max size of timezone */ 43 #endif 44 45 /* values for TZ_TYPE */ 46 #define TZ_NONE 0 /* no character timezone support */ 47 #define TZ_TM_NAME 1 /* use tm->tm_name */ 48 #define TZ_TM_ZONE 2 /* use tm->tm_zone */ 49 #define TZ_TZNAME 3 /* use tzname[] */ 50 #define TZ_TIMEZONE 4 /* use timezone() */ 51 52 char * 53 arpadate(ud) 54 register char *ud; 55 { 56 register char *p; 57 register char *q; 58 register int off; 59 register int i; 60 register struct tm *lt; 61 time_t t; 62 struct tm gmt; 63 char *tz; 64 static char b[43 + TZNAME_MAX]; 65 66 /* 67 ** Get current time. 68 ** This will be used if a null argument is passed and 69 ** to resolve the timezone. 70 */ 71 72 (void) time(&t); 73 if (ud == NULL) 74 ud = ctime(&t); 75 76 /* 77 ** Crack the UNIX date line in a singularly unoriginal way. 78 */ 79 80 q = b; 81 82 p = &ud[0]; /* Mon */ 83 *q++ = *p++; 84 *q++ = *p++; 85 *q++ = *p++; 86 *q++ = ','; 87 *q++ = ' '; 88 89 p = &ud[8]; /* 16 */ 90 if (*p == ' ') 91 p++; 92 else 93 *q++ = *p++; 94 *q++ = *p++; 95 *q++ = ' '; 96 97 p = &ud[4]; /* Sep */ 98 *q++ = *p++; 99 *q++ = *p++; 100 *q++ = *p++; 101 *q++ = ' '; 102 103 p = &ud[20]; /* 1979 */ 104 *q++ = *p++; 105 *q++ = *p++; 106 *q++ = *p++; 107 *q++ = *p++; 108 *q++ = ' '; 109 110 p = &ud[11]; /* 01:03:52 */ 111 for (i = 8; i > 0; i--) 112 *q++ = *p++; 113 114 /* 115 * should really get the timezone from the time in "ud" (which 116 * is only different if a non-null arg was passed which is different 117 * from the current time), but for all practical purposes, returning 118 * the current local zone will do (its all that is ever needed). 119 */ 120 gmt = *gmtime(&t); 121 lt = localtime(&t); 122 123 off = (lt->tm_hour - gmt.tm_hour) * 60 + lt->tm_min - gmt.tm_min; 124 125 /* assume that offset isn't more than a day ... */ 126 if (lt->tm_year < gmt.tm_year) 127 off -= 24 * 60; 128 else if (lt->tm_year > gmt.tm_year) 129 off += 24 * 60; 130 else if (lt->tm_yday < gmt.tm_yday) 131 off -= 24 * 60; 132 else if (lt->tm_yday > gmt.tm_yday) 133 off += 24 * 60; 134 135 *q++ = ' '; 136 if (off == 0) 137 { 138 *q++ = 'G'; 139 *q++ = 'M'; 140 *q++ = 'T'; 141 } 142 else 143 { 144 tz = NULL; 145 #if TZ_TYPE == TZ_TM_NAME 146 tz = lt->tm_name; 147 #endif 148 #if TZ_TYPE == TZ_TM_ZONE 149 tz = lt->tm_zone; 150 #endif 151 #if TZ_TYPE == TZ_TZNAME 152 { 153 extern char *tzname[]; 154 155 tz = tzname[lt->tm_isdst]; 156 } 157 #endif 158 #if TZ_TYPE == TZ_TIMEZONE 159 { 160 extern char *timezone(); 161 162 tz = timezone(off, lt->tm_isdst); 163 } 164 #endif 165 if (off < 0) 166 { 167 off = -off; 168 *q++ = '-'; 169 } 170 else 171 *q++ = '+'; 172 173 if (off >= 24*60) /* should be impossible */ 174 off = 23*60+59; /* if not, insert silly value */ 175 176 *q++ = (off / 600) + '0'; 177 *q++ = (off / 60) % 10 + '0'; 178 off %= 60; 179 *q++ = (off / 10) + '0'; 180 *q++ = (off % 10) + '0'; 181 if (tz != NULL && *tz != '\0') 182 { 183 *q++ = ' '; 184 *q++ = '('; 185 while (*tz != '\0') 186 *q++ = *tz++; 187 *q++ = ')'; 188 } 189 } 190 *q = '\0'; 191 192 return (b); 193 } 194