1 /* 2 ** Sendmail 3 ** Copyright (c) 1983 Eric P. Allman 4 ** Berkeley, California 5 ** 6 ** Copyright (c) 1983 Regents of the University of California. 7 ** All rights reserved. The Berkeley software License Agreement 8 ** specifies the terms and conditions for redistribution. 9 */ 10 11 #ifndef lint 12 static char SccsId[] = "@(#)arpadate.c 5.5 (Berkeley) 03/18/87"; 13 #endif not lint 14 15 # include "conf.h" 16 # ifdef USG 17 # include <time.h> 18 # else 19 # include <sys/time.h> 20 # ifndef V6 21 # include <sys/types.h> 22 # include <sys/timeb.h> 23 # endif V6 24 # endif USG 25 # include "useful.h" 26 27 # ifdef V6 28 # define OLDTIME 29 # endif V6 30 # ifdef USG 31 # define OLDTIME 32 # endif USG 33 34 /* 35 ** ARPADATE -- Create date in ARPANET format 36 ** 37 ** Parameters: 38 ** ud -- unix style date string. if NULL, one is created. 39 ** 40 ** Returns: 41 ** pointer to an ARPANET date field 42 ** 43 ** Side Effects: 44 ** none 45 ** 46 ** WARNING: 47 ** date is stored in a local buffer -- subsequent 48 ** calls will overwrite. 49 ** 50 ** Bugs: 51 ** Timezone is computed from local time, rather than 52 ** from whereever (and whenever) the message was sent. 53 ** To do better is very hard. 54 ** 55 ** Some sites are now inserting the timezone into the 56 ** local date. This routine should figure out what 57 ** the format is and work appropriately. 58 */ 59 60 char * 61 arpadate(ud) 62 register char *ud; 63 { 64 register char *p; 65 register char *q; 66 static char b[40]; 67 extern char *ctime(); 68 register int i; 69 extern struct tm *localtime(); 70 extern bool fconvert(); 71 # ifdef OLDTIME 72 long t; 73 extern long time(); 74 # else OLDTIME 75 struct timeb t; 76 extern struct timeb *ftime(); 77 # endif OLDTIME 78 # ifdef V6 79 extern char *StdTimezone, *DstTimezone; 80 # endif V6 81 # ifdef USG 82 extern char *tzname[2]; 83 # endif USG 84 85 /* 86 ** Get current time. 87 ** This will be used if a null argument is passed and 88 ** to resolve the timezone. 89 */ 90 91 # ifdef OLDTIME 92 (void) time(&t); 93 if (ud == NULL) 94 ud = ctime(&t); 95 # else 96 ftime(&t); 97 if (ud == NULL) 98 ud = ctime(&t.time); 99 # endif OLDTIME 100 101 /* 102 ** Crack the UNIX date line in a singularly unoriginal way. 103 */ 104 105 q = b; 106 107 p = &ud[0]; /* Mon */ 108 *q++ = *p++; 109 *q++ = *p++; 110 *q++ = *p++; 111 *q++ = ','; 112 *q++ = ' '; 113 114 p = &ud[8]; /* 16 */ 115 if (*p == ' ') 116 p++; 117 else 118 *q++ = *p++; 119 *q++ = *p++; 120 *q++ = ' '; 121 122 p = &ud[4]; /* Sep */ 123 *q++ = *p++; 124 *q++ = *p++; 125 *q++ = *p++; 126 *q++ = ' '; 127 128 p = &ud[22]; /* 79 */ 129 *q++ = *p++; 130 *q++ = *p++; 131 *q++ = ' '; 132 133 p = &ud[11]; /* 01:03:52 */ 134 for (i = 8; i > 0; i--) 135 *q++ = *p++; 136 137 /* -PST or -PDT */ 138 # ifdef V6 139 if (localtime(&t)->tm_isdst) 140 p = DstTimezone; 141 else 142 p = StdTimezone; 143 # else 144 # ifdef USG 145 if (localtime(&t)->tm_isdst) 146 p = tzname[1]; 147 else 148 p = tzname[0]; 149 # else 150 p = localtime(&t.time)->tm_zone; 151 # endif USG 152 # endif V6 153 if ((strncmp(p, "GMT", 3) == 0 || strncmp(p, "gmt", 3) == 0) && 154 p[3] != '\0') 155 { 156 /* hours from GMT */ 157 p += 3; 158 *q++ = *p++; 159 if (p[1] == ':') 160 *q++ = '0'; 161 else 162 *q++ = *p++; 163 *q++ = *p++; 164 p++; /* skip ``:'' */ 165 *q++ = *p++; 166 *q++ = *p++; 167 *q = '\0'; 168 } 169 else if (!fconvert(p, q)) 170 { 171 *q++ = ' '; 172 *q++ = *p++; 173 *q++ = *p++; 174 *q++ = *p++; 175 *q = '\0'; 176 } 177 178 return (b); 179 } 180 /* 181 ** FCONVERT -- convert foreign timezones to ARPA timezones 182 ** 183 ** This routine is essentially from Teus Hagen. 184 ** 185 ** Parameters: 186 ** a -- timezone as returned from UNIX. 187 ** b -- place to put ARPA-style timezone. 188 ** 189 ** Returns: 190 ** TRUE -- if a conversion was made (and b was filled in). 191 ** FALSE -- if this is not a recognized local time. 192 ** 193 ** Side Effects: 194 ** none. 195 */ 196 197 /* UNIX to arpa conversion table */ 198 struct foreign 199 { 200 char *f_from; 201 char *f_to; 202 }; 203 204 static struct foreign Foreign[] = 205 { 206 { "EET", "+0200" }, /* eastern europe */ 207 { "MET", "+0100" }, /* middle europe */ 208 { "WET", "GMT" }, /* western europe */ 209 { "EET DST", "+0300" }, /* daylight saving times */ 210 { "MET DST", "+0200" }, 211 { "WET DST", "+0100" }, 212 { NULL, NULL } 213 }; 214 215 bool 216 fconvert(a, b) 217 register char *a; 218 char *b; 219 { 220 register struct foreign *euptr; 221 register char *p; 222 223 for (euptr = Foreign; euptr->f_from != NULL; euptr++) 224 { 225 extern bool sameword(); 226 227 if (sameword(euptr->f_from, a)) 228 { 229 p = euptr->f_to; 230 *b++ = ' '; 231 while (*p != '\0') 232 *b++ = *p++; 233 *b = '\0'; 234 return (TRUE); 235 } 236 } 237 return (FALSE); 238 } 239