<?php
/**
 * $Horde: vacation/lib/Driver/forwards.php,v 1.24 2003/09/20 20:40:55 chuck Exp $
 *
 * Copyright 2001-2003 Eric Rostetter <eric.rostetter@physics.utexas.edu>
 *
 * See the enclosed file LICENSE for license information (BSD). If you
 * did not receive this file, see http://www.horde.org/licenses/bsdl.php.
 *
 * Vacation_Driver_forwards:: implements the Vacation_Driver API for ftp driven
 * dot-forward compliant mail servers.
 *
 * @author  Eric Rostetter <eric.rostetter@physics.utexas.edu>
 * @version $Revision: 1.24 $
 * @package Vacation
 */
class Vacation_Driver_forwards extends Vacation_Driver {

    /** The FTP stream we open via the VFS class. */
    var $_vfs;

    /** The current vacation details. */
    var $_details = null;

    /**
     * Check if the realm has a specific configuration. If not, try to
     * fall back on the default configuration. If still not a valid
     * configuration then exit with an error.
     *
     * @param string    $realm      The realm of the user, or "default" if none.
     *                              Note: passed by reference so we can change
     *                              its value.
     */
    function checkConfig(&$realm)
    {
        // If no realm passed in, or no host config for the realm
        // passed in, then we fall back to the default realm
        if (empty($realm) || empty($this->params[$realm]['host'])) {
            $realm = 'default';
        }

        // If still no host/port, then we have a misconfigured module.
        if (empty($this->params[$realm]['host']) ||
            empty($this->params[$realm]['port']) ) {
            $this->err_str = _("The vacation application is not properly configured.");
            return false;
        }
        return true;
    }

    /**
     * Set the vacation notice up.
     * @param string    $user       The username to enable vacation for.
     * @param string    $realm      The realm of the user.
     * @param string    $password   The password for the user.
     * @param string    $message    The message to install.
     * @param string    $alias      The email alias to pass to vacation
     * @return boolean  Returns true on success, false on error.
     */
    function setVacation($user, $realm, $password, $message, $alias)
    {
        // Make sure the configuration file is correct
        if (!$this->checkConfig($realm)) {
            return false;
        }

        // We need to find out what type of database file to use
        $conf = &$GLOBALS['conf'];
        $dbfile = VACATION_BASE . '/files/empty.' .
                  $this->params['dbtype'] . '.bin';

        // Build the params array to pass to VFS.
        $_args = array('hostspec' => $this->params[$realm]['host'],
                       'port' => $this->params[$realm]['port'],
                       'username' => $user,
                       'password' => $password);

        // Create the VFS ftp driver.
        require_once HORDE_LIBS . 'VFS.php';
        $_vfs = &VFS::singleton('ftp', $_args);

        // Try to login with the username/password, no realm.
        $status = $_vfs->checkCredentials();
        if (is_a($status, 'PEAR_Error')) {
            $this->err_str = $status->getMessage();
            $this->err_str .= '  ' .  _("Check your username and password.");
            return false;
        }

        // Set up the vacation specific files first.
        $status = $_vfs->writeData('', '.vacation.msg', $message);
        if (is_a($status, 'PEAR_Error')) {
            $this->err_str = $status->getMessage();
            return false;
        }
        $status = $_vfs->write('', '.vacation.pag', $dbfile);
        if (is_a($status, 'PEAR_Error')) {
            $this->err_str = $status->getMessage();
            return false;
        }
        $status = $_vfs->write('', '.vacation.dir', $dbfile);
        if (is_a($status, 'PEAR_Error')) {
            $this->err_str = $status->getMessage();
            return false;
        }
        $status = $_vfs->write('', '.vacation.db', $dbfile);
        if (is_a($status, 'PEAR_Error')) {
            $this->err_str = $status->getMessage();
            return false;
        }

        // Parse the email address and alias address passed in.
        $my_email = $this->_makeEmailAddress($user, $realm);
        if ($my_email === false) {
            return false;
        }
        if (!empty($alias)) {
            $alias = $this->_makeEmailAddress($alias, $realm);
            if ($alias === false) {
                return false;
            }
        }

        // Now set up the .forward file
        if (!empty($alias) && ($alias != $my_email)) {
           $contents = "\\$my_email, \"|" . $conf['vacation']['path'] .
                       " -a $alias $my_email\"";
        } else {
           $contents = "\\$my_email, \"|" . $conf['vacation']['path'] .
                       " $my_email\"";
        }
        $status = $_vfs->writeData('', '.forward', $contents);
        if (is_a($status, 'PEAR_Error')) {
            $this->err_str = $status->getMessage();
            return false;
        }

        // Try to change the permissions, but ignore any errors.
        $_vfs->changePermissions('', '.forward', '0600');

        $_vfs->_disconnect();

        // Update the current details.
        $this->_details = array('vacation' => 'y',
                                'message' => $message);
        return true;
    }

    /**
     * Remove any existing vacation notices.
     *
     * @param string    $user       The user to disable vacation notices for.
     * @param string    $realm      The realm of the user.
     * @param string    $password   The password of the user.
     *
     * @return boolean  Returns true on success, false on error.
     */
    function unsetVacation($user, $realm, $password)
    {
        if (!$this->checkConfig($realm)) {
            return false;
        }

        $_args = array('hostspec' => $this->params[$realm]['host'],
                       'port' => $this->params[$realm]['port'],
                       'username' => $user,
                       'password' => $password);

        require_once HORDE_LIBS . 'VFS.php';
        $_vfs = &VFS::singleton('ftp', $_args);

        // Try to login with the username/password, no realm.
        $status = $_vfs->checkCredentials();
        if (is_a($status, 'PEAR_Error')) {
            $this->err_str = $status->getMessage();
            $this->err_str .= '  ' .  _("Check your username and password.");
            return false;
        }

        $status = $_vfs->deleteFile('', '.forward');
        if (is_a($status, 'PEAR_Error')) {
            $this->err_str = $status->getMessage();
            $this->err_str .= '  ' .
                  _("Maybe you didn't have a vacation notice installed?");
            return false;
        }
        $status = $_vfs->deleteFile('', '.vacation.msg');
        if (is_a($status, 'PEAR_Error')) {
            $this->err_str = $status->getMessage();
            return false;
        }

        // We could, but don't, check for errors on these. They are
        // more-or-less harmless without the above two files.
        $_vfs->deleteFile('', '.vacation.pag');
        $_vfs->deleteFile('', '.vacation.dir');
        $_vfs->deleteFile('', '.vacation.db');

        $_vfs->_disconnect();

        // Update the current details.
        $this->_details = false;
        return true;
    }

    /**
     * Retrieve the current vacation details for the user.
     *
     * @param   $user        The username for which to retrieve details.
     * @param   $realm       The realm (domain) for the user.
     * @param   $password    The password for user.
     *
     * @return  mixed        Vacation details or false.
     */
    function _getUserDetails($user, $realm, $password)
    {
        if (is_null($this->_details)) {
            if (!$this->checkConfig($realm)) {
                return false;
            }

            $_args = array('hostspec' => $this->params[$realm]['host'],
                           'port' => $this->params[$realm]['port'],
                           'username' => $user,
                           'password' => $password);

            require_once HORDE_LIBS . 'VFS.php';
            $_vfs = &VFS::singleton('ftp', $_args);

            // Try to login with the username/password, no realm.
            $status = $_vfs->checkCredentials();
            if (is_a($status, 'PEAR_Error')) {
                $this->err_str = $status->getMessage();
                $this->err_str .= '  ' .  _("Check your username and password.");
                return false;
            }

            $message = $_vfs->read('', '.vacation.msg');
            if (is_a($message, 'PEAR_Error')) {
                $this->err_str = $message->getMessage();
                return false;
            }

            $this->_details['message'] = $message;
            $this->_details['vacation'] = 'y';

            $_vfs->_disconnect();
        }

        return $this->_details;
    }

}
