Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, libarchive.org for more info) to build successfully.

msgdate.c 4.33 KB
Newer Older
1 2 3 4 5 6
/* Synchronet RFC822 message date/time string conversion routines */

/****************************************************************************
 * @format.tab-size 4		(Plain Text/Source Code File Header)			*
 * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
 *																			*
7
 * Copyright Rob Swindell - http://www.synchro.net/copyright.html			*
8 9 10 11 12 13 14 15 16 17 18 19 20 21
 *																			*
 * This program is free software; you can redistribute it and/or			*
 * modify it under the terms of the GNU General Public License				*
 * as published by the Free Software Foundation; either version 2			*
 * of the License, or (at your option) any later version.					*
 * See the GNU General Public License for more details: gpl.txt or			*
 * http://www.fsf.org/copyleft/gpl.html										*
 *																			*
 * For Synchronet coding style and modification guidelines, see				*
 * http://www.synchro.net/source.html										*
 *																			*
 * Note: If this box doesn't appear square, then you need to fix your tabs.	*
 ****************************************************************************/

22 23 24 25
#include "msgdate.h"
#include "smblib.h"
#include "datewrap.h"
#include "date_str.h"
26 27 28 29

/****************************************************************************/
/* Convert when_t structure to RFC822 date header field (string)			*/
/****************************************************************************/
Rob Swindell's avatar
Rob Swindell committed
30
char* msgdate(when_t when, char* buf)
31 32 33 34
{
	struct tm	tm;
	char		plus='+';
	short		tz;
35
	time_t		tt;
36 37 38 39 40 41
	
	tz=smb_tzutc(when.zone);
	if(tz<0) {
		plus='-';
		tz=-tz;
	}
42 43 44

	tt=when.time;
	if(localtime_r(&tt,&tm)==NULL)
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
		memset(&tm,0,sizeof(tm));
	sprintf(buf,"%s, %d %s %d %02d:%02d:%02d %c%02u%02u"
		,wday[tm.tm_wday]
		,tm.tm_mday
		,mon[tm.tm_mon]
		,1900+tm.tm_year
		,tm.tm_hour
		,tm.tm_min
		,tm.tm_sec
		/* RFC1123: implementations SHOULD use numeric timezones instead of timezone names */
		,plus, tz/60, tz%60	
		);
	return(buf);
}

/****************************************************************************/
/* Convert RFC822 date header field to when_t structure						*/
/* dd mon yyyy hh:mm:ss [zone]												*/
/****************************************************************************/
Rob Swindell's avatar
Rob Swindell committed
64
when_t rfc822date(char* date)
65 66 67 68 69 70 71 72 73 74 75
{
	char*	p=date;
	char	str[32];
	char	month[32];
	when_t	when;
	struct tm tm;

	memset(&tm,0,sizeof(tm));
	memset(&when,0,sizeof(when));

	while(*p && *p<=' ') p++;
76
	while(*p && !IS_DIGIT(*p)) p++;
77 78
	/* DAY */
	tm.tm_mday=atoi(p);
79
	while(*p && IS_DIGIT(*p)) p++;
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
	/* MONTH */
	while(*p && *p<=' ') p++;
	sprintf(month,"%3.3s",p);
	if(!stricmp(month,"jan"))
		tm.tm_mon=0;
	else if(!stricmp(month,"feb"))
		tm.tm_mon=1;
	else if(!stricmp(month,"mar"))
		tm.tm_mon=2;
	else if(!stricmp(month,"apr"))
		tm.tm_mon=3;
	else if(!stricmp(month,"may"))
		tm.tm_mon=4;
	else if(!stricmp(month,"jun"))
		tm.tm_mon=5;
	else if(!stricmp(month,"jul"))
		tm.tm_mon=6;
	else if(!stricmp(month,"aug"))
		tm.tm_mon=7;
	else if(!stricmp(month,"sep"))
		tm.tm_mon=8;
	else if(!stricmp(month,"oct"))
		tm.tm_mon=9;
	else if(!stricmp(month,"nov"))
		tm.tm_mon=10;
	else
		tm.tm_mon=11;
	p+=4;
	/* YEAR */
	tm.tm_year=atoi(p);
	if(tm.tm_year<Y2K_2DIGIT_WINDOW)
		tm.tm_year+=100;
	else if(tm.tm_year>1900)
		tm.tm_year-=1900;

115
	while(*p && IS_DIGIT(*p)) p++;
116 117 118
	/* HOUR */
	while(*p && *p<=' ') p++;
	tm.tm_hour=atoi(p);
119
	while(*p && IS_DIGIT(*p)) p++;
120 121 122
	/* MINUTE */
	if(*p) p++;
	tm.tm_min=atoi(p);
123
	while(*p && IS_DIGIT(*p)) p++;
124 125 126
	/* SECONDS */
	if(*p) p++;
	tm.tm_sec=atoi(p);
127
	while(*p && IS_DIGIT(*p)) p++;
128 129 130
	/* TIME ZONE */
	while(*p && *p<=' ') p++;
	if(*p) {
131
		if(IS_DIGIT(*p) || *p=='-' || *p=='+') { /* [+|-]HHMM format */
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
			if(*p=='+') p++;
			sprintf(str,"%.*s",*p=='-'? 3:2,p);
			when.zone=atoi(str)*60;
			p+=(*p=='-') ? 3:2;
			if(when.zone<0)
				when.zone-=atoi(p);
			else
				when.zone+=atoi(p);
		}
		else if(!strnicmp(p,"PDT",3))
			when.zone=(short)PDT;
		else if(!strnicmp(p,"MDT",3))
			when.zone=(short)MDT;
		else if(!strnicmp(p,"CDT",3))
			when.zone=(short)CDT;
		else if(!strnicmp(p,"EDT",3))
			when.zone=(short)EDT;
		else if(!strnicmp(p,"PST",3))
			when.zone=(short)PST;
		else if(!strnicmp(p,"MST",3))
			when.zone=(short)MST;
		else if(!strnicmp(p,"CST",3))
			when.zone=(short)CST;
		else if(!strnicmp(p,"EST",3))
			when.zone=(short)EST;
	}

159
	tm.tm_isdst=-1;	/* Don't adjust for daylight-savings-time */
rswindell's avatar
rswindell committed
160
	when.time=(uint32_t)mktime(&tm);
161 162 163

	return(when);
}