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