1 /*
2  *  arpadate.c - get_arpadate() is a function returning the date in the
3  *               ARPANET format (see RFC822 and RFC1123)
4  *  Copyright (C) 1998 Hugo Haas
5  *
6  *  Inspired by smail source code by Ronald S. Karr and Landon Curt Noll
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22 
23 #define ARPADATE_LENGTH	32
24 
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <time.h>
28 
29 void
get_arpadate(char * d_string)30 get_arpadate (char *d_string)
31 {
32   struct tm *date;
33 #ifdef USE_OLD_ARPADATE
34   static char *week_day[] =
35   {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
36   static char *month[] =
37   {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
38    "Aug", "Sep", "Oct", "Nov", "Dec"};
39   static char timezone[3];
40 
41   time_t current;
42   int offset, gmt_yday, gmt_hour, gmt_min;
43 
44   /* Get current time */
45   (void) time (&current);
46 
47   /* Get GMT and then local dates */
48   date = gmtime ((const time_t *) &current);
49   gmt_yday = date->tm_yday;
50   gmt_hour = date->tm_hour;
51   gmt_min = date->tm_min;
52   date = localtime ((const time_t *) &current);
53 
54   /* Calculates offset */
55 
56   offset = (date->tm_hour - gmt_hour) * 60 + (date->tm_min - gmt_min);
57   /* Be careful, there can be problems if the day has changed between the
58      evaluation of local and gmt's one */
59   if (date->tm_yday != gmt_yday)
60     {
61       if (date->tm_yday == (gmt_yday + 1))
62 	offset += 1440;
63       else if (date->tm_yday == (gmt_yday - 1))
64 	offset -= 1440;
65       else
66 	offset += (date->tm_yday > gmt_yday) ? -1440 : 1440;
67     }
68 
69   if (offset >= 0)
70     sprintf (timezone, "+%02d%02d", offset / 60, offset % 60);
71   else
72     sprintf (timezone, "-%02d%02d", -offset / 60, -offset % 60);
73 
74   sprintf (d_string, "%s, %d %s %04d %02d:%02d:%02d %s",
75 	   week_day[date->tm_wday],
76 	   date->tm_mday, month[date->tm_mon], date->tm_year + 1900,
77 	   date->tm_hour, date->tm_min, date->tm_sec, timezone);
78 #else
79 	time_t now;
80 
81 	/* RFC822 format string borrowed from GNU shellutils date.c */
82 	/* Using %d instead of %_d, the second one isn't portable */
83 	const char *format = "%a, %d %b %Y %H:%M:%S %z";
84 
85 	now = time(NULL);
86 
87 	date = localtime((const time_t *)&now);
88 	(void)strftime(d_string, ARPADATE_LENGTH, format, date);
89 #endif
90 }
91