1 /* 2 * Copyright (c) 1983 Eric P. Allman 3 * Copyright (c) 1988 Regents of the University of California. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms are permitted 7 * provided that the above copyright notice and this paragraph are 8 * duplicated in all such forms and that any documentation, 9 * advertising materials, and other materials related to such 10 * distribution and use acknowledge that the software was developed 11 * by the University of California, Berkeley. The name of the 12 * University may not be used to endorse or promote products derived 13 * from this software without specific prior written permission. 14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 16 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 17 */ 18 19 #ifndef lint 20 static char sccsid[] = "@(#)arpadate.c 5.10 (Berkeley) 01/08/89"; 21 #endif /* not lint */ 22 23 # include "conf.h" 24 # include <time.h> 25 # include <sys/types.h> 26 # include "useful.h" 27 28 /* 29 ** ARPADATE -- Create date in ARPANET format 30 ** 31 ** Parameters: 32 ** ud -- unix style date string. if NULL, one is created. 33 ** 34 ** Returns: 35 ** pointer to an ARPANET date field 36 ** 37 ** Side Effects: 38 ** none 39 ** 40 ** WARNING: 41 ** date is stored in a local buffer -- subsequent 42 ** calls will overwrite. 43 ** 44 ** Bugs: 45 ** Timezone is computed from local time, rather than 46 ** from whereever (and whenever) the message was sent. 47 ** To do better is very hard. 48 ** 49 ** Some sites are now inserting the timezone into the 50 ** local date. This routine should figure out what 51 ** the format is and work appropriately. 52 */ 53 54 char * 55 arpadate(ud) 56 register char *ud; 57 { 58 register char *p; 59 register char *q; 60 register int off; 61 register int i; 62 register struct tm *lt; 63 time_t t; 64 struct tm gmt; 65 static char b[40]; 66 extern struct tm *localtime(), *gmtime(); 67 extern char *ctime(); 68 extern time_t time(); 69 70 /* 71 ** Get current time. 72 ** This will be used if a null argument is passed and 73 ** to resolve the timezone. 74 */ 75 76 (void) time(&t); 77 if (ud == NULL) 78 ud = ctime(&t); 79 80 /* 81 ** Crack the UNIX date line in a singularly unoriginal way. 82 */ 83 84 q = b; 85 86 p = &ud[0]; /* Mon */ 87 *q++ = *p++; 88 *q++ = *p++; 89 *q++ = *p++; 90 *q++ = ','; 91 *q++ = ' '; 92 93 p = &ud[8]; /* 16 */ 94 if (*p == ' ') 95 p++; 96 else 97 *q++ = *p++; 98 *q++ = *p++; 99 *q++ = ' '; 100 101 p = &ud[4]; /* Sep */ 102 *q++ = *p++; 103 *q++ = *p++; 104 *q++ = *p++; 105 *q++ = ' '; 106 107 p = &ud[22]; /* 79 */ 108 *q++ = *p++; 109 *q++ = *p++; 110 *q++ = ' '; 111 112 p = &ud[11]; /* 01:03:52 */ 113 for (i = 8; i > 0; i--) 114 *q++ = *p++; 115 116 /* 117 * should really get the timezone from the time in "ud" (which 118 * is only different if a non-null arg was passed which is different 119 * from the current time), but for all practical purposes, returning 120 * the current local zone will do (its all that is ever needed). 121 */ 122 gmt = *gmtime(&t); 123 lt = localtime(&t); 124 125 off = (lt->tm_hour - gmt.tm_hour) * 60 + lt->tm_min - gmt.tm_min; 126 127 /* assume that offset isn't more than a day ... */ 128 if (lt->tm_year < gmt.tm_year) 129 off -= 24 * 60; 130 else if (lt->tm_year > gmt.tm_year) 131 off += 24 * 60; 132 else if (lt->tm_yday < gmt.tm_yday) 133 off -= 24 * 60; 134 else if (lt->tm_yday > gmt.tm_yday) 135 off += 24 * 60; 136 137 *q++ = ' '; 138 if (off == 0) { 139 *q++ = 'G'; 140 *q++ = 'M'; 141 *q++ = 'T'; 142 } else { 143 if (off < 0) { 144 off = -off; 145 *q++ = '-'; 146 } else 147 *q++ = '+'; 148 149 if (off >= 24*60) /* should be impossible */ 150 off = 23*60+59; /* if not, insert silly value */ 151 152 *q++ = (off / 600) + '0'; 153 *q++ = (off / 60) % 10 + '0'; 154 off %= 60; 155 *q++ = (off / 10) + '0'; 156 *q++ = (off % 10) + '0'; 157 } 158 *q = '\0'; 159 160 return (b); 161 } 162