<?php
/**
 * $Horde: passwd/lib/Driver/poppassd.php,v 1.17 2003/06/26 01:38:00 mdjukic Exp $
 *
 * The poppassd class attempts to change a user's password via a
 * poppassd server.
 *
 * @author   Eric Jon Rostetter <eric.rostetter@physics.utexas.edu>
 * @package  passwd
 */
class Passwd_Driver_poppassd extends Passwd_Driver {

    /** Pointer to the soect connection. */
    var $_fp;

    /** Hash containing connection parameters. */
    var $params;

    /**
     * Constructs a new poppassd Passwd_Driver object.
     *
     * @param array  $params    A hash containing connection parameters.
     */
    function Passwd_Driver_poppassd($params = array())
    {
        $this->_params['host'] = array_key_exists('host', $params) ? $params['host'] : 'localhost';
        $this->_params['port'] = array_key_exists('port', $params) ? $params['port'] : 106;
    }

    /**
     * Connect to the server
     */
    function _connect() {
        $this->_fp = fsockopen($this->_params['host'], $this->_params['port'], $err_no, $err_str, 30);
        if (!$this->_fp) {
            return PEAR::raiseError($err_str);
        } else {
            return $this->_getPrompt();
        }
    }

    /**
     * Disconnect from the server
     */
    function _disconnect() {
        if (isset($this->_fp)) {
            fputs($this->_fp, "quit\n");
            fclose($this->_fp);
        }
    }

    /**
     * Parse a response from the server to see what it was
     */
    function _getPrompt() {
        $prompt = fgets($this->_fp, 4096);
        if (ereg("^[1-5][0-9][0-9]", $prompt))
        {
            if (substr($prompt, 0, 3) == '200' || substr($prompt, 0, 3) == '300') {
                return true;
            } else {
                return PEAR::raiseError($prompt);
            }
        } else {
            return true;
        }
    }

    /**
     * Send a command to the server
     */
    function _sendCommand($cmd, $arg) {
        $line = $cmd . ' ' . $arg . "\n";
        fputs($this->_fp, $line);
        return $this->_getPrompt();
    }

    /**
     * Change the user's password.
     *
     * @param   $username      The user for which to change the password.
     * @param   $old_password  The old (current) user password.
     * @param   $new_password  The new user password to set.
     *
     * @return  boolean        True or false based on success of the change.
     */
    function changePassword($username,  $old_password, $new_password) {
        $res = $this->_connect();
        if (is_a($res, 'PEAR_Error')) {
            return $res;
        }

        $res = $this->_sendCommand('user', $username);
        if (is_a($res, 'PEAR_Error')) {
            $this->_disconnect();
            return PEAR::raiseError(_("User not found"));
        }

        $res = $this->_sendCommand('pass', $old_password);
        if (is_a($res, 'PEAR_Error')) {
            $this->_disconnect();
            return PEAR::raiseError(_("Incorrect Password"));
        }

        $res = $this->_sendCommand('newpass', $new_password);
        $this->_disconnect();
        if (is_a($res, 'PEAR_Error')) {
            return $res;
        } else {
            $this->resetCredentials($username, $old_password, $new_password);
            return true;
        } 
    }
}
