1*22695Sdist /* 2*22695Sdist ** Sendmail 3*22695Sdist ** Copyright (c) 1983 Eric P. Allman 4*22695Sdist ** Berkeley, California 5*22695Sdist ** 6*22695Sdist ** Copyright (c) 1983 Regents of the University of California. 7*22695Sdist ** All rights reserved. The Berkeley software License Agreement 8*22695Sdist ** specifies the terms and conditions for redistribution. 9*22695Sdist */ 10*22695Sdist 11*22695Sdist #ifndef lint 12*22695Sdist static char SccsId[] = "@(#)arpadate.c 5.1 (Berkeley) 06/07/85"; 13*22695Sdist #endif not lint 14*22695Sdist 159152Seric # include "conf.h" 1616895Seric # ifdef USG 1716895Seric # include <time.h> 1816895Seric # else 1913587Swnj # include <sys/time.h> 202897Seric # ifndef V6 212897Seric # include <sys/types.h> 222897Seric # include <sys/timeb.h> 2316895Seric # endif V6 2416895Seric # endif USG 254437Seric # include "useful.h" 26293Seric 27*22695Sdist SCCSID(@(#)arpadate.c 5.1 06/07/85); 28403Seric 2916895Seric # ifdef V6 3016895Seric # define OLDTIME 3116895Seric # endif V6 3216895Seric # ifdef USG 3316895Seric # define OLDTIME 3416895Seric # endif USG 3516895Seric 36293Seric /* 37293Seric ** ARPADATE -- Create date in ARPANET format 38293Seric ** 39293Seric ** Parameters: 402897Seric ** ud -- unix style date string. if NULL, one is created. 41293Seric ** 42293Seric ** Returns: 43293Seric ** pointer to an ARPANET date field 44293Seric ** 45293Seric ** Side Effects: 46293Seric ** none 47293Seric ** 48293Seric ** WARNING: 49293Seric ** date is stored in a local buffer -- subsequent 50293Seric ** calls will overwrite. 513185Seric ** 523185Seric ** Bugs: 533185Seric ** Timezone is computed from local time, rather than 543185Seric ** from whereever (and whenever) the message was sent. 553185Seric ** To do better is very hard. 564315Seric ** 574315Seric ** Some sites are now inserting the timezone into the 584315Seric ** local date. This routine should figure out what 594315Seric ** the format is and work appropriately. 60293Seric */ 61293Seric 621586Seric char * 632897Seric arpadate(ud) 642897Seric register char *ud; 65293Seric { 66293Seric register char *p; 672897Seric register char *q; 68293Seric static char b[40]; 691586Seric extern char *ctime(); 702897Seric register int i; 712897Seric extern struct tm *localtime(); 7215137Seric extern bool fconvert(); 7316895Seric # ifdef OLDTIME 742897Seric long t; 754315Seric extern long time(); 7616895Seric # else OLDTIME 772897Seric struct timeb t; 782897Seric extern struct timeb *ftime(); 792897Seric extern char *timezone(); 8016895Seric # endif OLDTIME 8116895Seric # ifdef V6 8216895Seric extern char *StdTimezone, *DstTimezone; 8316895Seric # endif V6 8416895Seric # ifdef USG 8516895Seric extern char *tzname[2]; 8616895Seric # endif USG 87293Seric 884315Seric /* 894315Seric ** Get current time. 904315Seric ** This will be used if a null argument is passed and 914315Seric ** to resolve the timezone. 924315Seric */ 934315Seric 9416895Seric # ifdef OLDTIME 954315Seric (void) time(&t); 962897Seric if (ud == NULL) 972897Seric ud = ctime(&t); 982897Seric # else 992897Seric ftime(&t); 1002897Seric if (ud == NULL) 1012897Seric ud = ctime(&t.time); 10216895Seric # endif OLDTIME 103293Seric 1044315Seric /* 1054315Seric ** Crack the UNIX date line in a singularly unoriginal way. 1064315Seric */ 1074315Seric 1082897Seric q = b; 1092897Seric 11013932Seric p = &ud[0]; /* Mon */ 11113932Seric *q++ = *p++; 11213932Seric *q++ = *p++; 11313932Seric *q++ = *p++; 11413932Seric *q++ = ','; 11513932Seric *q++ = ' '; 11613932Seric 117293Seric p = &ud[8]; /* 16 */ 118293Seric if (*p == ' ') 119293Seric p++; 1202897Seric else 1212897Seric *q++ = *p++; 1222897Seric *q++ = *p++; 12310251Seric *q++ = ' '; 1242897Seric 1255184Seric p = &ud[4]; /* Sep */ 1265184Seric *q++ = *p++; 1275184Seric *q++ = *p++; 1285184Seric *q++ = *p++; 12910251Seric *q++ = ' '; 1302897Seric 13113932Seric p = &ud[22]; /* 79 */ 1325184Seric *q++ = *p++; 1335184Seric *q++ = *p++; 1342897Seric *q++ = ' '; 1352897Seric 1362897Seric p = &ud[11]; /* 01:03:52 */ 1375184Seric for (i = 8; i > 0; i--) 1382897Seric *q++ = *p++; 1392897Seric 1402897Seric /* -PST or -PDT */ 1412897Seric # ifdef V6 142293Seric if (localtime(&t)->tm_isdst) 1434315Seric p = DstTimezone; 144293Seric else 1454315Seric p = StdTimezone; 1462897Seric # else 14716895Seric # ifdef USG 14816895Seric if (localtime(&t)->tm_isdst) 14916895Seric p = tzname[1]; 15016895Seric else 15116895Seric p = tzname[0]; 15216895Seric # else 1532897Seric p = timezone(t.timezone, localtime(&t.time)->tm_isdst); 15416895Seric # endif USG 1552897Seric # endif V6 15615137Seric if ((strncmp(p, "GMT", 3) == 0 || strncmp(p, "gmt", 3) == 0) && 15715137Seric p[3] != '\0') 1582897Seric { 1592897Seric /* hours from GMT */ 1602897Seric p += 3; 1612897Seric *q++ = *p++; 1622897Seric if (p[1] == ':') 1632897Seric *q++ = '0'; 1642897Seric else 1652897Seric *q++ = *p++; 1662897Seric *q++ = *p++; 1672897Seric p++; /* skip ``:'' */ 1682897Seric *q++ = *p++; 1692897Seric *q++ = *p++; 17015109Skarels *q = '\0'; 1712897Seric } 17215137Seric else if (!fconvert(p, q)) 1732897Seric { 17410251Seric *q++ = ' '; 1752897Seric *q++ = *p++; 1762897Seric *q++ = *p++; 1772897Seric *q++ = *p++; 17815109Skarels *q = '\0'; 1792897Seric } 1802897Seric 181293Seric return (b); 182293Seric } 18315137Seric /* 18415137Seric ** FCONVERT -- convert foreign timezones to ARPA timezones 18515137Seric ** 18615137Seric ** This routine is essentially from Teus Hagen. 18715137Seric ** 18815137Seric ** Parameters: 18915137Seric ** a -- timezone as returned from UNIX. 19015137Seric ** b -- place to put ARPA-style timezone. 19115137Seric ** 19215137Seric ** Returns: 19315137Seric ** TRUE -- if a conversion was made (and b was filled in). 19415137Seric ** FALSE -- if this is not a recognized local time. 19515137Seric ** 19615137Seric ** Side Effects: 19715137Seric ** none. 19815137Seric */ 19915109Skarels 20015137Seric /* UNIX to arpa conversion table */ 20115137Seric struct foreign 20215137Seric { 20315109Skarels char *f_from; 20415109Skarels char *f_to; 20515109Skarels }; 20615109Skarels 20715137Seric static struct foreign Foreign[] = 20815137Seric { 20916895Seric { "EET", " -0200" }, /* eastern europe */ 21016895Seric { "MET", " -0100" }, /* middle europe */ 21116895Seric { "WET", " GMT" }, /* western europe */ 21216895Seric { "EET DST", " -0300" }, /* daylight saving times */ 21316895Seric { "MET DST", " -0200" }, 21416895Seric { "WET DST", " -0100" }, 21515137Seric { NULL, NULL } 21615137Seric }; 21715109Skarels 21815137Seric bool 21915137Seric fconvert(a, b) 22015137Seric register char *a; 22115137Seric char *b; 22215137Seric { 22315137Seric register struct foreign *euptr; 22415137Seric register char *p; 22515137Seric 22615137Seric for (euptr = Foreign; euptr->f_from != NULL; euptr++) 22715137Seric { 22816895Seric if (sameword(euptr->f_from, a)) 22915137Seric { 23015137Seric p = euptr->f_to; 23115137Seric while (*p) 23215137Seric *b++ = *p++; 23315109Skarels *b = '\0'; 23415137Seric return (TRUE); 23515109Skarels } 23615137Seric } 23715137Seric return (FALSE); 23815109Skarels } 239