Commit 808c722e authored by Manfred Kutas's avatar Manfred Kutas

Merge remote-tracking branch 'origin/develop' into AS14.1

parents 11ea9cd2 774744c6
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
case "$1" in case "$1" in
configure) configure)
/usr/sbin/z-push-admin -a fixstates /usr/sbin/z-push-admin -a fixstates-upgrade
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
YELLOW='\033[0;33m' YELLOW='\033[0;33m'
NC='\033[0m' # No Color NC='\033[0m' # No Color
......
...@@ -150,7 +150,7 @@ class BackendCalDAV extends BackendDiff { ...@@ -150,7 +150,7 @@ class BackendCalDAV extends BackendDiff {
$folder->displayname = $val->displayname; $folder->displayname = $val->displayname;
$folder->serverid = $id; $folder->serverid = $id;
if ($id[0] == "C") { if ($id[0] == "C") {
if (defined('CALDAV_PERSONAL') && strtolower(substr($id, 1)) == CALDAV_PERSONAL) { if (defined('CALDAV_PERSONAL') && strcasecmp(substr($id, 1), CALDAV_PERSONAL) == 0) {
$folder->type = SYNC_FOLDER_TYPE_APPOINTMENT; $folder->type = SYNC_FOLDER_TYPE_APPOINTMENT;
} }
else { else {
...@@ -158,7 +158,7 @@ class BackendCalDAV extends BackendDiff { ...@@ -158,7 +158,7 @@ class BackendCalDAV extends BackendDiff {
} }
} }
else { else {
if (defined('CALDAV_PERSONAL') && strtolower(substr($id, 1)) == CALDAV_PERSONAL) { if (defined('CALDAV_PERSONAL') && strcasecmp(substr($id, 1), CALDAV_PERSONAL) == 0) {
$folder->type = SYNC_FOLDER_TYPE_TASK; $folder->type = SYNC_FOLDER_TYPE_TASK;
} }
else { else {
...@@ -538,7 +538,7 @@ class BackendCalDAV extends BackendDiff { ...@@ -538,7 +538,7 @@ class BackendCalDAV extends BackendDiff {
$timezones = $ical->GetComponents("VTIMEZONE"); $timezones = $ical->GetComponents("VTIMEZONE");
$timezone = ""; $timezone = "";
if (count($timezones) > 0) { if (count($timezones) > 0) {
$timezone = TimezoneUtil::ParseTimezone($timezones[0]->GetPValue("TZID")); $timezone = TimezoneUtil::GetPhpSupportedTimezone($timezones[0]->GetPValue("TZID"));
} }
if (!$timezone) { if (!$timezone) {
$timezone = date_default_timezone_get(); $timezone = date_default_timezone_get();
...@@ -1449,65 +1449,9 @@ class BackendCalDAV extends BackendDiff { ...@@ -1449,65 +1449,9 @@ class BackendCalDAV extends BackendDiff {
* @throws Exception * @throws Exception
*/ */
private function _GetTimezoneString($timezone, $with_names = true) { private function _GetTimezoneString($timezone, $with_names = true) {
// UTC needs special handling ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendCalDAV->_GetTimezoneString(): using '%s' timezone", $timezone));
if ($timezone == "UTC") $tz = TimezoneUtil::GetFullTZFromTZName($timezone);
return base64_encode(pack('la64vvvvvvvvla64vvvvvvvvl', 0, '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 0, 0, 0, 0, 0, 0, 0, 0)); $blob = TimezoneUtil::GetSyncBlobFromTZ($tz);
try { return base64_encode($blob);
//Generate a timezone string (PHP 5.3 needed for this)
$timezone = new DateTimeZone($timezone);
$trans = $timezone->getTransitions(time());
$stdTime = null;
$dstTime = null;
if (count($trans) < 3) {
throw new Exception();
}
if ($trans[1]['isdst'] == 1) {
$dstTime = $trans[1];
$stdTime = $trans[2];
}
else {
$dstTime = $trans[2];
$stdTime = $trans[1];
}
$stdTimeO = new DateTime($stdTime['time']);
$stdFirst = new DateTime(sprintf("first sun of %s %s", $stdTimeO->format('F'), $stdTimeO->format('Y')), timezone_open("UTC"));
$stdBias = $stdTime['offset'] / -60;
$stdName = $stdTime['abbr'];
$stdYear = 0;
$stdMonth = $stdTimeO->format('n');
$stdWeek = floor(($stdTimeO->format("j")-$stdFirst->format("j"))/7)+1;
$stdDay = $stdTimeO->format('w');
$stdHour = $stdTimeO->format('H');
$stdMinute = $stdTimeO->format('i');
$stdTimeO->add(new DateInterval('P7D'));
if ($stdTimeO->format('n') != $stdMonth) {
$stdWeek = 5;
}
$dstTimeO = new DateTime($dstTime['time']);
$dstFirst = new DateTime(sprintf("first sun of %s %s", $dstTimeO->format('F'), $dstTimeO->format('Y')), timezone_open("UTC"));
$dstName = $dstTime['abbr'];
$dstYear = 0;
$dstMonth = $dstTimeO->format('n');
$dstWeek = floor(($dstTimeO->format("j")-$dstFirst->format("j"))/7)+1;
$dstDay = $dstTimeO->format('w');
$dstHour = $dstTimeO->format('H');
$dstMinute = $dstTimeO->format('i');
$dstTimeO->add(new DateInterval('P7D'));
if ($dstTimeO->format('n') != $dstMonth) {
$dstWeek = 5;
}
$dstBias = ($dstTime['offset'] - $stdTime['offset']) / -60;
if ($with_names) {
return base64_encode(pack('la64vvvvvvvvla64vvvvvvvvl', $stdBias, $stdName, 0, $stdMonth, $stdDay, $stdWeek, $stdHour, $stdMinute, 0, 0, 0, $dstName, 0, $dstMonth, $dstDay, $dstWeek, $dstHour, $dstMinute, 0, 0, $dstBias));
}
else {
return base64_encode(pack('la64vvvvvvvvla64vvvvvvvvl', $stdBias, '', 0, $stdMonth, $stdDay, $stdWeek, $stdHour, $stdMinute, 0, 0, 0, '', 0, $dstMonth, $dstDay, $dstWeek, $dstHour, $dstMinute, 0, 0, $dstBias));
}
}
catch (Exception $e) {
// If invalid timezone is given, we return UTC
return base64_encode(pack('la64vvvvvvvvla64vvvvvvvvl', 0, '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 0, 0, 0, 0, 0, 0, 0, 0));
}
return base64_encode(pack('la64vvvvvvvvla64vvvvvvvvl', 0, '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 0, 0, 0, 0, 0, 0, 0, 0));
} }
} }
\ No newline at end of file
...@@ -2508,6 +2508,7 @@ class MAPIProvider { ...@@ -2508,6 +2508,7 @@ class MAPIProvider {
else { else {
$body = $this->mapiReadStream($stream, $streamsize); $body = $this->mapiReadStream($stream, $streamsize);
$message->asbody->data = StringStreamWrapper::Open(Utils::ConvertCodepageStringToUtf8($message->internetcpid, $body)); $message->asbody->data = StringStreamWrapper::Open(Utils::ConvertCodepageStringToUtf8($message->internetcpid, $body));
$message->internetcpid = INTERNET_CPID_UTF8;
} }
} }
else { else {
......
...@@ -252,7 +252,7 @@ ...@@ -252,7 +252,7 @@
// point. You can add DeviceType strings to the categories. // point. You can add DeviceType strings to the categories.
// In general longer timeouts are better, because more data can be streamed at once. // In general longer timeouts are better, because more data can be streamed at once.
define('SYNC_TIMEOUT_MEDIUM_DEVICETYPES', "SAMSUNGGTI"); define('SYNC_TIMEOUT_MEDIUM_DEVICETYPES', "SAMSUNGGTI");
define('SYNC_TIMEOUT_LONG_DEVICETYPES', "iPod, iPad, iPhone, WP, WindowsOutlook"); define('SYNC_TIMEOUT_LONG_DEVICETYPES', "iPod, iPad, iPhone, WP, WindowsOutlook, WindowsMail");
// Time in seconds the device should wait whenever the service is unavailable, // Time in seconds the device should wait whenever the service is unavailable,
// e.g. when a backend service is unavailable. // e.g. when a backend service is unavailable.
......
...@@ -107,8 +107,10 @@ include_once(ZPUSH_CONFIG); ...@@ -107,8 +107,10 @@ include_once(ZPUSH_CONFIG);
RequestProcessor::HandleRequest(); RequestProcessor::HandleRequest();
// eventually the RequestProcessor wants to send other headers to the mobile // eventually the RequestProcessor wants to send other headers to the mobile
foreach (RequestProcessor::GetSpecialHeaders() as $header) foreach (RequestProcessor::GetSpecialHeaders() as $header) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("Special header: %s", $header));
header($header); header($header);
}
// stream the data // stream the data
$len = ob_get_length(); $len = ob_get_length();
......
...@@ -286,6 +286,17 @@ class SyncParameters extends StateObject { ...@@ -286,6 +286,17 @@ class SyncParameters extends StateObject {
$this->checkCPO($this->currentCPO); $this->checkCPO($this->currentCPO);
} }
/**
* Indicates if the confirmation status changed for the SyncKey.
*
* @access public
* @return boolean
*/
public function HasConfirmationChanged() {
return $this->confirmationChanged;
}
/** /**
* Indicates if a exporter run is required. This is the case if the given folderstat is different from the saved one * Indicates if a exporter run is required. This is the case if the given folderstat is different from the saved one
* or when the expiration time expired. * or when the expiration time expired.
......
...@@ -37,24 +37,24 @@ class Settings extends RequestProcessor { ...@@ -37,24 +37,24 @@ class Settings extends RequestProcessor {
if (!self::$decoder->getElementStartTag(SYNC_SETTINGS_SETTINGS)) if (!self::$decoder->getElementStartTag(SYNC_SETTINGS_SETTINGS))
return false; return false;
// add capability header for KOE // always add capability header - define the supported capabilites
$cap = array();
if (defined('KOE_CAPABILITY_GAB') && KOE_CAPABILITY_GAB) $cap[] = "gab";
if (defined('KOE_CAPABILITY_RECEIVEFLAGS') && KOE_CAPABILITY_RECEIVEFLAGS) $cap[] = "receiveflags";
if (defined('KOE_CAPABILITY_SENDFLAGS') && KOE_CAPABILITY_SENDFLAGS) $cap[] = "sendflags";
if (defined('KOE_CAPABILITY_OOFTIMES') && KOE_CAPABILITY_OOFTIMES) $cap[] = "ooftime";
elseif(defined('KOE_CAPABILITY_OOF') && KOE_CAPABILITY_OOF) $cap[] = "oof"; // 'ooftime' superseeds 'oof'. If 'ooftime' is set, 'oof' should not be defined.
if (defined('KOE_CAPABILITY_NOTES') && KOE_CAPABILITY_NOTES) $cap[] = "notes";
if (defined('KOE_CAPABILITY_SHAREDFOLDER') && KOE_CAPABILITY_SHAREDFOLDER) $cap[] = "sharedfolder";
if (defined('KOE_CAPABILITY_SENDAS') && KOE_CAPABILITY_SENDAS) $cap[] = "sendas";
if (defined('KOE_CAPABILITY_SECONDARYCONTACTS') && KOE_CAPABILITY_SECONDARYCONTACTS) $cap[] = "secondarycontacts";
if (defined('KOE_CAPABILITY_SIGNATURES') && KOE_CAPABILITY_SIGNATURES) $cap[] = "signatures";
if (defined('KOE_CAPABILITY_RECEIPTS') && KOE_CAPABILITY_RECEIPTS) $cap[] = "receipts";
self::$specialHeaders = array();
self::$specialHeaders[] = "X-Push-Capabilities: ". implode(",", $cap);
if(self::$deviceManager->IsKoe()) { if(self::$deviceManager->IsKoe()) {
// define the supported capabilites
$cap = array();
if (defined('KOE_CAPABILITY_GAB') && KOE_CAPABILITY_GAB) $cap[] = "gab";
if (defined('KOE_CAPABILITY_RECEIVEFLAGS') && KOE_CAPABILITY_RECEIVEFLAGS) $cap[] = "receiveflags";
if (defined('KOE_CAPABILITY_SENDFLAGS') && KOE_CAPABILITY_SENDFLAGS) $cap[] = "sendflags";
if (defined('KOE_CAPABILITY_OOFTIMES') && KOE_CAPABILITY_OOFTIMES) $cap[] = "ooftime";
elseif(defined('KOE_CAPABILITY_OOF') && KOE_CAPABILITY_OOF) $cap[] = "oof"; // 'ooftime' superseeds 'oof'. If 'ooftime' is set, 'oof' should not be defined.
if (defined('KOE_CAPABILITY_NOTES') && KOE_CAPABILITY_NOTES) $cap[] = "notes";
if (defined('KOE_CAPABILITY_SHAREDFOLDER') && KOE_CAPABILITY_SHAREDFOLDER) $cap[] = "sharedfolder";
if (defined('KOE_CAPABILITY_SENDAS') && KOE_CAPABILITY_SENDAS) $cap[] = "sendas";
if (defined('KOE_CAPABILITY_SECONDARYCONTACTS') && KOE_CAPABILITY_SECONDARYCONTACTS) $cap[] = "secondarycontacts";
if (defined('KOE_CAPABILITY_SIGNATURES') && KOE_CAPABILITY_SIGNATURES) $cap[] = "signatures";
if (defined('KOE_CAPABILITY_RECEIPTS') && KOE_CAPABILITY_RECEIPTS) $cap[] = "receipts";
self::$specialHeaders = array();
self::$specialHeaders[] = "X-Push-Capabilities: ". implode(",",$cap);
self::$specialHeaders[] = "X-Push-GAB-Name: ". bin2hex(KOE_GAB_NAME); self::$specialHeaders[] = "X-Push-GAB-Name: ". bin2hex(KOE_GAB_NAME);
if (defined('KOE_CAPABILITY_SIGNATURES') && KOE_CAPABILITY_SIGNATURES) { if (defined('KOE_CAPABILITY_SIGNATURES') && KOE_CAPABILITY_SIGNATURES) {
......
...@@ -637,7 +637,11 @@ class Sync extends RequestProcessor { ...@@ -637,7 +637,11 @@ class Sync extends RequestProcessor {
foreach($sc as $folderid => $spa) { foreach($sc as $folderid => $spa) {
// manually set getchanges parameter for this collection if it is synchronized // manually set getchanges parameter for this collection if it is synchronized
if ($spa->HasSyncKey()) { if ($spa->HasSyncKey()) {
$sc->AddParameter($spa, "getchanges", true); $actiondata = $sc->GetParameter($spa, "actiondata");
// request changes if no other actions are executed
if (empty($actiondata["modifyids"]) && empty($actiondata["clientids"]) && empty($actiondata["removeids"])) {
$sc->AddParameter($spa, "getchanges", true);
}
// announce WindowSize to DeviceManager // announce WindowSize to DeviceManager
self::$deviceManager->SetWindowSize($folderid, $spa->GetWindowSize()); self::$deviceManager->SetWindowSize($folderid, $spa->GetWindowSize());
...@@ -655,8 +659,8 @@ class Sync extends RequestProcessor { ...@@ -655,8 +659,8 @@ class Sync extends RequestProcessor {
} }
} }
// HEARTBEAT & Empty sync // HEARTBEAT
if ($status == SYNC_STATUS_SUCCESS && (isset($hbinterval) || $emptysync == true)) { if ($status == SYNC_STATUS_SUCCESS && isset($hbinterval)) {
$interval = (defined('PING_INTERVAL') && PING_INTERVAL > 0) ? PING_INTERVAL : 30; $interval = (defined('PING_INTERVAL') && PING_INTERVAL > 0) ? PING_INTERVAL : 30;
if (isset($hbinterval)) if (isset($hbinterval))
...@@ -889,7 +893,7 @@ class Sync extends RequestProcessor { ...@@ -889,7 +893,7 @@ class Sync extends RequestProcessor {
// Fir AS 14.0+ omit output for folder, if there were no incoming or outgoing changes and no Fetch // Fir AS 14.0+ omit output for folder, if there were no incoming or outgoing changes and no Fetch
if (Request::GetProtocolVersion() >= 14.0 && ! $spa->HasNewSyncKey() && $changecount == 0 && empty($actiondata["fetchids"]) && $status == SYNC_STATUS_SUCCESS && if (Request::GetProtocolVersion() >= 14.0 && ! $spa->HasNewSyncKey() && $changecount == 0 && empty($actiondata["fetchids"]) && $status == SYNC_STATUS_SUCCESS &&
($newFolderStat === false || ! $spa->IsExporterRunRequired($newFolderStat))) { ! $spa->HasConfirmationChanged() && ($newFolderStat === false || ! $spa->IsExporterRunRequired($newFolderStat))) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("HandleSync: No changes found for %s folder id '%s'. Omitting output.", $spa->GetContentClass(), $spa->GetFolderId())); ZLog::Write(LOGLEVEL_DEBUG, sprintf("HandleSync: No changes found for %s folder id '%s'. Omitting output.", $spa->GetContentClass(), $spa->GetFolderId()));
continue; continue;
} }
...@@ -1210,12 +1214,14 @@ class Sync extends RequestProcessor { ...@@ -1210,12 +1214,14 @@ class Sync extends RequestProcessor {
self::$deviceManager->SetFolderSyncStatus($spa->GetFolderId(), DeviceManager::FLD_SYNC_COMPLETED); self::$deviceManager->SetFolderSyncStatus($spa->GetFolderId(), DeviceManager::FLD_SYNC_COMPLETED);
// we should update the folderstat, but we recheck to see if it changed. If so, it's not updated to force another sync // we should update the folderstat, but we recheck to see if it changed. If so, it's not updated to force another sync
$newFolderStatAfterExport = self::$backend->GetFolderStat(ZPush::GetAdditionalSyncFolderStore($spa->GetBackendFolderId()), $spa->GetBackendFolderId()); if (self::$backend->HasFolderStats()) {
if ($newFolderStat === $newFolderStatAfterExport) { $newFolderStatAfterExport = self::$backend->GetFolderStat(ZPush::GetAdditionalSyncFolderStore($spa->GetBackendFolderId()), $spa->GetBackendFolderId());
$this->setFolderStat($spa, $newFolderStat); if ($newFolderStat === $newFolderStatAfterExport) {
} $this->setFolderStat($spa, $newFolderStat);
else { }
ZLog::Write(LOGLEVEL_DEBUG, "Sync() Folderstat differs after export, force another exporter run."); else {
ZLog::Write(LOGLEVEL_DEBUG, "Sync() Folderstat differs after export, force another exporter run.");
}
} }
} }
else else
......
...@@ -41,6 +41,7 @@ class SyncBaseBody extends SyncObject { ...@@ -41,6 +41,7 @@ class SyncBaseBody extends SyncObject {
SYNC_AIRSYNCBASE_TRUNCATED => array (self::STREAMER_VAR => "truncated"), SYNC_AIRSYNCBASE_TRUNCATED => array (self::STREAMER_VAR => "truncated"),
SYNC_AIRSYNCBASE_DATA => array (self::STREAMER_VAR => "data", SYNC_AIRSYNCBASE_DATA => array (self::STREAMER_VAR => "data",
self::STREAMER_TYPE => self::STREAMER_TYPE_STREAM_ASPLAIN, self::STREAMER_TYPE => self::STREAMER_TYPE_STREAM_ASPLAIN,
self::STREAMER_PROP => self::STREAMER_TYPE_MULTIPART,
self::STREAMER_RONOTIFY => true, self::STREAMER_RONOTIFY => true,
self::STREAMER_PRIVATE => true), // just remove the body when stripping private self::STREAMER_PRIVATE => true), // just remove the body when stripping private
); );
......
...@@ -1359,4 +1359,23 @@ class TimezoneUtil { ...@@ -1359,4 +1359,23 @@ class TimezoneUtil {
} }
return self::getMSTZnameFromTZName(trim($timezone, '"')); return self::getMSTZnameFromTZName(trim($timezone, '"'));
} }
/**
* Returns a timezone supported by PHP for DateTimeZone constructor.
* @see http://php.net/manual/en/timezones.php
*
* @param string $timezone
*
* @access public
* @return string
*/
public static function GetPhpSupportedTimezone($timezone) {
if (in_array($timezone, DateTimeZone::listIdentifiers())) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("TimezoneUtil::GetPhpSupportedTimezone(): '%s' is a PHP supported timezone", $timezone));
return $timezone;
}
$dtz = date_default_timezone_get();
ZLog::Write(LOGLEVEL_DEBUG, sprintf("TimezoneUtil::GetPhpSupportedTimezone(): '%s' is not a PHP supported timezone. Returning default timezone: '%s'", $timezone, $dtz));
return $dtz;
}
} }
...@@ -864,6 +864,7 @@ class Utils { ...@@ -864,6 +864,7 @@ class Utils {
/** /**
* Checks if a file has the same owner and group as the parent directory. * Checks if a file has the same owner and group as the parent directory.
* If not, owner and group are fixed (being updated to the owner/group of the directory). * If not, owner and group are fixed (being updated to the owner/group of the directory).
* If the given file is a special file (i.g., /dev/null, fifo), nothing is changed.
* Function code contributed by Robert Scheck aka rsc. * Function code contributed by Robert Scheck aka rsc.
* *
* @param string $file * @param string $file
...@@ -872,7 +873,7 @@ class Utils { ...@@ -872,7 +873,7 @@ class Utils {
* @return boolean * @return boolean
*/ */
public static function FixFileOwner($file) { public static function FixFileOwner($file) {
if(posix_getuid() == 0 && file_exists($file)) { if(posix_getuid() == 0 && is_file($file)) {
$dir = dirname($file); $dir = dirname($file);
$perm_dir = stat($dir); $perm_dir = stat($dir);
$perm_file = stat($file); $perm_file = stat($file);
......
...@@ -259,12 +259,25 @@ class ZPushAdminCLI { ...@@ -259,12 +259,25 @@ class ZPushAdminCLI {
self::$command = self::COMMAND_CLEARLOOP; self::$command = self::COMMAND_CLEARLOOP;
break; break;
// clear loop detection data // fix states
case "fixstates": case "fixstates":
case "fix": case "fix":
self::$command = self::COMMAND_FIXSTATES; self::$command = self::COMMAND_FIXSTATES;
break; break;
// hidden feature to run fixstates after upgrading the packages - this is called from postinst only
case "fixstates-upgrade":
// don't execute fixstates during upgrade if IGNORE_FIXSTATES_ON_UPGRADE is set to true
if (!defined('IGNORE_FIXSTATES_ON_UPGRADE') || IGNORE_FIXSTATES_ON_UPGRADE == false) {
self::$command = self::COMMAND_FIXSTATES;
}
else {
// print warning and exit gracefully
echo "\nZ-Push: Not executing 'fixstates' as IGNORE_FIXSTATES_ON_UPGRADE is set. You should execute 'z-push-admin -a fixstates' manually!\n\n";
exit(0);
}
break;
default: default:
self::UsageInstructions(); self::UsageInstructions();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment