steffen: server/kolab-resource-handlers/kolab-resource-handlers/freebusy freebusy.php, NONE, 1.1 .htaccess, 1.1.1.1, NONE freebusy, 1.4, NONE
cvs at intevation.de
cvs at intevation.de
Wed Jun 30 12:34:28 CEST 2004
Author: steffen
Update of /kolabrepository/server/kolab-resource-handlers/kolab-resource-handlers/freebusy
In directory doto:/tmp/cvs-serv3211/kolab-resource-handlers/freebusy
Added Files:
freebusy.php
Removed Files:
.htaccess freebusy
Log Message:
freebusy script
--- NEW FILE: freebusy.php ---
<?php
$params = array();
require_once '/kolab/etc/resmgr/freebusy.conf';
function shutdown()
{
global $imap, $ldap;
if (defined($imap) && $imap !== false) {
@imap_close($imap);
$imap = false;
}
if (defined($ldap) && $ldap !== false) {
@ldap_close($ldap);
$ldap = false;
}
}
function notFound($errortext = '')
{
shutdown();
header('HTTP/1.0 404 Not Found');
echo '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL ' . htmlentities($_SERVER['REQUEST_URI']) . ' was not found on this server.</p>
';
if (!empty($errortext)) {
echo "<hr>
<pre>$errortext</pre>
";
}
echo '<hr>
' . $_SERVER['SERVER_SIGNATURE'] . '</body></html>
';
exit;
}
function unauthorized($errortext = '')
{
shutdown();
header('WWW-Authenticate: Basic realm="freebusy-'.$params['email_domain'].'"');
header('HTTP/1.0 401 Unauthorized');
echo '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>401 Unauthorized</title>
</head><body>
<h1>Unauthorized</h1>
<p>You are not authorized to access the requested URL.</p>
';
if (!empty($errortext)) {
echo "<hr>
<pre>$errortext</pre>
";
}
echo '<hr>
' . $_SERVER['SERVER_SIGNATURE'] . '</body></html>
';
exit;
}
function testIMAPError()
{
$errors = imap_alerts();
$errortext = '';
if ($errors !== false && !empty($errors)) {
$errortext = 'IMAP Warning: ' . join("\nIMAP Warning: ", $errors) . "\n";
}
$errors = imap_errors();
if ($errors === false) {
return $errors;
}
$errortext .= 'IMAP Error: ' . join("\nIMAP Error: ", $errors);
$err = array_pop($errors);
if ( $err == 'Permission denied' || $err == 'Invalid credentials' || $err == 'Login aborted' ) {
unauthorized($errortext);
}
notFound($errortext);
}
function testLDAPError()
{
global $ldap;
$errno = ldap_errno($ldap);
if ($errno == 0) {
return false;
}
$error = ldap_err2str($errno);
notFound("LDAP Error $errno: $error");
}
function &generateFreeBusy($startstamp = NULL, $endstamp = NULL)
{
global $params, $imap, $user, $messages, $extended;
require_once 'PEAR.php';
require_once 'Horde/iCalendar.php';
require_once 'Horde/MIME.php';
require_once 'Horde/MIME/Message.php';
require_once 'Horde/MIME/Structure.php';
// Default the start date to today.
if (is_null($startstamp)) {
$month = date('n');
$year = date('Y');
$day = date('j');
$startstamp = mktime(0, 0, 0, $month, $day, $year);
}
// Default the end date to the start date + freebusy_days.
if (is_null($endstamp) || $endstamp < $startstamp) {
$month = date('n', $startstamp);
$year = date('Y', $startstamp);
$day = date('j', $startstamp);
$endstamp = mktime(0, 0, 0, $month, $day + $params['freebusy_days'], $year);
}
// Create the new iCalendar.
$vCal = &new Horde_iCalendar();
$vCal->setAttribute('PRODID', '-//proko2//freebusy 1.0//EN');
$vCal->setAttribute('METHOD', 'PUBLISH');
// Create new vFreebusy.
$vFb = &Horde_iCalendar::newComponent('vfreebusy', $vCal);
$vFb->setAttribute('ORGANIZER', 'MAILTO:' . $user);
$vFb->setAttribute('DTSTAMP', time());
$vFb->setAttribute('DTSTART', $startstamp);
$vFb->setAttribute('DTEND', $endstamp);
$vFb->setAttribute('URL', 'http://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI']);
$eventICal= &new Horde_iCalendar();
foreach ($messages as $msg) {
// Fetch the message
$textmsg = @imap_fetchheader($imap, $msg, FT_UID | FT_PREFETCHTEXT);
if( imap_last_error() == "Unexpected characters at end of address: <>") {
// We have a message with an empty address from OL,
// just ignore the error
imap_errors();
}
$textmsg .= @imap_body($imap, $msg, FT_UID);
testIMAPError();
$mimemsg = &MIME_Structure::parseTextMIMEMessage($textmsg);
// Get a text/calendar MIME part
$parts = $mimemsg->contentTypeMap();
$event = false;
foreach ($parts as $mimeid => $conttype) {
if ($conttype == 'text/calendar') {
$part = $mimemsg->getPart($mimeid);
$eventICal->parsevCalendar($part->toString());
$event = $eventICal->findComponent('VEVENT');
if ($event === false) {
continue;
}
}
}
if ($event === false) {
continue;
}
$uid = $event->getAttributeDefault('UID', 0);
// Get the events initial start
$initial_start = $event->getAttributeDefault('DTSTART', 0);
$initial_end = $event->getAttributeDefault('DTEND', 0);
// Don't bother adding the initial event if it's outside our free/busy window
if ($initial_start < $startstamp || $initial_end > $endstamp) {
continue;
}
if ($extended) {
//error_log("adding event uid $uid");
$vFb->addBusyPeriod('BUSY', $initial_start, $initial_end, null, array('X-UID' => base64_encode($uid)));
} else {
$vFb->addBusyPeriod('BUSY', $initial_start, $initial_end);
}
}
$vCal->addComponent($vFb);
// Generate the vCal file.
return $vCal->exportvCalendar();
}
// ========================================================================== //
// What is the name of our script
$scriptname = basename($_SERVER['SCRIPT_NAME']);
// Should we return extended information?
//$extended = array_key_exists('x', $GLOBALS['HTTP_GET_VARS']);
$extended = isset($_GET['x']);
// Determine who we're supposed to get f/b info for
//$user = preg_replace('/\.vfb$/i', '', basename($_SERVER['PATH_INFO']));
$user = preg_replace( "'/'", '', urldecode($_GET['uid']));
if (empty($user) || $user == $scriptname) {
notFound('No user specified');
}
$fbdir = $params['kolab_prefix'].'/var/kolab/www/freebusy/'.$user.'/';
$fbfilename = $fbdir.$user.($extended?'.xfb':'.vfb');
// Handle the case of 'user' instead of 'user at domain'
if (strstr($user, '@') === false) {
$user .= '@' . $params['email_domain'];
}
if ($params['multi_location']) {
// Handle multi-location setups
$ldap = @ldap_connect($params['server']);
if ($ldap === false) {
notFound('No user specified');
}
@ldap_bind($ldap, $params['bind_dn'], $params['bind_pw']);
testLDAPError();
// TODO: read in a 'fb_url' attribute, if one exists, and use that instead
// This will allow users to explicitly override where their free/busy info
// is read from.
$ldapsearch = @ldap_search($ldap, $params['base_dn'], "mail=$user", array($params['home_server']));
testLDAPError();
$ldapresults = @ldap_get_entries($ldap, $ldapsearch);
testLDAPError();
if ($ldapresults['count'] == 0) {
notFound("$user does not exist in the LDAP hierarchy");
} else if ($ldapresults['count'] > 1) {
notFound("More than one entry for $user were found in the LDAP hierarchy");
}
if (array_key_exists(strtolower($params['home_server']), $ldapresults[0])) {
$homeServer = $ldapresults[0][strtolower($params['home_server'])][0];
} else {
$homeServer = $params['server'];
}
// Redirect if the user is on a different server
if ($homeServer != $params['server']) {
$redirect = "http://$homeServer" . $_SERVER['REQUEST_URI'];
print "redirect: $redirect<br />";
if ($params['redirect']) {
header("Location: $redirect");
} else {
header("X-Redirect-To: $redirect");
if (!@readfile($redirect)) {
notFound("Unable to read free/busy information from $redirect");
}
}
shutdown();
exit;
}
}
// Handle virtual domains
$prefix = $user;
$suffix = '';
if ($params['virtual_domains']) {
list($prefix, $suffix) = split('@', $user);
if ($params['append_domains'] && !empty($suffix)) {
$suffix = '@' . $suffix;
} else {
$suffix = '';
}
}
// Get our mailbox strings for use in the imap_X functions
$server = '{' . $params['server'] . ':143/imap/notls/novalidate-cert}';
$mailbox = "user/$prefix/" . $params['calendar_store'] . "$suffix";
$fullmbox = $server . $mailbox;
$imapuser = $_SERVER['PHP_AUTH_USER'];
$imappw = $_SERVER['PHP_AUTH_PW'];
trigger_error( "user=$imapuser, mailbox=$fullmbox, fbfilename=$fbfilename", E_USER_NOTICE );
$vfb = false;
if( $imapuser || $extended ) {
// Open an IMAP connection to the requested users' calendar
$imap = @imap_open($fullmbox, $imapuser, $imappw);
if ( !$imap ) {
// Login error, try to fall back to cache
} else {
testIMAPError();
// Enumerate our calendar events
$messages = @imap_sort($imap, SORTDATE, 0, SE_UID);
testIMAPError();
// Generate the VFB file
$vfb = &generateFreeBusy();
$ts = mktime();
if( $vfb ) {
if( $extended ) {
// Don't cache
} else {
$tmpn = tempnam( $fbdir,'fb' );
$tmpf = fopen( $tmpn, 'w' );
fwrite( $tmpf, $vfb );
if( !is_dir( $fbdir ) ) {
mkdir( $fbdir );
}
rename( $tmpn, $fbfilename );
fclose( $tmpf );
}
}
}
}
if( !$vfb ) {
$vfb = file_get_contents( $fbfilename );
if( !$vfb ) notFound( "File not found on disk" );
$ts = filectime( $fbfilename );
}
// And finally send it out, ensuring it doesn't get cached along the way
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate("D, d M Y H:i:s",$ts) . ' GMT');
header('Pragma: public');
header('Content-Transfer-Encoding: none');
if ($params['send_content_type']) {
header('Content-Type: text/calendar');
}
if ($params['send_content_length']) {
header('Content-Length: ' . strlen($vfb));
}
if ($params['send_content_disposition']) {
header('Content-Disposition: attachment; filename="' . $user . '.vfb"');
}
echo $vfb;
// Finish up
shutdown();
?>
--- .htaccess DELETED ---
--- freebusy DELETED ---
More information about the commits
mailing list