[sork] qmail drivers added

Nate Mollring nmollring@cennecs.org
Fri Nov 15 14:58:03 2002


Quoting Eric Rostetter <eric.rostetter@physics.utexas.edu>:

> In case anyone cares, I've added (but not well tested) qmail drivers for
> the vacations and forwards modules in CVS HEAD.  The vacation one depends
> on Peter Samuel's qmail-vacation program (from e-smith) that is easily
> available.
> 
> If anyone tries them, let me know how they work.
> 
It looks like it should work without a problem if the .qmail file isn't already 
used.  For me, we use procmail on every account, so the qmail driver won't 
work.  How do you switch to the qmail driver?  An option in the conf.php file 
might work.  I attached the modified forward driver that makes my procmail work 
with vacation without a problem.  It's a little trickier since you have to 
delete the .qmail before it can be changed since VFS is used.
Nate
-------------- next part --------------
<?php
/**
 * $Horde: vacation/lib/Driver/forwards.php,v 1.12 2002/11/15 03:56:37 ericr Exp $
 *
 * Copyright 2001-2002 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/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.12 $
 * @package Vacation
 */

class Vacation_Driver_forwards extends Vacation_Driver {

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

    /** The error string returned to the user if an error occurs. */
    var $err_str;

    /** Hash containing configuration data. */
    var $params;

/**
 * Constructs a new ftp dot-forward Vacation_Driber object.
 *
 * @param array  $params    A hash containing connection parameters.
 */
function Vacation_Driver_forwards($params = array())
{
    $this->params = $params;
}


/**
 * 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
 *                              it's value!
 *
 */

function check_config(&$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 module is not properly configured!");
            return false;
    }
    return true;
}

/**
 * Parse an email address and return it in a known standard form.
 * This will attempt to add the domain (realm) to unqualified addresses.
 *
 * @param   $user       The email address.
 * @param   $realm      The domain/realm to add if none is present.
 * @return  string      The email address on success, false on error.
 */
function _make_email_address($user, $realm)
{
    if ($realm != 'default') {
        $domain = $realm;
    } else {
        $domain = '';
    }
    $parsed_email = imap_rfc822_parse_adrlist($user, $domain);
    if (! is_array($parsed_email)) {
        $this->err_str = _("Can't parse your email address");
        return false;
    }
    $email = $parsed_email[0]->mailbox;
    if (!empty($parsed_email[0]->host)) {
        $email .= '@' . $parsed_email[0]->host;
    }
    return $email;
}

/**
 * Set the vacation notice up.
 * @param string    $user       The username to enable vacation for.
 * @param string    $realm      The realm of the user.
 * @param string    $pass       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 set_vacation($user, $realm, $pass, $message, $alias) {

        // Make sure the configuration file is correct
        if (!$this->check_config($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 ftp array to pass to VFS
        $_args = array( 'hostspec' => $this->params[$realm]['host'],
                        'port' => $this->params[$realm]['port'],
                        'username' => $user,
                        'password' => $pass );

        // Create the VFS ftp driver
        $_vfs = &Horde_VFS::singleton('ftp', $_args);
        $_vfs->setParams($_args);

        // Try to login with the username/password, no realm
        $status = $_vfs->checkCredentials();
        if (PEAR::isError($status)) {
            $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 (PEAR::isError($status)) {
            $this->err_str = $status->getMessage();
            return false;
        }
        $status = $_vfs->write('', '.vacation.pag', $dbfile);
        if (PEAR::isError($status)) {
            $this->err_str = $status->getMessage();
            return false;
        }
        $status = $_vfs->write('', '.vacation.dir', $dbfile);
        if (PEAR::isError($status)) {
            $this->err_str = $status->getMessage();
            return false;
        }
        $status = $_vfs->write('', '.vacation.db', $dbfile);
        if (PEAR::isError($status)) {
            $this->err_str = $status->getMessage();
            return false;
        }

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

        
         // Now set up the .qmail file
        $_vfs->deleteFile('', '.qmail');
        if (!empty($alias) && ($alias != $my_email)) {
           $contents = "| /usr/bin/procmail ~/.procmailrc \n| " . $conf['vacation']['path'] . " -j -a $alias $my_email";
        } else {
           $contents = "| /usr/bin/procmail ~/.procmailrc \n| " . $conf['vacation']['path'] . " -j $my_email";
        }      
        $status = $_vfs->writeData('', '.qmail', $contents);
        if (PEAR::isError($status)) {
            $this->err_str = $status->getMessage();
            return false;
        }

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

        $_vfs->_disconnect();
        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    $pass       The password of the user.
 *
 * @return boolean  Returns true on success, false on error.
 */

    function unset_vacation($user, $realm, $pass) {
        if (!$this->check_config($realm)) {
	   return false;
	}

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

        $_vfs = &Horde_VFS::singleton('ftp', $_args);
        $_vfs->setParams($_args);

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


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

$contents = "| /usr/bin/procmail ~/.procmailrc";
$status = $_vfs->writeData('', '.qmail', $contents);
        if (PEAR::isError($status)) {
            $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();
        return true;
    }
}

?>


More information about the sork mailing list