Skip to content

Commit

Permalink
Merge branch 'prime'
Browse files Browse the repository at this point in the history
  • Loading branch information
jengelh committed Jan 28, 2025
2 parents 1cf4012 + 948fdc0 commit c887eb4
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 15 deletions.
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
AC_INIT([gromox], [2.39])
AC_INIT([gromox], [2.40])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([build-aux])
AC_PREFIX_DEFAULT([/usr])
Expand Down
17 changes: 17 additions & 0 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
Gromox 2.40 (2025-01-28)
========================

Fixes:

* zcore: avoid unwrapping Content-Transfer-Encoding twice for
clearsigned S/MIME
* ews: calculate timezone offsets for local time only
* ews: deserialize no-content XML tags as empty strings rather than as absence
of the element

Enhancements:

* imap, pop3: multi-server capability, replacing direct disk I/O by network
RPCs to the exmdb storage backend


Gromox 2.39 (2025-01-21)
========================

Expand Down
4 changes: 2 additions & 2 deletions exch/emsmdb/message_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ static ec_error_t message_object_save2(message_object *pmessage, bool b_fai,
pmessage->instance_id, pmsgctnt))
return ecRpcFailed;
uint32_t tmp_status = *mstatus | MSGSTATUS_IN_CONFLICT;
const TAGGED_PROPVAL propbuff[] = {PR_MSG_STATUS, &tmp_status};
const TAGGED_PROPVAL propbuff[] = {{PR_MSG_STATUS, &tmp_status}};
const TPROPVAL_ARRAY tmp_propvals = {std::size(propbuff), deconst(propbuff)};
PROBLEM_ARRAY tmp_problems;
if (!message_object_set_properties_internal(pmessage,
Expand All @@ -324,7 +324,7 @@ static ec_error_t message_object_save2(message_object *pmessage, bool b_fai,
pbin_pcl = common_util_pcl_merge(pbin_pcl, pbin_pcl1);
if (pbin_pcl == nullptr)
return ecRpcFailed;
const TAGGED_PROPVAL propbuff[] = {PR_PREDECESSOR_CHANGE_LIST, pbin_pcl};
const TAGGED_PROPVAL propbuff[] = {{PR_PREDECESSOR_CHANGE_LIST, pbin_pcl}};
const TPROPVAL_ARRAY tmp_propvals = {std::size(propbuff), deconst(propbuff)};
PROBLEM_ARRAY tmp_problems;
if (!message_object_set_properties_internal(pmessage,
Expand Down
2 changes: 1 addition & 1 deletion exch/emsmdb/oxcmsg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ ec_error_t rop_setreadflags(uint8_t want_asynchronous, uint8_t read_flags,
read_flags & rfClearReadFlag ? RELOP_NE : RELOP_EQ,
PR_READ, {PR_READ, deconst(&fake_false)}
};
const RESTRICTION res_top = {RES_PROPERTY, deconst(&res_prop)};
const RESTRICTION res_top = {RES_PROPERTY, {deconst(&res_prop)}};
uint32_t table_id = 0, row_count = 0;
auto username = plogon->readstate_user();
if (!exmdb_client::load_content_table(plogon->dir, CP_ACP,
Expand Down
16 changes: 11 additions & 5 deletions exch/ews/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1813,13 +1813,16 @@ void EWSContext::toContent(const std::string& dir, tCalendarItem& item, sShape&
shape.write(TAGGED_PROPVAL{PR_MESSAGE_CLASS, deconst("IPM.Appointment")});
int64_t startOffset = 0, endOffset = 0;
time_t startTime = 0, endTime = 0;
bool calcStartOffset, calcEndOffset = false;
if(item.Start) {
startTime = clock::to_time_t(item.Start.value().time);
startOffset = std::chrono::duration_cast<std::chrono::minutes>(item.Start.value().offset).count();
calcStartOffset = item.Start.value().needCalcOffset();
}
if(item.End) {
endTime = clock::to_time_t(item.End.value().time);
endOffset = std::chrono::duration_cast<std::chrono::minutes>(item.Start.value().offset).count();
calcEndOffset = item.Start.value().needCalcOffset();
}
// TODO handle no start and/or end times

Expand Down Expand Up @@ -2035,17 +2038,20 @@ void EWSContext::toContent(const std::string& dir, tCalendarItem& item, sShape&
shape.write(NtAppointmentTimeZoneDefinitionEndDisplay,
TAGGED_PROPVAL{PT_BINARY, temp_bin});

// If the offsets of start or end times are not set, probably
// the client didn't send the offset information in date tags.
// Try to get the offset from the timezone definition.
if(startOffset == 0 || endOffset == 0)
// If the offsets of start or end times are 0 and
// the client didn't send the offset information in date tags,
// try to get the offset from the timezone definition.
if((startOffset == 0 && calcStartOffset) || (endOffset == 0 && calcEndOffset))
{
EXT_PULL ext_pull;
TIMEZONEDEFINITION tzdef;
ext_pull.init(buf->data(), buf->size(), alloc, EXT_FLAG_UTF16);
if(ext_pull.g_tzdef(&tzdef) != EXT_ERR_SUCCESS)
throw EWS::DispatchError(E3294);
startOffset = endOffset = offset_from_tz(&tzdef, startTime);
if(calcStartOffset)
startOffset = offset_from_tz(&tzdef, startTime);
if(calcEndOffset)
endOffset = offset_from_tz(&tzdef, endTime);
}
item.Start.value().offset = std::chrono::minutes(startOffset);
item.End.value().offset = std::chrono::minutes(endOffset);
Expand Down
4 changes: 1 addition & 3 deletions exch/ews/serialization.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,7 @@ struct ExplicitConvert<std::string>
static tinyxml2::XMLError deserialize(const tinyxml2::XMLElement *xml, std::string &value)
{
const char* data = xml->GetText();
if(!data)
return tinyxml2::XML_NO_TEXT_NODE;
value = data;
value = data ? data : std::string("");
return tinyxml2::XML_SUCCESS;
}

Expand Down
28 changes: 27 additions & 1 deletion exch/ews/structures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1194,6 +1194,24 @@ sTimePoint::sTimePoint(time_point tp, const tSerializableTimeZone& tz) :
/**
* @brief Create time point from date-time string
*
* As of 2025-01-27 we have identified 3 different datetime formats sent by
* the clients.
* Zulu time (UTC), no DST, no offset:
* `<t:Start>2024-04-29T19:30:00Z</t:Start>`
* With the offset information in datetime, additionally a timezone tag:
* `<t:Start>2024-11-27T13:00:00+01:00</t:Start>`
* `<t:StartTimeZone Id="W. Europe Standard Time"/>`
* `<t:EndTimeZone Id="W. Europe Standard Time"/>`
* Local time with a timezone tag, it's necessary to calculate the offset:
* `<t:Start>2024-09-25T09:00:00</t:Start>`
* ```
* <t:ExtendedProperty>
* <t:ExtendedFieldURI PropertyName="CalendarTimeZone" PropertySetId="A7B529B5-4B75-47A7-A24F-20743D6C55CD" PropertyType="String"/>
* <t:Value>Europe/Vienna</t:Value>
* </t:ExtendedProperty>
* ```
* `<t:MeetingTimeZone TimeZoneName="W. Europe Standard Time"/>`
*
* @throw DeserializationError Conversion failed
*
* @param Date-time string
Expand All @@ -1217,7 +1235,9 @@ sTimePoint::sTimePoint(const char* dtstr)
throw EWSError::ValueOutOfRange(E3152);
time = clock::from_time_t(timestamp);
time += std::chrono::duration_cast<time_point::duration>(std::chrono::duration<double>(seconds));
offset = std::chrono::minutes(60*tz_hour+(tz_hour < 0? -tz_min : tz_min));
offset = std::chrono::minutes(60 * (-tz_hour) + (tz_hour > 0 ? -tz_min : tz_min));
if(strlen(dtstr) == 19)
calcOffset = true;
}

/**
Expand All @@ -1232,6 +1252,12 @@ sTimePoint sTimePoint::fromNT(uint64_t timestamp)
uint64_t sTimePoint::toNT() const
{return rop_util_unix_to_nttime(time-offset);}

/**
* @brief Whether it's necessary to calculate the offset from timezone
*/
bool sTimePoint::needCalcOffset() const
{return calcOffset;}

///////////////////////////////////////////////////////////////////////////////////////////////////
// Types implementation

Expand Down
2 changes: 2 additions & 0 deletions exch/ews/structures.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -452,9 +452,11 @@ struct sTimePoint

static sTimePoint fromNT(uint64_t);
uint64_t toNT() const;
bool needCalcOffset() const;

time_point time{};
std::chrono::minutes offset = std::chrono::minutes(0);
bool calcOffset = false;
};

///////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
2 changes: 0 additions & 2 deletions mra/midb_agent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,6 @@ static void *midbag_scanwork(void *);
static ssize_t read_line(int sockd, char *buff, size_t length);
static int connect_midb(const char *host, uint16_t port);

static constexpr unsigned int POLLIN_SET =
POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR | POLLNVAL;
std::atomic<size_t> g_midb_command_buffer_size{256 * 1024};
static int g_conn_num;
static gromox::atomic_bool g_notify_stop;
Expand Down

0 comments on commit c887eb4

Please sign in to comment.