steffen: server/kolab-resource-handlers/kolab-resource-handlers/freebusy freebusyimapcache.class.php, NONE, 1.1 freebusyldap_dummy.class.php, NONE, 1.1 freebusy.class.php.in, 1.5, 1.6 freebusy.conf, 1.2, 1.3 freebusy.php.in, 1.3, 1.4 freebusycache.class.php.in, 1.5, 1.6 misc.php, 1.6, 1.7 pfb.php.in, 1.5, 1.6
cvs at kolab.org
cvs at kolab.org
Wed Oct 25 04:28:59 CEST 2006
Author: steffen
Update of /kolabrepository/server/kolab-resource-handlers/kolab-resource-handlers/freebusy
In directory doto:/tmp/cvs-serv30232/kolab-resource-handlers/freebusy
Modified Files:
freebusy.class.php.in freebusy.conf freebusy.php.in
freebusycache.class.php.in misc.php pfb.php.in
Added Files:
freebusyimapcache.class.php freebusyldap_dummy.class.php
Log Message:
freebusy imap caching from Martin
--- NEW FILE: freebusyimapcache.class.php ---
<?php
/*
* Copyright (c) 2005 Intra2net AG
* Copyright (c) 2006 erfrakon Partnerschaftsgesellschaft
*
* Written by Thomas Jarosch <thomas.jarosch at intra2net.com>
* Written by Martin Konold <martin.konold at erfrakon.de>
*
* 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, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You can view the GNU General Public License, online, at the GNU
* Project's homepage; see <http://www.gnu.org/licenses/gpl.html>.
*/
/* Class to efficently cache kolab events stored on an IMAP server */
class FreeBusyIMAPCache {
var $version; // internal version of format
var $store_prefix; // prefix to prepend to all file operations
var $owner; // folder owner
var $foldername; // folder name
var $cache_modified; // indicates if we have to writeout the cache
var $cache; // cache data
function FreeBusyIMAPCache($store_prefix, &$owner, &$foldername) {
$this->store_prefix = $store_prefix;
$this->owner = $owner;
$this->foldername = $foldername;
$this->version = 1;
$this->reset_cache();
}
function reset_cache() {
$this->cache = array();
$this->cache["version"] = $this->version;
$this->cache["uidvalidity"] = -1;
$this->cache["uidnext"] = -1;
$this->cache["incidences-for"] = "";
$this->cache["imap2fb"] = array();
$this->cache_modified = true;
}
function check_folder_changed($uidvalidity, $uidnext, $incidences_for, &$new_uids) {
$changed = false;
// uidvalidity changed?
if ($uidvalidity != $this->cache["uidvalidity"]) {
myLog("uidvalidity changed (old: ".$this->cache["uidvalidity"].", new: $uidvalidity), clearing cache", RM_LOG_DEBUG);
$this->reset_cache();
$changed = true;
}
// uidnext changed?
if ($uidnext != $this->cache["uidnext"]) {
myLog("uidnext on folder changed (old: ".$this->cache["uidnext"].", new: ".$uidnext.")", RM_LOG_DEBUG);
$changed = true;
}
// incidences-for changed?
if ($incidences_for != $this->cache["incidences-for"]) {
myLog("incidences-for changed (old: ".$this->cache["incidences-for"].", new: $incidences_for), clearing cache", RM_LOG_DEBUG);
$this->reset_cache();
$changed = true;
}
$this->cache["uidvalidity"] = $uidvalidity;
$this->cache["uidnext"] = $uidnext;
$this->cache["incidences-for"] = $incidences_for;
// deleted a message?
$old_uids = array_keys($this->cache["imap2fb"]);
while(list($key, $old_uid) = each($old_uids)) {
if (!in_array($old_uid, $new_uids)) {
unset($this->cache["imap2fb"][$old_uid]);
$this->cache_modified = true;
$changed = true;
}
}
if (!$changed)
myLog("check_changed: folder didn't change", RM_LOG_DEBUG);
return $changed;
}
function check_uid_exists($uid) {
return array_key_exists($uid, $this->cache["imap2fb"]);
}
function add_empty_imap2fb(&$imap_uid) {
$this->cache["imap2fb"][$imap_uid] = array();
$this->cache_modified = true;
}
function add_imap2fb(&$imap_uid, $fb_start, $fb_end, $fb_duration, $fb_extra) {
/*
Internal imap2fb array structure:
0..n IMAP uid
|----------- 0..n free/busy periods
|----------- start
|----------- end
|----------- duration
|----------- extra
*/
myLog("added event to store: uid: $imap_uid, start: $fb_start, end: $fb_end, duration: $fb_duration", RM_LOG_DEBUG);
$store = array();
$store["start"] = $fb_start;
$store["end"] = $fb_end;
$store["duration"] = $fb_duration;
$store["extra"] = $fb_extra;
$this->cache["imap2fb"][$imap_uid][] = $store;
$this->cache_modified = true;
}
function output_fb(&$vFb) {
reset($this->cache["imap2fb"]);
while(list($uid, $periods) = each($this->cache["imap2fb"]))
while(list($key, $period) = each($periods))
$vFb->addBusyPeriod('BUSY', $period["start"], $period["end"], $period["duration"], $period["extra"]);
}
function compute_filename() {
$folder_parts = explode('/', $this->foldername);
unset($folder_parts[0]);
$folder_storename = join('/', $folder_parts);
$folder_storename = str_replace(".", "^", $folder_storename);
$folder_storename = str_replace("\0", "", $folder_storename);
$full_path = $this->store_prefix.$folder_storename.".imapcache";
return $full_path;
}
function cache_load() {
$filename = $this->compute_filename();
myLog("Trying to load file: $filename", RM_LOG_DEBUG);
if (!is_readable($filename))
return false;
$this->cache = unserialize(file_get_contents($filename));
// Delete disc cache if it's from an old version
if ($this->cache["version"] != $this->version) {
myLog("Version mismatch (got: ".$this->cache["version"].", current: ".$this->version.", dropping cache", RM_LOG_WARN);
$this->reset_cache();
}
else $this->cache_modified = false;
return true;
}
function cache_store($force=false) {
if ($this->cache_modified || $force) {
$filename = $this->compute_filename();
myLog("Trying to save cache to file: $filename", RM_LOG_DEBUG);
if (!$this->mkdirhier(dirname($filename))) {
myLog("can't create director hierachy: ".dirname($filename), RM_LOG_ERROR);
return;
}
$tmpname = tempnam(dirname($this->store_prefix), 'imapcache');
$fp = fopen($tmpname, 'w');
if(!$fp) return false;
if (fwrite($fp, serialize($this->cache)) === false) {
fclose ($fp);
myLog("can't write to file: $tmpname. Out of discspace?", RM_LOG_ERROR);
return;
}
if(!rename($tmpname, $filename)) {
myLog("can't rename $tmpname to $filename", RM_LOG_ERROR);
return false;
}
fclose($fp);
$this->cache_modified = false;
}
else {
myLog("IMAPcache unmodified, not saving", RM_LOG_DEBUG);
}
}
function cache_delete() {
unlink($this->compute_filename());
$this->reset_cache();
}
function mkdirhier( $dirname ) {
$base = substr($dirname,0,strrpos($dirname,'/'));
$base = str_replace(".", "^", $base);
if( !empty( $base ) && !is_dir( $base ) ) {
if( !$this->mkdirhier( $base ) ) return false;
}
if( !file_exists( $dirname ) ) return mkdir( $dirname, 0755 );
return true;
}
};
?>
--- NEW FILE: freebusyldap_dummy.class.php ---
<?php
/*
* Copyright (c) 2005 Intra2net AG
* Copyright (c) 2006 erfrakon Partnerschaftsgesellschaft
*
* Written by Thomas Jarosch <thomas.jarosch at intra2net.com>
* Written by Martin Konold <martin.konold at erfrakon.de>
*
* 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, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You can view the GNU General Public License, online, at the GNU
* Project's homepage; see <http://www.gnu.org/licenses/gpl.html>.
*/
class FreeBusyLDAP {
function FreeBusyLDAP( $uri, $base ) {
return true;
}
function error() {
return "LDAP::error not implemented";
}
function close() {
return true;
}
function bind( $dn = false , $pw = '' ) {
return true;
}
function freeBusyPast() {
return 0; // Default
}
// Return a hash of info about a user
function userInfo( $uid ) {
$rtn = array();
$rtn["MAIL"] = $uid;
$rtn["HOMESERVER"] = "";
$rtn["FBFUTURE"] = 60;
return $rtn;
}
function mailForUid( $uid ) {
return $uid;
}
function homeServer( $uid ) {
return "localhost";
}
function dn( $uid ) {
return "";
}
function distlists( $dn ) {
return array();
}
};
?>
Index: freebusy.class.php.in
===================================================================
RCS file: /kolabrepository/server/kolab-resource-handlers/kolab-resource-handlers/freebusy/freebusy.class.php.in,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- freebusy.class.php.in 30 Apr 2006 02:35:47 -0000 1.5
+++ freebusy.class.php.in 25 Oct 2006 02:28:57 -0000 1.6
@@ -1,8 +1,11 @@
<?php
/*
- * Copyright (c) 2004 Klaraelvdalens Datakonsult AB
+ * Copyright (c) 2004-12006 Klaraelvdalens Datakonsult AB, Intra2net AG,
+ * erfrakon Partnerschaftsgesellschaft
*
* Written by Steffen Hansen <steffen at klaralvdalens-datakonsult.se>
+ * Thomas Jarosch <thomas.jarosch at intra2net.com>
+ * Martin Konold <martin.konold at erfrakon.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -18,75 +21,104 @@
* Project's homepage; see <http://www.gnu.org/licenses/gpl.html>.
*/
+ /*
+ TODO: Looks like we don't get called for deleted folders.
+ Best thing would be to have a cron script which deletes
+ unmodified pfbs/caches after 2 months.
+ */
+
+
+require_once '@kolab_php_module_prefix at freebusy/freebusycache.class.php';
+require_once '@kolab_php_module_prefix at freebusy/freebusyimapcache.class.php';
require_once '@kolab_php_module_prefix at freebusy/recurrence.class.php';
class FreeBusyRecurrence extends Recurrence {
- function FreeBusyRecurrence( &$vfb, &$extra ) {
+ function FreeBusyRecurrence( &$imapcache, &$imapuid, &$vfb, &$extra ) {
+ $this->imapcache =& $imapcache;
+ $this->imapuid =& $imapuid;
$this->vfb =& $vfb;
$this->extra =& $extra;
}
function setBusy( $start, $end, $duration ) {
- $this->vfb->addBusyPeriod('BUSY', $start, null, $duration, $this->extra);
+ $this->imapcache->add_imap2fb($this->imapuid, $start, null, $duration, $this->extra);
}
+ var $imapcache;
var $vfb;
var $extra;
};
class FreeBusy {
- function FreeBusy( $username,
+ function FreeBusy( $cache_dir,
+ $username,
$password,
$imaphost,
+ $imapoptions,
$fbfuture=60,
$fbpast=0 ) {
+ $this->cache_dir = $cache_dir;
$this->username = $username;
$this->password = $password;
$this->imaphost = $imaphost;
+ $this->imapoptions = $imapoptions;
$this->fbfuture = $fbfuture;
$this->fbpast = $fbpast;
+ $this->relevance = null;
}
function imapConnect() {
- require_once('Net/IMAP.php');
- $this->imap = &new Net_IMAP( $this->imaphost, $this->imapport );
- #$this->imap->setDebug(true);
+ $this->imap_serverstring = "{".$this->imaphost.":".$this->imapport.$this->imapoptions."}";
+ $this->imap = imap_open( $this->imap_serverstring, $this->username, $this->password );
+
return $this->imap;
}
function imapDisconnect() {
- return $this->imap->disconnect();
- }
-
- function imapLogin() {
- return $this->imap->login($this->username,$this->password, true, false);
+ return imap_close($this->imap);
}
function imapOpenMailbox($foldername = 'INBOX') {
$this->foldername = $foldername;
- $rc = $this->imap->selectMailbox( $foldername );
- $a = $this->imap->getAnnotation( '/vendor/kolab/folder-type', '*' );
- //myLog( "$folder has annotation: ".print_r($a,true), RM_LOG_DEBUG);
+
+ $rc = imap_reopen($this->imap, $this->imap_serverstring . $this->foldername);
+ // PHP only returns false for imap_reopen() if we use an HALF_OPEN connection. doh!
+ if (imap_last_error() !== false)
+ $rc = false;
+
+ // $a = $this->imap->getAnnotation( '/vendor/kolab/folder-type', '*' );
+ // myLog( "$folder has annotation: ".print_r($a,true), RM_LOG_DEBUG);
+
return $rc;
}
function getACL() {
- return $this->imap->getACL();
+ $imap_acls = imap_getacl($this->imap, $this->foldername);
+
+ $rtn = array();
+ while (list($user, $rights) = each($imap_acls))
+ $rtn[] = array("USER" => $user, "RIGHTS" => $rights);
+
+ return $rtn;
}
function getRelevance() {
- $val = $this->imap->getAnnotation( '/vendor/kolab/incidences-for', 'value.shared' );
- if( PEAR::isError($val) || empty($val) ) {
+ // cached?
+ if (isset($this->relevance))
+ return $this->relevance;
+
+ $val = imap_getannotation( $this->imap, $this->foldername, '/vendor/kolab/incidences-for', 'value.shared' );
+ if( $val === false || empty($val) ) {
myLog("No /vendor/kolab/incidences-for found for ".$this->foldername, RM_LOG_DEBUG);
- return 'admins';
+ $this->relevance = "admins";
} else {
myLog("/vendor/kolab/incidences-for = ".print_r($val,true)." for ".$this->foldername, RM_LOG_DEBUG);
- return $val;
}
+
+ return $this->relevance;
}
function &generateFreeBusy($startstamp = NULL, $endstamp = NULL ) {
-
require_once 'PEAR.php';
require_once 'Horde/iCalendar.php';
require_once 'Horde/MIME.php';
@@ -102,7 +134,8 @@
$startstamp = strtotime( '-'.$this->fbpast.' days', mktime(0, 0, 0, $month, $day, $year) );
}
- // Default the end date to the start date + freebusy_days.
+ // Default the end date to the start date + fbfuture.
+
if (is_null($endstamp) || $endstamp < $startstamp) {
$endstamp = strtotime( '+'.$this->fbfuture.' days', $startstamp );
}
@@ -124,7 +157,9 @@
// URL is not required, so out it goes...
//$vFb->setAttribute('URL', 'http://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI']);
- if( $this->imap->getNumberOfMessages() == 0 ) {
+ $status = imap_status_current($this->imap, SA_MESSAGES | SA_UIDVALIDITY | SA_UIDNEXT);
+
+ if( $status->messages == 0 ) {
$vFb->setAttribute('DTSTART', 0, array(), false );
$vFb->setAttribute('DTEND', 0, array(), false );
$vFb->setAttribute('COMMENT', 'This is a dummy vfreebusy that indicates an empty calendar');
@@ -138,15 +173,53 @@
$retval = array($vCal->exportvCalendar(),$vCal->exportvCalendar());
return $retval;
}
- myLog("Reading messagelist", RM_LOG_DEBUG);
- $getMessages_start = microtime_float();
- $msglist = $this->imap->getMessagesList();
- //$msglist = &$this->imap->getMessages();
- myLog("FreeBusy::imap->getMessagesList() took ".(microtime_float()-$getMessages_start)." secs.", RM_LOG_DEBUG);
- if( PEAR::isError( $msglist ) ) return array( $msglist, null);
- foreach ($msglist as $msginfo) {
- //myLog("Reading message ".$msginfo['msg_id'], RM_LOG_DEBUG);
- $textmsg = $this->imap->getMsg($msginfo['msg_id']);
+ myLog("Reading messagelist", RM_LOG_DEBUG);
+ $getMessages_start = microtime_float();
+// $msglist = $this->imap->getMessagesList();
+ //$msglist = &$this->imap->getMessages();
+ myLog("FreeBusy::imap->getMessagesList() took ".(microtime_float()-$getMessages_start)." secs.", RM_LOG_DEBUG);
+// if( PEAR::isError( $msglist ) ) return array( $msglist, null);
+// foreach ($msglist as $msginfo) {
+
+ // This only happens in php standalone mode and is needed
+ // to make the debug log quiet
+ if (!isset($_SERVER["SERVER_NAME"]))
+ $_SERVER["SERVER_NAME"] = "localhost";
+
+ $imapcache = new FreeBusyIMAPCache($this->cache_dir."/", $this->username, $this->foldername);
+ $imapcache->cache_load();
+
+ $uids = imap_search($this->imap, "UNDELETED", SE_UID);
+
+ if ($imapcache->check_folder_changed($status->uidvalidity, $status->uidnext, $this->getRelevance(), $uids)) {
+ reset ($uids);
+ while(list($key, $uid) = each($uids))
+ if (!$imapcache->check_uid_exists($uid))
+ $this->process_imap_message($imapcache, $uid, $startstamp, $endstamp);
+ }
+
+ // store cache and output free busy list
+ $imapcache->cache_store();
+ $imapcache->output_fb($vFb);
+
+ $xvCal = $vCal;
+ $xvCal->addComponent($vFb);
+ $vCal->addComponent($this->clearExtra($vFb));
+
+ // Generate the vCal file.
+ $result = array( $vCal->exportvCalendar(), $xvCal->exportvCalendar() );
+ return $result;
+ }
+
+ /********************** Private API below this line ********************/
+
+ function process_imap_message(&$imapcache, &$imapuid, &$startstamp, &$endstamp)
+ {
+ myLog("Processing new message $imapuid", RM_LOG_DEBUG);
+ $imapcache->add_empty_imap2fb($imapuid);
+
+ $textmsg = imap_fetchheader($this->imap, $imapuid, FT_UID).imap_body($this->imap, $imapuid, FT_UID);
+
$mimemsg = &MIME_Structure::parseTextMIMEMessage($textmsg);
// Read in a Kolab event object, if one exists
@@ -166,21 +239,14 @@
if ($event === false) {
myLog("No x-vnd.kolab.events at all ", RM_LOG_DEBUG);
- continue;
+ return;
}
$uid = $event['uid'];
- /*
- // See if we need to ignore this event
- if (isset($params['ignore'][$uid])) {
- trigger_error("Ignoring event with uid=$uid", E_USER_NOTICE);
- continue;
- }
- */
if( array_key_exists( 'show-time-as', $event ) &&
strtolower(trim($event['show-time-as'])) == 'free' ) {
- continue;
+ return;
}
$summary = ($event['sensitivity'] == 'public' ? $event['summary'] : '');
@@ -205,7 +271,7 @@
if( array_key_exists( 'recurrence', $event ) ) {
myLog("Detected recurring event $uid", RM_LOG_DEBUG);
$rec = $event['recurrence'];
- $recurrence =& new FreeBusyRecurrence( $vFb, $extra );
+ $recurrence =& new FreeBusyRecurrence( $imapcache, $imapuid, $vFb, $extra );
$recurrence->setStartDate( $initial_start );
$recurrence->setEndDate( $initial_end );
$recurrence->setCycletype( $rec['cycle'] );
@@ -231,25 +297,15 @@
// Don't bother adding the initial event if it's outside our free/busy window
if ($initial_start < $startstamp || $initial_end > $endstamp) {
- continue;
+ return;
}
-
- $vFb->addBusyPeriod('BUSY', $initial_start/* + FreeBusy::tzOffset($initial_start)*/,
- $initial_end/* + FreeBusy::tzOffset($initial_end)*/, null, $extra);
+
+ // $initial_start/* + FreeBusy::tzOffset($initial_start)
+ $imapcache->add_imap2fb($imapuid, $initial_start, $initial_end, null, $extra);
+
}
- }
-
- $xvCal = $vCal;
- $xvCal->addComponent($vFb);
- $vCal->addComponent($this->clearExtra($vFb));
-
- // Generate the vCal file.
- $result = array( $vCal->exportvCalendar(), $xvCal->exportvCalendar() );
- return $result;
}
- /********************** Private API below this line ********************/
-
function tzOffset( $ts ) {
$dstr = date('O',$ts);
return 3600 * substr( $dstr, 0, 3) + 60 * substr( $dstr, 3, 2);
@@ -408,12 +464,15 @@
$vFb->_extraParams = array();
return $vFb;
}
-
+
+ var $cache_dir;
var $username;
var $password;
var $imaphost;
var $imapport = 143;
+ var $imapoptions;
var $foldername;
+ var $relevance;
// Settings
var $fbfuture;
@@ -422,6 +481,8 @@
var $week_starts_on_sunday = false;
var $imap;
+ var $imap_serverstring;
};
?>
+
Index: freebusy.conf
===================================================================
RCS file: /kolabrepository/server/kolab-resource-handlers/kolab-resource-handlers/freebusy/freebusy.conf,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- freebusy.conf 3 Feb 2006 07:05:11 -0000 1.2
+++ freebusy.conf 25 Oct 2006 02:28:57 -0000 1.3
@@ -65,3 +65,21 @@
// What db type to use for freebusy caches
$params['dbtype'] = 'gdbm';
+
+// Logging
+$params['log'] = "syslog:";
+$params['log_level'] = 2;
+
+// IMAP options passed to imap_open
+$params['imap_options'] = "/notls/secure/readonly";
+
+// Directory prefixes
+$params['kolab_prefix'] = "";
+$params['cache_dir'] = "/datastore/freebusy"; // default: /var/kolab/www/freebusy/cache
+
+$params['pfb_dbformat'] = ""; // default: gdbm
+
+// don't change this if you don't have to
++$params['ldap_uri'] = "";
++$params['ldap_classname_suffix'] = "_dummy";
+
Index: freebusy.php.in
===================================================================
RCS file: /kolabrepository/server/kolab-resource-handlers/kolab-resource-handlers/freebusy/freebusy.php.in,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- freebusy.php.in 5 Feb 2006 20:15:10 -0000 1.3
+++ freebusy.php.in 25 Oct 2006 02:28:57 -0000 1.4
@@ -1,8 +1,12 @@
<?php
/*
* Copyright (c) 2004 Klaraelvdalens Datakonsult AB
+ Copyright (c) 2006 Intra2net AG, erfrakon Partnerschaftsgesellschaft
+ *
*
* Written by Steffen Hansen <steffen at klaralvdalens-datakonsult.se>
+ * Thomas Jarosch <thomas.jarosch at intra2net.com>
+ * Martin Konold <martin.konold at erfrakon.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -18,12 +22,12 @@
* Project's homepage; see <http://www.gnu.org/licenses/gpl.html>.
*/
+require_once('@resmgr_confdir@/freebusy.conf');
require_once('@kolab_php_module_prefix at freebusy/freebusycache.class.php');
require_once('@kolab_php_module_prefix at freebusy/freebusycollector.class.php');
-require_once('@kolab_php_module_prefix at freebusy/freebusyldap.class.php');
-require_once('@kolab_php_module_prefix at freebusy/misc.php');
+require_once('@kolab_php_module_prefix at freebusy/freebusyldap'.$params['ldap_classname_suffix'].'.class.php');
-require_once('@resmgr_confdir@/freebusy.conf');
+require_once('@kolab_php_module_prefix at freebusy/misc.php');
logInit( 'freebusy' );
@@ -68,7 +72,8 @@
}
$user = strtolower($user);
-$cache =& new FreeBusyCache( '@freebusy_cachedir@', $req_extended );
+$cache =& new FreeBusyCache( '@freebusy_cachedir@', $params['pfb_dbformat'], $req_extended );
+
$collector =& new FreeBusyCollector( $user );
$groups = $ldap->distlists( $ldap->dn( $user ) );
@@ -128,3 +133,4 @@
echo $vfb;
?>
+
Index: freebusycache.class.php.in
===================================================================
RCS file: /kolabrepository/server/kolab-resource-handlers/kolab-resource-handlers/freebusy/freebusycache.class.php.in,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- freebusycache.class.php.in 9 Apr 2006 18:28:35 -0000 1.5
+++ freebusycache.class.php.in 25 Oct 2006 02:28:57 -0000 1.6
@@ -1,8 +1,12 @@
<?php
/*
* Copyright (c) 2004 Klaraelvdalens Datakonsult AB
+ * Copyright (c) 2005 Intra2net AG
+ * Copyright (c) 2006 erfrakon Partnerschaftsgesellschaft
*
* Written by Steffen Hansen <steffen at klaralvdalens-datakonsult.se>
+ * Written by Thomas Jarosch <thomas.jarosch at intra2net.com>
+ * Written by Martin Konold <martin.konold at erfrakon.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -25,8 +29,9 @@
require_once('@resmgr_confdir@/freebusy.conf');
class FreeBusyCache {
- function FreeBusyCache( $basedir, $extended = false ) {
+ function FreeBusyCache( $basedir, $dbformat, $extended = false ) {
$this->basedir = $basedir;
+ $this->dbformat = $dbformat;
$this->extended = $extended;
/* make sure that a database really exists before accessing it */
if( !file_exists( $this->basedir.'/pfbcache.db' ) ) {
@@ -37,10 +42,6 @@
function store( $filename, $fbdata, $acl, $relevance ) {
global $params;
- if( ereg( '\.\.', $filename ) ) {
- $this->error = $filename._(' is not absolute');
- return false;
- }
$fbfilename = $this->mkfbfilename($filename);
myLog("FreeBusyCache::store( file=$fbfilename, acl=[ "
@@ -150,6 +151,7 @@
."] )", RM_LOG_DEBUG);
return file_get_contents($fbfilename);
}
+ myLog("FreeBusyCache: file $fbfilename does not exist", RM_LOG_ERROR);
return false;
}
@@ -203,8 +205,10 @@
}
/*************** Private API below this line *************/
+ // a copy of this function exists in freebusyimapcache.class.php
function mkdirhier( $dirname ) {
$base = substr($dirname,0,strrpos($dirname,'/'));
+ $base = str_replace(".", "^", $base);
if( !empty( $base ) && !is_dir( $base ) ) {
if( !$this->mkdirhier( $base ) ) return false;
}
@@ -213,13 +217,14 @@
}
function mkfbfilename( $fbfilename ) {
- $fbfilename = str_replace( '..', '', $fbfilename );
+ $fbfilename = str_replace( '.', '^', $fbfilename );
+
$fbfilename = str_replace( "\0", '', $fbfilename );
return $this->basedir.'/'.$fbfilename.($this->extended?'.xpfb':'.pfb');
}
function mkaclfilename( $fbfilename ) {
- $fbfilename = str_replace( '..', '', $fbfilename );
+ $fbfilename = str_replace( '.', '^', $fbfilename );
$fbfilename = str_replace( "\0", '', $fbfilename );
return $this->basedir.'/'.$fbfilename.($this->extended?'.xpfb':'.pfb').'.acl';
}
@@ -339,7 +344,9 @@
}
var $basedir;
+ var $dbformat;
var $error;
};
?>
+
Index: misc.php
===================================================================
RCS file: /kolabrepository/server/kolab-resource-handlers/kolab-resource-handlers/freebusy/misc.php,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- misc.php 16 Jan 2005 08:17:49 -0000 1.6
+++ misc.php 25 Oct 2006 02:28:57 -0000 1.7
@@ -256,4 +256,4 @@
return assembleUri($parsed);
}
-?>
\ No newline at end of file
+?>
Index: pfb.php.in
===================================================================
RCS file: /kolabrepository/server/kolab-resource-handlers/kolab-resource-handlers/freebusy/pfb.php.in,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- pfb.php.in 23 Oct 2006 21:37:50 -0000 1.5
+++ pfb.php.in 25 Oct 2006 02:28:57 -0000 1.6
@@ -1,8 +1,12 @@
<?php
/*
* Copyright (c) 2004 Klaraelvdalens Datakonsult AB
+ * Copyright (c) 2005 Intra2net AG
+ * Copyright (c) 2006 erfrakon Partnerschaftsgesellschaft
*
* Written by Steffen Hansen <steffen at klaralvdalens-datakonsult.se>
+ * Thomas Jarosch <thomas.jarosch at intra2net.com>
+ * Martin Konold <martin.konold at erfrakon.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -30,11 +34,11 @@
$max_execution_time = ini_get('max_execution_time');
if( $max_execution_time < 200 ) ini_set('max_execution_time', '200');
-require_once('@kolab_php_module_prefix at freebusy/freebusyldap.class.php');
-require_once('@kolab_php_module_prefix at freebusy/freebusycache.class.php');
require_once('@kolab_php_module_prefix at freebusy/misc.php');
-
require_once('@resmgr_confdir@/freebusy.conf');
+require_once('@kolab_php_module_prefix at freebusy/freebusyldap'.$params['ldap_classname_suffix'].'.class.php');
+
+require_once('@kolab_php_module_prefix at freebusy/freebusycache.class.php');
logInit('pfb');
@@ -43,6 +47,18 @@
$req_cache = isset($_REQUEST['cache'])?(bool)$_REQUEST['cache']:false;
$req_folder = isset($_REQUEST['folder'])?$_REQUEST['folder']:false;
$req_extended = isset($_REQUEST['extended'])?(bool)$_REQUEST['extended']:false;
+// convert character encoding (stores utf7 folder names also on disc)
+require_once "Horde/Util.php";
+require_once "Horde/String.php";
+$req_folder = String::convertCharset($req_folder, "UTF-8", "UTF7-IMAP");
+/*
+// Debug test values
+$imapuser = "groupware";
+$imappw = "groupware";
+$req_cache = 0;
+$req_folder = "groupware/Kalender";
+$req_extended = 0;
+*/
myLog("pfb.php starting up: user=$imapuser, folder=$req_folder, extended=$req_extended",
RM_LOG_DEBUG);
@@ -59,7 +75,8 @@
//$homeserver = $userinfo['HOMESERVER'];
}
-$folder = array_values(array_filter(explode('/', $req_folder )));
+$folder = explode('/', $req_folder);
+
if( count($folder) < 1 ) {
// error
notFound( _('No such folder ').htmlentities($req_folder) );
@@ -101,10 +118,11 @@
exit;
}
-$cache =& new FreeBusyCache( '@freebusy_cachedir@',
- false );
-$xcache =& new FreeBusyCache( '@freebusy_cachedir@',
- true );
+$full_cache_dir = $params['kolab_prefix'] . $params['cache_dir'];
+
+$cache =& new FreeBusyCache( $full_cache_dir, $params['pfb_dbformat'], false );
+$xcache =& new FreeBusyCache( $full_cache_dir, $params['pfb_dbformat'], true );
+
if( $req_cache ) {
$acl = false;
@@ -143,35 +161,18 @@
unset($folder[0]);
$folder = join('/', $folder);
$fbpast = $ldap->freeBusyPast();
- $fb =& new FreeBusy( $imapuser, $imappw, 'localhost', $uinfo['FBFUTURE'], $fbpast );
- $fb->freebusy_days = $params['freebusy_days'];
+ $fb =& new FreeBusy( $full_cache_dir, $imapuser, $imappw, 'localhost', $params['imap_options'], $uinfo['FBFUTURE'], $fbpast );
+
$fb->default_domain = $params['email_domain'];
$rc = $fb->imapConnect();
- if( PEAR::isError( $rc ) ) {
- unauthorized($rc->toString());
- return false;
- }
- $rc = $fb->imapLogin();
- if( PEAR::isError( $rc ) ) {
- unauthorized("Access denied for user $imapuser: ".$rc->toString());
+ if( $rc === false ) {
+ unauthorized(imap_last_error());
return false;
}
$rc = $fb->imapOpenMailbox(FreeBusy::imapFolderName( $imapuser, $owner,
$folder, $params['email_domain']));
- if( PEAR::isError( $rc ) ) {
- // folder doesn't exist (anymore)
- $cache->store( $owner.'/'.$folder, false, array(), "delete folder");
- $xcache->store( $owner.'/'.$folder, false, array(), "delete folder");
-
- // clear IMAP cache
- $imapcache = new FreeBusyIMAPCache($full_cache_dir."/", $owner, $fb->foldername);
- $imapcache->cache_delete();
-
- // try to unlink (parent) directory, works only if empty
- $parent_folder = $full_cache_dir."/".str_replace(".", "^", $owner."/".$folder);
- @rmdir($parent_folder);
-
- notfound( "Folder: ".$fb->foldername.', '.$rc->toString());
+ if( $rc === false ) {
+ notfound( "Folder: ".$fb->foldername.', '.imap_last_error());
return false;
}
$relevance = $fb->getRelevance();
More information about the commits
mailing list