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