/** * Handles the GetAttachment command * * @param int $commandCode * * @access public * @return boolean */ public function Handle($commandCode) { $attname = Request::GetGETAttachmentName(); if (!$attname) { return false; } try { $attachment = self::$backend->GetAttachmentData($attname); $stream = $attachment->data; ZLog::Write(LOGLEVEL_DEBUG, sprintf("HandleGetAttachment(): attachment stream from backend: %s", $stream)); header("Content-Type: application/octet-stream"); $l = 0; while (!feof($stream)) { $d = fgets($stream, 4096); $l += strlen($d); echo $d; // announce an update every 100K if ($l / 1024 % 100 == 0) { self::$topCollector->AnnounceInformation(sprintf("Streaming attachment: %d KB sent", round($l / 1024))); } } fclose($stream); self::$topCollector->AnnounceInformation(sprintf("Streamed %d KB attachment", $l / 1024), true); ZLog::Write(LOGLEVEL_DEBUG, sprintf("HandleGetAttachment(): attachment with %d KB sent to mobile", $l / 1024)); } catch (StatusException $s) { // StatusException already logged so we just need to pass it upwards to send a HTTP error throw new HTTPReturnCodeException($s->getMessage(), HTTP_CODE_500, null, LOGLEVEL_DEBUG); } return true; }
public function OXreq($requestOBJ, $returnResponseObject) { $requestOBJ->setCookieJar($this->cookiejar); $requestOBJ->setHeader('User-Agent: z-push-ox (Version ' . BackendOX::getBackendVersion() . ')'); $response = $requestOBJ->send(); $this->cookiejar = $requestOBJ->getCookieJar(); if ($returnResponseObject) { return $response; } if (200 != $response->getStatus()) { ZLog::Write(LOGLEVEL_WARN, 'BackendOX::OXreq(error: ' . $response->getBody() . ')'); return false; } try { $data = json_decode($response->getBody(), true); if (is_array($data) && array_key_exists("error", $data)) { ZLog::Write(LOGLEVEL_WARN, 'BackendOX::OXreq(error: ' . $response->getBody() . ')'); return false; } else { return $data; } } catch (Exception $e) { return false; } }
function zarafa_error_handler($errno, $errstr, $errfile, $errline, $errcontext) { $bt = debug_backtrace(); switch ($errno) { case 8192: // E_DEPRECATED since PHP 5.3.0 // do not handle this message break; case E_NOTICE: case E_WARNING: // TODO check if there is a better way to avoid these messages if (stripos($errfile, 'interprocessdata') !== false && stripos($errstr, 'shm_get_var()') !== false) { break; } ZLog::Write(LOGLEVEL_WARN, "{$errfile}:{$errline} {$errstr} ({$errno})"); break; default: ZLog::Write(LOGLEVEL_ERROR, "trace error: {$errfile}:{$errline} {$errstr} ({$errno}) - backtrace: " . (count($bt) - 1) . " steps"); for ($i = 1, $bt_length = count($bt); $i < $bt_length; $i++) { $file = $line = "unknown"; if (isset($bt[$i]['file'])) { $file = $bt[$i]['file']; } if (isset($bt[$i]['line'])) { $line = $bt[$i]['line']; } ZLog::Write(LOGLEVEL_ERROR, "trace: {$i}:" . $file . ":" . $line . " - " . (isset($bt[$i]['class']) ? $bt[$i]['class'] . $bt[$i]['type'] : "") . $bt[$i]['function'] . "()"); } //throw new Exception("An error occured."); break; } }
/** * Handles a webservice command * * @param int $commandCode * * @access public * @return boolean * @throws SoapFault */ public function Handle($commandCode) { if (Request::GetDeviceType() !== "webservice" || Request::GetDeviceID() !== "webservice") { throw new FatalException("Invalid device id and type for webservice execution"); } if (Request::GetGETUser() != Request::GetAuthUser()) { ZLog::Write(LOGLEVEL_INFO, sprintf("Webservice::HandleWebservice('%s'): user '%s' executing action for user '%s'", $commandCode, Request::GetAuthUser(), Request::GetGETUser())); } // initialize non-wsdl soap server $this->server = new SoapServer(null, array('uri' => "http://z-push.sf.net/webservice")); // the webservice command is handled by its class if ($commandCode == ZPush::COMMAND_WEBSERVICE_DEVICE) { ZLog::Write(LOGLEVEL_DEBUG, sprintf("Webservice::HandleWebservice('%s'): executing WebserviceDevice service", $commandCode)); include_once 'webservicedevice.php'; $this->server->setClass("WebserviceDevice"); } // the webservice command is handled by its class if ($commandCode == ZPush::COMMAND_WEBSERVICE_USERS) { if (!defined("ALLOW_WEBSERVICE_USERS_ACCESS") || ALLOW_WEBSERVICE_USERS_ACCESS !== true) { throw new HTTPReturnCodeException(sprintf("Access to the WebserviceUsers service is disabled in configuration. Enable setting ALLOW_WEBSERVICE_USERS_ACCESS.", Request::GetAuthUser()), 403); } ZLog::Write(LOGLEVEL_DEBUG, sprintf("Webservice::HandleWebservice('%s'): executing WebserviceUsers service", $commandCode)); if (ZPush::GetBackend()->Setup("SYSTEM", true) == false) { throw new AuthenticationRequiredException(sprintf("User '%s' has no admin privileges", Request::GetAuthUser())); } include_once 'webserviceusers.php'; $this->server->setClass("WebserviceUsers"); } $this->server->handle(); ZLog::Write(LOGLEVEL_DEBUG, sprintf("Webservice::HandleWebservice('%s'): sucessfully sent %d bytes", $commandCode, ob_get_length())); return true; }
/** * Checks if there are newer ping requests for the same device & user so * the current process could be terminated * * @access public * @return boolean true if the current process is obsolete */ public function DoForcePingTimeout() { while (true) { self::$redis->watch($this->key); $savedtime = self::$redis->get($this->key); if ($savedtime === false || $savedtime < $_SERVER['REQUEST_TIME']) { $res = self::$redis->multi()->setex($this->key, self::TTL, $_SERVER['REQUEST_TIME'])->exec(); if ($res === false) { ZLog::Write(LOGLEVEL_DEBUG, "DoForcePingTimeout(): set just failed, retrying"); ZLog::Write(LOGLEVEL_DEBUG, sprintf("DoForcePingTimeout() key: '%s' reqtime: '%s' last_error: '%s'", $this->key, $_SERVER['REQUEST_TIME'], self::$redis->getLastError())); continue; } else { return false; } } // Don't compare types, only values if ($savedtime == $_SERVER['REQUEST_TIME']) { self::$redis->unwatch(); return false; } if ($savedtime > $_SERVER['REQUEST_TIME']) { self::$redis->unwatch(); return true; } } }
/** * Handles the GetAttachment command * * @param int $commandCode * * @access public * @return boolean */ public function Handle($commandCode) { $attname = Request::GetGETAttachmentName(); if (!$attname) { return false; } try { $attachment = self::$backend->GetAttachmentData($attname); $stream = $attachment->data; ZLog::Write(LOGLEVEL_DEBUG, sprintf("HandleGetAttachment(): attachment stream from backend: %s", $stream)); // need to check for a resource here, as eg. feof('Error') === false and causing infinit loop in while! if (!is_resource($stream)) { throw new StatusException(sprintf("HandleGetAttachment(): No stream resource returned by backend for attachment: %s", $attname), SYNC_ITEMOPERATIONSSTATUS_INVALIDATT); } header("Content-Type: application/octet-stream"); self::$topCollector->AnnounceInformation("Starting attachment streaming", true); $l = fpassthru($stream); fclose($stream); if ($l === false) { throw new FatalException("HandleGetAttachment(): fpassthru === false !!!"); } self::$topCollector->AnnounceInformation(sprintf("Streamed %d KB attachment", round($l / 1024)), true); ZLog::Write(LOGLEVEL_DEBUG, sprintf("HandleGetAttachment(): attachment with %d KB sent to mobile", round($l / 1024))); } catch (StatusException $s) { // StatusException already logged so we just need to pass it upwards to send a HTTP error throw new HTTPReturnCodeException($s->getMessage(), HTTP_CODE_500, null, LOGLEVEL_DEBUG); } return true; }
/** * Get ZLog instance * @return ZLog */ public static function &getInstance() { if (self::$m_instance == null) { self::$m_instance = new ZLog(); } return self::$m_instance; }
/** * Blocks the mutex * Method blocks until mutex is available! * ATTENTION: make sure that you *always* release a blocked mutex! * * @access public * @return boolean */ public function Block() { if ($this->IsActive()) { return $this->blockMutex(); } ZLog::Write(LOGLEVEL_WARN, "Could not enter mutex as InterProcessData is not available. This is not recommended on duty systems and may result in corrupt user/device linking!"); return true; }
public function __construct($message = "", $code = 0, $previous = NULL, $logLevel = false) { if (!$message) { $message = $this->httpReturnMessage; } if (!$logLevel) { $logLevel = $this->defaultLogLevel; } parent::__construct($message, (int) $code); ZLog::Write($logLevel, get_class($this) . ': ' . $message . ' - code: ' . $code . ' - file: ' . $this->getFile() . ':' . $this->getLine(), false); }
public function onTask($server, $taskId, $fromId, $data) { Request::parse($data); Request::addParams('taskId', $taskId . '_' . $fromId); try { ZRoute::route(); } catch (\Exception $e) { $model = Formater::exception($e); ZLog::info('exception', $model); } }
public function ZPushException($message = "", $code = 0, $previous = NULL, $logLevel = false) { if (!$message) { $message = $this->httpReturnMessage; } if (!$logLevel) { $logLevel = $this->defaultLogLevel; } ZLog::Write($logLevel, get_class($this) . ': ' . $message . ' - code: ' . $code); parent::__construct($message, (int) $code); }
public function ZPushException($message = "", $code = 0, $previous = NULL, $logLevel = false) { if (!$message) { $message = $this->httpReturnMessage; } if (!$logLevel) { $logLevel = $this->defaultLogLevel; } ZLog::Write($logLevel, sprintf("%s: %s - code: %s - file: %s:%s", get_class($this), $message, $code, $this->getFile(), $this->getLine()), false); parent::__construct($message, (int) $code); }
/** * Method checks if the object has the minimum of required parameters * and fullfills semantic dependencies * * This overloads the general check() with special checks to be executed * * @param boolean $logAsDebug (opt) default is false, so messages are logged in WARN log level * * @access public * @return boolean */ public function Check($logAsDebug = false) { $ret = parent::Check($logAsDebug); if (!$ret) { return false; } if (isset($this->start) && isset($this->until) && $this->until < $this->start) { ZLog::Write(LOGLEVEL_WARN, sprintf("SyncObject->Check(): Unmet condition in object from type %s: parameter 'start' is HIGHER than 'until'. Check failed!", get_class($this))); return false; } return true; }
/** * Opens the stream * The string to be streamed is passed over the context * * @param string $path Specifies the URL that was passed to the original function * @param string $mode The mode used to open the file, as detailed for fopen() * @param int $options Holds additional flags set by the streams API * @param string $opened_path If the path is opened successfully, and STREAM_USE_PATH is set in options, * opened_path should be set to the full path of the file/resource that was actually opened. * * @access public * @return boolean */ public function stream_open($path, $mode, $options, &$opened_path) { $contextOptions = stream_context_get_options($this->context); if (!isset($contextOptions[self::PROTOCOL]['string'])) { return false; } $this->position = 0; // this is our stream! $this->stringstream = $contextOptions[self::PROTOCOL]['string']; $this->stringlength = strlen($this->stringstream); ZLog::Write(LOGLEVEL_DEBUG, sprintf("StringStreamWrapper::stream_open(): initialized stream length: %d", $this->stringlength)); return true; }
/** * Instantiates a stream * * @param string $string The string to be wrapped * @access public * @return stream */ public static function Open($string) { ZLog::Write(LOGLEVEL_DEBUG, sprintf("StringStreamWrapper::Open(): len = %d", strlen($string))); if (defined('BUG68532FIXED') && BUG68532FIXED === true) { ZLog::Write(LOGLEVEL_DEBUG, "StringStreamWrapper::Open(): Using php://temp"); $stream = fopen('php://temp', 'r+'); } else { ZLog::Write(LOGLEVEL_DEBUG, "StringStreamWrapper::Open(): Using tmpfile()"); $stream = tmpfile(); } fwrite($stream, $string); rewind($stream); return $stream; }
/** * Returns a list of all known devices with users and when they synchronized for the first time * * @access public * @return array */ public function ListDevicesDetails() { $devices = ZPushAdmin::ListDevices(false); $output = array(); ZLog::Write(LOGLEVEL_INFO, sprintf("WebserviceUsers::ListLastSync(): found %d devices", count($devices))); ZPush::GetTopCollector()->AnnounceInformation(sprintf("Retrieved details of %d devices and getting users", count($devices)), true); foreach ($devices as $deviceId) { $output[$deviceId] = array(); $users = ZPushAdmin::ListUsers($deviceId); foreach ($users as $user) { $output[$deviceId][$user] = ZPushAdmin::GetDeviceDetails($deviceId, $user); } } return $output; }
/** * Opens the stream * The mapistream reference is passed over the context * * @param string $path Specifies the URL that was passed to the original function * @param string $mode The mode used to open the file, as detailed for fopen() * @param int $options Holds additional flags set by the streams API * @param string $opened_path If the path is opened successfully, and STREAM_USE_PATH is set in options, * opened_path should be set to the full path of the file/resource that was actually opened. * * @access public * @return boolean */ public function stream_open($path, $mode, $options, &$opened_path) { $contextOptions = stream_context_get_options($this->context); if (!isset($contextOptions[self::PROTOCOL]['stream'])) { return false; } $this->position = 0; // this is our stream! $this->mapistream = $contextOptions[self::PROTOCOL]['stream']; // get the data length from mapi $stat = mapi_stream_stat($this->mapistream); $this->streamlength = $stat["cb"]; ZLog::Write(LOGLEVEL_DEBUG, sprintf("MAPIStreamWrapper::stream_open(): initialized mapistream: %s streamlength: %d", $this->mapistream, $this->streamlength)); return true; }
/** * Returns a list of folders of the Request::GetGETUser(). * If the user has not enough permissions an empty result is returned. * * @access public * @return array */ public function ListUserFolders() { $user = Request::GetGETUser(); $output = array(); $hasRights = ZPush::GetBackend()->Setup($user); ZLog::Write(LOGLEVEL_INFO, sprintf("WebserviceInfo::ListUserFolders(): permissions to open store '%s': %s", $user, Utils::PrintAsString($hasRights))); if ($hasRights) { $folders = ZPush::GetBackend()->GetHierarchy(); ZPush::GetTopCollector()->AnnounceInformation(sprintf("Retrieved details of %d folders", count($folders)), true); foreach ($folders as $folder) { $folder->StripData(); unset($folder->Store, $folder->flags, $folder->content, $folder->NoBackendFolder); $output[] = $folder; } } return $output; }
/** * Sets the color index from a known category. * * @access public * @return void */ public function SetColorFromCategory() { if (!empty($this->categories)) { $result = array_intersect($this->categories, array_values(self::$colors)); if (empty($result)) { $result = array_intersect($this->categories, array_values(self::$unsupportedColors)); if (!empty($result)) { ZLog::Write(LOGLEVEL_DEBUG, sprintf("SyncNote->SetColorFromCategory(): unsupported color '%s', setting to color white", $result[0])); $result = array("White Category"); } } if (!empty($result)) { $this->Color = array_search($result[0], self::$colors); } } else { $this->Color = 3; } }
/** * Handles a webservice command * * @param int $commandCode * * @access public * @return boolean * @throws SoapFault */ public function Handle($commandCode) { if (Request::GetDeviceType() !== "webservice" || Request::GetDeviceID() !== "webservice") { throw new FatalException("Invalid device id and type for webservice execution"); } if (Request::GetGETUser() != Request::GetAuthUser()) { ZLog::Write(LOGLEVEL_INFO, sprintf("Webservice::HandleWebservice('%s'): user '%s' executing action for user '%s'", $commandCode, Request::GetAuthUser(), Request::GetGETUser())); } // initialize non-wsdl soap server $this->server = new SoapServer(null, array('uri' => "http://z-push.sf.net/webservice")); // the webservice command is handled by its class if ($commandCode == ZPush::COMMAND_WEBSERVICE_DEVICE) { ZLog::Write(LOGLEVEL_DEBUG, sprintf("Webservice::HandleWebservice('%s'): executing WebserviceDevice service", $commandCode)); include_once 'webservicedevice.php'; $this->server->setClass("WebserviceDevice"); } $this->server->handle(); ZLog::Write(LOGLEVEL_DEBUG, sprintf("Webservice::HandleWebservice('%s'): sucessfully sent %d bytes", $commandCode, ob_get_length())); return true; }
/** * Allocates shared memory. * * @access private * @return boolean */ private function initSharedMem() { if (!function_exists('sem_get') || !function_exists('shm_attach') || !function_exists('sem_acquire') || !function_exists('shm_get_var')) { ZLog::Write(LOGLEVEL_INFO, "IpcSharedMemoryProvider->initSharedMem(): PHP libraries for the use shared memory are not available. Check the isntalled php packages or use e.g. the memcache IPC provider."); return false; } // Create mutex $this->mutexid = @sem_get($this->type, 1); if ($this->mutexid === false) { ZLog::Write(LOGLEVEL_ERROR, "IpcSharedMemoryProvider->initSharedMem(): could not aquire semaphore"); return false; } // Attach shared memory $this->memid = shm_attach($this->type + 10, $this->allocate); if ($this->memid === false) { ZLog::Write(LOGLEVEL_ERROR, "IpcSharedMemoryProvider->initSharedMem(): could not attach shared memory"); @sem_remove($this->mutexid); $this->mutexid = false; return false; } // TODO mem cleanup has to be implemented //$this->setInitialCleanTime(); return true; }
/** * Returns available body preference objects * * @access public * @return array/boolean returns false if the client's body preference is not available */ public function GetBodyPreference() { if (!isset($this->bodypref) || !(is_array($this->bodypref) || empty($this->bodypref))) { ZLog::Write(LOGLEVEL_DEBUG, sprintf("ContentParameters->GetBodyPreference(): bodypref is empty or not set")); return false; } return array_keys($this->bodypref); }
/** * Get MAPI addressbook object * * @access private * @return MAPIAddressbook object to be used with mapi_ab_* or false on failure */ private function getAddressbook() { if (isset($this->addressbook) && $this->addressbook) { return $this->addressbook; } $this->addressbook = mapi_openaddressbook($this->session); $result = mapi_last_hresult(); if ($result && $this->addressbook === false) { ZLog::Write(LOGLEVEL_ERROR, sprintf("MAPIProvider->getAddressbook error opening addressbook 0x%X", $result)); return false; } return $this->addressbook; }
/** * Returns the HierarchyCache Object * * @access public * @return object HierarchyCache */ public function GetHierarchyCache() { if (!isset($this->hierarchyCache)) { $this->SetHierarchyCache(); } ZLog::Write(LOGLEVEL_DEBUG, "ASDevice->GetHierarchyCache(): " . $this->hierarchyCache->GetStat()); return $this->hierarchyCache; }
/** * Imports a folder change * * @param SyncFolder $folder folder to be changed * * @access public * @return boolean */ public function ImportFolderChange($folder) { // if the destinationImporter is set, then this folder should be processed by another importer // instead of being loaded in memory. if (isset($this->destinationImporter)) { $ret = $this->destinationImporter->ImportFolderChange($folder); // if the operation was sucessfull, update the HierarchyCache if ($ret) { // for folder creation, the serverid is not set and has to be updated before if (!isset($folder->serverid) || $folder->serverid == "") { $folder->serverid = $ret; } $this->AddFolder($folder); } return $ret; } else { if (isset($folder->serverid)) { // The Zarafa HierarchyExporter exports all kinds of changes for folders (e.g. update no. of unread messages in a folder). // These changes are not relevant for the mobiles, as something changes but the relevant displayname and parentid // stay the same. These changes will be dropped and are not sent! $cacheFolder = $this->GetFolder($folder->serverid); if ($folder->equals($this->GetFolder($folder->serverid))) { ZLog::Write(LOGLEVEL_DEBUG, sprintf("Change for folder '%s' will not be sent as modification is not relevant.", $folder->displayname)); return false; } // load this change into memory $this->changes[] = array(self::CHANGE, $folder); // HierarchyCache: already add/update the folder so changes are not sent twice (if exported twice) $this->AddFolder($folder); return true; } return false; } }
/** * Handles the Provisioning command * * @param int $commandCode * * @access public * @return boolean */ public function Handle($commandCode) { $status = SYNC_PROVISION_STATUS_SUCCESS; $policystatus = SYNC_PROVISION_POLICYSTATUS_SUCCESS; $rwstatus = self::$deviceManager->GetProvisioningWipeStatus(); $rwstatusWiped = false; // if this is a regular provisioning require that an authenticated remote user if ($rwstatus < SYNC_PROVISION_RWSTATUS_PENDING) { ZLog::Write(LOGLEVEL_DEBUG, "RequestProcessor::HandleProvision(): Forcing delayed Authentication"); self::Authenticate(); } $phase2 = true; if (!self::$decoder->getElementStartTag(SYNC_PROVISION_PROVISION)) { return false; } //handle android remote wipe. if (self::$decoder->getElementStartTag(SYNC_PROVISION_REMOTEWIPE)) { if (!self::$decoder->getElementStartTag(SYNC_PROVISION_STATUS)) { return false; } $instatus = self::$decoder->getElementContent(); if (!self::$decoder->getElementEndTag()) { return false; } if (!self::$decoder->getElementEndTag()) { return false; } $phase2 = false; $rwstatusWiped = true; } else { if (!self::$decoder->getElementStartTag(SYNC_PROVISION_POLICIES)) { return false; } if (!self::$decoder->getElementStartTag(SYNC_PROVISION_POLICY)) { return false; } if (!self::$decoder->getElementStartTag(SYNC_PROVISION_POLICYTYPE)) { return false; } $policytype = self::$decoder->getElementContent(); if ($policytype != 'MS-WAP-Provisioning-XML' && $policytype != 'MS-EAS-Provisioning-WBXML') { $status = SYNC_PROVISION_STATUS_SERVERERROR; } if (!self::$decoder->getElementEndTag()) { //policytype return false; } if (self::$decoder->getElementStartTag(SYNC_PROVISION_POLICYKEY)) { $devpolicykey = self::$decoder->getElementContent(); if (!self::$decoder->getElementEndTag()) { return false; } if (!self::$decoder->getElementStartTag(SYNC_PROVISION_STATUS)) { return false; } $instatus = self::$decoder->getElementContent(); if (!self::$decoder->getElementEndTag()) { return false; } $phase2 = false; } if (!self::$decoder->getElementEndTag()) { //policy return false; } if (!self::$decoder->getElementEndTag()) { //policies return false; } if (self::$decoder->getElementStartTag(SYNC_PROVISION_REMOTEWIPE)) { if (!self::$decoder->getElementStartTag(SYNC_PROVISION_STATUS)) { return false; } $status = self::$decoder->getElementContent(); if (!self::$decoder->getElementEndTag()) { return false; } if (!self::$decoder->getElementEndTag()) { return false; } $rwstatusWiped = true; } } if (!self::$decoder->getElementEndTag()) { //provision return false; } if (PROVISIONING !== true) { ZLog::Write(LOGLEVEL_INFO, "No policies deployed to device"); $policystatus = SYNC_PROVISION_POLICYSTATUS_NOPOLICY; } self::$encoder->StartWBXML(); //set the new final policy key in the device manager // START ADDED dw2412 Android provisioning fix if (!$phase2) { $policykey = self::$deviceManager->GenerateProvisioningPolicyKey(); self::$deviceManager->SetProvisioningPolicyKey($policykey); self::$topCollector->AnnounceInformation("Policies deployed", true); } else { // just create a temporary key (i.e. iPhone OS4 Beta does not like policykey 0 in response) $policykey = self::$deviceManager->GenerateProvisioningPolicyKey(); } // END ADDED dw2412 Android provisioning fix self::$encoder->startTag(SYNC_PROVISION_PROVISION); self::$encoder->startTag(SYNC_PROVISION_STATUS); self::$encoder->content($status); self::$encoder->endTag(); self::$encoder->startTag(SYNC_PROVISION_POLICIES); self::$encoder->startTag(SYNC_PROVISION_POLICY); if (isset($policytype)) { self::$encoder->startTag(SYNC_PROVISION_POLICYTYPE); self::$encoder->content($policytype); self::$encoder->endTag(); } self::$encoder->startTag(SYNC_PROVISION_STATUS); self::$encoder->content($policystatus); self::$encoder->endTag(); self::$encoder->startTag(SYNC_PROVISION_POLICYKEY); self::$encoder->content($policykey); self::$encoder->endTag(); if ($phase2 && $policystatus === SYNC_PROVISION_POLICYSTATUS_SUCCESS) { self::$encoder->startTag(SYNC_PROVISION_DATA); if ($policytype == 'MS-WAP-Provisioning-XML') { self::$encoder->content('<wap-provisioningdoc><characteristic type="SecurityPolicy"><parm name="4131" value="1"/><parm name="4133" value="1"/></characteristic></wap-provisioningdoc>'); } elseif ($policytype == 'MS-EAS-Provisioning-WBXML') { self::$encoder->startTag(SYNC_PROVISION_EASPROVISIONDOC); $prov = self::$deviceManager->GetProvisioningObject(); if (!$prov->Check()) { throw new FatalException("Invalid policies!"); } $prov->Encode(self::$encoder); self::$encoder->endTag(); } else { ZLog::Write(LOGLEVEL_WARN, "Wrong policy type"); self::$topCollector->AnnounceInformation("Policytype not supported", true); return false; } self::$topCollector->AnnounceInformation("Updated provisiong", true); self::$encoder->endTag(); //data } self::$encoder->endTag(); //policy self::$encoder->endTag(); //policies //wipe data if a higher RWSTATUS is requested if ($rwstatus > SYNC_PROVISION_RWSTATUS_OK && $policystatus === SYNC_PROVISION_POLICYSTATUS_SUCCESS) { self::$encoder->startTag(SYNC_PROVISION_REMOTEWIPE, false, true); self::$deviceManager->SetProvisioningWipeStatus($rwstatusWiped ? SYNC_PROVISION_RWSTATUS_WIPED : SYNC_PROVISION_RWSTATUS_REQUESTED); self::$topCollector->AnnounceInformation(sprintf("Remote wipe %s", $rwstatusWiped ? "executed" : "requested"), true); } self::$encoder->endTag(); //provision return true; }
/** * Publishes the infomation * @paam timestamp $starttime Time from which to publish data (usually now) * @paam integer $length Amount of seconds from $starttime we should publish */ function publishFB($starttime, $length) { $start = $starttime; $end = $starttime + $length; // Get all the items in the calendar that we need $calendaritems = array(); $restrict = array(RES_OR, array(array(RES_AND, array(array(RES_PROPERTY, array(RELOP => RELOP_GE, ULPROPTAG => $this->proptags["startdate"], VALUE => $start)), array(RES_PROPERTY, array(RELOP => RELOP_LE, ULPROPTAG => $this->proptags["startdate"], VALUE => $end)))), array(RES_AND, array(array(RES_PROPERTY, array(RELOP => RELOP_GE, ULPROPTAG => $this->proptags["duedate"], VALUE => $start)), array(RES_PROPERTY, array(RELOP => RELOP_LE, ULPROPTAG => $this->proptags["duedate"], VALUE => $end)))), array(RES_AND, array(array(RES_PROPERTY, array(RELOP => RELOP_LT, ULPROPTAG => $this->proptags["startdate"], VALUE => $start)), array(RES_PROPERTY, array(RELOP => RELOP_GT, ULPROPTAG => $this->proptags["duedate"], VALUE => $end)))), array(RES_OR, array(array(RES_AND, array(array(RES_EXIST, array(ULPROPTAG => $this->proptags["enddate_recurring"])), array(RES_PROPERTY, array(RELOP => RELOP_EQ, ULPROPTAG => $this->proptags["recurring"], VALUE => true)), array(RES_PROPERTY, array(RELOP => RELOP_GE, ULPROPTAG => $this->proptags["enddate_recurring"], VALUE => $start)))), array(RES_AND, array(array(RES_NOT, array(array(RES_EXIST, array(ULPROPTAG => $this->proptags["enddate_recurring"])))), array(RES_PROPERTY, array(RELOP => RELOP_LE, ULPROPTAG => $this->proptags["startdate"], VALUE => $end)), array(RES_PROPERTY, array(RELOP => RELOP_EQ, ULPROPTAG => $this->proptags["recurring"], VALUE => true)))))))); // global OR $contents = mapi_folder_getcontentstable($this->calendar); mapi_table_restrict($contents, $restrict); while (1) { $rows = mapi_table_queryrows($contents, array_values($this->proptags), 0, 50); if (!is_array($rows)) { break; } if (empty($rows)) { break; } foreach ($rows as $row) { $occurrences = array(); if (isset($row[$this->proptags['recurring']]) && $row[$this->proptags['recurring']]) { $recur = new Recurrence($this->store, $row); $occurrences = $recur->getItems($starttime, $starttime + $length); } else { $occurrences[] = $row; } $calendaritems = array_merge($calendaritems, $occurrences); } } // $calendaritems now contains all the calendar items in the specified time // frame. We now need to merge these into a flat array of begin/end/status // objects. This also filters out all the 'free' items (status 0) $freebusy = $this->mergeItemsFB($calendaritems); // $freebusy now contains the start, end and status of all items, merged. // Get the FB interface try { $fbsupport = mapi_freebusysupport_open($this->session, $this->store); } catch (MAPIException $e) { if ($e->getCode() == MAPI_E_NOT_FOUND) { $e->setHandled(); if (function_exists("dump")) { dump("Error in opening freebusysupport object."); } } } // Open updater for this user if (isset($fbsupport) && $fbsupport) { $updaters = mapi_freebusysupport_loadupdate($fbsupport, array($this->entryid)); $updater = $updaters[0]; // Send the data mapi_freebusyupdate_reset($updater); mapi_freebusyupdate_publish($updater, $freebusy); mapi_freebusyupdate_savechanges($updater, $start - 24 * 60 * 60, $end); // We're finished mapi_freebusysupport_close($fbsupport); } else { ZLog::Write(LOGLEVEL_WARN, "FreeBusyPublish is not available"); } }
/** * Log the a token to ZLog * * @param string $el token * * @access private * @return */ private function logToken($el) { if (!WBXML_DEBUG) { return; } $spaces = str_repeat(" ", count($this->logStack)); switch ($el[EN_TYPE]) { case EN_TYPE_STARTTAG: if ($el[EN_FLAGS] & EN_FLAGS_CONTENT) { ZLog::Write(LOGLEVEL_WBXML, "I " . $spaces . " <" . $el[EN_TAG] . ">"); array_push($this->logStack, $el[EN_TAG]); } else { ZLog::Write(LOGLEVEL_WBXML, "I " . $spaces . " <" . $el[EN_TAG] . "/>"); } break; case EN_TYPE_ENDTAG: $tag = array_pop($this->logStack); ZLog::Write(LOGLEVEL_WBXML, "I " . $spaces . "</" . $tag . ">"); break; case EN_TYPE_CONTENT: ZLog::Write(LOGLEVEL_WBXML, "I " . $spaces . " " . $el[EN_CONTENT]); break; } }
/** * Called when a message has been changed on the mobile. * This functionality is not available for emails. * * @param string $folderid id of the folder * @param string $id id of the message * @param SyncXXX $message the SyncObject containing a message * * @access public * @return array same return value as StatMessage() * @throws StatusException could throw specific SYNC_STATUS_* exceptions */ public function ChangeMessage($folderid, $id, $message) { ZLog::Write(LOGLEVEL_DEBUG, 'VCDir::ChangeMessage(' . $folderid . ', ' . $id . ', ..)'); $mapping = array('fileas' => 'FN', 'lastname;firstname;middlename;title;suffix' => 'N', 'email1address' => 'EMAIL;INTERNET', 'email2address' => 'EMAIL;INTERNET', 'email3address' => 'EMAIL;INTERNET', 'businessphonenumber' => 'TEL;WORK', 'business2phonenumber' => 'TEL;WORK', 'businessfaxnumber' => 'TEL;WORK;FAX', 'homephonenumber' => 'TEL;HOME', 'home2phonenumber' => 'TEL;HOME', 'homefaxnumber' => 'TEL;HOME;FAX', 'mobilephonenumber' => 'TEL;CELL', 'carphonenumber' => 'TEL;CAR', 'pagernumber' => 'TEL;PAGER', ';;businessstreet;businesscity;businessstate;businesspostalcode;businesscountry' => 'ADR;WORK', ';;homestreet;homecity;homestate;homepostalcode;homecountry' => 'ADR;HOME', ';;otherstreet;othercity;otherstate;otherpostalcode;othercountry' => 'ADR', 'companyname' => 'ORG', 'body' => 'NOTE', 'jobtitle' => 'ROLE', 'webpage' => 'URL'); $data = "BEGIN:VCARD\nVERSION:2.1\nPRODID:Z-Push\n"; foreach ($mapping as $k => $v) { $val = ''; $ks = explode(';', $k); foreach ($ks as $i) { if (!empty($message->{$i})) { $val .= $this->escape($message->{$i}); } $val .= ';'; } if (empty($val)) { continue; } $val = substr($val, 0, -1); if (strlen($val) > 50) { $data .= $v . ":\n\t" . substr(chunk_split($val, 50, "\n\t"), 0, -1); } else { $data .= $v . ':' . $val . "\n"; } } if (!empty($message->categories)) { $data .= 'CATEGORIES:' . implode(',', $this->escape($message->categories)) . "\n"; } if (!empty($message->picture)) { $data .= 'PHOTO;ENCODING=BASE64;TYPE=JPEG:' . "\n\t" . substr(chunk_split($message->picture, 50, "\n\t"), 0, -1); } if (isset($message->birthday)) { $data .= 'BDAY:' . date('Y-m-d', $message->birthday) . "\n"; } $data .= "END:VCARD"; // not supported: anniversary, assistantname, assistnamephonenumber, children, department, officelocation, radiophonenumber, spouse, rtf if (!$id) { if (!empty($message->fileas)) { $name = u2wi($message->fileas); } elseif (!empty($message->lastname)) { $name = $name = u2wi($message->lastname); } elseif (!empty($message->firstname)) { $name = $name = u2wi($message->firstname); } elseif (!empty($message->companyname)) { $name = $name = u2wi($message->companyname); } else { $name = 'unknown'; } $name = preg_replace('/[^a-z0-9 _-]/i', '', $name); $id = $name . '.vcf'; $i = 0; while (file_exists($this->getPath() . '/' . $id)) { $i++; $id = $name . $i . '.vcf'; } } file_put_contents($this->getPath() . '/' . $id, $data); return $this->StatMessage($folderid, $id); }
/** * Sets the importer the exporter will sent it's changes to * and initializes the Exporter * * @param object &$importer Implementation of IImportChanges * * @access public * @return boolean * @throws StatusException */ public function InitializeExporter(&$importer) { $this->changes = array(); $this->step = 0; $this->importer = $importer; if ($this->folderid) { // Get the changes since the last sync if (!isset($this->syncstate) || !$this->syncstate) { $this->syncstate = array(); } ZLog::Write(LOGLEVEL_DEBUG, sprintf("ExportChangesDiff->InitializeExporter(): Initializing message diff engine. '%d' messages in state", count($this->syncstate))); //do nothing if it is a dummy folder if ($this->folderid != SYNC_FOLDER_TYPE_DUMMY) { // Get our lists - syncstate (old) and msglist (new) $msglist = $this->backend->GetMessageList($this->folderid, $this->cutoffdate); // if the folder was deleted, no information is available anymore. A hierarchysync should be executed if ($msglist === false) { throw new StatusException("ExportChangesDiff->InitializeExporter(): Error, no message list available from the backend", SYNC_STATUS_FOLDERHIERARCHYCHANGED, null, LOGLEVEL_INFO); } $this->changes = $this->getDiffTo($msglist); } } else { ZLog::Write(LOGLEVEL_DEBUG, "Initializing folder diff engine"); ZLog::Write(LOGLEVEL_DEBUG, "ExportChangesDiff->InitializeExporter(): Initializing folder diff engine"); $folderlist = $this->backend->GetFolderList(); if ($folderlist === false) { throw new StatusException("ExportChangesDiff->InitializeExporter(): error, no folders available from the backend", SYNC_FSSTATUS_CODEUNKNOWN, null, LOGLEVEL_WARN); } if (!isset($this->syncstate) || !$this->syncstate) { $this->syncstate = array(); } $this->changes = $this->getDiffTo($folderlist); } ZLog::Write(LOGLEVEL_INFO, sprintf("ExportChangesDiff->InitializeExporter(): Found '%d' changes", count($this->changes))); }