aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Hoa V. DINH <dinh.viet.hoa@gmail.com>2014-07-15 23:54:09 -0700
committerGravatar Hoa V. DINH <dinh.viet.hoa@gmail.com>2014-07-15 23:54:09 -0700
commit64f52dae67ba57d03e45ba35c626ddd6ea907367 (patch)
tree08922b224592016b299aeb05eac0315b719f2d99 /src/core
parentdd6e71efeb4cc0260df4646fb222de217528790b (diff)
Fixed #715: ability to set a date while adding messages
Diffstat (limited to 'src/core')
-rw-r--r--src/core/abstract/MCMessageHeader.cc180
-rw-r--r--src/core/basetypes/MCArray.cc1
-rw-r--r--src/core/basetypes/MCLibetpan.cc202
-rw-r--r--src/core/basetypes/MCLibetpan.h12
-rwxr-xr-xsrc/core/imap/MCIMAPSession.cc16
-rwxr-xr-xsrc/core/imap/MCIMAPSession.h2
6 files changed, 236 insertions, 177 deletions
diff --git a/src/core/abstract/MCMessageHeader.cc b/src/core/abstract/MCMessageHeader.cc
index fb3e43cb..6d2d8066 100644
--- a/src/core/abstract/MCMessageHeader.cc
+++ b/src/core/abstract/MCMessageHeader.cc
@@ -2,6 +2,7 @@
#include "MCAddress.h"
#include "MCIterator.h"
+#include "MCLibetpan.h"
#include <string.h>
#include <unistd.h>
@@ -9,12 +10,6 @@
using namespace mailcore;
-static time_t timestamp_from_date(struct mailimf_date_time * date_time);
-static struct mailimf_date_time * get_date_from_timestamp(time_t timeval);
-static time_t timestamp_from_imap_date(struct mailimap_date_time * date_time);
-static time_t mkgmtime(struct tm * tmp);
-static int tmcomp(struct tm * atmp, struct tm * btmp);
-
static struct mailimf_address_list * lep_address_list_from_array(Array * addresses);
static struct mailimf_mailbox_list * lep_mailbox_list_from_array(Array * addresses);
static Array * lep_address_list_from_lep_addr(struct mailimf_address_list * addr_list);
@@ -388,7 +383,7 @@ void MessageHeader::importIMFFields(struct mailimf_fields * fields)
if (single_fields.fld_orig_date != NULL) {
time_t timestamp;
- timestamp = timestamp_from_date(single_fields.fld_orig_date->dt_date_time);
+ timestamp = timestampFromDate(single_fields.fld_orig_date->dt_date_time);
setDate(timestamp);
setReceivedDate(timestamp);
//MCLog("%lu %lu", (unsigned long) timestamp, date());
@@ -523,169 +518,6 @@ void MessageHeader::importIMFFields(struct mailimf_fields * fields)
}
}
-static time_t timestamp_from_date(struct mailimf_date_time * date_time)
-{
- struct tm tmval;
- time_t timeval;
- int zone_min;
- int zone_hour;
-
- tmval.tm_sec = date_time->dt_sec;
- tmval.tm_min = date_time->dt_min;
- tmval.tm_hour = date_time->dt_hour;
- tmval.tm_mday = date_time->dt_day;
- tmval.tm_mon = date_time->dt_month - 1;
- if (date_time->dt_year < 1000) {
- // workaround when century is not given in year
- tmval.tm_year = date_time->dt_year + 2000 - 1900;
- }
- else {
- tmval.tm_year = date_time->dt_year - 1900;
- }
-
- timeval = mkgmtime(&tmval);
-
- if (date_time->dt_zone >= 0) {
- zone_hour = date_time->dt_zone / 100;
- zone_min = date_time->dt_zone % 100;
- }
- else {
- zone_hour = -((- date_time->dt_zone) / 100);
- zone_min = -((- date_time->dt_zone) % 100);
- }
- timeval -= zone_hour * 3600 + zone_min * 60;
-
- return timeval;
-}
-
-static struct mailimf_date_time * get_date_from_timestamp(time_t timeval)
-{
- struct tm gmt;
- struct tm lt;
- int off;
- struct mailimf_date_time * date_time;
- int sign;
- int hour;
- int min;
-
- gmtime_r(&timeval, &gmt);
- localtime_r(&timeval, &lt);
-
- off = (int) ((mkgmtime(&lt) - mkgmtime(&gmt)) / 60);
- if (off < 0) {
- sign = -1;
- }
- else {
- sign = 1;
- }
- off = off * sign;
- min = off % 60;
- hour = off / 60;
- off = hour * 100 + min;
- off = off * sign;
-
- date_time = mailimf_date_time_new(lt.tm_mday, lt.tm_mon + 1,
- lt.tm_year + 1900,
- lt.tm_hour, lt.tm_min, lt.tm_sec,
- off);
-
- return date_time;
-}
-
-static time_t timestamp_from_imap_date(struct mailimap_date_time * date_time)
-{
- struct tm tmval;
- time_t timeval;
- int zone_min;
- int zone_hour;
-
- tmval.tm_sec = date_time->dt_sec;
- tmval.tm_min = date_time->dt_min;
- tmval.tm_hour = date_time->dt_hour;
- tmval.tm_mday = date_time->dt_day;
- tmval.tm_mon = date_time->dt_month - 1;
- if (date_time->dt_year < 1000) {
- // workaround when century is not given in year
- tmval.tm_year = date_time->dt_year + 2000 - 1900;
- }
- else {
- tmval.tm_year = date_time->dt_year - 1900;
- }
-
- timeval = mkgmtime(&tmval);
-
- if (date_time->dt_zone >= 0) {
- zone_hour = date_time->dt_zone / 100;
- zone_min = date_time->dt_zone % 100;
- }
- else {
- zone_hour = -((- date_time->dt_zone) / 100);
- zone_min = -((- date_time->dt_zone) % 100);
- }
- timeval -= zone_hour * 3600 + zone_min * 60;
-
- return timeval;
-}
-
-#define INVALID_TIMESTAMP (-1)
-
-static int tmcomp(struct tm * atmp, struct tm * btmp)
-{
- int result;
-
- if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
- (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
- (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
- (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
- (result = (atmp->tm_min - btmp->tm_min)) == 0)
- result = atmp->tm_sec - btmp->tm_sec;
- return result;
-}
-
-static time_t mkgmtime(struct tm * tmp)
-{
- int dir;
- int bits;
- int saved_seconds;
- time_t t;
- struct tm yourtm, mytm;
-
- yourtm = *tmp;
- saved_seconds = yourtm.tm_sec;
- yourtm.tm_sec = 0;
- /*
- ** Calculate the number of magnitude bits in a time_t
- ** (this works regardless of whether time_t is
- ** signed or unsigned, though lint complains if unsigned).
- */
- for (bits = 0, t = 1; t > 0; ++bits, t <<= 1)
- ;
- /*
- ** If time_t is signed, then 0 is the median value,
- ** if time_t is unsigned, then 1 << bits is median.
- */
- if(bits > 40) bits = 40;
- t = (t < 0) ? 0 : ((time_t) 1 << bits);
- for ( ; ; ) {
- gmtime_r(&t, &mytm);
- dir = tmcomp(&mytm, &yourtm);
- if (dir != 0) {
- if (bits-- < 0) {
- return INVALID_TIMESTAMP;
- }
- if (bits < 0)
- --t;
- else if (dir > 0)
- t -= (time_t) 1 << bits;
- else t += (time_t) 1 << bits;
- continue;
- }
- break;
- }
- t += saved_seconds;
- return t;
-}
-
#pragma mark RFC 2822 mailbox conversion
static Array * lep_address_list_from_lep_mailbox(struct mailimf_mailbox_list * mb_list)
@@ -851,7 +683,7 @@ struct mailimf_fields * MessageHeader::createIMFFieldsAndFilterBcc(bool filterBc
imfDate = NULL;
if (date() != (time_t) -1) {
//MCLog("%lu", date());
- imfDate = get_date_from_timestamp(date());
+ imfDate = dateFromTimestamp(date());
}
imfFrom = NULL;
if (from() != NULL) {
@@ -952,7 +784,7 @@ void MessageHeader::importIMAPEnvelope(struct mailimap_envelope * env)
time_t timestamp;
// date
- timestamp = timestamp_from_date(date_time);
+ timestamp = timestampFromDate(date_time);
setDate(timestamp);
setReceivedDate(timestamp);
mailimf_date_time_free(date_time);
@@ -964,7 +796,7 @@ void MessageHeader::importIMAPEnvelope(struct mailimap_envelope * env)
if (r == MAILIMAP_NO_ERROR) {
time_t timestamp;
- timestamp = timestamp_from_imap_date(imap_date);
+ timestamp = timestampFromIMAPDate(imap_date);
setDate(timestamp);
setReceivedDate(timestamp);
mailimap_date_time_free(imap_date);
@@ -1132,7 +964,7 @@ void MessageHeader::importIMAPReferences(Data * data)
void MessageHeader::importIMAPInternalDate(struct mailimap_date_time * date)
{
- setReceivedDate(timestamp_from_imap_date(date));
+ setReceivedDate(timestampFromIMAPDate(date));
}
Array * MessageHeader::recipientWithReplyAll(bool replyAll, bool includeTo, bool includeCc, Array * senderEmails)
diff --git a/src/core/basetypes/MCArray.cc b/src/core/basetypes/MCArray.cc
index 15e9a2be..43ee6bd4 100644
--- a/src/core/basetypes/MCArray.cc
+++ b/src/core/basetypes/MCArray.cc
@@ -212,7 +212,6 @@ static int sortCompare(Object ** pa, Object ** pb, struct sortData * data)
Array * Array::sortedArray(int (* compare)(void * a, void * b, void * context), void * context)
{
- struct sortData data;
Array * result = (Array *) this->copy()->autorelease();
result->sortArray(compare, context);
return result;
diff --git a/src/core/basetypes/MCLibetpan.cc b/src/core/basetypes/MCLibetpan.cc
index fcc1b772..1779d605 100644
--- a/src/core/basetypes/MCLibetpan.cc
+++ b/src/core/basetypes/MCLibetpan.cc
@@ -10,9 +10,211 @@
#include <libetpan/libetpan.h>
+using namespace mailcore;
+
+static time_t mkgmtime(struct tm * tmp);
+static int tmcomp(struct tm * atmp, struct tm * btmp);
+
__attribute__((constructor))
static void initialize()
{
// It will enable CFStream on platforms that supports it.
mailstream_cfstream_enabled = 1;
}
+
+time_t mailcore::timestampFromDate(struct mailimf_date_time * date_time)
+{
+ struct tm tmval;
+ time_t timeval;
+ int zone_min;
+ int zone_hour;
+
+ tmval.tm_sec = date_time->dt_sec;
+ tmval.tm_min = date_time->dt_min;
+ tmval.tm_hour = date_time->dt_hour;
+ tmval.tm_mday = date_time->dt_day;
+ tmval.tm_mon = date_time->dt_month - 1;
+ if (date_time->dt_year < 1000) {
+ // workaround when century is not given in year
+ tmval.tm_year = date_time->dt_year + 2000 - 1900;
+ }
+ else {
+ tmval.tm_year = date_time->dt_year - 1900;
+ }
+
+ timeval = mkgmtime(&tmval);
+
+ if (date_time->dt_zone >= 0) {
+ zone_hour = date_time->dt_zone / 100;
+ zone_min = date_time->dt_zone % 100;
+ }
+ else {
+ zone_hour = -((- date_time->dt_zone) / 100);
+ zone_min = -((- date_time->dt_zone) % 100);
+ }
+ timeval -= zone_hour * 3600 + zone_min * 60;
+
+ return timeval;
+}
+
+struct mailimf_date_time * mailcore::dateFromTimestamp(time_t timeval)
+{
+ struct tm gmt;
+ struct tm lt;
+ int off;
+ struct mailimf_date_time * date_time;
+ int sign;
+ int hour;
+ int min;
+
+ gmtime_r(&timeval, &gmt);
+ localtime_r(&timeval, &lt);
+
+ off = (int) ((mkgmtime(&lt) - mkgmtime(&gmt)) / 60);
+ if (off < 0) {
+ sign = -1;
+ }
+ else {
+ sign = 1;
+ }
+ off = off * sign;
+ min = off % 60;
+ hour = off / 60;
+ off = hour * 100 + min;
+ off = off * sign;
+
+ date_time = mailimf_date_time_new(lt.tm_mday, lt.tm_mon + 1,
+ lt.tm_year + 1900,
+ lt.tm_hour, lt.tm_min, lt.tm_sec,
+ off);
+
+ return date_time;
+}
+
+struct mailimap_date_time * mailcore::imapDateFromTimestamp(time_t timeval)
+{
+ struct tm gmt;
+ struct tm lt;
+ int off;
+ struct mailimap_date_time * date_time;
+ int sign;
+ int hour;
+ int min;
+
+ gmtime_r(&timeval, &gmt);
+ localtime_r(&timeval, &lt);
+
+ off = (int) ((mkgmtime(&lt) - mkgmtime(&gmt)) / 60);
+ if (off < 0) {
+ sign = -1;
+ }
+ else {
+ sign = 1;
+ }
+ off = off * sign;
+ min = off % 60;
+ hour = off / 60;
+ off = hour * 100 + min;
+ off = off * sign;
+
+ date_time = mailimap_date_time_new(lt.tm_mday, lt.tm_mon + 1,
+ lt.tm_year + 1900,
+ lt.tm_hour, lt.tm_min, lt.tm_sec,
+ off);
+
+ return date_time;
+}
+
+time_t mailcore::timestampFromIMAPDate(struct mailimap_date_time * date_time)
+{
+ struct tm tmval;
+ time_t timeval;
+ int zone_min;
+ int zone_hour;
+
+ tmval.tm_sec = date_time->dt_sec;
+ tmval.tm_min = date_time->dt_min;
+ tmval.tm_hour = date_time->dt_hour;
+ tmval.tm_mday = date_time->dt_day;
+ tmval.tm_mon = date_time->dt_month - 1;
+ if (date_time->dt_year < 1000) {
+ // workaround when century is not given in year
+ tmval.tm_year = date_time->dt_year + 2000 - 1900;
+ }
+ else {
+ tmval.tm_year = date_time->dt_year - 1900;
+ }
+
+ timeval = mkgmtime(&tmval);
+
+ if (date_time->dt_zone >= 0) {
+ zone_hour = date_time->dt_zone / 100;
+ zone_min = date_time->dt_zone % 100;
+ }
+ else {
+ zone_hour = -((- date_time->dt_zone) / 100);
+ zone_min = -((- date_time->dt_zone) % 100);
+ }
+ timeval -= zone_hour * 3600 + zone_min * 60;
+
+ return timeval;
+}
+
+#define INVALID_TIMESTAMP (-1)
+
+static int tmcomp(struct tm * atmp, struct tm * btmp)
+{
+ int result;
+
+ if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
+ (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
+ (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
+ (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
+ (result = (atmp->tm_min - btmp->tm_min)) == 0)
+ result = atmp->tm_sec - btmp->tm_sec;
+ return result;
+}
+
+static time_t mkgmtime(struct tm * tmp)
+{
+ int dir;
+ int bits;
+ int saved_seconds;
+ time_t t;
+ struct tm yourtm, mytm;
+
+ yourtm = *tmp;
+ saved_seconds = yourtm.tm_sec;
+ yourtm.tm_sec = 0;
+ /*
+ ** Calculate the number of magnitude bits in a time_t
+ ** (this works regardless of whether time_t is
+ ** signed or unsigned, though lint complains if unsigned).
+ */
+ for (bits = 0, t = 1; t > 0; ++bits, t <<= 1)
+ ;
+ /*
+ ** If time_t is signed, then 0 is the median value,
+ ** if time_t is unsigned, then 1 << bits is median.
+ */
+ if(bits > 40) bits = 40;
+ t = (t < 0) ? 0 : ((time_t) 1 << bits);
+ for ( ; ; ) {
+ gmtime_r(&t, &mytm);
+ dir = tmcomp(&mytm, &yourtm);
+ if (dir != 0) {
+ if (bits-- < 0) {
+ return INVALID_TIMESTAMP;
+ }
+ if (bits < 0)
+ --t;
+ else if (dir > 0)
+ t -= (time_t) 1 << bits;
+ else t += (time_t) 1 << bits;
+ continue;
+ }
+ break;
+ }
+ t += saved_seconds;
+ return t;
+}
diff --git a/src/core/basetypes/MCLibetpan.h b/src/core/basetypes/MCLibetpan.h
index 9670a47b..41024137 100644
--- a/src/core/basetypes/MCLibetpan.h
+++ b/src/core/basetypes/MCLibetpan.h
@@ -10,6 +10,16 @@
#define MAILCORE_MCLIBETPAN_H
-// No API in this file.
+#include <time.h>
+#include <libetpan/libetpan.h>
+
+namespace mailcore {
+
+ time_t timestampFromDate(struct mailimf_date_time * date_time);
+ time_t timestampFromIMAPDate(struct mailimap_date_time * date_time);
+ struct mailimf_date_time * dateFromTimestamp(time_t timeval);
+ struct mailimap_date_time * imapDateFromTimestamp(time_t timeval);
+
+}
#endif
diff --git a/src/core/imap/MCIMAPSession.cc b/src/core/imap/MCIMAPSession.cc
index 780012d4..5efc5e12 100755
--- a/src/core/imap/MCIMAPSession.cc
+++ b/src/core/imap/MCIMAPSession.cc
@@ -23,6 +23,7 @@
#include "MCHTMLBodyRendererTemplateCallback.h"
#include "MCCertificateUtils.h"
#include "MCIMAPIdentity.h"
+#include "MCLibetpan.h"
using namespace mailcore;
@@ -1589,6 +1590,12 @@ void IMAPSession::appendMessage(String * folder, Data * messageData, MessageFlag
void IMAPSession::appendMessageWithCustomFlags(String * folder, Data * messageData, MessageFlag flags, Array * customFlags,
IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError)
{
+ this->appendMessageWithCustomFlagsAndDate(folder, messageData, flags, NULL, (time_t) -1, progressCallback, createdUID, pError);
+}
+
+void IMAPSession::appendMessageWithCustomFlagsAndDate(String * folder, Data * messageData, MessageFlag flags, Array * customFlags, time_t date,
+ IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError)
+{
int r;
struct mailimap_flag_list * flag_list;
uint32_t uidvalidity;
@@ -1612,8 +1619,15 @@ void IMAPSession::appendMessageWithCustomFlags(String * folder, Data * messageDa
mailimap_flag_list_add(flag_list, f);
}
}
- r = mailimap_uidplus_append(mImap, MCUTF8(folder), flag_list, NULL, messageData->bytes(), messageData->length(),
+ struct mailimap_date_time * imap_date = NULL;
+ if (date != (time_t) -1) {
+ imap_date = imapDateFromTimestamp(date);
+ }
+ r = mailimap_uidplus_append(mImap, MCUTF8(folder), flag_list, imap_date, messageData->bytes(), messageData->length(),
&uidvalidity, &uidresult);
+ if (imap_date != NULL) {
+ mailimap_date_time_free(imap_date);
+ }
mailimap_flag_list_free(flag_list);
bodyProgress(messageData->length(), messageData->length());
diff --git a/src/core/imap/MCIMAPSession.h b/src/core/imap/MCIMAPSession.h
index 9ebe48d6..e52dc74f 100755
--- a/src/core/imap/MCIMAPSession.h
+++ b/src/core/imap/MCIMAPSession.h
@@ -83,6 +83,8 @@ namespace mailcore {
IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError);
virtual void appendMessageWithCustomFlags(String * folder, Data * messageData, MessageFlag flags, Array * customFlags,
IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError);
+ virtual void appendMessageWithCustomFlagsAndDate(String * folder, Data * messageData, MessageFlag flags, Array * customFlags, time_t date,
+ IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError);
void copyMessages(String * folder, IndexSet * uidSet, String * destFolder,
HashMap ** pUidMapping, ErrorCode * pError);