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