19152Seric # include "conf.h" 2*16895Seric # ifdef USG 3*16895Seric # include <time.h> 4*16895Seric # else 513587Swnj # include <sys/time.h> 62897Seric # ifndef V6 72897Seric # include <sys/types.h> 82897Seric # include <sys/timeb.h> 9*16895Seric # endif V6 10*16895Seric # endif USG 114437Seric # include "useful.h" 12293Seric 13*16895Seric SCCSID(@(#)arpadate.c 4.4 08/11/84); 14403Seric 15*16895Seric # ifdef V6 16*16895Seric # define OLDTIME 17*16895Seric # endif V6 18*16895Seric # ifdef USG 19*16895Seric # define OLDTIME 20*16895Seric # endif USG 21*16895Seric 22293Seric /* 23293Seric ** ARPADATE -- Create date in ARPANET format 24293Seric ** 25293Seric ** Parameters: 262897Seric ** ud -- unix style date string. if NULL, one is created. 27293Seric ** 28293Seric ** Returns: 29293Seric ** pointer to an ARPANET date field 30293Seric ** 31293Seric ** Side Effects: 32293Seric ** none 33293Seric ** 34293Seric ** WARNING: 35293Seric ** date is stored in a local buffer -- subsequent 36293Seric ** calls will overwrite. 373185Seric ** 383185Seric ** Bugs: 393185Seric ** Timezone is computed from local time, rather than 403185Seric ** from whereever (and whenever) the message was sent. 413185Seric ** To do better is very hard. 424315Seric ** 434315Seric ** Some sites are now inserting the timezone into the 444315Seric ** local date. This routine should figure out what 454315Seric ** the format is and work appropriately. 46293Seric */ 47293Seric 481586Seric char * 492897Seric arpadate(ud) 502897Seric register char *ud; 51293Seric { 52293Seric register char *p; 532897Seric register char *q; 54293Seric static char b[40]; 551586Seric extern char *ctime(); 562897Seric register int i; 572897Seric extern struct tm *localtime(); 5815137Seric extern bool fconvert(); 59*16895Seric # ifdef OLDTIME 602897Seric long t; 614315Seric extern long time(); 62*16895Seric # else OLDTIME 632897Seric struct timeb t; 642897Seric extern struct timeb *ftime(); 652897Seric extern char *timezone(); 66*16895Seric # endif OLDTIME 67*16895Seric # ifdef V6 68*16895Seric extern char *StdTimezone, *DstTimezone; 69*16895Seric # endif V6 70*16895Seric # ifdef USG 71*16895Seric extern char *tzname[2]; 72*16895Seric # endif USG 73293Seric 744315Seric /* 754315Seric ** Get current time. 764315Seric ** This will be used if a null argument is passed and 774315Seric ** to resolve the timezone. 784315Seric */ 794315Seric 80*16895Seric # ifdef OLDTIME 814315Seric (void) time(&t); 822897Seric if (ud == NULL) 832897Seric ud = ctime(&t); 842897Seric # else 852897Seric ftime(&t); 862897Seric if (ud == NULL) 872897Seric ud = ctime(&t.time); 88*16895Seric # endif OLDTIME 89293Seric 904315Seric /* 914315Seric ** Crack the UNIX date line in a singularly unoriginal way. 924315Seric */ 934315Seric 942897Seric q = b; 952897Seric 9613932Seric p = &ud[0]; /* Mon */ 9713932Seric *q++ = *p++; 9813932Seric *q++ = *p++; 9913932Seric *q++ = *p++; 10013932Seric *q++ = ','; 10113932Seric *q++ = ' '; 10213932Seric 103293Seric p = &ud[8]; /* 16 */ 104293Seric if (*p == ' ') 105293Seric p++; 1062897Seric else 1072897Seric *q++ = *p++; 1082897Seric *q++ = *p++; 10910251Seric *q++ = ' '; 1102897Seric 1115184Seric p = &ud[4]; /* Sep */ 1125184Seric *q++ = *p++; 1135184Seric *q++ = *p++; 1145184Seric *q++ = *p++; 11510251Seric *q++ = ' '; 1162897Seric 11713932Seric p = &ud[22]; /* 79 */ 1185184Seric *q++ = *p++; 1195184Seric *q++ = *p++; 1202897Seric *q++ = ' '; 1212897Seric 1222897Seric p = &ud[11]; /* 01:03:52 */ 1235184Seric for (i = 8; i > 0; i--) 1242897Seric *q++ = *p++; 1252897Seric 1262897Seric /* -PST or -PDT */ 1272897Seric # ifdef V6 128293Seric if (localtime(&t)->tm_isdst) 1294315Seric p = DstTimezone; 130293Seric else 1314315Seric p = StdTimezone; 1322897Seric # else 133*16895Seric # ifdef USG 134*16895Seric if (localtime(&t)->tm_isdst) 135*16895Seric p = tzname[1]; 136*16895Seric else 137*16895Seric p = tzname[0]; 138*16895Seric # else 1392897Seric p = timezone(t.timezone, localtime(&t.time)->tm_isdst); 140*16895Seric # endif USG 1412897Seric # endif V6 14215137Seric if ((strncmp(p, "GMT", 3) == 0 || strncmp(p, "gmt", 3) == 0) && 14315137Seric p[3] != '\0') 1442897Seric { 1452897Seric /* hours from GMT */ 1462897Seric p += 3; 1472897Seric *q++ = *p++; 1482897Seric if (p[1] == ':') 1492897Seric *q++ = '0'; 1502897Seric else 1512897Seric *q++ = *p++; 1522897Seric *q++ = *p++; 1532897Seric p++; /* skip ``:'' */ 1542897Seric *q++ = *p++; 1552897Seric *q++ = *p++; 15615109Skarels *q = '\0'; 1572897Seric } 15815137Seric else if (!fconvert(p, q)) 1592897Seric { 16010251Seric *q++ = ' '; 1612897Seric *q++ = *p++; 1622897Seric *q++ = *p++; 1632897Seric *q++ = *p++; 16415109Skarels *q = '\0'; 1652897Seric } 1662897Seric 167293Seric return (b); 168293Seric } 16915137Seric /* 17015137Seric ** FCONVERT -- convert foreign timezones to ARPA timezones 17115137Seric ** 17215137Seric ** This routine is essentially from Teus Hagen. 17315137Seric ** 17415137Seric ** Parameters: 17515137Seric ** a -- timezone as returned from UNIX. 17615137Seric ** b -- place to put ARPA-style timezone. 17715137Seric ** 17815137Seric ** Returns: 17915137Seric ** TRUE -- if a conversion was made (and b was filled in). 18015137Seric ** FALSE -- if this is not a recognized local time. 18115137Seric ** 18215137Seric ** Side Effects: 18315137Seric ** none. 18415137Seric */ 18515109Skarels 18615137Seric /* UNIX to arpa conversion table */ 18715137Seric struct foreign 18815137Seric { 18915109Skarels char *f_from; 19015109Skarels char *f_to; 19115109Skarels }; 19215109Skarels 19315137Seric static struct foreign Foreign[] = 19415137Seric { 195*16895Seric { "EET", " -0200" }, /* eastern europe */ 196*16895Seric { "MET", " -0100" }, /* middle europe */ 197*16895Seric { "WET", " GMT" }, /* western europe */ 198*16895Seric { "EET DST", " -0300" }, /* daylight saving times */ 199*16895Seric { "MET DST", " -0200" }, 200*16895Seric { "WET DST", " -0100" }, 20115137Seric { NULL, NULL } 20215137Seric }; 20315109Skarels 20415137Seric bool 20515137Seric fconvert(a, b) 20615137Seric register char *a; 20715137Seric char *b; 20815137Seric { 20915137Seric register struct foreign *euptr; 21015137Seric register char *p; 21115137Seric 21215137Seric for (euptr = Foreign; euptr->f_from != NULL; euptr++) 21315137Seric { 214*16895Seric if (sameword(euptr->f_from, a)) 21515137Seric { 21615137Seric p = euptr->f_to; 21715137Seric while (*p) 21815137Seric *b++ = *p++; 21915109Skarels *b = '\0'; 22015137Seric return (TRUE); 22115109Skarels } 22215137Seric } 22315137Seric return (FALSE); 22415109Skarels } 225