[pkg-horde] [SCM] Debian Horde Packages repository: sork-forwards-h3 package branch, debian-sid, updated. 491bf862e3eab7e4c4c8c9b859120d9546652228

Gregory Colpart reg at foulademer.gcolpart.com
Sun May 31 20:02:08 UTC 2009


The following commit has been merged in the debian-sid branch:
commit 8cbdefe281828e7aac50c7bcb12fc2b1aaa6a688
Author: Gregory Colpart <reg at foulademer.gcolpart.com>
Date:   Sun May 31 18:16:31 2009 +0200

    merge from upstream

diff --git a/LICENSE b/LICENSE
index cde41c2..b95305d 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2002-2006 The Horde Project.  All rights reserved.
+Copyright 2002-2009 The Horde Project.  All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
diff --git a/README b/README
index 41a7cd9..cec81ca 100644
--- a/README
+++ b/README
@@ -1,8 +1,8 @@
 What is Forwards?
 =================
 
-:Last update:   $Date: 2006/06/20 09:10:56 $
-:Revision:      $Revision: 1.8.2.1 $
+:Last update:   $Date: 2008/10/09 17:36:35 $
+:Revision:      $Revision: 1.8.2.2 $
 :Contact:       sork at lists.horde.org
 
 .. contents:: Contents
diff --git a/config/conf.xml b/config/conf.xml
index e51663e..a15f330 100644
--- a/config/conf.xml
+++ b/config/conf.xml
@@ -1,137 +1,163 @@
 <?xml version="1.0"?>
-<!-- $Horde: forwards/config/conf.xml,v 1.7 2005/04/13 18:06:16 chuck Exp $ -->
+<!-- $Horde: forwards/config/conf.xml,v 1.7.2.1 2008/10/09 17:36:36 jan Exp $ -->
 <configuration>
  <configsection name="server">
   <configheader>Server configuration</configheader>
+  <configdescription>
+    If not using realms (multiple domains or virtual hosting) then there is
+    only one possible default configuration. Even if you are using
+    realms/hosting, you have to set a default configuration. This may be
+    overriden by realm/domain specific values by defining additional arrays,
+    one per realm/domain, with the realm/domain name as the key instead of the
+    key 'default'. This not possible with this interface though.
+  </configdescription>
   <configswitch name="driver" desc="The driver to use">forwards
+   <case name="customsql" desc="Custom SQL based forwarding driver">
+    <configsection name="params">
+     <configsql switchname="driverconfig"/>
+     <configdescription>
+       This driver allows for custom SQL queries into which variables will be
+       substituted. The current FULL username will be provided as \U, target
+       address will be provided as \T, the given password will be provided as
+       \P, and the option to keep a local copy of forwarded addresses will be
+       a "Y" or "N" value provided as \L. If the query to check the forwarding
+       status returns no rows, it will be assumed that forwarding is not
+       enabled.
+     </configdescription>
+     <configstring name="query_select" desc="Query to retrieve forwarding
+     status"/>
+     <configstring name="query_set" desc="Query to set forwarding address"/>
+     <configstring name="query_disable" desc="Query to disable forwarding"/>
+     <configstring name="column_target" desc="Column specifying the target
+     forwarding address"/>
+     <configstring name="column_keeplocal" desc="Column telling us if we are
+     keeping a local copy"/>
+    </configsection>
+   </case>
+
+   <case name="sql" desc="Exim mailer based SQL driver">
+    <configsection name="params">
+     <configsection name="default">
+      <configsql switchname="driverconfig">
+       <configstring name="table" desc="Database table">users</configstring>
+       <configstring name="user_col" desc="Column which contains user
+       names">user</configstring>
+       <configstring name="pass_col" desc="Column with
+       passwords">password</configstring>
+       <configstring name="altemail" desc="Alternative email column name"/>
+       <configstring name="forward" desc="Email forward yes or no"/>
+      </configsql>
+     </configsection>
+    </configsection>
+   </case>
+
    <case name="forwards" desc="FTP driver for dot-forward compliant mailers">
-    <configdescription>
-     If not using realms (multiple domains or virtual hosting) then there is
-     only one possible default configuration.
-     Even if you are using realms/hosting, you have to set a default
-     configuration.  This may be overriden by realm/domain specific values by
-     defining additional arrays, one per realm/domain, with the realm/domain
-     name as the key instead of the key 'default'. This not possible with this
-     interface though.
-    </configdescription>
     <configsection name="params">
      <configsection name="default">
-      <configstring name="host" desc="Hostname where the FTP server is running on">localhost</configstring>
-      <configinteger name="port" desc="Port that the FTP server is using">21</configinteger>
+      <configstring name="host" desc="Hostname where the FTP server is running
+      on">localhost</configstring>
+      <configinteger name="port" desc="Port that the FTP server is
+      using">21</configinteger>
       <configenum name="pasv" desc="Use FTP passive mode?">false
        <values>
         <value desc="No">false</value>
         <value desc="Yes">true</value>
        </values>
       </configenum>
+      <configboolean name="ssl" required="false" desc="Use a secure SSL FTP
+      connection?"/>
      </configsection>
     </configsection>
    </case>
+
    <case name="qmail" desc="FTP driver for qmail compliant mailers">
-    <configdescription>
-     If not using realms (multiple domains or virtual hosting) then there is
-     only one possible default configuration.
-     Even if you are using realms/hosting, you have to set a default
-     configuration.  This may be overriden by realm/domain specific values by
-     defining additional arrays, one per realm/domain, with the realm/domain
-     name as the key instead of the key 'default'. This not possible with this
-     interface though.
-    </configdescription>
     <configsection name="params">
      <configsection name="default">
-      <configstring name="host" desc="Hostname where the FTP server is running on">localhost</configstring>
-      <configinteger name="port" desc="Port that the FTP server is using">21</configinteger>
+      <configstring name="host" desc="Hostname where the FTP server is running
+      on">localhost</configstring>
+      <configinteger name="port" desc="Port that the FTP server is
+      using">21</configinteger>
       <configenum name="pasv" desc="Use FTP passive mode?">false
        <values>
         <value desc="No">false</value>
         <value desc="Yes">true</value>
        </values>
       </configenum>
+      <configboolean name="ssl" required="false" desc="Use a secure SSL FTP
+      connection?"/>
      </configsection>
     </configsection>
    </case>
-   <case name="mdaemon" desc="MDaemon mail server driver">
-    <configdescription>
-     If not using realms (multiple domains or virtual hosting) then there is
-     only one possible default configuration.
-     Even if you are using realms/hosting, you have to set a default
-     configuration.  This may be overriden by realm/domain specific values by
-     defining additional arrays, one per realm/domain, with the realm/domain
-     name as the key instead of the key 'default'. This not possible with this
-     interface though.
-    </configdescription>
+
+   <case name="ldap" desc="LDAP driver">
     <configsection name="params">
      <configsection name="default">
-      <configstring name="location" desc="Directory where MDaemon is installed"></configstring>
+      <configswitch name="schema" desc="LDAP schema to use">
+       <configdescription>
+        Select the schema your mail server expects to see in LDAP.
+       </configdescription>
+       <case name="qmail-ldap" desc="qmail+ldap schema from
+       http://www.nrg4u.com" />
+       <case name="sunone" desc="SunONE Directory Server schema" />
+       <case name="exim" desc="Exim-based schema" />
+       <case name="custom" desc="Custom attribute for forwarding addresses">
+        <configstring name="attribute" desc="Custom attribute name">
+         mailForwardingAddress
+        </configstring>
+       </case>
+      </configswitch>
+      <configstring name="hostspec" desc="The hostname of the LDAP server">
+      localhost</configstring>
+      <configinteger name="port" desc="The port of the LDAP server">
+      389</configinteger>
+      <configenum name="version" desc="LDAP Protocol Version">3
+       <values>
+        <value desc="LDAPv2 (Deprecated)">2</value>
+        <value desc="LDAPv3">3</value>
+       </values>
+      </configenum>
+      <configstring name="basedn" desc="The base DN for LDAP preference
+      searches"/>
+      <configstring name="searchdn" required="false" desc="DN with which to
+      bind for searches - blank for anonymous"/>
+      <configstring name="searchpw" required="false"  desc="Password with
+      which to bind for searches - blank for anonymous"/>
+      <configswitch name="writedn" desc="Bind to LDAP as which user when
+      writing permissions to LDAP">
+        <case name="user" desc="Bind as User" />
+        <case name="admin" desc="Bind as Admin">
+          <configstring name="admindn" desc="DN of the administrative account
+          with which to bind for write operations"/>
+          <configstring name="adminpw" desc="Password of the administrative
+          DN"/>
+        </case>
+        <case name="searchdn" desc="Use search credentials"/>
+      </configswitch>
+      <configstring name="uid" desc="The username search key"/>
      </configsection>
     </configsection>
    </case>
-   <case name="sql" desc="Exim mailer based SQL driver">
-    <configdescription>
-     If not using realms (multiple domains or virtual hosting) then there is
-     only one possible default configuration.
-     Even if you are using realms/hosting, you have to set a default
-     configuration.  This may be overriden by realm/domain specific values by
-     defining additional arrays, one per realm/domain, with the realm/domain
-     name as the key instead of the key 'default'. This not possible with this
-     interface though.
-    </configdescription>
+
+   <case name="mdaemon" desc="MDaemon mail server driver">
     <configsection name="params">
      <configsection name="default">
-      <configsql switchname="driverconfig">
-       <configstring name="table" desc="Database table">users</configstring>
-       <configstring name="user_col" desc="Column which contains user names">user</configstring>
-       <configstring name="pass_col" desc="Column with passwords">password</configstring>
-       <configstring name="altemail" desc="Alternative email column name"/>
-       <configstring name="forward" desc="Email forward yes or no"/>
-      </configsql>
+      <configstring name="location" desc="Directory where MDaemon is
+      installed"/>
      </configsection>
     </configsection>
    </case>
-   <case name="ldap" desc="Exim mailer based LDAP driver">
-    <configdescription>
-     If not using realms (multiple domains or virtual hosting) then there is
-     only one possible default configuration.
-     Even if you are using realms/hosting, you have to set a default
-     configuration.  This may be overriden by realm/domain specific values by
-     defining additional arrays, one per realm/domain, with the realm/domain
-     name as the key instead of the key 'default'. This not possible with this
-     interface though.
-    </configdescription>
+
+   <case name="plesk" desc="Plesk driver">
     <configsection name="params">
      <configsection name="default">
-      <configstring name="host" desc="Hostname where the LDAP server is running on">localhost</configstring>
-      <configinteger name="port" desc="Port that the LDAP server is using">389</configinteger>
-      <configinteger name="version" required="false" desc="LDAP version">2</configinteger>
-      <configstring name="basedn" desc="Basedn">ou=mailaccount,dc=example,dc=com</configstring>
-      <configstring name="userdn" required="false" desc="Userdn"></configstring>
-      <configstring name="realm" required="false" desc="Realm"></configstring>
-      <configstring name="uid" desc="The attribute that is searched for the user ID">uid</configstring>
-      <configstring name="forwards" desc="The attribute that defines where the mail should go">mailforward</configstring>
+      <configphp name="host" desc="Hostname where the Plesk server is running
+       on">$_SERVER['SERVER_NAME']</configphp>
+      <configstring name="user" desc="Administrator or client user"/>
+      <configstring name="pass" desc="Password"/>
      </configsection>
     </configsection>
    </case>
 
-   <case name="customsql" desc="Custom SQL based forwarding driver">
-    <configsection name="params">
-     <configsql switchname="driverconfig"/>
-     <configdescription>
-       This driver allows for custom SQL queries into which variables
-       will be substituted. The current FULL username will be provided as \U,
-       target address will be provided as \T, the given password will be
-       provided as \P, and the option to keep a local copy of forwarded
-       addresses will be a "Y" or "N" value provided as \L. If the query
-       to check the forwarding status returns no rows, it will be assumed
-       that forwarding is not enabled.
-     </configdescription>
-     <configstring name="query_select" desc="Query to retrieve forwarding status"/>
-     <configstring name="query_set" desc="Query to set forwarding address"/>
-     <configstring name="query_disable" desc="Query to disable forwarding"/>
-     <configstring name="column_target" desc="Column specifying the target forwarding address"/>
-     <configstring name="column_keeplocal" desc="Column telling us if we are keeping a local copy"/>
-    </configsection>
-   </case>
-
    <case name="soap" desc="SOAP based forwarding driver">
     <configsection name="params">
      <configdescription>
@@ -140,13 +166,20 @@
      </configdescription>
      <configstring name="soap_proxy" desc="address of the soap server"/>
      <configstring name="soap_uri" desc="Namespace"/>
-     <configstring name="fwd_fetch_func" desc="name of the SOAP function to get current settings"/>
-     <configstring name="fwd_enable_func" desc="name of the SOAP function to set forwarding"/>
-     <configstring name="fwd_disable_func" desc="name of the SOAP function to reset forwarding"/>
-     <configstring name="username_varname" desc="SOAP argument name holding the mailbox"/>
-     <configstring name="password_varname" required="false" desc="SOAP argument name holding the password"/>
-     <configstring name="target_varname" desc="SOAP argument name holding the target email address"/>
-     <configstring name="keeplocal_varname" desc="SOAP argument name holding whether or not to keep a local copy"/>
+     <configstring name="fwd_fetch_func" desc="name of the SOAP function to
+     get current settings"/>
+     <configstring name="fwd_enable_func" desc="name of the SOAP function to
+     set forwarding"/>
+     <configstring name="fwd_disable_func" desc="name of the SOAP function to
+     reset forwarding"/>
+     <configstring name="username_varname" desc="SOAP argument name holding
+     the mailbox"/>
+     <configstring name="password_varname" required="false" desc="SOAP
+     argument name holding the password"/>
+     <configstring name="target_varname" desc="SOAP argument name holding the
+     target email address"/>
+     <configstring name="keeplocal_varname" desc="SOAP argument name holding
+     whether or not to keep a local copy"/>
     </configsection>
    </case>
   </configswitch>
@@ -154,18 +187,25 @@
 
  <configsection name="enabled">
   <configheader>General Options</configheader>
-  <configboolean name="keeplocal" desc="Setting this option will allow a user the choice of keeping a local copy of forwarded mail.">true</configboolean>
-  <configboolean name="authenticate" desc="Setting this option will force the user to provide a password.">true</configboolean>
+  <configboolean name="keeplocal" desc="Setting this option will allow a user
+  the choice of keeping a local copy of forwarded mail.">true</configboolean>
+  <configboolean name="authenticate" desc="Setting this option will force the
+  user to provide a password.">true</configboolean>
+  <configboolean name="fullemail" desc="Use the full email address as the user
+  ID?">true</configboolean>
  </configsection>
 
  <configsection name="user">
   <configheader>Refused user names</configheader>
-   <configlist name="refused" desc="Define usernames for which we will refuse to forward mails.">root,bin,daemon,adm,lp,shutdown,halt,uucp,ftp,anonymous,nobody,httpd,operator,guest,diginext,bind,cyrus,courier,games,kmem,mailnull,man,mysql,news,postfix,sshd,tty,www</configlist>
+   <configlist name="refused" desc="Define usernames for which we will refuse
+   to forward
+   mails.">root,bin,daemon,adm,lp,shutdown,halt,uucp,ftp,anonymous,nobody,httpd,operator,guest,diginext,bind,cyrus,courier,games,kmem,mailnull,man,mysql,news,postfix,sshd,tty,www</configlist>
  </configsection>
 
  <configsection name="menu">
   <configheader>Menu Settings</configheader>
-  <configmultienum name="apps" desc="Select any applications that should be linked in Forward's menu">
+  <configmultienum name="apps" desc="Select any applications that should be
+  linked in Forward's menu">
    <values>
     <configspecial name="list-horde-apps" />
    </values>
diff --git a/docs/CHANGES b/docs/CHANGES
index bc94937..682497e 100644
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -1,3 +1,13 @@
+----
+v3.1
+----
+
+[jan] Add Plesk driver.
+[bak] Rewrite LDAP driver to support qmail-ldap, SunONE and Exim.
+[jan] Add SSL option to ftp and qmail drivers (Request #5511).
+[jan] Add Turkish translation (METU <horde-tr at metu.edu.tr>).
+
+
 ------
 v3.0.1
 ------
diff --git a/docs/CREDITS b/docs/CREDITS
index 08058da..20d618f 100644
--- a/docs/CREDITS
+++ b/docs/CREDITS
@@ -33,28 +33,33 @@ Localization
 ============
 
 =====================   ======================================================
+Brazilian Portuguese    João César Marigonda <joao at webnow.com.br>
+                        Gestores da Rede Academica de Computacão
+                        <graco at dcc.ufba.br>
 Chinese (Traditional)   David Chang <david at tmv.gov.tw>
 Czech                   Pavel Chytil <pavel at chytil.tk>
-Danish                  Espen Jürgensen <espen at hhkol.dk>
+Danish                  Espen Jürgensen <espen at hhkol.dk>
                         Brian Truelsen <horde+i18n at briantruelsen.dk>
 Finnish                 Tero Matinlassi <terom at iki.fi>
 French                  Daniel Huhardeaux <daniel.huhardeaux at tootai.com>
-                        Benoit St-André
+                        Benoit St-André
                         Pierre Lachance <pl at pierrelachance.net>
 Galician                Rafael Varela <rafael.varela at usc.es>
                         Guillermo Mendez <guille at usc.es>
 German                  Jens A Tkotz <jens.tkotz at f2h9.de>
                         Jan Schneider <jan at horde.org>
-Hungarian               Matin Tamás <matintom at web.de>
+Hungarian               Matin Tamás <matintom at web.de>
 Italian                 Alessio Ciregia <alessio at ifc.cnr.it>
+                        Fabio Pedretti <fabio.pedretti at ing.unibs.it>
 Norwegian Nynorsk       Per-Stian Vatne <psv at orsta.org>
 Persian                 MetaNET Amirkabir <persian-horde at metanetworking.com>
 Polish                  Piotr Kuczynski <pkuczynski at hypode.pl>
-Portuguese              João César Marigonda <joao at webnow.com.br>
+Portuguese              João César Marigonda <joao at webnow.com.br>
 Romanian                Marius Dragulescu <mariusd at urban-grafx.ro>
                         Eugen Hoanca <eugenh at urban-grafx.ro>
 Russian                 Dmitriy MiksIr <miksir at maker.ru>
 Spanish                 Manuel Perez Ayala <mayala at unex.es>
+Turkish                 Middle East Technical University <horde-tr at metu.edu.tr>
 =====================   ======================================================
 
 
diff --git a/docs/INSTALL b/docs/INSTALL
index 0020a70..1603673 100644
--- a/docs/INSTALL
+++ b/docs/INSTALL
@@ -2,8 +2,8 @@
  Installing Forwards 3.0
 =========================
 
-:Last update:   $Date: 2006/03/30 10:15:29 $
-:Revision:      $Revision: 1.16.2.2 $
+:Last update:   $Date: 2008/10/09 17:36:36 $
+:Revision:      $Revision: 1.16.2.3 $
 :Contact:       sork at lists.horde.org
 
 .. contents:: Contents
@@ -211,9 +211,8 @@ subscription information can be found at
 
   http://www.horde.org/mail/
 
-Lastly, Horde developers, contributors and users also make occasional
-appearances on IRC, on the channel #horde on the Freenode Network
-(irc.freenode.net).
+Lastly, Horde developers, contributors and users may also be found on IRC,
+on the channel #horde on the Freenode Network (irc.freenode.net).
 
 Please keep in mind that Forwards is free software written by volunteers.
 For information on reasonable support expectations, please read
diff --git a/docs/RELEASE_NOTES b/docs/RELEASE_NOTES
index b8b6f51..d62bb16 100644
--- a/docs/RELEASE_NOTES
+++ b/docs/RELEASE_NOTES
@@ -17,27 +17,28 @@ $this->notes['fm']['focus'] = 4;
 /* Mailing list release notes. */
 $this->notes['ml']['changes'] = <<<ML
 The Horde Team is pleased to announce the final release of the Forwards Email
-Forwarding Manager version H3 (3.0.1).
+Forwarding Manager version H3 (3.1).
 
 Forwards is a Horde module for setting user email forwards via the .forward
 mechanism supported by several popular mailers.
 
-Right now, Forwards provides fairly complete support for setting .forward
-style forwards on Sendmail, Courier, or Qmail mail based systems via an FTP
-transport. It now also has drivers for Mdaemon, Exim SQL, Exim LDAP, Custom
-SQL, and SOAP based systems.
+Forwards provides fairly complete support for setting .forward style forwards on
+Sendmail, Courier, or Qmail mail based systems via an FTP transport. It now also
+has drivers for Mdaemon, Exim SQL, Exim LDAP, Qmail LDAP, SunONE LDAP, Plesk,
+Custom SQL, and SOAP based systems.
 
-The major changes compared to the Forwards H3 (3.0) version are:
-    * Switched to BSD-like license.
-    * Added Russian translation.
-    * Updated German and Traditional Chinese translations.
+The major changes compared to the Forwards 3.0 versions are:
+    * A Plesk forwards driver
+    * The LDAP driver supports qmail-ldap, SunONE, and Exim
+    * The FTP and qmail drivers support SSL
+    * Added a Turkish translation
 ML;
 
 /* Freshmeat release notes. */
 $this->notes['fm']['changes'] = <<<FM
-The license has been switched a BSD-like license.
-A Russian translation has been added and German and Traditional Chinese
-translations have been updated.
+Forwards now includes a Plesk driver, LDAP drivers for qmail-ldap, SunONE, and
+Exim, and supports SSL for FTP and qmail drivers. This release also includes a
+Turkish translation.
 FM;
 
 $this->notes['name'] = 'Forwards';
diff --git a/docs/TODO b/docs/TODO
index 8b6181f..f2fdc41 100644
--- a/docs/TODO
+++ b/docs/TODO
@@ -2,8 +2,8 @@
  Forwards Development TODO List
 ================================
 
-:Last update:   $Date: 2006/02/16 17:10:45 $
-:Revision:      $Revision: 1.10 $
+:Last update:   $Date: 2008/10/09 17:36:36 $
+:Revision:      $Revision: 1.10.2.1 $
 :Contact:       sork at lists.horde.org
 
 - Merge functionality into Ingo.
diff --git a/index.php b/index.php
index c337d9b..2b4b9e7 100644
--- a/index.php
+++ b/index.php
@@ -1,15 +1,17 @@
 <?php
 /**
- * $Horde: forwards/index.php,v 1.17.2.2 2007/01/02 13:54:05 jan Exp $
+ * $Horde: forwards/index.php,v 1.17.2.4 2009/01/06 15:22:46 jan Exp $
  *
- * Copyright 2001-2007 Eric Rostetter <eric.rostetter at physics.utexas.edu>
+ * Copyright 2001-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (BSDL). If you
  * did not receive this file, see http://www.horde.org/licenses/bsdl.php.
+ *
+ * @author Eric Rostetter <eric.rostetter at physics.utexas.edu>
  */
 
 @define('FORWARDS_BASE', dirname(__FILE__));
-$forwards_configured = (@is_readable(FORWARDS_BASE . '/config/conf.php'));
+$forwards_configured = (is_readable(FORWARDS_BASE . '/config/conf.php'));
 
 if (!$forwards_configured) {
     require FORWARDS_BASE . '/../lib/Test.php';
diff --git a/lib/Block/summary.php b/lib/Block/summary.php
index d4f6d61..92f2d5b 100644
--- a/lib/Block/summary.php
+++ b/lib/Block/summary.php
@@ -3,7 +3,7 @@
 $block_name = _("Forwards Summary");
 
 /**
- * $Horde: forwards/lib/Block/summary.php,v 1.7 2005/09/09 04:33:25 chuck Exp $
+ * $Horde: forwards/lib/Block/summary.php,v 1.7.2.1 2008/10/09 17:36:37 jan Exp $
  *
  * @package Horde_Block
  */
diff --git a/lib/Driver.php b/lib/Driver.php
old mode 100644
new mode 100755
index cf0ff03..596cba4
--- a/lib/Driver.php
+++ b/lib/Driver.php
@@ -3,165 +3,180 @@
  * Forwards_Driver:: defines an API for implementing forwarding backends
  * for Forwards.
  *
- * $Horde: forwards/lib/Driver.php,v 1.29.2.2 2007/01/02 13:54:05 jan Exp $
+ * $Horde: forwards/lib/Driver.php,v 1.29.2.4 2009/01/06 15:22:46 jan Exp $
  *
- * Copyright 2001-2007 Mike Cochrane <mike at graftonhall.co.nz>
+ * Copyright 2001-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (BSDL). If you
  * did not receive this file, see http://www.horde.org/licenses/bsdl.php.
  *
  * @author  Mike Cochrane <mike at graftonhall.co.nz>
+ * @author  Jan Schneider <jan at horde.org>
  * @since   Forwards 2.1
  * @package Forwards
  */
 class Forwards_Driver {
 
     /**
-     * Hash containing configuration data.
+     * The current user name.
      *
-     * @var array
+     * @var string
      */
-    var $_params;
+    var $_user;
 
     /**
-     * The error string returned to the user if an error occurs.
+     * The user's realm.
      *
      * @var string
      */
-    var $_error = '';
+    var $_realm;
+
+    /**
+     * Hash containing configuration data.
+     *
+     * @var array
+     */
+    var $_params;
 
     /**
-     * Constructs a new Forwards_Driver object.
+     * Constructor.
      *
+     * @param string $user   A user name.
+     * @param string $realm  The realm of the user.
      * @param array $params  A hash containing connection parameters.
      */
-    function Forwards_Driver($params = null)
+    function Forwards_Driver($user, $realm, $params = null)
     {
         if (is_null($params)) {
             $params = Horde::getDriverConfig('server', null);
         }
         $this->_params = $params;
+        $this->_user = $user;
+        if (!isset($params[$realm])) {
+            $realm = 'default';
+        }
+        $this->_realm = $realm;
     }
 
     /**
-     * Gets the error message.
+     * Returns the current user.
      *
-     * @return string  The error message.
+     * @return string  The current user name.
      */
-    function getError()
+    function getUser()
     {
-        return $this->_error;
+        return $this->_user;
     }
 
     /**
      * Begins forwarding of mail for a user.
      *
-     * @param string $user        The username of the user.
-     * @param string $realm       The realm of the user.
+     * @abstract
+     *
      * @param string $password    The password of the user.
      * @param string $target      The email address that mail should be
      *                            forwarded to.
      * @param boolean $keeplocal  Keep a copy of forwarded mail in the local
      *                            mailbox.
-     *
-     * @return boolean  True on success, false otherwise.
      */
-    function enableForwarding($user, $realm = 'default', $password = '',
-                              $target, $keeplocal = false)
+    function enableForwarding($password, $target, $keeplocal = false)
     {
-        return false;
+        return PEAR::raiseError('Abstract method enableForwarding() not implemented');
     }
 
     /**
      * Stops forwarding of mail for a user.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
-     * @param string $password  The password of the user.
+     * @abstract
      *
-     * @return boolean  True on success, false otherwise.
+     * @param string $password  The password of the user.
      */
-    function disableForwarding($user, $realm = 'default', $password = '')
+    function disableForwarding($password)
     {
-        return false;
+        return PEAR::raiseError('Abstract method disableForwarding() not implemented');
     }
 
     /**
      * Retrieves current state of mail redirection for a user.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
+     * @abstract
+     *
      * @param string $password  The password of the user.
      *
-     * @return boolean  True if forwarding is enabled, false otherwise.
+     * @return mixed  Returns 'Y' if forwarding is enabled for the user, 'N' if
+     *                forwarding is currently disabled, false if the status
+     *                cannot be determined, and PEAR_Error on error.
      */
-    function isEnabledForwarding($user, $realm = 'default', $password)
+    function isEnabledForwarding($password)
     {
-        return false;
+        return PEAR::raiseError('Abstract method disableForwarding() not implemented');
     }
 
     /**
      * Checks if user is keeping a local copy of forwarded mail.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
+     * @abstract
+     *
      * @param string $password  The password of the user.
      *
      * @return boolean  True if user is keeping a local copy of mail,
      *                  otherwise false.
      */
-    function isKeepLocal($user, $realm = 'default', $password)
+    function isKeepLocal($password)
     {
-        return false;
+        return PEAR::raiseError('Abstract method isKeepLocal() not implemented');
     }
 
     /**
      * Retrieves current target of mail redirection for a user.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
+     * @abstract
+     *
      * @param string $password  The password of the user.
      *
-     * @return string  The current forwarding mail address, or false on error.
+     * @return string  The current forwarding mail address, or PEAR_Error on
+     *                 error.
      */
-    function currentTarget($user, $realm = 'default', $password)
+    function currentTarget($password)
     {
-        return false;
+        return PEAR::raiseError('Abstract method currentTarget() not implemented');
     }
 
     /**
-     * Parse an email address list and return it in a known standard form.
-     * This will attempt to add the domain (realm) to unqualified addresses
-     * if the realm is non-blank and not 'default'.
+     * Parses an email address list and returns it in a known standard form.
+     *
+     * This will attempt to add the domain (realm) to unqualified addresses if
+     * the realm is non-blank and not 'default'.
      *
      * @param string $user   The email address.
      * @param string $realm  The domain/realm to add if none is present.
      *
-     * @return string  The email address(es), or false on error.
+     * @return string  The email address(es) on success, false on error.
      */
-    function _make_email_address($user, $realm)
+    function _makeEmailAddress($user)
     {
-        $domain = ($realm != 'default') ? $realm : '';
+        $domain = $this->_realm != 'default' ? $this->_realm : '';
         $email = '';
 
         require_once 'Mail/RFC822.php';
-        $parser = &new Mail_RFC822();
-        $parsed_email = $parser->parseAddressList($user, $domain, false);
-        if (is_array($parsed_email) && count($parsed_email) > 0) {
-            for ($i=0; $i < count($parsed_email); $i++) {
-               $email .= !empty($email) ? ',' : '';
-               if (is_object($parsed_email[$i])) {
-                 $email .= $parsed_email[$i]->mailbox;
-                 $email .= !empty($parsed_email[$i]->host)
-                        ? '@' . $parsed_email[$i]->host
-                        : '';
-              } else {
-                 $email .= $parsed_email[$i];
-              }
+        $parser = new Mail_RFC822();
+        $parsed_email = $parser->parseAddressList($user, $domain, false, false);
+        if (!is_array($parsed_email) || !count($parsed_email)) {
+            return PEAR::raiseError(_("Cannot parse your email address"));
+        }
+
+        for ($i = 0; $i < count($parsed_email); $i++) {
+            if (!empty($email)) {
+                $email .= ',';
+            }
+            if (is_object($parsed_email[$i])) {
+                $email .= $parsed_email[$i]->mailbox;
+                if (!empty($parsed_email[$i]->host)) {
+                    $email .=  '@' . $parsed_email[$i]->host;
+                }
+            } else {
+                $email .= $parsed_email[$i];
             }
-        } else {
-            $this->_error = _("Can't parse your email address");
-            $email = false;
         }
 
         return $email;
@@ -170,6 +185,8 @@ class Forwards_Driver {
     /**
      * Gets a concrete Forwards_Driver instance.
      *
+     * @param string $user    A user name.
+     * @param string $realm   The realm of the user.
      * @param string $driver  The type of concrete Forwards_Driver subclass to
      *                        return.  The code for the driver is dynamically
      *                        included.
@@ -179,66 +196,20 @@ class Forwards_Driver {
      * @return Forwards_Driver  The newly created concrete Forwards_Driver
      *                          instance, or false on error.
      */
-    function &factory($driver = null, $params = null)
+    function factory($user, $realm, $driver = null, $params = null)
     {
         if (is_null($driver)) {
             $driver = $GLOBALS['conf']['server']['driver'];
         }
-
         $driver = basename($driver);
 
         include_once dirname(__FILE__) . '/Driver/' . $driver . '.php';
         $class = 'Forwards_Driver_' . $driver;
         if (class_exists($class)) {
-            $forwards = &new $class($params);
-        } else {
-            $forwards = false;
+            return new $class($user, $realm, $params);
         }
 
-        return $forwards;
-    }
-
-    /**
-     * Gets a reference to a concrete Forwards_Driver instance.
-     *
-     * It will only create a new instance if no Forwards_Driver instance with
-     * the same parameters currently exists.
-     *
-     * This should be used if multiple storage sources are required.
-     *
-     * This method must be invoked as follows:<pre>
-     *   $var = &Forwards_Driver::singleton();</pre>
-     *
-     * @param string $driver  The type of concrete Forwards_Driver subclass to
-     *                        The code for the driver is dynamically included.
-     * @param array $params   A hash containing any additional configuration or
-     *                        connection parameters a a subclass might need.
-     *
-     * @return Forwards_Driver  The created concrete Forwards_Driver instance,
-     *                          or false on error.
-     */
-    function &singleton($driver = null, $params = null)
-    {
-        static $instances;
-
-        if (is_null($driver)) {
-            $driver = $GLOBALS['conf']['server']['driver'];
-        }
-
-        if (is_null($params)) {
-            $params = Horde::getDriverConfig('server', $driver);
-        }
-
-        if (!isset($instances)) {
-            $instances = array();
-        }
-
-        $signature = serialize(array($driver, $params));
-        if (!isset($instances[$signature])) {
-            $instances[$signature] = &Forwards_Driver::factory($driver, $params);
-        }
-
-        return $instances[$signature];
+        return false;
     }
 
 }
diff --git a/lib/Driver/customsql.php b/lib/Driver/customsql.php
index 726e0c6..27fbfec 100644
--- a/lib/Driver/customsql.php
+++ b/lib/Driver/customsql.php
@@ -2,7 +2,7 @@
 /**
  * Forwards_Driver_sql:: implements the Forwards_Driver API for SQL servers.
  *
- * $Horde: forwards/lib/Driver/customsql.php,v 1.13.2.3 2007/01/02 13:54:06 jan Exp $
+ * $Horde: forwards/lib/Driver/customsql.php,v 1.13.2.5 2009/01/24 15:26:34 chuck Exp $
  *
  * Copyright 2004-2007 Kendrick Vargas <ken at hudat.com>
  *
@@ -10,6 +10,7 @@
  * did not receive this file, see http://www.horde.org/licenses/bsdl.php.
  *
  * @author  Kendrick Vargas <ken at hudat.com>
+ * @author  Jan Schneider <jan at horde.org>
  * @since   Forwards 3.0
  * @package Forwards
  */
@@ -30,276 +31,296 @@ class Forwards_Driver_customsql extends Forwards_Driver {
     var $_connected = false;
 
     /**
-     * Constructs a new Forwards_Driver_customsql object.
+     * List of required parameters.
      *
+     * @var array
+     */
+    var $_requiredParams = array('phptype', 'query_select', 'query_set',
+                                 'query_disable', 'column_target',
+                                 'column_keeplocal');
+
+    /**
+     * Constructor.
+     *
+     * @param string $user   A user name.
+     * @param string $realm  The realm of the user.
      * @param array $params  A hash containing connection parameters.
      */
-    function Forwards_Driver_customsql($params = null)
+    function Forwards_Driver_customsql($user, $realm, $params = null)
     {
         if (is_null($params)) {
             $params = Horde::getDriverConfig('server', 'sql');
         }
-        parent::Forwards_Driver($params);
+        parent::Forwards_Driver($user, $realm, $params);
     }
 
     /**
-     * Disconnect from the SQL server and clean up the connection.
+     * Begins forwarding of mail for a user.
      *
-     * @return boolean  True on success, false otherwise.
+     * @param string $password    The password of the user.
+     * @param string $target      The email address that mail should be
+     *                            forwarded to.
+     * @param boolean $keeplocal  Keep a copy of forwarded mail in the local
+     *                            mailbox.
      */
-    function _disconnect()
+    function enableForwarding($password, $target, $keeplocal)
     {
-        if ($this->_connected) {
-            $this->_connected = false;
-            return $this->_db->disconnect();
-        }
-
-        return true;
+        return $this->_enableForwarding($this->_params['query_set'], $password,
+                                        $target, $keeplocal);
     }
 
     /**
-     * Begins forwarding of mail for a user.
+     * Execute the query that begins forwarding of mail for a user.
      *
-     * @param string $user        The username of the user.
-     * @param string $realm       The realm of the user.
+     * @param string $query       The query to execute, including placeholders.
      * @param string $password    The password of the user.
      * @param string $target      The email address that mail should be
      *                            forwarded to.
      * @param boolean $keeplocal  Keep a copy of forwarded mail in the local
      *                            mailbox.
-     *
-     * @return boolean  True on success, false otherwise.
      */
-    function enableForwarding($user, $realm, $password, $target, $keeplocal)
+    function _enableForwarding($query, $password, $target, $keeplocal = null)
     {
-        // _connect() will die with Horde::fatal() upon failure.
-        $this->_connect();
-        $keeplocal = ($keeplocal == 'on') ? 'Yes' : 'No';
+        // Connect to database.
+        if (is_a($connected = $this->_connect(), 'PEAR_Error')) {
+            return $connected;
+        }
 
         // Build the SQL query.
-        $query = $this->_params['query_set'];
-        $query = str_replace("\U", $this->_db->quote(Auth::getAuth()), $query);
-        $query = str_replace("\T", $this->_db->quote($target), $query);
-        $query = str_replace("\L", $this->_db->quote($keeplocal), $query);
-        $query = str_replace("\P", $this->_db->quote($password), $query);
+        $query = str_replace(
+            array('\U', '\T', '\L', '\P'),
+            array($this->_db->quote($this->_buildUsername()),
+                  $this->_db->quote($target),
+                  $this->_db->quote($keeplocal == 'on' ? 'Y' : 'N'),
+                  $this->_db->quote($password)),
+            $query);
 
         // Execute the query.
         $result = $this->_db->query($query);
-
-        if (!is_a($result, 'PEAR_Error')) {
-            if ($result === DB_OK) {
-                $this->_disconnect();
-                return true;
-            }
+        if (is_a($result, 'PEAR_Error')) {
+            return $result;
+        }
+        if ($result !== DB_OK) {
+            return PEAR::raiseError(_("An unknown error occured while enabling forwarding."));
         }
-
-        $this->_disconnect();
-        return false;
     }
 
     /**
      * Stops forwarding of mail for a user.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
      * @param string $password  The password of the user.
+     */
+    function disableForwarding($password)
+    {
+        return $this->_disableForwarding($this->_params['query_disable'],
+                                         $password);
+    }
+
+    /**
+     * Execute the query that stops forwarding of mail for a user.
      *
-     * @return boolean  True on success, false otherwise.
+     * @param string $query     The query to execute, including placeholders.
+     * @param string $password  The password of the user.
      */
-    function disableForwarding($user, $realm, $password)
+    function _disableForwarding($query, $password)
     {
-        // _connect() will die with Horde::fatal() upon failure.
-        $this->_connect();
+        // Connect to database.
+        if (is_a($connected = $this->_connect(), 'PEAR_Error')) {
+            return $connected;
+        }
+
+        // Build username.
+        $myuser = $this->_buildUsername();
 
         // Build the SQL query.
-        $query = $this->_params['query_disable'];
-        $query = str_replace("\U", $this->_db->quote(Auth::getAuth()), $query);
-        $query = str_replace("\P", $this->_db->quote($password), $query);
+        $query = str_replace(array('\U', '\P'),
+                             array($this->_db->quote($this->_buildUsername()),
+                                   $this->_db->quote($password)),
+                             $query);
 
         // Execute the query.
         $result = $this->_db->query($query);
-
-        if (!is_a($result, 'PEAR_Error')) {
-            if ($result === DB_OK) {
-                $this->_disconnect();
-                return true;
-            }
+        if (is_a($result, 'PEAR_Error')) {
+            return $result;
+        }
+        if ($this->_db->affectedRows() == 0) {
+            return PEAR::raiseError(_("The forwarding cannot be disabled. Check the password."));
+        }
+        if ($result !== DB_OK) {
+            return PEAR::raiseError(_("An unknown error occured while disabling forwarding."));
         }
-
-        $this->_disconnect();
-        return false;
     }
 
     /**
      * Retrieves current state of mail redirection for a user.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
      * @param string $password  The password of the user.
      *
-     * @return mixed  'Y' if forwarding is enabled, or false.
+     * @return mixed  Returns 'Y' if forwarding is enabled for the user, 'N' if
+     *                forwarding is currently disabled, false if the status
+     *                cannot be determined, and PEAR_Error on error.
      */
-    function isEnabledForwarding($user, $realm, $password)
+    function isEnabledForwarding($password)
     {
         // Build username.
-        $myuser = $this->_buildUsername($user, $realm);
+        $myuser = $this->_buildUsername();
 
         // Get current details.
-        $current_details = $this->_getUserDetails($myuser, $realm, $password);
-        if ($current_details === false) {
-            return false;
-        } else {
-            return 'Y';
+        $current_details = $this->_getUserDetails($password);
+        if ($current_details === false ||
+            is_a($current_details, 'PEAR_Error')) {
+            return $current_details;
         }
+
+        return 'Y';
     }
 
     /**
      * Checks if user is keeping a local copy of forwarded mail.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
      * @param string $password  The password of the user.
      *
      * @return boolean  True if user is keeping a local copy of mail,
      *                  otherwise false.
      */
-    function isKeepLocal($user, $realm, $password)
+    function isKeepLocal($password)
     {
-        // Build username.
-        $myuser = $this->_buildUsername($user, $realm);
-
         // Get current details.
-        $current_details = $this->_getUserDetails($myuser, $realm, $password);
-        if ($current_details === false) {
-            return false;
+        $current_details = $this->_getUserDetails($password);
+        if ($current_details === false ||
+            is_a($current_details, 'PEAR_Error')) {
+            return $current_details;
         }
 
         // Check retain copy flag.
-        if (substr($current_details[$this->_params['column_keeplocal']], 0, 1) == 'Y') {
-            return true;
-        } else {
-            return false;
-        }
+        return substr($current_details[$this->_params['column_keeplocal']], 0, 1) == 'Y';
     }
 
     /**
      * Retrieves current target of mail redirection for a user.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
      * @param string $password  The password of the user.
      *
-     * @return string  The current forwarding mail address, or false on error.
+     * @return string  The current forwarding mail address, false if no
+     *                 forwarding is set, or PEAR_Error on error.
      */
-    function currentTarget($user, $realm, $password)
+    function currentTarget($password)
     {
-        $current_details = $this->_getUserDetails($user, $realm, $password);
+        $current_details = $this->_getUserDetails($password);
+        if ($current_details === false ||
+            is_a($current_details, 'PEAR_Error')) {
+            return $current_details;
+        }
 
         // Check current forwarding mail address.
-        $target = $current_details[$this->_params['column_target']];
-        return $target;
+        return $current_details[$this->_params['column_target']];
     }
 
     /**
      * Retrieves user details from the backend.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
      * @param string $password  The password of the user.
      *
-     * @return mixed  Hash with user details, or false.
+     * @return array  Hash with user details, or PEAR_Error.
      */
-    function _getUserDetails($user, $realm, $password)
+    function _getUserDetails($password)
     {
-        // _connect() will die with Horde::fatal() upon failure.
-        $this->_connect();
+        static $row;
+
+        // If we already have the details, return now.
+        if (isset($row)) {
+            return $row;
+        }
+
+        // Connect to database.
+        if (is_a($connected = $this->_connect(), 'PEAR_Error')) {
+            return $connected;
+        }
 
         // Build the SQL query.
-        $query = $this->_params['query_select'];
-        $query = str_replace("\U", $this->_db->quote(Auth::getAuth()), $query);
-        $query = str_replace("\P", $this->_db->quote($password), $query);
+        $query = str_replace(array('\U', '\P'),
+                             array($this->_db->quote($this->_buildUsername()),
+                                   $this->_db->quote($password)),
+                             $this->_params['query_select']);
 
         // Execute the query.
         $result = $this->_db->query($query);
 
-        if (!is_a($result, 'PEAR_Error')) {
-            $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
+        if (is_a($result, 'PEAR_Error')) {
+            return $result;
+        }
 
-            $this->_disconnect();
-            if (is_array($row)) {
-                return $row;
-            } else {
-                $result->free();
-                return false;
-            }
+        $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
+        if (is_array($row)) {
+            return $row;
         }
 
-        $this->_disconnect();
         return false;
     }
 
     /**
      * Builds a username based on presence of realm.
      *
-     * @param string $user   Username.
-     * @param string $realm  Realm name.
-     *
      * @return string  Fully qualified username.
      */
-    function _buildUsername($user, $realm)
+    function _buildUsername()
     {
-        if ($realm === 'default' ||
-            $realm === '') {
-            return $user;
+        if ($this->_realm === 'default' ||
+            $this->_realm === '') {
+            return $this->_user;
         } else {
-            return $user . '@' . $realm;
+            return $this->_user . '@' . $this->_realm;
         }
     }
 
     /**
-     * Connects to SQL server and logs in as user with privilege to change
-     * password.
+     * Does an SQL connect and logs in as user with privilege to change
+     * vacation.
      *
-     * @return boolean  True on success, false otherwise.
+     * @return boolean  True or PEAR_Error based on success of connect.
      */
     function _connect()
     {
-        if (!$this->_connected) {
-            Horde::assertDriverConfig($this->_params, 'server',
-                array('phptype', 'query_select', 'query_set', 'query_disable', 'column_target', 'column_keeplocal'),
-                'Forwards SQL');
-
-            if (!isset($this->_params['database'])) {
-                $this->_params['database'] = '';
-            }
-            if (!isset($this->_params['username'])) {
-                $this->_params['username'] = '';
-            }
-            if (!isset($this->_params['hostspec'])) {
-                $this->_params['hostspec'] = '';
-            }
-
-            // Connect to SQL server using supplied parameters.
-            include_once 'DB.php';
-            $this->_db = &DB::connect($this->_params,
-                                      array('persistent' => !empty($this->_params['persistent'])));
-            if (is_a($this->_db, 'PEAR_Error')) {
-                Horde::fatal(PEAR::raiseError(_("Unable to connect to SQL server.")), __FILE__, __LINE__);
-            }
-
-            // Set DB portability options.
-            switch ($this->_db->phptype) {
-            case 'mssql':
-                $this->_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS | DB_PORTABILITY_RTRIM);
-                break;
-            default:
-                $this->_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
-            }
-
-            $this->_connected = true;
+        if ($this->_connected) {
+            return;
+        }
+
+        // Build the params array to pass to DB
+        $args = array_merge($this->_params, isset($this->_params[$this->_realm]) ? $this->_params[$this->_realm] : array());
+        Horde::assertDriverConfig($args, 'server', $this->_requiredParams, 'Forwards SQL');
+
+        if (!isset($args['database'])) {
+            $args['database'] = '';
+        }
+        if (!isset($args['username'])) {
+            $args['username'] = '';
+        }
+        if (!isset($args['hostspec'])) {
+            $args['hostspec'] = '';
+        }
+
+        // Connect to the SQL server using the supplied parameters.
+        require_once 'DB.php';
+        $this->_db = &DB::connect($args, array('persistent' => !empty($args['persistent'])));
+        if (is_a($this->_db, 'PEAR_Error')) {
+            return $this->_db;
+        }
+
+        // Set DB portability options.
+        switch ($this->_db->phptype) {
+        case 'mssql':
+            $this->_db->setOption(
+                'portability',
+                DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS | DB_PORTABILITY_RTRIM);
+            break;
+
+        default:
+            $this->_db->setOption(
+                'portability',
+                DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
         }
 
-        return true;
+        $this->_connected = true;
     }
 
 }
diff --git a/lib/Driver/forwards.php b/lib/Driver/forwards.php
old mode 100644
new mode 100755
index 938b931..e3f0dec
--- a/lib/Driver/forwards.php
+++ b/lib/Driver/forwards.php
@@ -3,20 +3,28 @@
  * Forwards_Driver_forwards:: implements the Forwards_Driver API for ftp
  * driven dot-forward compliant mail servers.
  *
- * $Horde: forwards/lib/Driver/forwards.php,v 1.36.2.3 2007/01/02 13:54:06 jan Exp $
+ * $Horde: forwards/lib/Driver/forwards.php,v 1.36.2.5 2009/01/06 15:22:46 jan Exp $
  *
- * Copyright 2001-2007 Eric Rostetter <eric.rostetter at physics.utexas.edu>
+ * Copyright 2001-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (BSDL). If you
  * did not receive this file, see http://www.horde.org/licenses/bsdl.php.
  *
  * @author  Eric Rostetter <eric.rostetter at physics.utexas.edu>
+ * @author  Jan Schneider <jan at horde.org>
  * @since   Forwards 2.1
  * @package Forwards
  */
 class Forwards_Driver_forwards extends Forwards_Driver {
 
     /**
+     * The name of the forwards file.
+     *
+     * @var string
+     */
+    var $_forwardsFile = '.forward';
+
+    /**
      * The FTP stream we open via the VFS class.
      *
      * @var VFS_ftp
@@ -24,255 +32,227 @@ class Forwards_Driver_forwards extends Forwards_Driver {
     var $_vfs;
 
     /**
-     * Checks 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!
+     * Begins forwarding of mail for a user.
      *
-     * @return boolean  True on success, false otherwise.
+     * @param string $password    The password of the user.
+     * @param string $target      The email address that mail should be
+     *                            forwarded to.
+     * @param boolean $keeplocal  Keep a copy of forwarded mail in the local
+     *                            mailbox.
      */
-    function checkConfiguration(&$realm)
+    function enableForwarding($password, $target, $keeplocal = false)
     {
-        // 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';
+        // Make sure the configuration file is correct
+        if (is_a($checked = $this->_checkConfig(), 'PEAR_Error')) {
+            return $checked;
         }
 
-        // If still no host/port, then we have a misconfigured module.
-        if (empty($this->_params[$realm]['host']) ||
-            empty($this->_params[$realm]['port'])) {
-            $this->_error = _("The module is not properly configured!");
-            return false;
+        // Connect to the server.
+        if (is_a($connected = $this->_connect($password), 'PEAR_Error')) {
+            return $connected;
         }
 
-        return true;
+        return $this->_createForwardsFile($target, $keeplocal);
     }
 
     /**
-     * Begins forwarding of mail for a user.
+     * Creates the main forwards file.
      *
-     * @param string $user        The username of the user.
-     * @param string $realm       The realm of the user.
-     * @param string $password    The password of the user.
      * @param string $target      The email address that mail should be
      *                            forwarded to.
      * @param boolean $keeplocal  Keep a copy of forwarded mail in the local
      *                            mailbox.
-     *
-     * @return boolean  True on success, false otherwise.
      */
-    function enableForwarding($user, $realm = 'default', $password, $target,
-                              $keeplocal = false)
+    function _createForwardsFile($target, $keeplocal = false)
     {
-        // Make sure the configuration file is correct
-        if (!$this->checkConfiguration($realm)) {
-            return false;
-        }
-
-        // Build the FTP array to pass to VFS.
-        $_args = array('hostspec' => $this->_params[$realm]['host'],
-                       'port' => $this->_params[$realm]['port'],
-                       'pasv' => $this->_params[$realm]['pasv'],
-                       'username' => $user,
-                       'password' => $password);
-
-        // Create the VFS ftp driver.
-        require_once 'VFS.php';
-        $_vfs = &VFS::singleton('ftp', $_args);
-        if (is_a($_vfs, 'PEAR_Error')) {
-            $this->_error = $_vfs->getMessage();
-            return false;
-        }
-
-        // Try to login with the username/password, no realm
-        // This isn't really needed, but allows for a better error message
-        $status = $_vfs->checkCredentials();
-        if (is_a($status, 'PEAR_Error')) {
-            $this->_error = $status->getMessage();
-            $this->_error .= '  ' .  _("Check your username and password");
-            return false;
-        }
-
         // Create the forwarding information
-        $address = $this->_make_email_address($target, $realm);
-        if ($address === false) {
-            return false;
+        if (is_a($address = $this->_makeEmailAddress($target), 'PEAR_Error')) {
+            return $address;
         }
 
         // Append the user if they want to save a copy to themselves...
-        if ($keeplocal == "on") {
-            $address = $address . ", \\$user";
+        if ($keeplocal == 'on') {
+            $address = $address . ', \\' . $this->_user;
         }
 
         // Set the forward
-        $status = $_vfs->writeData('', '.forward', $address);
-        if (is_a($status, 'PEAR_Error')) {
-            $this->_error = $status->getMessage();
-            return false;
+        if (is_a($status = $this->_vfs->writeData('', '.forward', $address), 'PEAR_Error')) {
+            return $status;
         }
 
         // Try to change the permissions, but ignore any errors
-        $_vfs->changePermissions('', '.forward', '0600');
-
-        return true;
+        $this->_vfs->changePermissions('', '.forward', '0600');
     }
 
     /**
      * Stops forwarding of mail for a user.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
      * @param string $password  The password of the user.
-     *
-     * @return boolean  True on success, false otherwise.
      */
-    function disableForwarding($user, $realm = 'default', $password)
+    function disableForwarding($password)
     {
-        if (!$this->checkConfiguration($realm)) {
-            return false;
+        // Make sure the configuration file is correct
+        if (is_a($checked = $this->_checkConfig(), 'PEAR_Error')) {
+            return $checked;
         }
 
-        $_args = array('hostspec' => $this->_params[$realm]['host'],
-                       'port' => $this->_params[$realm]['port'],
-                       'pasv' => $this->_params[$realm]['pasv'],
-                       'username' => $user,
-                       'password' => $password);
+        // Connect to the server.
+        if (is_a($connected = $this->_connect($password), 'PEAR_Error')) {
+            return $connected;
+        }
 
-        require_once 'VFS.php';
-        $_vfs = &VFS::singleton('ftp', $_args);
+        if (is_a($status = $this->_vfs->deleteFile('', $this->_forwardsFile), 'PEAR_Error')) {
+            $status->message .= '  '
+                . _("Maybe you didn't have a vacation notice installed?");
+            return $status;
+        }
+    }
 
-        // Try to login with the username/password, no realm.
-        $status = $_vfs->checkCredentials();
-        if (is_a($status, 'PEAR_Error')) {
-            $this->_error = $status->getMessage();
-            $this->_error .= '  ' .  _("Check your username and password");
-            return false;
+    /**
+     * Retrieves current state of mail redirection for a user.
+     *
+     * @TODO FIXME: This function is implemented poorly, and should be
+     * rewritten.
+     *
+     * @param string $password  The password of the user.
+     *
+     * @return mixed  Returns 'Y' if forwarding is enabled for the user, 'N' if
+     *                forwarding is currently disabled, false if the status
+     *                cannot be determined, and PEAR_Error on error.
+     */
+    function isEnabledForwarding($password)
+    {
+        $yn = $this->currentTarget($password);
+        if (is_a($yn, 'PEAR_Error')) {
+            return $yn;
         }
+        if ($yn) {
+            return 'Y';
+        }
+        return false;
+    }
 
-        $status = $_vfs->deleteFile('', '.forward');
-        if (is_a($status, 'PEAR_Error')) {
-            $this->_error = $status->getMessage();
-            $this->_error .= '  ' .  _("Maybe you didn't have a forward enabled?");
-            return false;
+    /**
+     * Checks if user is keeping a local copy of forwarded mail.
+     *
+     * @param string $password  The password of the user.
+     *
+     * @return boolean  True if user is keeping a local copy of mail,
+     *                  otherwise false.
+     */
+    function isKeepLocal($password)
+    {
+        // Make sure the configuration file is correct
+        if (is_a($checked = $this->_checkConfig(), 'PEAR_Error')) {
+            return $checked;
+        }
+
+        // Connect to the server.
+        if (is_a($connected = $this->_connect($password), 'PEAR_Error')) {
+            return $connected;
+        }
+
+        if (is_a($status = $this->_vfs->read('', '.forward'), 'PEAR_Error')) {
+            return $status;
         }
 
-        return true;
+        return preg_match('/(^|, *)\\\\' . preg_quote($this->_user, '/') . '( *,|$)/',
+                          $status);
     }
 
     /**
      * Retrieves current target of mail redirection for a user.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
      * @param string $password  The password of the user.
      *
-     * @return mixed  The current forwarding mail address, or false.
+     * @return string  The current forwarding mail address, false if no
+     *                 forwarding is set, or PEAR_Error on error.
      */
-    function currentTarget($user, $realm = 'default', $password)
+    function currentTarget($password)
     {
-        // Make sure the configuration file is correct.
-        if (!$this->checkConfiguration($realm)) {
-            return false;
+        // Make sure the configuration file is correct
+        if (is_a($checked = $this->_checkConfig(), 'PEAR_Error')) {
+            return $checked;
         }
 
-        // Build the FTP array to pass to VFS.
-        $_args = array('hostspec' => $this->_params[$realm]['host'],
-                       'port' => $this->_params[$realm]['port'],
-                       'pasv' => $this->_params[$realm]['pasv'],
-                       'username' => $user,
-                       'password' => $password);
-
-        // Create the VFS ftp driver.
-        require_once '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->_error = $status->getMessage();
-            $this->_error .= '  ' .  _("Check your username and password");
-            return false;
+        // Connect to the server.
+        if (is_a($connected = $this->_connect($password), 'PEAR_Error')) {
+            return $connected;
         }
 
-        $status = $_vfs->read('', '.forward');
-        if (is_a($status, 'PEAR_Error')) {
-            $this->_error = $status->getMessage();
+        if (!$this->_vfs->exists('', $this->_forwardsFile)) {
             return false;
         }
+        if (is_a($status = $this->_vfs->read('', $this->_forwardsFile), 'PEAR_Error')) {
+            return $status;
+        }
 
-        return preg_replace('/ *(^|, *)\\\\' . $user . '( *, *|$)/', "", $status);
+        return $this->_parseForwardsFile($status);
     }
 
     /**
-     * Retrieves current state of mail redirection for a user.
+     * Parses the target information out of the forwards file content.
      *
-     * @TODO FIXME: This function is implemented poorly, and should be
-     * rewritten.
+     * @param string $content  The file content.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
-     * @param string $password  The password of the user.
+     * @return string  The forwards target.
+     */
+    function _parseForwardsFile($content)
+    {
+        return preg_replace('/ *(^|, *)\\\\' . preg_quote($this->_user, '/') . '( *, *|$)/',
+                            '', $content);
+    }
+
+    /**
+     * Checks if the realm has a specific configuration.
      *
-     * @return mixed  'Y' if forwarding is enabled, or false otherwise.
+     * If not, try to fall back on the default configuration. If still not a
+     * valid configuration then return an error.
      */
-    function isEnabledForwarding($user, $realm, $password)
+    function _checkConfig()
     {
-        $yn = $this->currentTarget($user, $realm, $password);
-        if ($yn) {
-            return 'Y';
-        } else {
-            return false;
+        // If no host config for the realm, then we fall back to the default
+        // realm.
+        if (empty($this->_params[$this->_realm]['host'])) {
+            $this->_realm = 'default';
+        }
+
+        // If still no host/port, then we have a misconfigured module.
+        if (empty($this->_params[$this->_realm]['host']) ||
+            empty($this->_params[$this->_realm]['port'])) {
+            return PEAR::raiseError(_("The module is not properly configured!"));
         }
     }
 
     /**
-     * Checks if user is keeping a local copy of forwarded mail.
-     *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
-     * @param string $password  The password of the user.
+     * Connects to the FTP server.
      *
-     * @return boolean  True if user is keeping a local copy of mail,
-     *                  otherwise false.
+     * @param string $password  The password to connect with.
      */
-    function isKeepLocal($user, $realm, $password)
+    function _connect($password)
     {
-        // Make sure the configuration file is correct.
-        if (!$this->checkConfiguration($realm)) {
-            return false;
+        if ($this->_vfs) {
+            return;
         }
 
         // Build the FTP array to pass to VFS.
-        $_args = array('hostspec' => $this->_params[$realm]['host'],
-                       'port' => $this->_params[$realm]['port'],
-                       'pasv' => $this->_params[$realm]['pasv'],
-                       'username' => $user,
-                       'password' => $password);
+        $args = array('hostspec' => $this->_params[$this->_realm]['host'],
+                      'port' => $this->_params[$this->_realm]['port'],
+                      'pasv' => $this->_params[$this->_realm]['pasv'],
+                      'ssl' => $this->_params[$this->_realm]['ssl'],
+                      'username' => $this->_user,
+                      'password' => $password);
 
         // Create the VFS ftp driver.
         require_once '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->_error = $status->getMessage();
-            $this->_error .= '  ' .  _("Check your username and password");
-            return false;
+        $vfs = &VFS::singleton('ftp', $args);
+        if (is_a($vfs, 'PEAR_Error')) {
+            return $vfs;
         }
+        $this->_vfs = &$vfs;
 
-        $status = $_vfs->read('', '.forward');
-        if (is_a($status, 'PEAR_Error')) {
-            $this->_error = $status->getMessage();
-            return false;
-        }
-
-        return preg_match('/(^|, *)\\\\' . $user . '( *,|$)/', $status);
+        // Try to login with the username/password, no realm.
+        return $this->_vfs->checkCredentials();
     }
 
 }
diff --git a/lib/Driver/ldap.php b/lib/Driver/ldap.php
index 6ba47fa..21460b2 100644
--- a/lib/Driver/ldap.php
+++ b/lib/Driver/ldap.php
@@ -3,14 +3,16 @@
  * Forwards_Driver_ldap:: implements the Forwards_Driver API for LDAP driven
  * mail servers.
  *
- * $Horde: forwards/lib/Driver/ldap.php,v 1.10.2.2 2007/01/02 13:54:06 jan Exp $
+ * $Horde: forwards/lib/Driver/ldap.php,v 1.10.2.4 2009/01/06 15:22:46 jan Exp $
  *
- * Copyright 2001-2007 Eric Rostetter <eric.rostetter at physics.utexas.edu>
+ * Copyright 2001-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (BSDL). If you
  * did not receive this file, see http://www.horde.org/licenses/bsdl.php.
  *
  * @author  Eric Rostetter <eric.rostetter at physics.utexas.edu>
+ * @author  Ben Klang <ben at alkaloid.net>
+ * @author  Jan Schneider <jan at horde.org>
  * @package Forwards
  */
 class Forwards_Driver_ldap extends Forwards_Driver {
@@ -20,314 +22,611 @@ class Forwards_Driver_ldap extends Forwards_Driver {
      *
      * @var resource
      */
-    var $_ds;
+    var $_connection;
 
     /**
-     * Check if the realm has a specific configuration.
+     * Boolean true if connected, false otherwise
      *
-     * If not, try to fall back on the default configuration.  If
-     * still not a valid configuration then exit with an error.
+     * @var boolean
+     */
+    var $_connected = false;
+
+    /**
+     * The current user's corresponding distinguished name
      *
-     * @param string $realm  The realm of the user, or "default" if none.
-     *                       Note: passed by reference so we can change
-     *                       its value!
+     * @var string
      */
-    function checkConfiguration(&$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]['server'])) {
-            $realm = 'default';
-        }
+    var $_dn;
 
-        // If still no host/port, then we have a misconfigured module.
-        if (empty($this->_params[$realm]['host']) ||
-            empty($this->_params[$realm]['port']) ) {
-            $this->_error = _("The module is not properly configured!");
-            return false;
-        }
-        return true;
-    }
+    /**
+     * The current user's password
+     *
+     * @var string
+     */
+    var $_password;
 
     /**
      * Begins forwarding of mail for a user.
      *
-     * @param string $user        The username of the user.
-     * @param string $realm       The realm of the user.
      * @param string $password    The password of the user.
      * @param string $target      The email address that mail should be
      *                            forwarded to.
      * @param boolean $keeplocal  Keep a copy of forwarded mail in the local
-     *                            mailbox. (Ignored)
-     *
-     * @return boolean  True on success, false otherwise.
+     *                            mailbox.
      */
-    function enableForwarding($user, $realm, $password, $target, $keeplocal)
+    function enableForwarding($password, $target, $keeplocal = false)
     {
-        // Make sure the configuration file is correct.
-        if (!$this->checkConfiguration($realm)) {
-            return false;
+        $res = $this->_connect($password);
+        if (is_a($res, 'PEAR_Error')) {
+            return $res;
         }
 
-        // Get the user's DN.
-        if (isset($this->_params[$realm]['userdn'])) {
-            $userdn = $this->_params[$realm]['userdn'];
-        } else {
-            $userdn = $this->_lookupdn($user, $realm);
-            if (is_a($userdn, 'PEAR_Error')) {
-                return $userdn;
-            }
-        }
+        // $keeplocal is one of "on" or "off"
+        $keeplocal = $keeplocal == 'on';
 
-        // Connect as the user.
-        $res = $this->_connect($userdn, $password, $realm);
-        if (is_a($res, 'PEAR_Error')) {
-            $this->_error = $res->getMessage();
-            $this->_error .= ' - ' .  _("Check your password");
-            return false;
-        }
+        list($forwardattr, $keeplocalattr) = $this->_getSchemaAttrs();
 
         // Change the user's forwards.
-        $newDetails[$this->_params[$realm]['forwards']] = $target;
-        $res = ldap_mod_replace($this->_ds, $userdn, $newDetails);
-        if (!$res) {
-            $res = PEAR::raiseError(ldap_error($this->_ds));
+        switch($this->_params[$this->_realm]['schema']) {
+        case 'sunone':
+            $newDetails[$forwardattr] = array($target);
+            $newDetails[$keeplocalattr] = array('forward');
+            if ($keeplocal) {
+                $newDetails[$keeplocalattr][] = 'mailbox';
+            }
+            break;
+
+        case 'qmail-ldap':
+            $newDetails[$forwardattr] = array($target);
+            if ($keeplocal) {
+                // If the record previously had data, we have to send an
+                // empty array to remove the attribute.  However sending an
+                // an empty array when the attribute is not already populated
+                // causes PHP to return with "Protocol Error". 
+                $res = $this->_getForwardInfo();
+                if (is_a($res, 'PEAR_Error')) {
+                    return $res;
+                }
+                if (!$res['keeplocal']) {
+                    $newDetails[$keeplocalattr] = array();
+                }
+            } else {
+                $newDetails[$keeplocalattr] = array('nolocal');
+            }
+            break;
+
+        case 'exim':
+            $newDetails[$forwardattr] = array($target);
+            break;
+
+        case 'custom':
+            // The "custom" schema has no way to track $keeplocal because even
+            // if we knew the attribute name there would be no way to know what
+            // value(s) are expected.
+            $newDetails[$forwardattr] = array($target);
+            break;
         }
 
-        // Disconnect from the ldap server.
-        $this->_disconnect();
-
-        return true;
+        $res = ldap_mod_replace($this->_connection, $this->_dn, $newDetails);
+        if ($res === false) {
+            Horde::logMessage(sprintf("Error while updating LDAP object: %s",
+                                      ldap_error($this->_connection)),
+                              __FILE__, __LINE__, PEAR_LOG_ERR);
+            return PEAR::raiseError(_("An internal error has occurred.  Details have been logged for the administrator."));
+        }
     }
 
     /**
      * Stops forwarding of mail for a user.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
      * @param string $password  The password of the user.
-     *
-     * @return boolean  True on success, false otherwise.
      */
-    function disableForwarding($user, $realm, $password)
+    function disableForwarding($password)
     {
-        // Make sure the configuration file is correct.
-        if (!$this->checkConfiguration($realm)) {
-            return false;
-        }
-
-        // Get the user's DN.
-        if (isset($this->_params[$realm]['userdn'])) {
-            $userdn = $this->_params[$realm]['userdn'];
-        } else {
-            $userdn = $this->_lookupdn($user, $realm);
-            if (is_a($userdn, 'PEAR_Error')) {
-                return $userdn;
-            }
+        $res = $this->_connect($password);
+        if (is_a($res, 'PEAR_Error')) {
+            return $res;
         }
 
-        // Connect as the user.
-        $res = $this->_connect($userdn, $password, $realm);
+        $res = $this->_getForwardInfo();
         if (is_a($res, 'PEAR_Error')) {
-            $this->_error = $res->getMessage();
-            $this->_error .= ' - ' .  _("Check your password");
-            return false;
+            return $res;
         }
+        $forwards = $res['forwards'];
+        $keeplocal = $res['keeplocal'];
+        list($forwardattr, $keeplocalattr) = $this->_getSchemaAttrs();
 
-        // Delete the user's forwards.
-        $attribs = array($this->_params[$realm]['forwards']);
-        $value = $this->_getForwards($userdn, $attribs);
-        if (!$value) {
+        if (empty($forwards) && !$keeplocal) {
             // Nothing to delete, so treat as success.
-            return true;
+            return;
         }
 
-        $newDetails[$this->_params[$realm]['forwards']] = $value;
-        $res = ldap_mod_del($this->_ds, $userdn, $newDetails);
-        if (!$res) {
-            $res = PEAR::raiseError(ldap_error($this->_ds));
-        }
+        switch($this->_params[$this->_realm]['schema']) {
+        case 'sunone':
+            if (!empty($forwards)) {
+                $newDetails[$forwardattr] = array();
+            }
+            $newDetails[$keeplocalattr] = array('mailbox');
+            break;
 
-        // Disconnect from the ldap server.
-        $this->_disconnect();
+        case 'qmail-ldap':
+            if (!empty($forwards)) {
+                $newDetails[$forwardattr] = array();
+            }
+            if (!$keeplocal) {
+                // FIXME: Should this be set to the default behavior (empty)
+                // or set explicitly ('localonly')?  I think the default
+                // behavior is most appropriate.
+                $newDetails[$keeplocalattr] = array();
+            }
+            break;
+
+        case 'exim':
+            if (!empty($forwards)) {
+                $newDetails[$forwardattr] = array();
+            }
+            break;
 
-        return $res;
+        case 'custom':
+            if (!empty($forwards)) {
+                $newDetails[$forwardattr] = array();
+            }
+            break;
+        }
+        $res = ldap_modify($this->_connection, $this->_dn, $newDetails);
+        if ($res === false) {
+            Horde::logMessage(sprintf('Error while removing forwarding information from LDAP: %s',
+                                      ldap_error($this->_connection)),
+                              __FILE__, __LINE__, PEAR_LOG_ERR);
+            return PEAR::raiseError(_("An internal error has occurred.  Details have been logged for the administrator."));
+        }
     }
 
     /**
      * Retrieves current state of mail redirection for a user.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
      * @param string $password  The password of the user.
      *
-     * @return mixed  'Y' if forwarding is enabled, or false otherwise.
+     * @return mixed  Returns 'Y' if forwarding is enabled for the user, 'N' if
+     *                forwarding is currently disabled, false if the status
+     *                cannot be determined, and PEAR_Error on error.
      */
-    function isEnabledForwarding($user, $realm, $password)
+    function isEnabledForwarding($password)
     {
-        // Make sure the configuration file is correct.
-        if (!$this->checkConfiguration($realm)) {
-            return false;
-        }
-
-        // Get the user's DN.
-        if (isset($this->_params[$realm]['userdn'])) {
-            $userdn = $this->_params[$realm]['userdn'];
-        } else {
-            $userdn = $this->_lookupdn($user, $realm);
-            if (is_a($userdn, 'PEAR_Error')) {
-                return $userdn;
-            }
+        $res = $this->_connect($password);
+        if (is_a($res, 'PEAR_Error')) {
+            return $res;
         }
-
-        // Connect as the user.
-        $res = $this->_connect($userdn, $password, $realm);
+ 
+        $res = $this->_getForwardInfo();
         if (is_a($res, 'PEAR_Error')) {
-            $this->_disconnect();
-            if ($res->getMessage() == _("Could not bind to ldap server")) {
-                return PEAR::raiseError(_("Incorrect Password"));
-            }
             return $res;
         }
 
-        $attribs = array($this->_params[$realm]['forwards']);
-        if ($this->_getForwards($userdn, $attribs)) {
-            $this->_disconnect();
+        if ($res['forwards'] != null) {
             return 'Y';
         } else {
-            $this->_disconnect();
             return 'N';
         }
     }
 
     /**
-     * Retrieves current target of mail redirection for a user.
+     * Checks if user is keeping a local copy of forwarded mail.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
      * @param string $password  The password of the user.
      *
-     * @return string  The current forwarding mail address, or false on error.
+     * @return boolean  True if user is keeping a local copy of mail,
+     *                  otherwise false.
      */
-    function currentTarget($user, $realm = 'default', $password)
+    function isKeepLocal($password)
     {
-        // Make sure the configuration file is correct.
-        if (!$this->checkConfiguration($realm)) {
-            return false;
+        $res = $this->_connect($password);
+        if (is_a($res, 'PEAR_Error')) {
+            return $res;
         }
-
-        // Get the user's dn.
-        if (isset($this->_params[$realm]['userdn'])) {
-            $userdn = $this->_params[$realm]['userdn'];
-        } else {
-            $userdn = $this->_lookupdn($user, $realm);
-            if (is_a($userdn, 'PEAR_Error')) {
-                return $userdn;
-            }
+ 
+        $res = $this->_getForwardInfo();
+        if (is_a($res, 'PEAR_Error')) {
+            return $res;
         }
 
-        // Connect as the user.
-        $res = $this->_connect($userdn, $password, $realm);
+        return $res['keeplocal'];
+    }
+
+    /**
+     * Retrieves current target of mail redirection for a user.
+     *
+     * @param string $password  The password of the user.
+     *
+     * @return string  The current forwarding mail address, false if no
+     *                 forwarding is set, or PEAR_Error on error.
+     */
+    function currentTarget($password)
+    {
+        $res = $this->_connect($password);
         if (is_a($res, 'PEAR_Error')) {
-            $this->_disconnect();
-            if ($res->getMessage() == _("Could not bind to ldap server")) {
-                return PEAR::raiseError(_("Incorrect Password"));
-            }
             return $res;
         }
 
-        $attribs = array($this->_params[$realm]['forwards']);
+        $res = $this->_getForwardInfo();
+        if (is_a($res, 'PEAR_Error')) {
+            return $res;
+        }
 
-        return $this->_getForwards($userdn, $attribs);
+        return $res['forwards'];
     }
 
     /**
-     * Lookup and return the user's dn.
-     *
-     * @param string $user   The username of the user.
-     * @param string $realm  The realm of the user.
+     * Get the forwarding information for the requested user
      *
-     * @return string  The ldap dn for the user.
+     * @return mixed  Array of forwarding data on succes, false on failure
      */
-    function _lookupdn($user, $realm)
+    function _getForwardInfo()
     {
-        // Bind as guest.
-        $this->_connect();
+        $error = _("Internal error while searching LDAP.  Details have been logged for the administrator.");
+        list($forwardattr, $keeplocalattr) = $this->_getSchemaAttrs();
+        $attribs = array();
+        if (!is_null($forwardattr)) {
+            $attribs[] = $forwardattr;
+        }
+        if (!is_null($keeplocalattr)) {
+            $attribs[] = $keeplocalattr;
+        }
+        $sr = ldap_read($this->_connection, $this->_dn, 'objectClass=*', $attribs);
 
-        // Construct search.
-        $search = $this->_params[$realm]['uid'] . '=' . $user;
-        if (!empty($this->_params[$realm]['realm'])) {
-            $search .= '@' . $this->_params[$realm]['realm'];
+        if ($sr === false) {
+            Horde::logMessage(sprintf('Error while searching LDAP: %s',
+                                      ldap_error($this->_connection)),
+                              __FILE__, __LINE__, PEAR_LOG_ERR);
+            return PEAR::raiseError($error);
         }
 
-        // Get userdn.
-        $result = ldap_search($this->_ds, $this->_params[$realm]['basedn'], $search);
-        $entry = ldap_first_entry($this->_ds, $result);
-        if ($entry === false) {
-            $this->_disconnect();
-            return PEAR::raiseError(_("User not found."));
+        $res = ldap_get_entries($this->_connection, $sr);
+        if ($res === false) {
+            Horde::logMessage(sprintf('Error while getting LDAP results: %s',
+                                      ldap_error($this->_connection)),
+                              __FILE__, __LINE__, PEAR_LOG_ERR);
+            return PEAR::raiseError($error);
         }
-        $userdn = ldap_get_dn($this->_ds, $entry);
 
-        // Disconnect from ldap server.
-        $this->_disconnect();
+        // LDAP results always return attribute names in lower case
+        $forwardattr = String::lower($forwardattr);
+        $keeplocalattr = String::lower($keeplocalattr);
 
-        return $userdn;
+        // Note: we only process the first result.
+
+        // This block is sufficient for determining the configured forwards for
+        // all the various supported schemas.
+        if (isset($res[0][$forwardattr])) {
+            $forwards = $res[0][$forwardattr];
+            // Prune unnecessary 'count' field from forward array
+            unset($forwards['count']);
+        } else {
+            $forwards = array();
+        }
+
+        // Determining the keeplocal state is a bit more tricky.
+        switch($this->_params[$this->_realm]['schema']) {
+        case 'sunone':
+            if (in_array('mailbox', $res[0][$keeplocalattr])) {
+                $keeplocal = true;
+            } else {
+                $keeplocal = false;
+            }
+            break;
+
+        case 'qmail-ldap':
+            if (!isset($res[0][$keeplocalattr][0])) {
+                // No entry defaults to local delivery enabled
+                $keeplocal = true;
+                break;
+            }
+            switch($res[0][$keeplocalattr][0]) {
+            // FIXME: Handle other valid attribute values
+            case 'nolocal':
+                $keeplocal = false;
+                break;
+            case 'localonly':
+                // Technically this means forwarding is disabled but there
+                // is no way (currently) to handle that in the Horde Vaction
+                // UI so we just treat it as if local delivery is enabled.
+            default:
+                $keeplocal = true;
+                break;
+            }
+            break;
+
+        case 'exim':
+            // FIXME: There is no way to indicate keeplocal on Exim
+            // configurations because at the time of this writing I don't
+            // know what (if any) attributes or values Exim uses to store 
+            // this information.
+            // If forward addresses are configured we'll guess keeplocal is
+            // false.  Without forward addresses we'll guess it's true.
+            if (isset($res[0][$forwardattr]) &&
+                count($res[0][$forwardattr]) != 0) {
+                $keeplocal = true;
+            } else {
+                $keeplocal = false;
+            }
+            break;
+       
+        case 'custom':
+            // FIXME: There is no way to indicate keeplocal on custom
+            // configurations because we don't know what values to look for
+            // even if we knew the attributes.
+            // If forward addresses are configured we'll guess keeplocal is
+            // false.  Without forward addresses we'll guess it's true.
+            if (count($forwards) != 0) {
+                $keeplocal = false;
+            } else {
+                $keeplocal = true;
+            }
+            break;
+        }
+
+        // FIXME:
+        // This application only allows a single configured forward address.
+        if (count($forwards) > 0) {
+            $forwards = $forwards[0];
+        } else {
+            $forwards = null;
+        }
+        
+        return array('forwards' => $forwards, 'keeplocal' => $keeplocal);
     }
 
-    function _getForwards($userdn, $attribs)
+    /**
+     * Get the attributes for storing forward addresses and local delivery
+     * option based on the configured schema.
+     *
+     * @return array  List of attributes (forwardsattr, keeplocalattr)
+     */
+    function _getSchemaAttrs()
     {
-        $sr = ldap_search($this->_ds, $userdn, 'uid=*', $attribs);
-        $entry = ldap_first_entry($this->_ds, $sr);
-        $res = ldap_get_attributes($this->_ds, $entry);
-        if ($res['count'] == 0) {
-            return false;
+        switch($this->_params[$this->_realm]['schema']) {
+        case 'sunone':
+            $attribs = array('mailForwardingAddress', 'mailDeliveryOption');
+            break;
+        case 'qmail-ldap':
+            $attribs = array('mailForwardingAddress', 'deliveryMode');
+            break;
+        case 'exim':
+            $attribs = array('mailForward', null);
+        case 'custom':
+            $attribs = array($this->_params[$this->_realm]['attribute'], null);
+            break;
         }
 
-        $values = ldap_get_values($this->_ds, $entry, $attribs[0]);
-        return $values[0];
+        return $attribs;
     }
 
     /**
-     * Connects to an LDAP server and binds as the guest user or as the
-     * optional userdn.
-     *
-     * @param string $userdn    The DN to use when binding non-anonymously.
-     * @param string $password  The password for $userdn.
-     * @param string $realm     The realm of the user.
+     * Opens a connection to the LDAP server.
      *
-     * @return boolean  True on success, false otherwise.
+     * @return mixed  True on success or a PEAR_Error object on failure.
      */
-    function _connect($userdn = null, $password = null, $realm = 'default')
+    function _connect($password)
     {
-        $this->_ds = ldap_connect($this->_params[$realm]['host'], $this->_params[$realm]['port']);
-        if (!$this->_ds) {
-            return PEAR::raiseError(_("Could not connect to ldap server"));
+        if ($this->_connected) {
+            return true;
         }
-        if (isset($this->_params[$realm]['version'])) {
-            ldap_set_option($this->_ds, LDAP_OPT_PROTOCOL_VERSION,
-                            $this->_params[$realm]['version']);
+
+        if (!Util::extensionExists('ldap')) {
+            return PEAR::raiseError("Forwards_Driver_ldap: Required LDAP extension not found.");
         }
 
-        if (!is_null($userdn)) {
-            $result = @ldap_bind($this->_ds, $userdn, $password);
-        } else {
-            $result = @ldap_bind($this->_ds);
+        if (is_a($checked = $this->_checkConfig($this->_realm), 'PEAR_Error')) {
+            return $checked;
+        }
+
+        $this->_password = $password;
+        $error = _("Internal LDAP error.  Details have been logged for the administrator.");
+
+        /* Connect to the LDAP server anonymously. */
+        $conn = ldap_connect($this->_params[$this->_realm]['hostspec'],
+                             $this->_params[$this->_realm]['port']);
+        if (!$conn) {
+            Horde::logMessage(
+                sprintf('Failed to open an LDAP connection to %s.',
+                        $this->_params[$this->_realm]['hostspec']),
+                __FILE__, __LINE__, PEAR_LOG_ERR);
+            return PEAR::raiseError();
         }
 
-        if (!$result) {
-            return PEAR::raiseError(_("Could not bind to ldap server"));
+        /* Set the LDAP protocol version. */
+        if (isset($this->_params[$this->_realm]['version'])) {
+            $result = @ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION,
+                                       $this->_params[$this->_realm]['version']);
+            if ($result === false) {
+                Horde::logMessage(
+                    sprintf('Set LDAP protocol version to %d failed: [%d] %s',
+                            $this->_params[$this->_realm]['version'],
+                            @ldap_errno($conn),
+                            @ldap_error($conn)),
+                    __FILE__, __LINE__, PEAR_LOG_WARNING);
+                return PEAR::raiseError($error);
+            }
         }
 
+        /* If necessary, bind to the LDAP server as the user with search
+         * permissions. */
+        if (!empty($this->_params[$this->_realm]['searchdn'])) {
+            $bind = @ldap_bind($conn, $this->_params[$this->_realm]['searchdn'],
+                               $this->_params[$this->_realm]['searchpw']);
+            if ($bind === false) {
+                Horde::logMessage(
+                    sprintf('Bind to server %s:%d with DN %s failed: [%d] %s',
+                            $this->_params[$this->_realm]['hostspec'],
+                            $this->_params[$this->_realm]['port'],
+                            $this->_params[$this->_realm]['searchdn'],
+                            @ldap_errno($conn),
+                            @ldap_error($conn)),
+                    __FILE__, __LINE__, PEAR_LOG_ERR);
+                return PEAR::raiseError($error);
+            }
+        }
+
+        /* Register our callback function to handle referrals. */
+        if (function_exists('ldap_set_rebind_proc')) {
+            $result = @ldap_set_rebind_proc($conn, array($this, '_rebindProc'));
+            if ($result === false) {
+                Horde::logMessage(
+                    sprintf('Setting referral callback failed: [%d] %s',
+                            @ldap_errno($conn),
+                            @ldap_error($conn)),
+                    __FILE__, __LINE__, PEAR_LOG_WARNING);
+                return PEAR::raiseError($error);
+            }
+        }
+
+        /* Store the connection handle at the instance level. */
+        $this->_connection = $conn;
+
+        /* Search for the user's full DN. */
+        $search = @ldap_search($this->_connection,
+                               $this->_params[$this->_realm]['basedn'],
+                               $this->_params[$this->_realm]['uid'] . '=' . $this->_user,
+                               array('dn'));
+
+        if ($search === false) {
+            Horde::logMessage(
+                sprintf('Error while searching the directory for the user\'s DN: [%d]: %s %s',
+                        @ldap_errno($this->_connection),
+                        @ldap_error($this->_connection)),
+                __FILE__, __LINE__, PEAR_LOG_ERR);
+            return PEAR::raiseError($error);
+        }
+
+        $result = @ldap_get_entries($this->_connection, $search);
+        if ($result === false) {
+            Horde::logMessage(
+                sprintf('Error while retrieving LDAP search results for the user\'s DN: [%d]: %s',
+                        @ldap_errno($this->_connection),
+                        @ldap_error($this->_connection)),
+                __FILE__, __LINE__, PEAR_LOG_ERR);
+            return PEAR::raiseError($error);
+        }
+
+        if ($result['count'] != 1) {
+            Horde::logMessage(
+                'Zero or more than one DN returned from search; unable to determine user\'s correct DN.',
+                __FILE__, __LINE__, PEAR_LOG_ERR);
+            return PEAR::raiseError($error);
+        }
+        $this->_dn = $result[0]['dn'];
+
+        // Now we should have the user's DN.  Re-bind as appropriate with write
+        // permissions to be able to store preferences.
+        switch($this->_params[$this->_realm]['writedn']) {
+        case 'user':
+            $result = @ldap_bind($this->_connection,
+                                 $this->_dn, $password);
+            break;
+        case 'admin':
+            $result = @ldap_bind($this->_connection,
+                                 $this->_params[$this->_realm]['admindn'],
+                                 $this->_params[$this->_realm]['adminpw']);
+            break;
+        case 'searchdn':
+            // Since we've already bound as the search DN above, no rebinding
+            // is necessary.
+            $result = true;
+            break;
+        }
+
+        if ($result === false) {
+            Horde::logMessage(
+                sprintf('Error rebinding for forwards writing: [%d]: %s',
+                        @ldap_errno($this->_connection),
+                        @ldap_error($this->_connection)),
+                __FILE__, __LINE__, PEAR_LOG_ERR);
+            return PEAR::raiseError($error);
+        }
+
+        // The connection is now fully initialized and usable.
+        $this->_connected = true;
         return true;
     }
 
     /**
-     * Close the ldap connection.
+     * Callback function for LDAP referrals.
+     *
+     * This function is called when an LDAP operation returns a referral to an
+     * alternate server.
+     *
+     * @return integer  1 on error, 0 on success.
+     */
+    function _rebindProc($conn, $who)
+    {
+        /* Strip out the hostname we're being redirected to. */
+        $who = preg_replace(array('|^.*://|', '|:\d*$|'), '', $who);
+
+        /* Make sure the server we're being redirected to is in our list of
+         * valid servers. */
+        if (strpos($this->_params[$this->_realm]['hostspec'], $who) === false) {
+            Horde::logMessage(
+                sprintf('Referral target %s for DN %s is not in the authorized server list.',
+                        $who, $bind_dn),
+                __FILE__, __LINE__, PEAR_LOG_ERR);
+            return 1;
+        }
+
+        /* Figure out the DN of the authenticating user. */
+        switch($this->_params[$this->_realm]['writedn']) {
+        case 'user':
+            $bind_dn = $this->_dn;
+            $bind_pw = $this->_password;
+            break;
+        case 'admin':
+            $bind_dn = $this->_params[$this->_realm]['admindn'];
+            $bind_pw = $this->_params[$this->_realm]['adminpw'];
+            break;
+        case 'searchdn':
+            $bind_dn = $this->_params[$this->_realm]['searchdn'];
+            $bind_dn = $this->_params[$this->_realm]['searchpw'];
+            break;
+        }
+
+        /* Bind to the new server. */
+        $bind = @ldap_bind($conn, $bind_dn, $bind_pw);
+        if ($bind === false) {
+            Horde::logMessage(
+                sprintf('Rebind to server %s:%d with DN %s failed: [%d] %s',
+                        $this->_params[$this->_realm]['hostspec'],
+                        $this->_params[$this->_realm]['port'],
+                        $bind_dn,
+                        @ldap_errno($this->_connection),
+                        @ldap_error($this->_connection)),
+                __FILE__, __LINE__, PEAR_LOG_ERR);
+        }
+
+        return 0;
+    }
+
+    /**
+     * 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.
      */
-    function _disconnect()
+    function _checkConfig()
     {
-        @ldap_close($this->_ds);
+        // If no host config for the realm, then we fall back to the default
+        // realm.
+        if (!isset($this->_params[$this->_realm])) {
+            $this->_realm = 'default';
+        }
+
+        // If still no host/port, then we have a misconfigured module.
+        if (empty($this->_params[$this->_realm]['schema']) ||
+            empty($this->_params[$this->_realm]['hostspec']) ||
+            empty($this->_params[$this->_realm]['port']) ||
+            empty($this->_params[$this->_realm]['version']) ||
+            empty($this->_params[$this->_realm]['basedn']) ||
+            empty($this->_params[$this->_realm]['uid'])) {
+            return PEAR::raiseError(_("The module is not properly configured!"));
+        }
     }
 
 }
diff --git a/lib/Driver/mdaemon.php b/lib/Driver/mdaemon.php
old mode 100644
new mode 100755
index 59fe06c..ca9c7a1
--- a/lib/Driver/mdaemon.php
+++ b/lib/Driver/mdaemon.php
@@ -3,14 +3,15 @@
  * Forwards_Driver_mdaemon:: implements the Forwards_Driver API for the
  * Mdaemon mail servers.
  *
- * $Horde: forwards/lib/Driver/mdaemon.php,v 1.17.2.2 2007/01/02 13:54:06 jan Exp $
+ * $Horde: forwards/lib/Driver/mdaemon.php,v 1.17.2.4 2009/01/06 15:22:46 jan Exp $
  *
- * Copyright 2001-2007 Mike Cochrane <mike at graftonhall.co.nz>
+ * Copyright 2001-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (BSDL). If you
  * did not receive this file, see http://www.horde.org/licenses/bsdl.php.
  *
  * @author  Mike Cochrane <mike at graftonhall.co.nz>
+ * @author  Jan Schneider <jan at horde.org>
  * @since   Forwards 2.1
  * @package Forwards
  */
@@ -19,50 +20,45 @@ class Forwards_Driver_mdaemon extends Forwards_Driver {
     /**
      * Begins forwarding of mail for a user.
      *
-     * @param string $user        The username of the user.
-     * @param string $realm       The realm of the user.
      * @param string $password    The password of the user.
      * @param string $target      The email address that mail should be
      *                            forwarded to.
      * @param boolean $keeplocal  Keep a copy of forwarded mail in the local
      *                            mailbox.
-     *
-     * @return boolean  True on success, false otherwise.
      */
-    function enableForwarding($user, $realm = 'default', $password = '',
-                              $target, $keeplocal = false)
+    function enableForwarding($password, $target, $keeplocal = false)
     {
-        if (!is_dir($this->_params[$realm]['location'])) {
-           $this->_error = _("Mdaemon path not found");
-           return false;
+        if (!is_dir($this->_params[$this->_realm]['location'])) {
+            return PEAR::raiseError(_("Mdaemon path not found"));
         }
 
         // Update forward target list.
-        if ($fp = fopen($this->_params[$realm]['location'] . '/forward.dat', 'rb')) {
-            $current = fread ($fp, filesize($this->_params[$realm]['location'] . '/forward.dat'));
+        $forward_file = $this->_params[$this->_realm]['location'] . '/forward.dat';
+        if ($fp = fopen($forward_file, 'rb')) {
+            $current = fread($fp, filesize($forward_file));
             fclose($fp);
-            if ($fp = fopen($this->_params[$realm]['location'] . '/forward.dat', 'wb')) {
-                fwrite($fp, "[$user@$realm]\nAddress=$target\n$current");
+            if ($fp = fopen($forward_file, 'wb')) {
+                fwrite($fp, '[' . $this->_user . '@' . $this->_realm. "]\nAddress=$target\n$current");
                 fclose($fp);
             } else {
-                return false;
+                return PEAR::raiseError(sprintf(_("Cannot open %s."), $forward_file));
             }
         } else {
-            return false;
+            return PEAR::raiseError(sprintf(_("Cannot open %s."), $forward_file));
         }
 
         // Create lock file.
-        $fp = fopen($this->_params[$realm]['location'] . '/edituser.lck', 'w');
+        $fp = fopen($this->_params[$this->_realm]['location'] . '/edituser.lck', 'w');
         if (!$fp) {
-            return false;
+            return PEAR::raiseError(_("Cannot create lockfile."));
         } else {
             fclose($fp);
         }
 
         // Get current details.
-        $current_details = $this->_getUserDetails($user, $realm);
-        if ($current_details === false) {
-            return false;
+        $current_details = $this->_getUserDetails();
+        if (is_a($current_details, 'PEAR_Error')) {
+            return $current_details;
         }
 
         // Set forwarding flag.
@@ -76,17 +72,16 @@ class Forwards_Driver_mdaemon extends Forwards_Driver {
         }
 
         // Create semaphore file.
-        $fp = fopen($this->_params[$realm]['location'] . '/edituser.sem', 'wb');
+        $fp = fopen($this->_params[$this->_realm]['location'] . '/edituser.sem', 'wb');
         if (!$fp) {
-            $this->_error = _("Not able to create semaphore file");
-            return false;
+            return PEAR::raiseError(_("Not able to create semaphore file"));
         } else {
-            fwrite($fp, "$user@$realm, " . $new_details);
+            fwrite($fp, $this->_user . '@' . $this->_realm . ', ' . $new_details);
             fclose($fp);
         }
 
         // Remove lock file.
-        @unlink($this->_params[$realm]['location'] . '/edituser.lck');
+        @unlink($this->_params[$this->_realm]['location'] . '/edituser.lck');
 
         return true;
     }
@@ -94,48 +89,42 @@ class Forwards_Driver_mdaemon extends Forwards_Driver {
     /**
      * Stops forwarding of mail for a user.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
      * @param string $password  The password of the user.
-     *
-     * @return boolean  True on success, false otherwise.
      */
-    function disableForwarding($user, $realm = 'default', $password = '')
+    function disableForwarding($password)
     {
-        if (!is_dir($this->_params[$realm]['location'])) {
-           $this->_error = _("Mdaemon path not found");
-           return false;
+        if (!is_dir($this->_params[$this->_realm]['location'])) {
+            return PEAR::raiseError(_("Mdaemon path not found"));
         }
 
         // Create lock file.
-        $fp = fopen($this->_params[$realm]['location'] . '/edituser.lck', 'w');
+        $fp = fopen($this->_params[$this->_realm]['location'] . '/edituser.lck', 'w');
         if (!$fp) {
-            return false;
+            return PEAR::raiseError(_("Cannot create lockfile."));
         } else {
             fclose($fp);
         }
 
         // Get current details.
-        $current_details = $this->_getUserDetails($user, $realm);
-        if ($current_details === false) {
-            return false;
+        $current_details = $this->_getUserDetails();
+        if (is_a($current_details, 'PEAR_Error')) {
+            return $current_details;
         }
 
         // Set forwarding flag.
         $new_details = substr_replace($current_details, 'N', 216, 1);
 
         // Create semaphore file.
-        $fp = fopen($this->_params[$realm]['location'] . '/edituser.sem', 'wb');
+        $fp = fopen($this->_params[$this->_realm]['location'] . '/edituser.sem', 'wb');
         if (!$fp) {
-           $this->_error = _("Not able to create semaphore file");
-           return false;
+            return PEAR::raiseError(_("Not able to create semaphore file"));
         } else {
-            fwrite($fp, "$user@$realm, " . $new_details);
+            fwrite($fp, $this->_user . '@' . $this->_realm . ', ' . $new_details);
             fclose($fp);
         }
 
         // Remove lock file.
-        @unlink($this->_params[$realm]['location'] . '/edituser.lck');
+        @unlink($this->_params[$this->_realm]['location'] . '/edituser.lck');
 
         return true;
     }
@@ -143,111 +132,103 @@ class Forwards_Driver_mdaemon extends Forwards_Driver {
     /**
      * Retrieves current state of mail redirection for a user.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
      * @param string $password  The password of the user.
      *
-     * @return mixed  'Y' if forwarding is enabled, or false.
+     * @return mixed  Returns 'Y' if forwarding is enabled for the user, 'N' if
+     *                forwarding is currently disabled, false if the status
+     *                cannot be determined, and PEAR_Error on error.
      */
-    function isEnabledForwarding($user, $realm = 'default', $password = '')
+    function isEnabledForwarding($password)
     {
         // Get current details.
-        $current_details = $this->_getUserDetails($user, $realm);
-        if ($current_details === false) {
-            return false;
+        $current_details = $this->_getUserDetails();
+        if (is_a($current_details, 'PEAR_Error')) {
+            return $current_details;
         }
 
         // Check forwarding flag.
         if (substr($current_details, 216, 1) == 'Y') {
             return 'Y';
-        } else {
-            return false;
         }
+
+        return false;
     }
 
     /**
      * Checks if user is keeping a local copy of forwarded mail.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
      * @param string $password  The password of the user.
      *
      * @return boolean  True if user is keeping a local copy of mail,
      *                  otherwise false.
      */
-    function isKeepLocal($user, $realm = 'default', $password = '')
+    function isKeepLocal($password)
     {
         // Get current details.
-        $current_details = $this->_getUserDetails($user, $realm);
-        if ($current_details === false) {
-            return false;
+        $current_details = $this->_getUserDetails();
+        if (is_a($current_details, 'PEAR_Error')) {
+            return $current_details;
         }
 
         // Check retain copy flag.
-        if (substr($current_details, 219, 1) == 'Y') {
-            return true;
-        } else {
-            return false;
-        }
+        return substr($current_details, 219, 1) == 'Y';
     }
 
     /**
-     * Retrieves current target of mail redirection
+     * Retrieves current target of mail redirection for a user.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
      * @param string $password  The password of the user.
      *
-     * @return string  The current forwarding mail address, or false.
+     * @return string  The current forwarding mail address, false if no
+     *                 forwarding is set, or PEAR_Error on error.
      */
-    function currentTarget($user, $realm = 'default', $password = '')
+    function currentTarget($password)
     {
-        $searchString = "[$user@$realm]";
+        $searchString = '[' . $this->_user . '@' . $this->_realm . ']';
 
-        $fp = fopen($this->_params[$realm]['location'] . '/forward.dat', 'rb');
+        $fp = fopen($this->_params[$this->_realm]['location'] . '/forward.dat', 'rb');
         if (!$fp) {
-            return false;
+            return PEAR::raiseError(
+                sprintf(_("Cannot open %s."),
+                        $this->_params[$this->_realm]['location'] . '/forward.dat'));
         }
 
         while (!feof($fp)) {
             $line = fgets($fp, 4096);
-            if (substr($line,0,strlen($searchString)) == $searchString) {
+            if (strpos($line, $searchString) === 0) {
                 $line = fgets($fp, 4096);
                 fclose($fp);
-                return substr($line,8);
+                return substr($line, 8);
             }
         }
         fclose($fp);
-
-        return false;
     }
 
     /**
      * Retrieves user details from userlist.dat
      *
-     * @param string $user   The username of the user.
-     * @param string $realm  The realm for the user.
-     *
      * @return string  Line from userlist.dat, or false.
      */
-    function _getUserDetails($user, $realm = 'default')
+    function _getUserDetails()
     {
-        $searchString = str_pad($realm, 45) . str_pad($user, 30);
+        $searchString = str_pad($this->_realm, 45) . str_pad($this->_user, 30);
 
-        $fp = fopen($this->_params[$realm]['location'] . '/userlist.dat', 'rb');
+        $fp = fopen($this->_params[$this->_realm]['location'] . '/userlist.dat', 'rb');
         if (!$fp) {
-            return false;
+            return PEAR::raiseError(
+                sprintf(_("Cannot open %s."),
+                        $this->_params[$this->_realm]['location'] . '/userlist.dat'));
         }
 
         while (!feof ($fp)) {
             $line = fgets($fp, 4096);
-            if (substr($line,0,strlen($searchString)) == $searchString) {
+            if (strpos($line, $searchString) === 0) {
+                fclose($fp);
                 return $line;
             }
         }
 
         fclose($fp);
-        return false;
     }
 
 }
diff --git a/lib/Driver/plesk.php b/lib/Driver/plesk.php
new file mode 100644
index 0000000..38278d0
--- /dev/null
+++ b/lib/Driver/plesk.php
@@ -0,0 +1,366 @@
+<?php
+/**
+ * Forwards_Driver_plesk implements the Forwards_Driver API for Plesk control
+ * panel servers.
+ *
+ * Plesk 8.1 or later is required.
+ *
+ * $Horde: forwards/lib/Driver/plesk.php,v 1.2.2.2 2009/01/06 15:22:46 jan Exp $
+ *
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file LICENSE for license information (BSDL). If you
+ * did not receive this file, see http://www.horde.org/licenses/bsdl.php.
+ *
+ * @author  Jan Schneider <jan at horde.org>
+ * @since   Forwards 3.1
+ * @package Forwards
+ */
+class Forwards_Driver_plesk extends Forwards_Driver {
+
+    /**
+     * The curl resource handler
+     *
+     * @var resource
+     */
+    var $_curl;
+
+    /**
+     * The Plesk domain id of the current realm.
+     *
+     * @var integer
+     */
+    var $_domain_id;
+
+    /**
+     * The current forwards details.
+     *
+     * @var array
+     */
+    var $_details = null;
+
+    /**
+     * Begins forwarding of mail for a user.
+     *
+     * @param string $password    The password of the user.
+     * @param string $target      The email address that mail should be
+     *                            forwarded to.
+     * @param boolean $keeplocal  Keep a copy of forwarded mail in the local
+     *                            mailbox.
+     */
+    function enableForwarding($password, $target, $keeplocal = false)
+    {
+        // Make sure the configuration file is correct
+        if (is_a($checked = $this->_checkConfig($password), 'PEAR_Error')) {
+            return $checked;
+        }
+
+        // Query the server.
+        @list($user,) = explode('@', $this->_user);
+        $request = '<mail><update><set><filter><domain_id>'
+            . $this->_domain_id . '</domain_id><mailname><name>'
+            . htmlspecialchars($user)
+            . '</name><redirect><enabled>true</enabled>'
+            . '<address>' . htmlspecialchars($target) . '</address>'
+            . '</redirect></mailname></filter>'
+            . '</set></update></mail>';
+        $result = $this->_request($password, $request);
+
+        if (is_a($result, 'PEAR_Error')) {
+            return $result;
+        }
+        if (isset($result['mail']['update']['set']['result'])) {
+            $result = $result['mail']['update']['set']['result'];
+        } else {
+            $result = false;
+        }
+        if (isset($result['status']['_']) &&
+            $result['status']['_'] == 'error') {
+            return PEAR::raiseError(sprintf(_("Cannot set forwarding for mail user %s: %s"),
+                                            $this->_user, $result['errtext']['_']));
+        }
+        if (!isset($result['status']['_']) ||
+            $result['status']['_'] != 'ok' ||
+            empty($result)) {
+            return PEAR::raiseError(sprintf(_("Cannot set forwarding for mail user %s."),
+                                            $this->_user));
+        }
+    }
+
+    /**
+     * Stops forwarding of mail for a user.
+     *
+     * @param string $password  The password of the user.
+     */
+    function disableForwarding($password)
+    {
+        // Make sure the configuration file is correct
+        if (is_a($checked = $this->_checkConfig($password), 'PEAR_Error')) {
+            return $checked;
+        }
+
+        // Get current forward address.
+        if (is_a($target = $this->_getUserDetails($password), 'PEAR_Error')) {
+            return $target;
+        }
+        if ($target === false) {
+           return PEAR::raiseError(_("Cannot determine the current forward address."));
+        }
+
+        // Query the server.
+        @list($user,) = explode('@', $this->_user);
+        $request = '<mail><update><set><filter><domain_id>'
+            . $this->_domain_id . '</domain_id><mailname><name>'
+            . htmlspecialchars($user)
+            . '</name><redirect><enabled>false</enabled>'
+            . '<address>' . htmlspecialchars($target) . '</address>'
+            . '</redirect></mailname></filter>'
+            . '</set></update></mail>';
+        $result = $this->_request($password, $request);
+
+        if (is_a($result, 'PEAR_Error')) {
+            return $result;
+        }
+        if (isset($result['mail']['update']['set']['result'])) {
+            $result = $result['mail']['update']['set']['result'];
+        } else {
+            $result = false;
+        }
+        if (isset($result['status']['_']) &&
+            $result['status']['_'] == 'error') {
+            return PEAR::raiseError(sprintf(_("Cannot remove vacation notice for mail user %s: %s"), $this->_user, $result['errtext']['_']));
+        }
+        if (!isset($result['status']['_']) ||
+            $result['status']['_'] != 'ok' ||
+            empty($result)) {
+            return PEAR::raiseError(sprintf(_("Cannot remove vacation notice for mail user %s."), $this->_user));
+        }
+
+        $this->_details = false;
+    }
+
+    /**
+     * Retrieves current state of mail redirection for a user.
+     *
+     * @param string $password  The password of the user.
+     *
+     * @return mixed  Returns 'Y' if forwarding is enabled for the user, 'N' if
+     *                forwarding is currently disabled, false if the status
+     *                cannot be determined, and PEAR_Error on error.
+     */
+    function isEnabledForwarding($password)
+    {
+        // Make sure the configuration file is correct
+        if (is_a($checked = $this->_checkConfig($password), 'PEAR_Error')) {
+            return $checked;
+        }
+        if (is_a($details = $this->_getUserDetails($password), 'PEAR_Error')) {
+            return $details;
+        }
+
+        return $details === false ? 'N' : 'Y';
+    }
+
+    /**
+     * Checks if user is keeping a local copy of forwarded mail.
+     *
+     * @param string $password  The password of the user.
+     *
+     * @return boolean  True if user is keeping a local copy of mail,
+     *                  otherwise false.
+     */
+    function isKeepLocal($password)
+    {
+        return true;
+    }
+
+    /**
+     * Retrieves current target of mail redirection for a user.
+     *
+     * @param string $password  The password of the user.
+     *
+     * @return string  The current forwarding mail address, false if no
+     *                 forwarding is set, or PEAR_Error on error.
+     */
+    function currentTarget($password)
+    {
+        // Make sure the configuration file is correct
+        if (is_a($checked = $this->_checkConfig($password), 'PEAR_Error')) {
+            return $checked;
+        }
+        return $this->_getUserDetails($password);
+    }
+
+    /**
+     * Retrieves the current forwards details for the user.
+     *
+     * @param string $password  The password for user.
+     *
+     * @return mixed  Target address if enabled, false if disabled, PEAR_Error
+     *                on failure.
+     */
+    function _getUserDetails($password)
+    {
+        if (!is_null($this->_details)) {
+            return $this->_details;
+        }
+
+        if (is_a($checked = $this->_checkConfig($password),
+                 'PEAR_Error')) {
+            return $checked;
+        }
+        @list($user,) = explode('@', $this->_user);
+
+        // Query the server.
+        $request = '<mail><get_info><filter><domain_id>'
+            . $this->_domain_id . '</domain_id><name>'
+            . htmlspecialchars($user)
+            . '</name></filter><redirect/></get_info></mail>';
+        $result = $this->_request($password, $request);
+        if (is_a($result, 'PEAR_Error')) {
+            return $result;
+        }
+        if (isset($result['mail']['get_info']['result']['status']['_']) &&
+            $result['mail']['get_info']['result']['status']['_'] == 'error') {
+            return PEAR::raiseError(sprintf(_("Cannot retrieve information about mail user %s: %s"), $this->_user, $result['mail']['get_info']['result']['errtext']['_']));
+        } elseif (!isset($result['mail']['get_info']['result']['status']['_']) ||
+                  $result['mail']['get_info']['result']['status']['_'] != 'ok' ||
+                  !isset($result['mail']['get_info']['result']['mailname'])) {
+            return PEAR::raiseError(sprintf(_("Cannot retrieve information about mail user %s."), $this->_user));
+        }
+
+        if (!isset($result['mail']['get_info']['result']['mailname']['redirect']) ||
+            $result['mail']['get_info']['result']['mailname']['redirect']['enabled']['_'] == 'false') {
+            $this->_details = false;
+        } else {
+            $this->_details = $result['mail']['get_info']['result']['mailname']['redirect']['address']['_'];
+        }
+
+        return $this->_details;
+    }
+
+    /**
+     * Checks if the realm has a specific configuration. If not, tries to fall
+     * back on the default configuration. If still not a valid configuration
+     * then returns an error.
+     *
+     * @param string $password  The password for the user.
+     */
+    function _checkConfig($password)
+    {
+        if (!(@include_once 'Horde/DOM.php')) {
+            return PEAR::raiseError(_("The Plesk driver requires the Horde_DOM package from Horde 3.2 or later. See http://pear.horde.org/index.php?package=Horde_DOM"));
+        }
+
+        // If no realm passed in, or no host config for the realm passed in,
+        // then we fall back to the default realm
+        if (empty($this->_params[$this->_realm]['host'])) {
+            $this->_realm = 'default';
+        }
+
+        if (!isset($this->_domain_id)) {
+            @list(, $domain) = explode('@', $this->_user, 2);
+            $request = '<domain><get><filter><domain_name>'
+                . htmlspecialchars($domain)
+                . '</domain_name></filter><dataset><gen_info/></dataset></get></domain>';
+            $result = $this->_request($password, $request);
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+            if (isset($result['domain']['get']['result']['status']['_']) &&
+                $result['domain']['get']['result']['status']['_'] == 'ok' &&
+                isset($result['domain']['get']['result']['id']['_'])) {
+                $this->_domain_id = $result['domain']['get']['result']['id']['_'];
+            } elseif (isset($result['domain']['get']['result']['status']['_']) &&
+                      $result['domain']['get']['result']['status']['_'] == 'error') {
+                return PEAR::raiseError(sprintf(_("Cannot retrieve domain ID of domain %s: %s"), $domain, $result['domain']['get']['result']['errtext']['_']));
+            } else {
+                return PEAR::raiseError(sprintf(_("Cannot retrieve domain ID of domain %s."), $domain));
+            }
+        }
+
+        // If still no host/port, then we have a misconfigured module.
+        if (empty($this->_params[$this->_realm]['host']) ||
+            empty($this->_params[$this->_realm]['user']) ||
+            empty($this->_params[$this->_realm]['pass'])) {
+            return PEAR::raiseError(_("The forwards application is not properly configured."));
+        }
+    }
+
+    /**
+     * Connects to the Plesk RPC API server and sends a request.
+     *
+     * @param string $password  The password to connect with.
+     * @param string $packet    The XML fragment for the request.
+     *
+     * @return boolean  True on success, PEAR_Error otherwise.
+     */
+    function _request($password, $packet)
+    {
+        if (!$this->_curl) {
+            $url = 'https://' . $this->_params[$this->_realm]['host']
+                . ':8443/enterprise/control/agent.php';
+            $headers = array(
+                'HTTP_AUTH_LOGIN: ' . $this->_params[$this->_realm]['user'],
+                'HTTP_AUTH_PASSWD: ' . $this->_params[$this->_realm]['pass'],
+                'Content-Type: text/xml');
+            $this->_curl = curl_init();
+            curl_setopt($this->_curl, CURLOPT_SSL_VERIFYHOST, 0);
+            curl_setopt($this->_curl, CURLOPT_SSL_VERIFYPEER, false);
+            curl_setopt($this->_curl, CURLOPT_HTTPHEADER, $headers);
+            curl_setopt($this->_curl, CURLOPT_URL, $url);
+            curl_setopt($this->_curl, CURLOPT_RETURNTRANSFER, true);
+        }
+
+        $content = '<?xml version="1.0" encoding="' . NLS::getCharset()
+            . '"?><packet version="1.4.2.0">' . $packet . '</packet>';
+        curl_setopt($this->_curl, CURLOPT_POSTFIELDS, $content);
+        $retval = curl_exec($this->_curl);
+        if ($retval === false) {
+            return PEAR::raiseError(curl_error($this->_curl));
+        }
+
+        $doc = Horde_DOM_Document::factory(
+            array('xml' => $retval,
+                  'options' => HORDE_DOM_LOAD_REMOVE_BLANKS));
+        $result = array();
+        $this->_parseResponse($doc->root(), $result);
+        if (isset($result['packet']['system']['status']['_']) &&
+            $result['packet']['system']['status']['_'] == 'error') {
+            return PEAR::raiseError($result['packet']['system']['errtext']['_']);
+        }
+
+        return $result['packet'];
+    }
+
+    /**
+     * Parses the XML response body of the Plesk API call into a hash.
+     *
+     * @param Horde_DOM_Node $node  A DOM node object.
+     * @param array $array          The result hash.
+     */
+    function _parseResponse($node, &$array)
+    {
+        $name = $node->node_name();
+        $element = array();
+        if (isset($array[$name])) {
+            $array[$name] = array($array[$name]);
+            $array[$name][] = &$element;
+        } else {
+            $array[$name] = &$element;
+        }
+        $array[$name] = array();
+        if ($node->has_child_nodes()) {
+            for ($child = $node->first_child();
+                 $child;
+                 $child = $child->next_sibling())  {
+                if ($child->node_type() == XML_TEXT_NODE) {
+                    $array[$name]['_'] = $child->node_value();
+                } else {
+                    $this->_parseResponse($child, $array[$name]);
+                }
+            }
+        }
+    }
+
+}
diff --git a/lib/Driver/qmail.php b/lib/Driver/qmail.php
old mode 100644
new mode 100755
index 6f11305..bed442e
--- a/lib/Driver/qmail.php
+++ b/lib/Driver/qmail.php
@@ -1,97 +1,57 @@
 <?php
+
+require_once dirname(__FILE__) . '/forwards.php';
+
 /**
  * Forwards_Driver_qmail:: implements the Forwards_Driver API for FTP driven
  * Qmail mail servers.
  *
- * $Horde: forwards/lib/Driver/qmail.php,v 1.17.2.2 2007/01/02 13:54:06 jan Exp $
+ * $Horde: forwards/lib/Driver/qmail.php,v 1.17.2.4 2009/01/06 15:22:46 jan Exp $
  *
- * Copyright 2001-2007 Eric Rostetter <eric.rostetter at physics.utexas.edu>
+ * Copyright 2001-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (BSDL). If you
  * did not receive this file, see http://www.horde.org/licenses/bsdl.php.
  *
  * @author  Eric Rostetter <eric.rostetter at physics.utexas.edu>
+ * @author  Jan Schneider <jan at horde.org>
  * @since   Forwards 2.2
  * @package Forwards
  */
-class Forwards_Driver_qmail extends Forwards_Driver {
+class Forwards_Driver_qmail extends Forwards_Driver_forwards {
 
     /**
-     * The FTP stream we open via the VFS class.
+     * The name of the forwards file.
      *
-     * @var VFS_ftp
+     * @var string
      */
-    var $_vfs;
+    var $_forwardsFile = '.qmail';
 
     /**
-     * Checks if the realm has a specific configuration.
+     * Checks if user is keeping a local copy of forwarded mail.
      *
-     * If not, try to fall back on the default configuration.  If
-     * still not a valid configuration then exit with an error.
+     * @todo Implement this method.
+     *
+     * @param string $password  The password of the user.
      *
-     * @param string $realm  The realm of the user, or "default" if none.
-     *                       Note: passed by reference so we can change
-     *                       its value!
+     * @return boolean  True if user is keeping a local copy of mail,
+     *                  otherwise false.
      */
-    function checkConfiguration(&$realm)
+    function isKeepLocal($password)
     {
-        // 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->_error = _("The module is not properly configured!");
-            return false;
-        }
-        return true;
+        return false;
     }
 
     /**
-     * Begins forwarding of mail for a user.
+     * Creates the main forwards file.
      *
-     * @param string $user        The username of the user.
-     * @param string $realm       The realm of the user.
-     * @param string $password    The password of the user.
      * @param string $target      The email address that mail should be
      *                            forwarded to.
      * @param boolean $keeplocal  Keep a copy of forwarded mail in the local
      *                            mailbox.
-     *
-     * @return boolean  True on success, false otherwise.
      */
-    function enableForwarding($user, $realm = 'default', $password, $target,
-                              $keeplocal = false)
+    function _createForwardsFile($target, $keeplocal = false)
     {
-        // Make sure the configuration file is correct.
-        if (!$this->checkConfiguration($realm)) {
-            return false;
-        }
-
-        // Build the ftp array to pass to VFS.
-        $_args = array('hostspec' => $this->_params[$realm]['host'],
-                       'port' => $this->_params[$realm]['port'],
-                       'pasv' => $this->_params[$realm]['pasv'],
-                       'username' => $user,
-                       'password' => $password);
-
-        // Create the VFS ftp driver.
-        require_once 'VFS.php';
-        $_vfs = &VFS::singleton('ftp', $_args);
-        $_vfs->setParams($_args);
-
-        // Try to login with the username/password, no realm. This
-        // isn't really needed, but allows for a better error message.
-        $status = $_vfs->checkCredentials();
-        if (is_a($status, 'PEAR_Error')) {
-            $this->_error = $status->getMessage();
-            $this->_error .= '  ' .  _("Check your username and password");
-            return false;
-        }
-
         // Create the forwarding information.
         $address = '&' . $target;
         if ($keeplocal == 'on') {
@@ -99,124 +59,25 @@ class Forwards_Driver_qmail extends Forwards_Driver {
         }
 
         // Set the forward.
-        $status = $_vfs->writeData('', '.qmail', $address);
+        $status = $this->_vfs->writeData('', '.qmail', $address);
         if (is_a($status, 'PEAR_Error')) {
-            $this->_error = $status->getMessage();
-            return false;
+            return $status;
         }
 
         // Try to change the permissions, but ignore any errors.
-        $_vfs->changePermissions('', '.qmail', '0600');
-
-        return true;
-    }
-
-    /**
-     * Stops forwarding of mail for a user.
-     *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
-     * @param string $password  The password of the user.
-     *
-     * @return boolean  True on success, false otherwise.
-     */
-    function disableForwarding($user, $realm = 'default', $password)
-    {
-        if (!$this->checkConfiguration($realm)) {
-            return false;
-        }
-
-        $_args = array('hostspec' => $this->_params[$realm]['host'],
-                       'port' => $this->_params[$realm]['port'],
-                       'pasv' => $this->_params[$realm]['pasv'],
-                       'username' => $user,
-                       'password' => $password);
-
-        require_once 'VFS.php';
-        $_vfs = &VFS::singleton('ftp', $_args);
-        $_vfs->setParams($_args);
-
-        // Try to login with the username/password, no realm.
-        $status = $_vfs->checkCredentials();
-        if (is_a($status, 'PEAR_Error')) {
-            $this->_error = $status->getMessage();
-            $this->_error .= '  ' .  _("Check your username and password");
-            return false;
-        }
-
-        $status = $_vfs->deleteFile('', '.qmail');
-        if (is_a($status, 'PEAR_Error')) {
-            $this->_error = $status->getMessage();
-            $this->_error .= '  ' .  _("Maybe you didn't have a forward enabled?");
-            return false;
-        }
-
-        return true;
+        $this->_vfs->changePermissions('', '.qmail', '0600');
     }
 
     /**
-     * Retrieves current target of mail redirection for a user.
+     * Parses the target information out of the forwards file content.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
-     * @param string $password  The password of the user.
+     * @param string $content  The file content.
      *
-     * @return mixed  The current forwarding mail address, or false.
+     * @return string  The forwards target.
      */
-    function currentTarget($user, $realm = 'default', $password)
+    function _parseForwardsFile($content)
     {
-        // Make sure the configuration file is correct.
-        if (!$this->checkConfiguration($realm)) {
-            return false;
-        }
-
-        // Build the ftp array to pass to VFS.
-        $_args = array('hostspec' => $this->_params[$realm]['host'],
-                       'port' => $this->_params[$realm]['port'],
-                       'pasv' => $this->_params[$realm]['pasv'],
-                       'username' => $user,
-                       'password' => $password);
-
-        // Create the VFS ftp driver.
-        require_once 'VFS.php';
-        $_vfs = &VFS::singleton('ftp', $_args);
-        $_vfs->setParams($_args);
-
-        // Try to login with the username/password, no realm.
-        $status = $_vfs->checkCredentials();
-        if (is_a($status, 'PEAR_Error')) {
-            $this->_error = $status->getMessage();
-            $this->_error .= '  ' .  _("Check your username and password");
-            return false;
-        }
-
-        $status = $_vfs->read('', '.qmail');
-        if (is_a($status, 'PEAR_Error')) {
-            $this->_error = $status->getMessage();
-            return false;
-        }
-        return $status;
-    }
-
-    /**
-     * Retrieves current state of mail redirection for a user.
-     *
-     * @todo This function is implemented poorly, and should be rewritten.
-     *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
-     * @param string $password  The password of the user.
-     *
-     * @return mixed  'Y' if forwarding is enabled, or false otherwise.
-     */
-    function isEnabledForwarding($user, $realm, $password)
-    {
-        $yn = $this->currentTarget($user, $realm, $password);
-        if ($yn) {
-            return 'Y';
-        } else {
-            return false;
-        }
+        return preg_replace('/&(.*)(\n.*)?/', '$1', $content);
     }
 
 }
diff --git a/lib/Driver/soap.php b/lib/Driver/soap.php
index 26bf713..3ae4cd6 100644
--- a/lib/Driver/soap.php
+++ b/lib/Driver/soap.php
@@ -6,14 +6,15 @@ require_once 'SOAP/Client.php';
  * Forwards_Driver_soap:: implements the Forwards_Driver API for SOAP
  * services.
  *
- * $Horde: forwards/lib/Driver/soap.php,v 1.8.2.2 2007/01/02 13:54:06 jan Exp $
+ * $Horde: forwards/lib/Driver/soap.php,v 1.8.2.4 2009/01/06 15:22:46 jan Exp $
  *
- * Copyright 2004-2007 Marc Jauvin <marc at r4l.com>
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (BSDL). If you
  * did not receive this file, see http://www.horde.org/licenses/bsdl.php.
  *
  * @author  Marc Jauvin <marc at r4l.com>
+ * @author  Jan Schneider <jan at horde.org>
  * @since   Forwards 3.0
  * @package Forwards
  */
@@ -34,230 +35,202 @@ class Forwards_Driver_soap extends Forwards_Driver {
     var $_initialised = false;
 
     /**
-     * Initialise the SOAP connection object.
+     * Begins forwarding of mail for a user.
      *
-     * @return boolean  True or False based on success of connect.
+     * @param string $password    The password of the user.
+     * @param string $target      The email address that mail should be
+     *                            forwarded to.
+     * @param boolean $keeplocal  Keep a copy of forwarded mail in the local
+     *                            mailbox.
      */
-    function _initialise()
+    function enableForwarding($password, $target, $keeplocal = false)
     {
-        if (!$this->_initialised) {
-            Horde::assertDriverConfig($this->_params, 'server',
-                array(
-                    'soap_proxy',
-                    'soap_uri',
-                    'fwd_fetch_func',
-                    'fwd_enable_func',
-                    'fwd_disable_func',
-                    'username_varname',
-                    'target_varname',
-                    'keeplocal_varname',
-                ),
-                'SOAP initialisation'
-            );
-
-            $this->_client = &new SOAP_Client($this->_params['soap_proxy']);
-            $this->_client->setOpt('curl', CURLOPT_FAILONERROR, false);
-            $this->_client->setOpt('curl', CURLOPT_SSL_VERIFYPEER, false);
-
-            $this->_initialised = true;
+        // _initialise() will die with Horde::fatal() upon failure.
+        $this->_initialise();
+
+        // Build username.
+        $account = $this->_buildUsername();
+
+        $data[$this->_params['username_varname']] = $account;
+        if ($password && $this->_params['password_varname']) {
+            $data[$this->_params['password_varname']] = $password;
         }
+        $data[$this->_params['target_varname']] = $target;
+        $data[$this->_params['keeplocal_varname']] = ($keeplocal === 'on') ? 1 : 0;
+
+        $args = new SOAP_Value('args', 'array', $data);
 
-        return true;
+        $result = $this->_client->call($this->_params['fwd_enable_func'], $args,
+                                       $this->_params['soap_uri']);
+        if (is_a($result, 'PEAR_Error')) {
+            return $result;
+        }
     }
 
     /**
-     * Retrieves user details from the backend.
+     * Stops forwarding of mail for a user.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
      * @param string $password  The password of the user.
-     *
-     * @return mixed  SOAP result resource or (boolean) False.
      */
-    function _getUserDetails($user, $realm, $password)
+    function disableForwarding($password)
     {
         // _initialise() will die with Horde::fatal() upon failure.
         $this->_initialise();
 
-        if ($this->_current_details) {
-            return $this->_current_details;
-        }
-
         // Build username.
-        $account = $this->_buildUsername($user, $realm);
+        $account = $this->_buildUsername();
 
         $data[$this->_params['username_varname']] = $account;
-        $args = &new SOAP_Value("args", "array", $data);
+        if ($password && $this->_params['password_varname']) {
+            $data[$this->_params['password_varname']] = $password;
+        }
 
-        $result = $this->_client->call($this->_params['fwd_fetch_func'], $args, $this->_params['soap_uri']);
+        $args = new SOAP_Value('args', 'array', $data);
 
+        $result = $this->_client->call($this->_params['fwd_disable_func'],
+                                       $args, $this->_params['soap_uri']);
         if (is_a($result, 'PEAR_Error')) {
-            $this->_current_details = array();
-            return false;
-        } else {
-            $this->_current_details = get_object_vars($result);
-            return $this->_current_details;
+            return $result;
         }
     }
 
     /**
      * Retrieves current state of mail redirection for a user.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
      * @param string $password  The password of the user.
      *
-     * @return boolean  True if forwarding is enabled, or false otherwise.
+     * @return mixed  Returns 'Y' if forwarding is enabled for the user, 'N' if
+     *                forwarding is currently disabled, false if the status
+     *                cannot be determined, and PEAR_Error on error.
      */
-    function isEnabledForwarding($user, $realm, $password)
+    function isEnabledForwarding($password)
     {
         // Get current details.
-        $current_details = $this->_getUserDetails($user, $realm, $password);
-        if ($current_details === false) {
-            return false;
+        $current_details = $this->_getUserDetails($password);
+        if ($current_details === false ||
+            is_a($current_details, 'PEAR_Error')) {
+            return $current_details;
         }
 
         // Check forwarding flag.
-        if ($current_details[$this->_params['target_varname']]) {
-            return true;
-        } else {
-            return false;
-        }
+        return (bool)$current_details[$this->_params['target_varname']];
     }
 
     /**
      * Checks if user is keeping a local copy of forwarded mail.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
      * @param string $password  The password of the user.
      *
      * @return boolean  True if user is keeping a local copy of mail,
      *                  otherwise false.
      */
-    function isKeepLocal($user, $realm, $password)
+    function isKeepLocal($password)
     {
         // Get current details.
-        $current_details = $this->_getUserDetails($user, $realm, $password);
-        if ($current_details === false) {
-            return false;
+        $current_details = $this->_getUserDetails($password);
+        if ($current_details === false ||
+            is_a($current_details, 'PEAR_Error')) {
+            return $current_details;
         }
 
-        if ($current_details[$this->_params['keeplocal_varname']]) {
-            return true;
-        } else {
-            return false;
-        }
+        return (bool)$current_details[$this->_params['keeplocal_varname']];
     }
 
     /**
      * Retrieves current target of mail redirection for a user.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
      * @param string $password  The password of the user.
      *
-     * @return string  The current forwarding mail address, or false on error.
+     * @return string  The current forwarding mail address, false if no
+     *                 forwarding is set, or PEAR_Error on error.
      */
-    function currentTarget($user, $realm, $password)
+    function currentTarget($password)
     {
-        $current_details = $this->_getUserDetails($user, $realm, $password);
+        $current_details = $this->_getUserDetails($password);
+        if ($current_details === false ||
+            is_a($current_details, 'PEAR_Error')) {
+            return $current_details;
+        }
 
         if ($current_details[$this->_params['target_varname']]) {
             return $current_details[$this->_params['target_varname']];
-        } else {
-            return false;
         }
     }
 
     /**
-     * Begins forwarding of mail for a user.
-     *
-     * @param string $user        The username of the user.
-     * @param string $realm       The realm of the user.
-     * @param string $password    The password of the user.
-     * @param string $target      The email address that mail should be
-     *                            forwarded to.
-     * @param boolean $keeplocal  Keep a copy of forwarded mail in the local
-     *                            mailbox.
+     * Builds a username based on presence of realm.
      *
-     * @return boolean  True on success, false otherwise.
+     * @return string  Fully qualified username.
      */
-    function enableForwarding($user, $realm, $password, $target, $keeplocal)
+    function _buildUsername()
     {
-        // _initialise() will die with Horde::fatal() upon failure.
-        $this->_initialise();
-
-        // Build username.
-        $account = $this->_buildUsername($user, $realm);
-
-        $data[$this->_params['username_varname']] = $account;
-        if ($password && $this->_params['password_varname']) {
-            $data[$this->_params['password_varname']] = $password;
-        }
-        $data[$this->_params['target_varname']] = $target;
-        $data[$this->_params['keeplocal_varname']] = ($keeplocal === 'on') ? 1 : 0;
-
-        $args = &new SOAP_Value('args', 'array', $data);
-
-        $result = $this->_client->call($this->_params['fwd_enable_func'], $args, $this->_params['soap_uri']);
-        if (is_a($result, 'PEAR_Error')) {
-            $this->_current_details = array();
-            return false;
+        if ($this->_realm === 'default' ||
+            $this->_realm == '') {
+            return $this->_user;
+        } else {
+            return $this->_user . '@' . $this->_realm;
         }
-
-        return true;
     }
 
     /**
-     * Stops forwarding of mail for a user.
+     * Retrieves user details from the backend.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
      * @param string $password  The password of the user.
      *
-     * @return boolean  True on success, false otherwise.
+     * @return mixed  SOAP result resource or PEAR_Error.
      */
-    function disableForwarding($user, $realm, $password)
+    function _getUserDetails($password)
     {
         // _initialise() will die with Horde::fatal() upon failure.
         $this->_initialise();
 
+        if ($this->_current_details) {
+            return $this->_current_details;
+        }
+
         // Build username.
-        $account = $this->_buildUsername($user, $realm);
+        $account = $this->_buildUsername();
 
         $data[$this->_params['username_varname']] = $account;
-        if ($password && $this->_params['password_varname']) {
-            $data[$this->_params['password_varname']] = $password;
-        }
+        $args = new SOAP_Value('args', 'array', $data);
 
-        $args = &new SOAP_Value("args", "array", $data);
+        $result = $this->_client->call($this->_params['fwd_fetch_func'], $args,
+                                       $this->_params['soap_uri']);
 
-        $result = $this->_client->call($this->_params['fwd_disable_func'], $args, $this->_params['soap_uri']);
         if (is_a($result, 'PEAR_Error')) {
             $this->_current_details = array();
-            return false;
+            return $result;
         }
 
-        return true;
+        $this->_current_details = get_object_vars($result);
+        return $this->_current_details;
     }
 
     /**
-     * Builds a username based on presence of realm.
-     *
-     * @param string $user   Username.
-     * @param string $realm  Realm name.
-     *
-     * @return string  Fully qualified username.
+     * Initialises the SOAP connection object.
      */
-    function _buildUsername($user, $realm)
+    function _initialise()
     {
-        if ($realm === 'default' ||
-            $realm == '') {
-            return $user;
-        } else {
-            return $user . '@' . $realm;
+        if ($this->_initialised) {
+            return;
         }
+
+        Horde::assertDriverConfig($this->_params, 'server',
+                                  array('soap_proxy',
+                                        'soap_uri',
+                                        'fwd_fetch_func',
+                                        'fwd_enable_func',
+                                        'fwd_disable_func',
+                                        'username_varname',
+                                        'target_varname',
+                                        'keeplocal_varname'),
+                                  'SOAP initialisation');
+
+        $this->_client = new SOAP_Client($this->_params['soap_proxy']);
+        $this->_client->setOpt('curl', CURLOPT_FAILONERROR, false);
+        $this->_client->setOpt('curl', CURLOPT_SSL_VERIFYPEER, false);
+
+        $this->_initialised = true;
     }
 
 }
diff --git a/lib/Driver/sql.php b/lib/Driver/sql.php
index 3c82136..7818255 100644
--- a/lib/Driver/sql.php
+++ b/lib/Driver/sql.php
@@ -1,351 +1,163 @@
 <?php
+
+require_once dirname(__FILE__) . '/customsql.php';
+
 /**
  * Forwards_Driver_sql:: implements the Forwards_Driver API for SQL servers.
  *
- * $Horde: forwards/lib/Driver/sql.php,v 1.29.2.2 2007/01/02 13:54:06 jan Exp $
+ * $Horde: forwards/lib/Driver/sql.php,v 1.29.2.4 2009/01/06 15:22:46 jan Exp $
  *
- * Copyright 2001-2007 Ilya Krel <mail at krel.org>
- * Copyright 2001-2007 Mike Cochrane <mike at graftonhall.co.nz>
+ * Copyright 2001-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (BSDL). If you
  * did not receive this file, see http://www.horde.org/licenses/bsdl.php.
  *
  * @author  Ilya Krel <mail at krel.org>
  * @author  Mike Cochrane <mike at graftonhall.co.nz>
+ * @author  Jan Schneider <jan at horde.org>
  * @since   Forwards 2.1
  * @package Forwards
  */
-class Forwards_Driver_sql extends Forwards_Driver {
-
-    /**
-     * SQL connection object.
-     *
-     * @var DB
-     */
-    var $_db;
+class Forwards_Driver_sql extends Forwards_Driver_customsql {
 
     /**
-     * State of SQL connection.
+     * List of required parameters.
      *
-     * @var boolean
+     * @var array
      */
-    var $_connected = false;
+    var $_requiredParams = array('phptype', 'table');
 
     /**
-     * Constructs a new Forwards_Driver_sql object.
+     * Constructor.
      *
+     * @param string $user   A user name.
+     * @param string $realm  The realm of the user.
      * @param array $params  A hash containing connection parameters.
      */
-    function Forwards_Driver_sql($params = null)
+    function Forwards_Driver_sql($user, $realm, $params = null)
     {
-        if (is_null($params)) {
-            $params = Horde::getDriverConfig('server', 'sql');
-        }
-        parent::Forwards_Driver($params);
-    }
-
-    /**
-     * Disconnect from the SQL server and clean up the connection.
-     *
-     * @return boolean  True on success, false otherwise.
-     */
-    function _disconnect()
-    {
-        if ($this->_connected) {
-            $this->_connected = false;
-            return $this->_db->disconnect();
-        }
-
-        return true;
+        parent::Forwards_Driver_customsql($user, $realm, $params);
+        $this->_params['query_select'] = 'SELECT * FROM '
+            . $this->_params[$this->_realm]['table']
+            . ' WHERE ' . $this->_params[$this->_realm]['user_col'] . ' = \U'
+            . ' AND ' . $this->_params[$this->_realm]['pass_col'] . ' = \P';
     }
 
     /**
      * Begins forwarding of mail for a user.
      *
-     * @param string $user        The username of the user.
-     * @param string $realm       The realm of the user.
      * @param string $password    The password of the user.
      * @param string $target      The email address that mail should be
      *                            forwarded to.
      * @param boolean $keeplocal  Keep a copy of forwarded mail in the local
      *                            mailbox.
-     *
-     * @return boolean  True on success, false otherwise.
      */
-    function enableForwarding($user, $realm, $password, $target, $keeplocal)
+    function enableForwarding($password, $target, $keeplocal)
     {
-        // _connect() will die with Horde::fatal() upon failure.
-        $this->_connect();
-        $local_target = $user . '@' . $realm;
-
-        // Build username.
-        $myuser = $this->_buildUsername($user, $realm);
-
         // Build the SQL query.
-        $query = 'UPDATE ' . $this->_params['table'] .
-                 ' SET ' . $this->_params['forward'] . ' = ?' .
-                 ' WHERE ' . $this->_params['user_col'] . ' = ?' .
-                 ' AND ' . $this->_params['pass_col'] . ' = ?';
-        $values = array('y', $myuser, md5($password));
-
-        $query1 = 'UPDATE ' . $this->_params['table'];
-        $values1 = array();
-        if ($keeplocal === 'on') {
-            if (!strstr($target, $local_target)) {
-                $query1 .= ' SET ' . $this->_params['altemail'] . ' = ?';
-                $values1[] = $target . ',' . $local_target;
-            }
-        } else {
-            $query1 .= ' SET ' . $this->_params['altemail'] . ' = ?';
-            $values1[] = $target;
-        }
-        $query1 .= ' WHERE ' . $this->_params['user_col'] . ' = ?' .
-                   ' AND ' . $this->_params['pass_col'] . ' = ?';
-        array_push($values1, $myuser, md5($password));
+        $query = 'UPDATE ' . $this->_params[$this->_realm]['table']
+            . ' SET ' . $this->_params[$this->_realm]['forward'] . ' = \'Y\', '
+            . $this->_params[$this->_realm]['altemail'] . ' = \T'
+            . ' WHERE ' . $this->_params[$this->_realm]['user_col'] . ' = \U'
+            . ' AND ' . $this->_params[$this->_realm]['pass_col'] . ' = \P';
 
-        // Execute the query.
-        $result = $this->_db->query($query, $values);
-        $result1 = $this->_db->query($query1, $values1);
-
-        if (!is_a($result, 'PEAR_Error') && !is_a($result1, 'PEAR_Error')) {
-            if ($result === DB_OK && $result1 === DB_OK) {
-                $this->_disconnect();
-                return true;
-            }
+        // Build username.
+        $myuser = $this->_buildUsername();
+        if ($keeplocal === 'on' && !strstr($target, $myuser)) {
+            $target .= ',' . $myuser;
         }
 
-        $this->_disconnect();
-        return false;
+        return $this->_enableForwarding($query, md5($password), $target);
     }
 
     /**
      * Stops forwarding of mail for a user.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
      * @param string $password  The password of the user.
-     *
-     * @return boolean  True on success, false otherwise.
      */
-    function disableForwarding($user, $realm, $password)
+    function disableForwarding($password)
     {
-        // _connect() will die with Horde::fatal() upon failure.
-        $this->_connect();
-
-        // Build username.
-        $myuser = $this->_buildUsername($user, $realm);
-
         // Build the SQL query.
-        $query = 'UPDATE ' . $this->_params['table'] .
-                 ' SET ' . $this->_params['forward'] . ' = ?,' .
-                 ' ' . $this->_params['altemail'] . ' = ?' .
-                 ' WHERE ' . $this->_params['user_col'] . ' = ?' .
-                 ' AND ' . $this->_params['pass_col'] . ' = ?';
-        $values = array('n', '', $myuser, md5($password));
-
-        // Execute the query.
-        $result = $this->_db->query($query, $values);
-
-        if (!is_a($result, 'PEAR_Error')) {
-            if ($result === DB_OK) {
-                $this->_disconnect();
-                return true;
-            }
-        }
+        $query = 'UPDATE ' . $this->_params[$this->_realm]['table'] .
+                 ' SET ' . $this->_params[$this->_realm]['forward'] . ' = \'N\',' .
+                 ' ' . $this->_params[$this->_realm]['altemail'] . ' = \'\'' .
+                 ' WHERE ' . $this->_params[$this->_realm]['user_col'] . ' = \U' .
+                 ' AND ' . $this->_params[$this->_realm]['pass_col'] . ' = \P';
 
-        $this->_disconnect();
-        return false;
+        return $this->_disableForwarding($query, md5($password));
     }
 
     /**
      * Retrieves current state of mail redirection for a user.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
      * @param string $password  The password of the user.
      *
-     * @return mixed  'Y' if forwarding is enabled, or false.
+     * @return mixed  Returns 'Y' if forwarding is enabled for the user, 'N' if
+     *                forwarding is currently disabled, false if the status
+     *                cannot be determined, and PEAR_Error on error.
      */
-    function isEnabledForwarding($user, $realm, $password)
+    function isEnabledForwarding($password)
     {
-        // Build username.
-        $myuser = $this->_buildUsername($user, $realm);
-
-        // get current details
-        $current_details = $this->_getUserDetails($myuser, $realm, $password);
-        if ($current_details === false) {
-            return false;
+        // Get current details.
+        $current_details = $this->_getUserDetails(md5($password));
+        if ($current_details === false ||
+            is_a($current_details, 'PEAR_Error')) {
+            return $current_details;
         }
 
-        // check forwarding flag
-        if ($current_details[$this->_params['forward']] === 'y' ||
-             $current_details[$this->_params['forward']] === 'Y') {
+        // Check forwarding flag.
+        if ($current_details[$this->_params[$this->_realm]['forward']] === 'y' ||
+            $current_details[$this->_params[$this->_realm]['forward']] === 'Y') {
             return 'Y';
-        } else {
-            return false;
         }
+        if ($current_details[$this->_params[$this->_realm]['forward']] === 'n' ||
+            $current_details[$this->_params[$this->_realm]['forward']] === 'N') {
+            return 'N';
+        }
+        return false;
     }
 
     /**
      * Checks if user is keeping a local copy of forwarded mail.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
      * @param string $password  The password of the user.
      *
      * @return boolean  True if user is keeping a local copy of mail,
      *                  otherwise false.
      */
-    function isKeepLocal($user, $realm, $password)
+    function isKeepLocal($password)
     {
-        // Build username.
-        $myuser = $this->_buildUsername($user, $realm);
-
         // Get current details.
-        $current_details = $this->_getUserDetails($myuser, $realm, $password);
-        if ($current_details === false) {
-            return false;
+        $current_details = $this->_getUserDetails(md5($password));
+        if ($current_details === false ||
+            is_a($current_details, 'PEAR_Error')) {
+            return $current_details;
         }
 
         // Check retain copy flag.
-        if (substr_count($current_details[$this->_params['altemail']], $user . '@' . $realm)) {
-            return true;
-        } else {
-            return false;
-        }
+        return false !== strpos($current_details[$this->_params[$this->_realm]['altemail']],
+                                $this->_buildUsername());
     }
 
     /**
      * Retrieves current target of mail redirection for a user.
      *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
-     * @param string $password  The password of the user.
-     *
-     * @return string  The current forwarding mail address, or false on error.
-     */
-    function currentTarget($user, $realm, $password)
-    {
-        $searchString = ",$user@$realm";
-        $current_details = $this->_getUserDetails($user, $realm, $password);
-
-        // Check current forwarding mail address.
-        $targets = $current_details[$this->_params['altemail']];
-        return str_replace($searchString, "", $current_details[$this->_params['altemail']]);
-    }
-
-    /**
-     * Retrieves user details from the backend.
-     *
-     * @param string $user      The username of the user.
-     * @param string $realm     The realm of the user.
      * @param string $password  The password of the user.
      *
-     * @return array|boolean  Hash with user details, or false.
+     * @return string  The current forwarding mail address, false if no
+     *                 forwarding is set, or PEAR_Error on error.
      */
-    function _getUserDetails($user, $realm, $password)
+    function currentTarget($password)
     {
-        static $row;
-
-        // If we already have the details, return now.
-        if (isset($row)) {
-            return $row;
+        $current_details = $this->_getUserDetails(md5($password));
+        if ($current_details === false ||
+            is_a($current_details, 'PEAR_Error')) {
+            return $current_details;
         }
 
-        // _connect() will die with Horde::fatal() upon failure.
-        $this->_connect();
-
-        // Build username.
-        $myuser = $this->_buildUsername($user, $realm);
-
-        // Build the SQL query.
-        $query = 'SELECT * FROM ' . $this->_params['table'] .
-                 ' WHERE ' . $this->_params['user_col'] . ' = ?' .
-                 ' AND ' . $this->_params['pass_col'] . ' = ?';
-        $values = array($myuser, md5($password));
-
-        // Execute the query.
-        $result = $this->_db->query($query, $values);
-
-        if (!is_a($result, 'PEAR_Error')) {
-            $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
-
-            if (is_array($row)) {
-                $this->_disconnect();
-                return $row;
-            } else {
-                $this->_disconnect();
-                $result->free();
-                return false;
-            }
-        }
-
-        $this->_disconnect();
-        return false;
-    }
-
-    /**
-     * Builds a username based on presence of realm.
-     *
-     * @param string $user   Username.
-     * @param string $realm  Realm name.
-     *
-     * @return string  Fully qualified username.
-     */
-    function _buildUsername($user, $realm)
-    {
-        if ($realm === 'default' ||
-            $realm === '') {
-            return $user;
-        } else {
-            return $user . '@' . $realm;
-        }
-    }
-
-    /**
-     * Connects to SQL server and logs in as user with privilege to change
-     * password.
-     *
-     * @return boolean  True on success, false otherwise.
-     */
-    function _connect()
-    {
-        if (!$this->_connected) {
-            Horde::assertDriverConfig($this->_params, 'server',
-                array('phptype', 'table'),
-                'Forwards SQL');
-
-            if (!isset($this->_params['database'])) {
-                $this->_params['database'] = '';
-            }
-            if (!isset($this->_params['username'])) {
-                $this->_params['username'] = '';
-            }
-            if (!isset($this->_params['hostspec'])) {
-                $this->_params['hostspec'] = '';
-            }
-
-            // Connect to SQL server using supplied parameters.
-            include_once 'DB.php';
-            $this->_db = &DB::connect($this->_params,
-                                      array('persistent' => !empty($this->_params['persistent'])));
-            if (is_a($this->_db, 'PEAR_Error')) {
-                Horde::fatal(PEAR::raiseError(_("Unable to connect to SQL server.")), __FILE__, __LINE__);
-            }
-
-            // Set DB portability options.
-            switch ($this->_db->phptype) {
-            case 'mssql':
-                $this->_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS | DB_PORTABILITY_RTRIM);
-                break;
-            default:
-                $this->_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
-            }
-
-            $this->_connected = true;
-        }
-
-        return true;
+        // Check current forwarding mail address.
+        return str_replace(',' . $this->_buildUsername(), '',
+                           $current_details[$this->_params[$this->_realm]['altemail']]);
     }
 
 }
diff --git a/lib/base.php b/lib/base.php
index 4232faf..0c74775 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -5,9 +5,9 @@
  * This file brings in all of the dependencies that every Forwards script will
  * need, and sets up objects that all scripts use.
  *
- * $Horde: forwards/lib/base.php,v 1.38.2.2 2007/01/02 13:54:05 jan Exp $
+ * $Horde: forwards/lib/base.php,v 1.38.2.5 2009/01/06 15:22:46 jan Exp $
  *
- * Copyright 2001-2007 Eric Rostetter <eric.rostetter at physics.utexas.edu>
+ * Copyright 2001-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (BSDL). If you
  * did not receive this file, see http://www.horde.org/licenses/bsdl.php.
@@ -37,7 +37,7 @@ $conf = &$GLOBALS['conf'];
 $notification = &Notification::singleton();
 $notification->attach('status');
 
-// Don't allow access unless there is a Horde login. NOTE: We explicitely do
+// Don't allow access unless there is a Horde login. NOTE: We explicitly do
 // NOT honor the guests flag here.
 if (!Auth::isAuthenticated()) {
     Horde::authenticationFailureRedirect();
diff --git a/lib/version.php b/lib/version.php
index 190e4f4..3aef8f9 100644
--- a/lib/version.php
+++ b/lib/version.php
@@ -1 +1 @@
-<?php define('FORWARDS_VERSION', 'H3 (3.0.1)') ?>
+<?php define('FORWARDS_VERSION', 'H3 (3.1)') ?>
diff --git a/locale/cs_CZ/LC_MESSAGES/forwards.mo b/locale/cs_CZ/LC_MESSAGES/forwards.mo
index 9a1d642..ca49b1f 100644
Binary files a/locale/cs_CZ/LC_MESSAGES/forwards.mo and b/locale/cs_CZ/LC_MESSAGES/forwards.mo differ
diff --git a/locale/de_DE/LC_MESSAGES/forwards.mo b/locale/de_DE/LC_MESSAGES/forwards.mo
index 6d0f248..fc2526b 100644
Binary files a/locale/de_DE/LC_MESSAGES/forwards.mo and b/locale/de_DE/LC_MESSAGES/forwards.mo differ
diff --git a/locale/en_US/help.xml b/locale/en_US/help.xml
index 8928187..be2ed7f 100644
--- a/locale/en_US/help.xml
+++ b/locale/en_US/help.xml
@@ -1,5 +1,5 @@
 <?xml version='1.0'?>
-<!-- $Horde: forwards/locale/en_US/help.xml,v 1.2 2005/02/09 14:21:57 jan Exp $ -->
+<!-- $Horde: forwards/locale/en_US/help.xml,v 1.2.2.1 2008/10/09 17:36:39 jan Exp $ -->
 <help>
 
 <entry id="problem-button">
diff --git a/locale/es_ES/LC_MESSAGES/forwards.mo b/locale/es_ES/LC_MESSAGES/forwards.mo
index f1d871c..878eeb8 100644
Binary files a/locale/es_ES/LC_MESSAGES/forwards.mo and b/locale/es_ES/LC_MESSAGES/forwards.mo differ
diff --git a/locale/es_ES/help.xml b/locale/es_ES/help.xml
index c982815..2858391 100644
--- a/locale/es_ES/help.xml
+++ b/locale/es_ES/help.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<!-- $Horde: forwards/locale/es_ES/help.xml,v 1.1 2006/02/03 10:57:17 jan Exp $ -->
+<!-- $Horde: forwards/locale/es_ES/help.xml,v 1.1.2.1 2008/10/09 17:36:39 jan Exp $ -->
 <help>
 
 <entry id="problem-button" md5="c370763f2b46f373da7df4050c8afd59" state="uptodate">
diff --git a/locale/fi_FI/LC_MESSAGES/forwards.mo b/locale/fi_FI/LC_MESSAGES/forwards.mo
index a3eec6c..a915975 100644
Binary files a/locale/fi_FI/LC_MESSAGES/forwards.mo and b/locale/fi_FI/LC_MESSAGES/forwards.mo differ
diff --git a/locale/fi_FI/help.xml b/locale/fi_FI/help.xml
index 8d656d6..3a22dd5 100644
--- a/locale/fi_FI/help.xml
+++ b/locale/fi_FI/help.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<!-- $Horde: forwards/locale/fi_FI/help.xml,v 1.1 2005/03/16 15:30:28 jan Exp $ -->
+<!-- $Horde: forwards/locale/fi_FI/help.xml,v 1.1.2.1 2008/10/09 17:36:40 jan Exp $ -->
 <help>
   <entry id="problem-button" md5="c370763f2b46f373da7df4050c8afd59" state="uptodate">
     <title>Valikkopainikkeet: Problem?</title>
diff --git a/locale/fr_FR/LC_MESSAGES/forwards.mo b/locale/fr_FR/LC_MESSAGES/forwards.mo
index 1af877b..45b3e48 100644
Binary files a/locale/fr_FR/LC_MESSAGES/forwards.mo and b/locale/fr_FR/LC_MESSAGES/forwards.mo differ
diff --git a/locale/hu_HU/LC_MESSAGES/forwards.mo b/locale/hu_HU/LC_MESSAGES/forwards.mo
index 319405b..3a94175 100644
Binary files a/locale/hu_HU/LC_MESSAGES/forwards.mo and b/locale/hu_HU/LC_MESSAGES/forwards.mo differ
diff --git a/locale/it_IT/LC_MESSAGES/forwards.mo b/locale/it_IT/LC_MESSAGES/forwards.mo
index bab3fb7..ba0c7a5 100644
Binary files a/locale/it_IT/LC_MESSAGES/forwards.mo and b/locale/it_IT/LC_MESSAGES/forwards.mo differ
diff --git a/locale/pl_PL/LC_MESSAGES/forwards.mo b/locale/pl_PL/LC_MESSAGES/forwards.mo
index 7d0a5b8..a538605 100644
Binary files a/locale/pl_PL/LC_MESSAGES/forwards.mo and b/locale/pl_PL/LC_MESSAGES/forwards.mo differ
diff --git a/locale/pt_BR/LC_MESSAGES/forwards.mo b/locale/pt_BR/LC_MESSAGES/forwards.mo
index a2a716e..3bdca7d 100644
Binary files a/locale/pt_BR/LC_MESSAGES/forwards.mo and b/locale/pt_BR/LC_MESSAGES/forwards.mo differ
diff --git a/locale/ru_RU/LC_MESSAGES/forwards.mo b/locale/ru_RU/LC_MESSAGES/forwards.mo
index b13b6c4..fe7034f 100644
Binary files a/locale/ru_RU/LC_MESSAGES/forwards.mo and b/locale/ru_RU/LC_MESSAGES/forwards.mo differ
diff --git a/locale/tr_TR/LC_MESSAGES/forwards.mo b/locale/tr_TR/LC_MESSAGES/forwards.mo
new file mode 100644
index 0000000..7382dc3
Binary files /dev/null and b/locale/tr_TR/LC_MESSAGES/forwards.mo differ
diff --git a/locale/zh_TW/LC_MESSAGES/forwards.mo b/locale/zh_TW/LC_MESSAGES/forwards.mo
index bdf56f6..28008ef 100644
Binary files a/locale/zh_TW/LC_MESSAGES/forwards.mo and b/locale/zh_TW/LC_MESSAGES/forwards.mo differ
diff --git a/main.php b/main.php
index 1a2d4d3..d09c10d 100644
--- a/main.php
+++ b/main.php
@@ -1,51 +1,53 @@
 <?php
 /**
- * $Horde: forwards/main.php,v 1.36.2.2 2007/01/02 13:54:05 jan Exp $
+ * $Horde: forwards/main.php,v 1.36.2.4 2009/01/06 15:22:46 jan Exp $
  *
- * Copyright 2001-2007 Eric Rostetter <eric.rostetter at physics.utexas.edu>
+ * Copyright 2001-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file LICENSE for license information (BSDL). If you
  * did not receive this file, see http://www.horde.org/licenses/bsdl.php.
+ *
+ * @author Eric Rostetter <eric.rostetter at physics.utexas.edu>
+ * @author Jan Schneider <jan at horde.org>
  */
 
 @define('FORWARDS_BASE', dirname(__FILE__));
 require_once FORWARDS_BASE . '/lib/base.php';
-require_once FORWARDS_BASE . '/lib/Driver.php';
-
-$driver = &Forwards_Driver::factory();
 
 // Get the current login username and realm.
-$split = explode('@', Auth::getAuth());
-$user = @$split[0];
-$realm = @$split[1];
+ at list(, $realm) = explode('@', Auth::getAuth(), 2);
 if (empty($realm)) {
     $realm = 'default';
 }
 
-$submit = Util::getFormData('submit', false);
-if ($submit) {
+// Create a driver.
+require_once FORWARDS_BASE . '/lib/Driver.php';
+$driver = Forwards_Driver::factory(Auth::getAuth(), $realm);
+
+if (Util::getFormData('submit')) {
     $forwardmode = Util::getFormData('mode', 'error');
     if ($forwardmode === 'error') {
         $notification->push(_("You must specify the mode (set or remove)"), 'horde.warning');
     }
 
     // Check for refused usernames, using current horde username.
-    if (in_array($user, $conf['user']['refused'])) {
-        $notification->push(sprintf(_("You can't change Forwards for user %s"), $user), 'horde.error');
+    if (in_array($driver->getUser(), $conf['user']['refused'])) {
+        $notification->push(sprintf(_("You can't change Forwards for user %s"), $driver->getUser()),
+                            'horde.error');
         $forwardmode = 'error';
     }
 
     if ($conf['enabled']['authenticate']) {
-        $oldpassword = Util::getFormData('oldpassword', false);
-        if (!$oldpassword) {
+        $password = Util::getFormData('password');
+        if (!$password) {
             $notification->push(_("You must give your password"), 'horde.warning');
             $forwardmode = 'error';
         }
     } else {
-        $oldpassword = Auth::getCredential('password');
+        $password = Auth::getCredential('password');
     }
 
-    $metoo = Util::getFormData('metoo', false);
+    $metoo = Util::getFormData('metoo');
     if ($metoo != 'on') {
         $metoo = 'off';
     }
@@ -53,39 +55,57 @@ if ($submit) {
     // Do the action requested.
     switch ($forwardmode) {
     case 'set':
-        $forwardwhere = Util::getFormData('where', false);
+        $forwardwhere = Util::getFormData('where');
         if (!$forwardwhere) {
             $notification->push(_("You must supply an e-mail address!"), 'horde.warning');
         } else {
-            if ($driver->enableForwarding($user, $realm, $oldpassword, $forwardwhere, $metoo)) {
-                $notification->push(_("Forward set!"), 'horde.success');
+            $result = $driver->enableForwarding($password, $forwardwhere, $metoo);
+            if (is_a($result, 'PEAR_Error')) {
+                $notification->push($result);
             } else {
-                $notification->push(sprintf(_("Failure in setting forward: %s"), $driver->getError()),
-                                    'horde.error');
+                $notification->push(_("Forward set!"), 'horde.success');
             }
         }
         break;
 
     case 'unset':
-        if ($driver->disableForwarding($user, $realm, $oldpassword)) {
-            $notification->push(_("Forward removed!"), 'horde.success');
+        $result = $driver->disableForwarding($password);
+        if (is_a($result, 'PEAR_Error')) {
+            $notification->push($result);
         } else {
-            $notification->push(sprintf(_("Failure in removing forward: %s"), $driver->getError()),
-                                'horde.error');
+            $notification->push(_("Forward removed!"), 'horde.success');
         }
         break;
     }
 }
 
-// The backend always returns 'Y' if forwarding is enabled, but may
-// not be able to say with certainty that forwarding is *disabled* -
-// 'N' means "there is definitely no forwarding address set", false
-// means that we can't determine the current state.
-$pass = Auth::getCredential('password');
-if ($driver->isEnabledForwarding($user, $realm, $pass) == 'Y') {
-    $notification->push(_("Forwarding is currently enabled."), 'horde.success');
-} elseif ($driver->isEnabledForwarding($user, $realm, $pass) == 'N') {
-    $notification->push(_("Forwarding is currently disabled."), 'horde.warning');
+// The backend always returns 'Y' if forwarding is enabled, but may not be
+// able to say with certainty that forwarding is *disabled* - 'N' means "there
+// is definitely no forwarding address set", false means that we can't
+// determine the current state.
+$password = Auth::getCredential('password');
+$enabled = $driver->isEnabledForwarding($password);
+$current_target = '';
+$current_keeplocal = '';
+if (is_a($enabled, 'PEAR_Error')) {
+    $notification->push($enabled);
+    $enabled = false;
+} else {
+    if ($enabled == 'Y') {
+        $notification->push(_("Forwarding is currently enabled."), 'horde.message');
+        $current_target = $driver->currentTarget($password);
+        if (is_a($current_target, 'PEAR_Error')) {
+            $notification->push($current_target);
+            $current_target = '';
+        }
+        $current_keeplocal = $driver->isKeepLocal($password);
+        if (is_a($current_keeplocal, 'PEAR_Error')) {
+            $notification->push($current_keeplocal);
+            $current_keeplocal = '';
+        }
+    } elseif ($enabled == 'N') {
+        $notification->push(_("Forwarding is currently disabled."), 'horde.message');
+    }
 }
 
 $notification->push('setFocus()', 'javascript');
diff --git a/po/cs_CZ.po b/po/cs_CZ.po
index 5433ab8..379fa65 100644
--- a/po/cs_CZ.po
+++ b/po/cs_CZ.po
@@ -1,5 +1,5 @@
 # Czech translations for Forwards package.
-# Copyright (C) 2004 Horde Project
+# Copyright 2004-2009 The Horde Project
 # This file is distributed under the same license as the Horde package.
 # Pavel Chytil <pavel at chytil.tk>, 2004.
 #
diff --git a/po/da_DK.po b/po/da_DK.po
index 80c8835..41f5c4b 100644
--- a/po/da_DK.po
+++ b/po/da_DK.po
@@ -1,6 +1,6 @@
 # Danish translations for Forwards package
 # Danske oversættelser for pakke Forwards.
-# Copyright (C) 2004-2006 Horde Project
+# Copyright 2004-2009 The Horde Project
 # This file is distributed under the same license as the Forwards package.
 # Espen Jürgensen <espen at hhkol.dk>, 2004.
 # Brian Truelsen <horde+i18n at briantruelsen.dk>, 2006.
diff --git a/po/de_DE.po b/po/de_DE.po
index 94b5ec5..f7ec1bc 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -1,21 +1,22 @@
-# forwards module translations
-# Copyright (C) 2002 Horde Project.
+# German translations for Forwards.
+# Copyright 2002-2009 The Horde Project
+# This file is distributed under the same license as the Forwards package.
 # Jens Tkotz <jens.tkotz at f2h9.de> , 2002.
-# Jan Schneider <jan at horde.org>, 2002-2005.
+# Jan Schneider <jan at horde.org>, 2002-2008.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: Forwards 3.0-cvs\n"
 "Report-Msgid-Bugs-To: dev at lists.horde.org\n"
-"POT-Creation-Date: 2006-07-31 18:12+0200\n"
-"PO-Revision-Date: 2006-08-09 17:20+0200\n"
+"POT-Creation-Date: 2008-08-01 10:45+0200\n"
+"PO-Revision-Date: 2008-08-01 16:24+0200\n"
 "Last-Translator: Jan Schneider <jan at horde.org>\n"
 "Language-Team: German <dev at lists.horde.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=iso-8859-1\n"
 "Content-Transfer-Encoding: 8-bit\n"
 
-#: templates/main/main.inc:63
+#: templates/main/main.inc:49
 msgid ""
 "An e-mail forward lets you redirect your mail to another address (or a comma "
 "separated list of addresses if you wish). You can even forward to another "
@@ -26,43 +27,94 @@ msgstr ""
 "Adressen, wenn Sie möchten). Sie können auch eine Weiterleitung einrichten "
 "und eine lokale Kopie behalten."
 
-#: lib/Driver.php:163
-msgid "Can't parse your email address"
+#: lib/Driver/ldap.php:115 lib/Driver/ldap.php:181
+msgid ""
+"An internal error has occurred.  Details have been logged for the "
+"administrator."
+msgstr ""
+"Ein interner Fehler ist aufgetreten. Details wurden für den Administrator "
+"mitgeloggt."
+
+#: lib/Driver/customsql.php:150
+msgid "An unknown error occured while disabling forwarding."
+msgstr ""
+"Beim Deaktivieren der Weiterleitung ist ein unbekannter Fehler aufgetreten."
+
+#: lib/Driver/customsql.php:104
+msgid "An unknown error occured while enabling forwarding."
+msgstr ""
+"Beim Aktivieren der Weiterleitung ist ein unbekannter Fehler aufgetreten."
+
+#: lib/Driver/mdaemon.php:53 lib/Driver/mdaemon.php:103
+msgid "Cannot create lockfile."
+msgstr "Die Lockdatei konnte nicht erstellt werden."
+
+#: lib/Driver/plesk.php:107
+msgid "Cannot determine the current forward address."
+msgstr "Die aktuelle Weiterleitungsadresse konnte nicht ermittelt werden."
+
+#: lib/Driver/mdaemon.php:44 lib/Driver/mdaemon.php:47
+#: lib/Driver/mdaemon.php:192 lib/Driver/mdaemon.php:219
+#, php-format
+msgid "Cannot open %s."
+msgstr "%s kann nicht geöffnet werden."
+
+#: lib/Driver.php:165
+msgid "Cannot parse your email address"
 msgstr "Ihre E-Mail-Adresse konnte nicht ausgewertet werden"
 
-#: lib/Driver/ldap.php:86 lib/Driver/ldap.php:133
-msgid "Check your password"
-msgstr "Überprüfen Sie Ihr Passwort"
+#: lib/Driver/plesk.php:136
+#, php-format
+msgid "Cannot remove vacation notice for mail user %s."
+msgstr ""
+"Die Abwesenheitsnotiz für den Mail-Benutzer %s konnte nicht gelöscht werden."
 
-#: lib/Driver/forwards.php:97 lib/Driver/forwards.php:153
-#: lib/Driver/forwards.php:198 lib/Driver/forwards.php:265
-#: lib/Driver/qmail.php:91 lib/Driver/qmail.php:143 lib/Driver/qmail.php:189
-msgid "Check your username and password"
-msgstr "Überprüfen Sie Ihren Benutzernamen und Ihr Passwort"
+#: lib/Driver/plesk.php:131
+#, php-format
+msgid "Cannot remove vacation notice for mail user %s: %s"
+msgstr ""
+"Die Abwesenheitsnotiz für den Mail-Benutzer %s konnte nicht gelöscht werden: "
+"%s"
 
-#: lib/Driver/ldap.php:187 lib/Driver/ldap.php:233 lib/Driver/ldap.php:319
-msgid "Could not bind to ldap server"
-msgstr "Verbindung zum LDAP-Server fehlgeschlagen"
+#: lib/Driver/plesk.php:278
+#, php-format
+msgid "Cannot retrieve domain ID of domain %s."
+msgstr "Die Domain-ID der Domain %s konnte nicht ausgelesen werden."
 
-#: lib/Driver/ldap.php:305
-msgid "Could not connect to ldap server"
-msgstr "Verbindung zum LDAP-Server fehlgeschlagen"
+#: lib/Driver/plesk.php:276
+#, php-format
+msgid "Cannot retrieve domain ID of domain %s: %s"
+msgstr "Die Domain-ID der Domain %s konnte nicht ausgelesen werden: %s"
 
-#: lib/Block/summary.php:37
-msgid "Failed to create a forwards driver"
-msgstr "Verbindung zum forwards-Treiber fehlgeschlagen"
+#: lib/Driver/plesk.php:229
+#, php-format
+msgid "Cannot retrieve information about mail user %s."
+msgstr ""
+"Die Informationen zum Mail-Benutzer %s konnten nicht ausgelesen werden."
+
+#: lib/Driver/plesk.php:225
+#, php-format
+msgid "Cannot retrieve information about mail user %s: %s"
+msgstr ""
+"Die Informationen zum Mail-Benutzer %s konnten nicht ausgelesen werden: %s"
 
-#: main.php:73
+#: lib/Driver/plesk.php:85
 #, php-format
-msgid "Failure in removing forward: %s"
-msgstr "Fehler beim Entfernen der Weiterleitung: %s"
+msgid "Cannot set forwarding for mail user %s."
+msgstr ""
+"Die Weiterleitung für den Mail-Benutzer %s konnte nicht angelegt werden."
 
-#: main.php:63
+#: lib/Driver/plesk.php:79
 #, php-format
-msgid "Failure in setting forward: %s"
-msgstr "Fehler beim Erstellen der Weiterleitung: %s"
+msgid "Cannot set forwarding for mail user %s: %s"
+msgstr ""
+"Die Weiterleitung für den Mail-Benutzer %s konnte nicht angelegt werden: %s"
 
-#: templates/main/main.inc:88
+#: lib/Block/summary.php:37
+msgid "Failed to create a forwards driver"
+msgstr "Verbindung zum forwards-Treiber fehlgeschlagen"
+
+#: templates/main/main.inc:74
 msgid ""
 "For your protection and safety, you must identify yourself with your login "
 "password to verify this change."
@@ -83,19 +135,19 @@ msgstr "Weiterleitung ist aktiviert."
 msgid "Forward is not active."
 msgstr "Weiterleitung ist nicht aktiviert."
 
-#: main.php:71
+#: main.php:76
 msgid "Forward removed!"
 msgstr "Weiterleitung entfernt!"
 
-#: main.php:61
+#: main.php:66
 msgid "Forward set!"
 msgstr "Weiterleitung erstellt!"
 
-#: main.php:88
+#: main.php:107
 msgid "Forwarding is currently disabled."
 msgstr "Die Weiterleitung ist zur Zeit deaktiviert."
 
-#: main.php:86
+#: main.php:95
 msgid "Forwarding is currently enabled."
 msgstr "Die Weiterleitung ist zur Zeit aktiv."
 
@@ -103,73 +155,90 @@ msgstr "Die Weiterleitung ist zur Zeit aktiv."
 msgid "Forwards Summary"
 msgstr "Weiterleitungsübersicht"
 
-#: lib/Driver/ldap.php:188 lib/Driver/ldap.php:234
-msgid "Incorrect Password"
-msgstr "Falsches Passwort"
+#: lib/Driver/ldap.php:424
+msgid "Internal LDAP error.  Details have been logged for the administrator."
+msgstr "Interner LDAP-Fehler. Details wurden für den Administrator mitgeloggt."
 
-#: templates/main/main.inc:79
+#: lib/Driver/ldap.php:266
+msgid ""
+"Internal error while searching LDAP.  Details have been logged for the "
+"administrator."
+msgstr ""
+"Interner Fehler beim Durchsuchen des LDAP-Servers. Details wurden für den "
+"Administrator mitgeloggt."
+
+#: templates/main/main.inc:65
 msgid "Keep a copy in your local mailbox?"
 msgstr "Möchten Sie eine Kopie in Ihrer Mailbox behalten?"
 
-#: lib/Driver/forwards.php:160 lib/Driver/qmail.php:150
-msgid "Maybe you didn't have a forward enabled?"
-msgstr "Vielleicht haben Sie keine Weiterleitung aktiviert?"
+#: lib/Driver/forwards.php:106
+msgid "Maybe you didn't have a vacation notice installed?"
+msgstr "Vielleicht haben Sie keine Abwesenheitsnotiz installiert?"
 
-#: lib/Driver/mdaemon.php:36 lib/Driver/mdaemon.php:106
+#: lib/Driver/mdaemon.php:32 lib/Driver/mdaemon.php:97
 msgid "Mdaemon path not found"
 msgstr "Pfad zu mdaemon nicht gefunden"
 
-#: lib/Driver/mdaemon.php:81 lib/Driver/mdaemon.php:130
+#: lib/Driver/mdaemon.php:77 lib/Driver/mdaemon.php:120
 msgid "Not able to create semaphore file"
 msgstr "Semaphoredatei konnte nicht erstellt werden"
 
-#: main.php:92 templates/main/main.inc:58
+#: main.php:112 templates/main/main.inc:44
 msgid "Set or Remove E-Mail Forwards"
 msgstr "Erstellen und Entfernen von E-Mail-Weiterleitungen"
 
-#: templates/main/main.inc:73
+#: templates/main/main.inc:59
 msgid "Set/install a forward to:"
 msgstr "Setzen/installieren Sie eine Weiterleitung nach:"
 
-#: templates/main/main.inc:94
+#: templates/main/main.inc:80
 msgid "Submit"
 msgstr "Abschicken"
 
-#: lib/Driver/forwards.php:49 lib/Driver/ldap.php:46 lib/Driver/qmail.php:47
+#: lib/Driver/plesk.php:252
+msgid ""
+"The Plesk driver requires the Horde_DOM package from Horde 3.2 or later. See "
+"http://pear.horde.org/index.php?package=Horde_DOM"
+msgstr ""
+"Der Plesk-Treiber benötigt das Horde_DOM-Paket aus Horde 3.2 oder größer. "
+"Siehe http://pear.horde.org/index.php?package=Horde_DOM"
+
+#: lib/Driver/customsql.php:147
+msgid "The forwarding cannot be disabled. Check the password."
+msgstr ""
+"Die Weiterleitung kann nicht deaktiviert werden, Überprüfen Sie das Passwort."
+
+#: lib/Driver/plesk.php:286
+msgid "The forwards application is not properly configured."
+msgstr "Die Anwendung Forwards ist nicht vollständig konfiguriert."
+
+#: lib/Driver/forwards.php:223 lib/Driver/ldap.php:628
 msgid "The module is not properly configured!"
 msgstr "Forwards ist nicht vollständig konfiguriert!"
 
-#: templates/main/main.inc:89
+#: templates/main/main.inc:75
 msgid "Then submit the form so that your forward can be updated."
 msgstr ""
 "Anschließend bestätigen Sie bitte das Formular, so dass Ihre Weiterleitung "
 "aktualisiert werden kann."
 
-#: templates/main/main.inc:64
+#: templates/main/main.inc:50
 msgid ""
 "This form lets you install (or remove) e-mail forwarding for your account."
 msgstr ""
 "Mit diesem Formular können Sie Weiterleitungen für Ihr Konto einrichten "
 "(oder löschen),"
 
-#: lib/Driver/customsql.php:287 lib/Driver/sql.php:333
-msgid "Unable to connect to SQL server."
-msgstr "Verbindung zum SQL Server kann nicht hergestellt werden."
-
-#: templates/main/main.inc:84
-msgid "Unset/remove a forward"
-msgstr "Löschen Sie eine Weiterleitung"
-
-#: lib/Driver/ldap.php:268
-msgid "User not found."
-msgstr "Benutzer nicht gefunden."
+#: templates/main/main.inc:70
+msgid "Unset/remove the forward"
+msgstr "Weiterleitung löschen/deaktivieren"
 
-#: main.php:34
+#: main.php:35
 #, php-format
 msgid "You can't change Forwards for user %s"
 msgstr "Sie können Weiterleitungen von Benutzer %s nicht ändern"
 
-#: main.php:41
+#: main.php:43
 msgid "You must give your password"
 msgstr "Sie müssen Ihr Passwort angeben"
 
@@ -181,14 +250,14 @@ msgstr "Sie m
 msgid "You must provide your password"
 msgstr "Sie müssen Ihr Passwort angeben"
 
-#: main.php:29
+#: main.php:30
 msgid "You must specify the mode (set or remove)"
 msgstr "Sie müssen den Modus (Erstellen oder Entfernen) angeben"
 
-#: main.php:58
+#: main.php:60
 msgid "You must supply an e-mail address!"
 msgstr "Sie müssen eine E-Mail-Adresse angeben!"
 
-#: templates/main/main.inc:91
+#: templates/main/main.inc:77
 msgid "Your password:"
 msgstr "Ihr Passwort:"
diff --git a/po/es_ES.po b/po/es_ES.po
index 4f4f8a9..caaf628 100644
--- a/po/es_ES.po
+++ b/po/es_ES.po
@@ -1,23 +1,23 @@
-# Spanish translations for horde package
-# Traducciones al español para el paquete horde.
-# Copyright (C) 2004 Horde Project
-# This file is distributed under the same license as the horde package.
-# Automatically generated, 2004.
+# Spanish translations for forwards package.
+# Traducciones al español para el paquete forwards.
+# Copyright 2008-2009 The Horde Project
+# This file is distributed under the same license as the forwards package.
+# Automatically generated, 2008.
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Forwards 3.0-cvs\n"
+"Project-Id-Version: Forwards 3.0.1\n"
 "Report-Msgid-Bugs-To: dev at lists.horde.org\n"
-"POT-Creation-Date: 2006-02-02 16:15+0100\n"
-"PO-Revision-Date: 2006-02-02 16:15+0100\n"
+"POT-Creation-Date: 2009-02-20 14:46+0100\n"
+"PO-Revision-Date: 2009-02-20 14:46+0100\n"
 "Last-Translator: Manuel P. Ayala <mayala at unex.es>\n"
 "Language-Team: i18n at lists.horde.org\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: templates/main/main.inc:63
+#: templates/main/main.inc:49
 msgid ""
 "An e-mail forward lets you redirect your mail to another address (or a comma "
 "separated list of addresses if you wish). You can even forward to another "
@@ -28,43 +28,87 @@ msgstr ""
 "comas). También se puede redirigir el correo y conservar en el buzón local "
 "una copia de los mensajes recibidos."
 
-#: lib/Driver.php:160
-msgid "Can't parse your email address"
-msgstr "No se puede procesar su dirección electrónica"
+#: lib/Driver/ldap.php:115 lib/Driver/ldap.php:181
+msgid ""
+"An internal error has occurred.  Details have been logged for the "
+"administrator."
+msgstr ""
+"Se ha producido un error interno. Se han registrado los detalles para el "
+"administrador."
 
-#: lib/Driver/ldap.php:86 lib/Driver/ldap.php:133
-msgid "Check your password"
-msgstr "Compruebe la contraseña"
+#: lib/Driver/customsql.php:150
+msgid "An unknown error occured while disabling forwarding."
+msgstr "Se produjo un error desconocido al desactivar el reenvío."
 
-#: lib/Driver/forwards.php:97 lib/Driver/forwards.php:153
-#: lib/Driver/forwards.php:198 lib/Driver/forwards.php:265
-#: lib/Driver/qmail.php:91 lib/Driver/qmail.php:143 lib/Driver/qmail.php:189
-msgid "Check your username and password"
-msgstr "Compruebe su nombre de usuario y contraseña"
+#: lib/Driver/customsql.php:104
+msgid "An unknown error occured while enabling forwarding."
+msgstr "Se produjo un error desconocido al activar el reenvío."
 
-#: lib/Driver/ldap.php:187 lib/Driver/ldap.php:233 lib/Driver/ldap.php:319
-msgid "Could not bind to ldap server"
-msgstr "No se puede enlazar al servidor ldap"
+#: lib/Driver/mdaemon.php:53 lib/Driver/mdaemon.php:103
+msgid "Cannot create lockfile."
+msgstr "No se pudo crear el archivo de bloqueo."
 
-#: lib/Driver/ldap.php:305
-msgid "Could not connect to ldap server"
-msgstr "No se puede conectar al servidor ldap"
+#: lib/Driver/plesk.php:107
+msgid "Cannot determine the current forward address."
+msgstr "No se puede determinar la dirección de reenvío actual."
 
-#: lib/Block/summary.php:37
-msgid "Failed to create a forwards driver"
-msgstr "Fallo al crear un controlador de reenvíos"
+#: lib/Driver/mdaemon.php:44 lib/Driver/mdaemon.php:47
+#: lib/Driver/mdaemon.php:192 lib/Driver/mdaemon.php:219
+#, php-format
+msgid "Cannot open %s."
+msgstr "No se puede abrir %s."
+
+#: lib/Driver.php:165
+msgid "Cannot parse your email address"
+msgstr "No se puede procesar su dirección de correo"
+
+#: lib/Driver/plesk.php:136
+#, php-format
+msgid "Cannot remove vacation notice for mail user %s."
+msgstr ""
+"No se puede eliminar la notificación de ausencia del usuario de correo %s."
+
+#: lib/Driver/plesk.php:131
+#, php-format
+msgid "Cannot remove vacation notice for mail user %s: %s"
+msgstr ""
+"No se puede eliminar la notificación de ausencia del usuario de correo %s: %s"
+
+#: lib/Driver/plesk.php:278
+#, php-format
+msgid "Cannot retrieve domain ID of domain %s."
+msgstr "No se puede recuperar el ID de dominio del dominio %s."
+
+#: lib/Driver/plesk.php:276
+#, php-format
+msgid "Cannot retrieve domain ID of domain %s: %s"
+msgstr "No se puede recuperar el ID de dominio del dominio %s: %s"
+
+#: lib/Driver/plesk.php:229
+#, php-format
+msgid "Cannot retrieve information about mail user %s."
+msgstr "No se puede recuperar la información del usuario de correo %s."
+
+#: lib/Driver/plesk.php:225
+#, php-format
+msgid "Cannot retrieve information about mail user %s: %s"
+msgstr "No se puede recuperar la información del usuario de correo %s: %s"
 
-#: main.php:73
+#: lib/Driver/plesk.php:85
 #, php-format
-msgid "Failure in removing forward: %s"
-msgstr "Fallo al eliminar el reenvío: %s"
+msgid "Cannot set forwarding for mail user %s."
+msgstr "No se puede definir un reenvío para el usuario de correo %s."
 
-#: main.php:63
+#: lib/Driver/plesk.php:79
 #, php-format
-msgid "Failure in setting forward: %s"
-msgstr "Fallo estableciendo el reenvío: %s"
+msgid "Cannot set forwarding for mail user %s: %s"
+msgstr "No se puede definir un reenvío para el usuario de correo %s: %s"
 
-#: templates/main/main.inc:88
+#: lib/Block/summary.php:37
+msgid "Failed to create a forwards driver"
+msgstr "Fallo al crear un controlador de reenvíos"
+
+#: templates/main/main.inc:74
 msgid ""
 "For your protection and safety, you must identify yourself with your login "
 "password to verify this change."
@@ -84,19 +128,19 @@ msgstr "El reenv
 msgid "Forward is not active."
 msgstr "El reenvío está inactivo."
 
-#: main.php:71
+#: main.php:76
 msgid "Forward removed!"
 msgstr "¡Reenvío eliminado!"
 
-#: main.php:61
+#: main.php:66
 msgid "Forward set!"
 msgstr "¡Reenvío activado!"
 
-#: main.php:88
+#: main.php:107
 msgid "Forwarding is currently disabled."
 msgstr "Actualmente el reenvío está desactivado."
 
-#: main.php:86
+#: main.php:95
 msgid "Forwarding is currently enabled."
 msgstr "Actualmente el reenvío está activado."
 
@@ -104,71 +148,88 @@ msgstr "Actualmente el reenv
 msgid "Forwards Summary"
 msgstr "Resumen de reenvíos"
 
-#: lib/Driver/ldap.php:188 lib/Driver/ldap.php:234
-msgid "Incorrect Password"
-msgstr "Contraseña incorrecta"
+#: lib/Driver/ldap.php:424
+msgid "Internal LDAP error.  Details have been logged for the administrator."
+msgstr ""
+"Error LDAP interno. Se han registrado los detalles para el administrador."
+
+#: lib/Driver/ldap.php:266
+msgid ""
+"Internal error while searching LDAP.  Details have been logged for the "
+"administrator."
+msgstr ""
+"Error interno al buscar en el LDAP. Se han registrado los detalles para el "
+"administrador."
 
-#: templates/main/main.inc:79
+#: templates/main/main.inc:65
 msgid "Keep a copy in your local mailbox?"
 msgstr "¿Conservar una copia en el buzón?"
 
-#: lib/Driver/forwards.php:160 lib/Driver/qmail.php:150
-msgid "Maybe you didn't have a forward enabled?"
-msgstr "¿Puede que no haya activado ningún reenvío?"
+#: lib/Driver/forwards.php:106
+msgid "Maybe you didn't have a vacation notice installed?"
+msgstr "¿Puede que no haya instalado ninguna notificación de ausencia?"
 
-#: lib/Driver/mdaemon.php:36 lib/Driver/mdaemon.php:106
+#: lib/Driver/mdaemon.php:32 lib/Driver/mdaemon.php:97
 msgid "Mdaemon path not found"
 msgstr "No se ha encontrado la vía de acceso del Mdaemon"
 
-#: lib/Driver/mdaemon.php:81 lib/Driver/mdaemon.php:130
+#: lib/Driver/mdaemon.php:77 lib/Driver/mdaemon.php:120
 msgid "Not able to create semaphore file"
 msgstr "No se puede crear un archivo semáforo"
 
-#: main.php:92 templates/main/main.inc:58
+#: main.php:112 templates/main/main.inc:44
 msgid "Set or Remove E-Mail Forwards"
 msgstr "Define o anula reenvíos de correo"
 
-#: templates/main/main.inc:73
+#: templates/main/main.inc:59
 msgid "Set/install a forward to:"
 msgstr "Activar/definir un reenvío a:"
 
-#: templates/main/main.inc:94
+#: templates/main/main.inc:80
 msgid "Submit"
 msgstr "Enviar"
 
-#: lib/Driver/forwards.php:49 lib/Driver/qmail.php:47 lib/Driver/ldap.php:46
+#: lib/Driver/plesk.php:252
+msgid ""
+"The Plesk driver requires the Horde_DOM package from Horde 3.2 or later. See "
+"http://pear.horde.org/index.php?package=Horde_DOM"
+msgstr ""
+"El manejador Ples precisa el paquete Horde_DOM de Horde 3.2 o posterior. "
+"Consulte http://pear.horde.org/index.php?package=Horde_DOM"
+
+#: lib/Driver/customsql.php:147
+msgid "The forwarding cannot be disabled. Check the password."
+msgstr "No se puede desactivar el reenvío. Compruebe la contraseña."
+
+#: lib/Driver/plesk.php:286
+msgid "The forwards application is not properly configured."
+msgstr "La aplicación de reenvíos no está bien configurada."
+
+#: lib/Driver/ldap.php:628 lib/Driver/forwards.php:223
 msgid "The module is not properly configured!"
 msgstr "¡El módulo no está bien configurado!"
 
-#: templates/main/main.inc:89
+#: templates/main/main.inc:75
 msgid "Then submit the form so that your forward can be updated."
 msgstr "Envíe el formulario para que se pueda actualizar el reenvío."
 
-#: templates/main/main.inc:64
+#: templates/main/main.inc:50
 msgid ""
 "This form lets you install (or remove) e-mail forwarding for your account."
 msgstr ""
 "Este formulario le permite definir (o anular) reenvíos de correo de su "
 "cuenta."
 
-#: lib/Driver/sql.php:332 lib/Driver/customsql.php:288
-msgid "Unable to connect to SQL server."
-msgstr "Incapaz de conectarse al servidor SQL."
-
-#: templates/main/main.inc:84
-msgid "Unset/remove a forward"
-msgstr "Anular/eliminar un reenvío de correo"
-
-#: lib/Driver/ldap.php:268
-msgid "User not found."
-msgstr "No se encontró el usuario."
+#: templates/main/main.inc:70
+msgid "Unset/remove the forward"
+msgstr "Anular/eliminar el reenvío"
 
-#: main.php:34
+#: main.php:35
 #, php-format
 msgid "You can't change Forwards for user %s"
 msgstr "No puede cambiar el reenvío del usuario %s"
 
-#: main.php:41
+#: main.php:43
 msgid "You must give your password"
 msgstr "Tiene que introducir su contraseña"
 
@@ -180,14 +241,14 @@ msgstr "Tiene que introducir una direcci
 msgid "You must provide your password"
 msgstr "Tiene que introducir su contraseña"
 
-#: main.php:29
+#: main.php:30
 msgid "You must specify the mode (set or remove)"
 msgstr "Tiene que especificar el modo (establecer o eliminar)"
 
-#: main.php:58
+#: main.php:60
 msgid "You must supply an e-mail address!"
 msgstr "¡Tiene que especificar una dirección de correo!"
 
-#: templates/main/main.inc:91
+#: templates/main/main.inc:77
 msgid "Your password:"
 msgstr "Su contraseña:"
diff --git a/po/fa_IR.po b/po/fa_IR.po
index b6e2f99..8381c59 100644
--- a/po/fa_IR.po
+++ b/po/fa_IR.po
@@ -1,7 +1,7 @@
 # Persian translations for Accounts package.
 # This file is distributed under the same license as the Accounts package.
-# 
-# Copyright (C) 2004 High Concil of Informatics (www.shci.ir)
+#
+# Copyright 2004 High Concil of Informatics (www.shci.ir)
 # Provided by  Amirkabir Metanetworking Ltd, 2004 <persian-horde at metanetworking.com>
 # Mohsen Nader-Badr       <naderi at metanetworking.com>
 # Chakameh Mortezania     <mortezania at metanetworking.com>
@@ -9,7 +9,7 @@
 # Hamed Gheybi            <gheybi at metanetworking.com>
 # Vahid Ghafarpour        <ghafarpour at metanetworking.com>
 # Zahra Ahmadi Firouzjaee <ahmadi at metanetworking.com>
-# 
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: Forwards 3 ALPHA\n"
diff --git a/po/fi_FI.po b/po/fi_FI.po
index 769cb3c..89bdffa 100644
--- a/po/fi_FI.po
+++ b/po/fi_FI.po
@@ -1,21 +1,21 @@
 # Finnish translation for Forwards.
-# Copyright (C)
+# Copyright
 # Tero Matinlassi <terom at iki.fi>, 2002.
-# Leena Heino <liinu at uta.fi>, 2002-2004.
+# Leena Heino <liinu at uta.fi>, 2002-2008.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: Forwards 3.0-cvs\n"
 "Report-Msgid-Bugs-To: dev at lists.horde.org\n"
-"POT-Creation-Date: 2004-11-17 12:36+0100\n"
-"PO-Revision-Date: 2004-12-10 12:59+0200\n"
+"POT-Creation-Date: 2008-08-01 10:45+0200\n"
+"PO-Revision-Date: 2008-11-27 12:59+0200\n"
 "Last-Translator: Leena Heino <liinu at uta.fi>\n"
 "Language-Team: Finnish <i18n at lists.horde.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=iso-8859-1\n"
 "Content-Transfer-Encoding: 8-bit\n"
 
-#: templates/main/main.inc:62
+#: templates/main/main.inc:49
 msgid ""
 "An e-mail forward lets you redirect your mail to another address (or a comma "
 "separated list of addresses if you wish). You can even forward to another "
@@ -25,43 +25,83 @@ msgstr ""
 "osoitteeseen, jos haluat - erota osoitteet pilkulla). Voit myös ohjata "
 "toiseen osoitteeseen ja pitää kopion paikallisessa sähköpostilaatikossasi."
 
-#: lib/Driver.php:169
-msgid "Can't parse your email address"
+#: lib/Driver/ldap.php:115 lib/Driver/ldap.php:181
+msgid ""
+"An internal error has occurred.  Details have been logged for the "
+"administrator."
+msgstr "Sisäinen virhetilanne. Yksityiskohdat on kirjattu ylläpidon tiedoksi."
+
+#: lib/Driver/customsql.php:150
+msgid "An unknown error occured while disabling forwarding."
+msgstr "Tuntematon virhe tapahtui otettaessa pois uudelleenohjausta."
+
+#: lib/Driver/customsql.php:104
+msgid "An unknown error occured while enabling forwarding."
+msgstr "Tuntematon virhe tapahtui laitettaessa uudelleenohjausta päälle."
+
+#: lib/Driver/mdaemon.php:53 lib/Driver/mdaemon.php:103
+msgid "Cannot create lockfile."
+msgstr "Ei voida luoda lukkotiedostoa"
+
+#: lib/Driver/plesk.php:107
+msgid "Cannot determine the current forward address."
+msgstr "Ohjattava sähköpostiosoite on epäkelpo."
+
+#: lib/Driver/mdaemon.php:44 lib/Driver/mdaemon.php:47
+#: lib/Driver/mdaemon.php:192 lib/Driver/mdaemon.php:219
+#, php-format
+msgid "Cannot open %s."
+msgstr "Ei voida aukaista: %s."
+
+#: lib/Driver.php:165
+msgid "Cannot parse your email address"
 msgstr "Sähköpostiosoitettasi ei voi tulkita"
 
-#: lib/Driver/ldap.php:83 lib/Driver/ldap.php:130
-msgid "Check your password"
-msgstr "Tarkista salasanasi"
+#: lib/Driver/plesk.php:136
+#, php-format
+msgid "Cannot remove vacation notice for mail user %s."
+msgstr "Et voi poistaa uudelleenohjausta käyttäjältä %s"
+
+#: lib/Driver/plesk.php:131
+#, php-format
+msgid "Cannot remove vacation notice for mail user %s: %s"
+msgstr "Et voi poistaa uudelleenohjausta käyttäjältä %s: %s"
 
-#: lib/Driver/forwards.php:94 lib/Driver/forwards.php:149
-#: lib/Driver/forwards.php:192 lib/Driver/qmail.php:89
-#: lib/Driver/qmail.php:140 lib/Driver/qmail.php:184
-msgid "Check your username and password"
-msgstr "Tarkista tunnuksesi ja salasanasi"
+#: lib/Driver/plesk.php:278
+#, php-format
+msgid "Cannot retrieve domain ID of domain %s."
+msgstr "Ei voida hakea domain ID toimialueelle %s."
 
-#: lib/Driver/ldap.php:186 lib/Driver/ldap.php:231 lib/Driver/ldap.php:318
-msgid "Could not bind to ldap server"
-msgstr "LDAP-palvelinta ei voitu käyttää"
+#: lib/Driver/plesk.php:276
+#, php-format
+msgid "Cannot retrieve domain ID of domain %s: %s"
+msgstr "Ei voida hakea domain ID toimialueelle %s: %s"
 
-#: lib/Driver/ldap.php:304
-msgid "Could not connect to ldap server"
-msgstr "LDAP-palvelimeen ei saatu yhteyttä"
+#: lib/Driver/plesk.php:229
+#, php-format
+msgid "Cannot retrieve information about mail user %s."
+msgstr "Ei voida hakea tietoja käyttäjästä %s."
 
-#: lib/Block/summary.php:37
-msgid "Failed to create a forwards driver"
-msgstr "Forwards-ajurin luonti epäonnistui"
+#: lib/Driver/plesk.php:225
+#, php-format
+msgid "Cannot retrieve information about mail user %s: %s"
+msgstr "Ei voida hakea tietoja käyttäjästä %s: %s"
 
-#: main.php:69
+#: lib/Driver/plesk.php:85
 #, php-format
-msgid "Failure in removing forward: %s"
-msgstr "Virhe poistettaessa uudelleenohjausta: %s"
+msgid "Cannot set forwarding for mail user %s."
+msgstr "Ei voida asettaa uudelleenohjausta käyttäjälle %s"
 
-#: main.php:59
+#: lib/Driver/plesk.php:79
 #, php-format
-msgid "Failure in setting forward: %s"
-msgstr "Virhe uudelleenohjauksen asetuksessa: %s"
+msgid "Cannot set forwarding for mail user %s: %s"
+msgstr "Ei voida asettaa uudelleenohjausta käyttäjälle %s: %s"
 
-#: templates/main/main.inc:87
+#: lib/Block/summary.php:37
+msgid "Failed to create a forwards driver"
+msgstr "Forwards-ajurin luonti epäonnistui"
+
+#: templates/main/main.inc:74
 msgid ""
 "For your protection and safety, you must identify yourself with your login "
 "password to verify this change."
@@ -69,27 +109,31 @@ msgstr ""
 "Turvallisuutesi vuoksi tämä muutostoimenpide pitää varmistaa. Sinun täytyy "
 "todentaa itsesi käyttämällä tunnustasi ja salasanaasi."
 
-#: lib/Block/summary.php:42
+#: lib/Block/summary.php:51
+msgid "Forward is active, unable to retrieve additional details."
+msgstr "Uudelleenohjaus on nyt aktiivisena, lisätietoja ei voitu hakea."
+
+#: lib/Block/summary.php:47
 msgid "Forward is active."
 msgstr "Uudelleenohjaus on asetettu."
 
-#: lib/Block/summary.php:40
+#: lib/Block/summary.php:41
 msgid "Forward is not active."
 msgstr "Uudelleenohjaus ei ole aktivoitu"
 
-#: main.php:67
+#: main.php:76
 msgid "Forward removed!"
 msgstr "Uudelleenohjaus poistettu!"
 
-#: main.php:57
+#: main.php:66
 msgid "Forward set!"
 msgstr "Uudelleenohjaus asetettu!"
 
-#: main.php:84
+#: main.php:107
 msgid "Forwarding is currently disabled."
 msgstr "Uudelleenohjaus ei ole käytettävissä."
 
-#: main.php:82
+#: main.php:95
 msgid "Forwarding is currently enabled."
 msgstr "Uudelleenohjaus on käytettävissä."
 
@@ -97,86 +141,107 @@ msgstr "Uudelleenohjaus on k
 msgid "Forwards Summary"
 msgstr "Uudelleenohjauksen yhteenveto"
 
-#: lib/Driver/ldap.php:187 lib/Driver/ldap.php:232
-msgid "Incorrect Password"
-msgstr "Väärä salasana"
+#: lib/Driver/ldap.php:424
+msgid "Internal LDAP error.  Details have been logged for the administrator."
+msgstr "Sisäinen LDAP-virhe. Yksityiskohdat on kirjattu tiedoksi ylläpidolle."
+
+#: lib/Driver/ldap.php:266
+msgid ""
+"Internal error while searching LDAP.  Details have been logged for the "
+"administrator."
+msgstr ""
+"Sisäinen haettaessa LDAP-puuta. Yksityiskohdat on kirjattu tiedoksi "
+"ylläpidolle."
 
-#: templates/main/main.inc:78
+#: templates/main/main.inc:65
 msgid "Keep a copy in your local mailbox?"
 msgstr "Pidä kopio paikallisessa sähköpostilaatikossasi."
 
-#: lib/Driver/forwards.php:156 lib/Driver/qmail.php:147
-msgid "Maybe you didn't have a forward enabled?"
-msgstr "Ehkä sinulla ei ole uudelleenohjaus sallittuna?"
+#: lib/Driver/forwards.php:106
+msgid "Maybe you didn't have a vacation notice installed?"
+msgstr "Ehkä sinulla ei ole poissaoloviestiä asennettuna?"
 
-#: lib/Driver/mdaemon.php:38 lib/Driver/mdaemon.php:108
+#: lib/Driver/mdaemon.php:32 lib/Driver/mdaemon.php:97
 msgid "Mdaemon path not found"
 msgstr "Mdaemon polkua ei löytynyt"
 
-#: lib/Driver/mdaemon.php:83 lib/Driver/mdaemon.php:132
+#: lib/Driver/mdaemon.php:77 lib/Driver/mdaemon.php:120
 msgid "Not able to create semaphore file"
 msgstr "Ei voi luoda semaforitiedostoa"
 
-#: main.php:88 templates/main/main.inc:57
+#: main.php:112 templates/main/main.inc:44
 msgid "Set or Remove E-Mail Forwards"
 msgstr "Voit asettaa tai poistaa uudellenohjauksen"
 
-#: templates/main/main.inc:72
+#: templates/main/main.inc:59
 msgid "Set/install a forward to:"
 msgstr "Aseta uudelleenohjaus osoitteeseen:"
 
-#: templates/main/main.inc:93
+#: templates/main/main.inc:80
 msgid "Submit"
 msgstr "Lähetä"
 
-#: lib/Driver/forwards.php:47 lib/Driver/ldap.php:46 lib/Driver/qmail.php:46
+#: lib/Driver/plesk.php:252
+msgid ""
+"The Plesk driver requires the Horde_DOM package from Horde 3.2 or later. See "
+"http://pear.horde.org/index.php?package=Horde_DOM"
+msgstr ""
+"Plesk-ajuri vaatii Horde_DOM paketin Horde versiosta 3.2 tai sitä uudemmasta "
+"versiosta. Tarkemmat tiedot: http://pear.horde.org/index.php?"
+"package=Horde_DOM"
+
+#: lib/Driver/customsql.php:147
+msgid "The forwarding cannot be disabled. Check the password."
+msgstr "Uudelleenohjausta ei voida poistaa. Tarkista salasana."
+
+#: lib/Driver/plesk.php:286
+msgid "The forwards application is not properly configured."
+msgstr "Uudelleenohjaus ohjelmistoa ei ole asennettu oikein!"
+
+#: lib/Driver/forwards.php:223 lib/Driver/ldap.php:628
 msgid "The module is not properly configured!"
 msgstr "Moduulia ei ole asennettu oikein!"
 
-#: templates/main/main.inc:88
+#: templates/main/main.inc:75
 msgid "Then submit the form so that your forward can be updated."
 msgstr "Lähetä sitten lomake, jotta uudelleenohjauksen tiedot päivittyisivät."
 
-#: templates/main/main.inc:63
+#: templates/main/main.inc:50
 msgid ""
 "This form lets you install (or remove) e-mail forwarding for your account."
 msgstr ""
 "Tällä lomakkeella voit asettaa (tai poistaa) käyttäjätunnuksesi sähköpostin "
 "uudelleenohjauksen "
 
-#: lib/Driver/customsql.php:270 lib/Driver/sql.php:308
-msgid "Unable to connect to SQL server."
-msgstr "SQL-palvelimeen ei saada yhteyttä."
-
-#: lib/Block/summary.php:47
-msgid "Unable to retrieve forwarding information"
-msgstr "Uudelleenohjaustietoa ei pystytty hakemaan"
-
-#: templates/main/main.inc:83
-msgid "Unset/remove a forward"
+#: templates/main/main.inc:70
+msgid "Unset/remove the forward"
 msgstr "Poista uudelleenohjaus"
 
-#: lib/Driver/ldap.php:268
-msgid "User not found."
-msgstr "Käyttäjää ei löytynyt."
-
-#: main.php:34
+#: main.php:35
 #, php-format
 msgid "You can't change Forwards for user %s"
 msgstr "Et voi muuttaa uudelleenohjausta käyttäjälle %s"
 
-#: main.php:40
+#: main.php:43
 msgid "You must give your password"
 msgstr "Sinun täytyy antaa salasanasi"
 
-#: main.php:29
+#: templates/main/main.inc:11
+msgid "You must provide a forwarding address to set"
+msgstr "Sinun täytyy osoite, johon viestit uudelleenohjataan."
+
+#: templates/main/main.inc:7
+msgid "You must provide your password"
+msgstr "Sinun täytyy antaa salasanasi"
+
+#: main.php:30
 msgid "You must specify the mode (set or remove)"
 msgstr "Sinun täytyy määritellä toiminto (aseta tai poista)"
 
-#: main.php:54
+#: main.php:60
 msgid "You must supply an e-mail address!"
 msgstr "Sinun täytyy antaa sähköpostiosoite!"
 
-#: templates/main/main.inc:90
+#: templates/main/main.inc:77
 msgid "Your password:"
 msgstr "Salasanasi:"
diff --git a/po/forwards.pot b/po/forwards.pot
index 232a782..16db8e5 100644
--- a/po/forwards.pot
+++ b/po/forwards.pot
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: dev at lists.horde.org\n"
-"POT-Creation-Date: 2006-07-31 18:12+0200\n"
+"POT-Creation-Date: 2009-03-19 10:37+0100\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
 "Language-Team: LANGUAGE <LL at li.org>\n"
@@ -16,50 +16,90 @@ msgstr ""
 "Content-Type: text/plain; charset=CHARSET\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: templates/main/main.inc:63
+#: templates/main/main.inc:49
 msgid ""
 "An e-mail forward lets you redirect your mail to another address (or a comma "
 "separated list of addresses if you wish). You can even forward to another "
 "address and keep a copy in your local mailbox."
 msgstr ""
 
-#: lib/Driver.php:163
-msgid "Can't parse your email address"
+#: lib/Driver/ldap.php:115 lib/Driver/ldap.php:181
+msgid ""
+"An internal error has occurred.  Details have been logged for the "
+"administrator."
 msgstr ""
 
-#: lib/Driver/ldap.php:86 lib/Driver/ldap.php:133
-msgid "Check your password"
+#: lib/Driver/customsql.php:150
+msgid "An unknown error occured while disabling forwarding."
 msgstr ""
 
-#: lib/Driver/forwards.php:97 lib/Driver/forwards.php:153
-#: lib/Driver/forwards.php:198 lib/Driver/forwards.php:265
-#: lib/Driver/qmail.php:91 lib/Driver/qmail.php:143 lib/Driver/qmail.php:189
-msgid "Check your username and password"
+#: lib/Driver/customsql.php:104
+msgid "An unknown error occured while enabling forwarding."
 msgstr ""
 
-#: lib/Driver/ldap.php:187 lib/Driver/ldap.php:233 lib/Driver/ldap.php:319
-msgid "Could not bind to ldap server"
+#: lib/Driver/mdaemon.php:53 lib/Driver/mdaemon.php:103
+msgid "Cannot create lockfile."
 msgstr ""
 
-#: lib/Driver/ldap.php:305
-msgid "Could not connect to ldap server"
+#: lib/Driver/plesk.php:107
+msgid "Cannot determine the current forward address."
 msgstr ""
 
-#: lib/Block/summary.php:37
-msgid "Failed to create a forwards driver"
+#: lib/Driver/mdaemon.php:44 lib/Driver/mdaemon.php:47
+#: lib/Driver/mdaemon.php:192 lib/Driver/mdaemon.php:219
+#, php-format
+msgid "Cannot open %s."
+msgstr ""
+
+#: lib/Driver.php:165
+msgid "Cannot parse your email address"
+msgstr ""
+
+#: lib/Driver/plesk.php:136
+#, php-format
+msgid "Cannot remove vacation notice for mail user %s."
+msgstr ""
+
+#: lib/Driver/plesk.php:131
+#, php-format
+msgid "Cannot remove vacation notice for mail user %s: %s"
+msgstr ""
+
+#: lib/Driver/plesk.php:278
+#, php-format
+msgid "Cannot retrieve domain ID of domain %s."
+msgstr ""
+
+#: lib/Driver/plesk.php:276
+#, php-format
+msgid "Cannot retrieve domain ID of domain %s: %s"
+msgstr ""
+
+#: lib/Driver/plesk.php:229
+#, php-format
+msgid "Cannot retrieve information about mail user %s."
 msgstr ""
 
-#: main.php:73
+#: lib/Driver/plesk.php:225
 #, php-format
-msgid "Failure in removing forward: %s"
+msgid "Cannot retrieve information about mail user %s: %s"
 msgstr ""
 
-#: main.php:63
+#: lib/Driver/plesk.php:85
 #, php-format
-msgid "Failure in setting forward: %s"
+msgid "Cannot set forwarding for mail user %s."
 msgstr ""
 
-#: templates/main/main.inc:88
+#: lib/Driver/plesk.php:79
+#, php-format
+msgid "Cannot set forwarding for mail user %s: %s"
+msgstr ""
+
+#: lib/Block/summary.php:37
+msgid "Failed to create a forwards driver"
+msgstr ""
+
+#: templates/main/main.inc:74
 msgid ""
 "For your protection and safety, you must identify yourself with your login "
 "password to verify this change."
@@ -77,19 +117,19 @@ msgstr ""
 msgid "Forward is not active."
 msgstr ""
 
-#: main.php:71
+#: main.php:76
 msgid "Forward removed!"
 msgstr ""
 
-#: main.php:61
+#: main.php:66
 msgid "Forward set!"
 msgstr ""
 
-#: main.php:88
+#: main.php:107
 msgid "Forwarding is currently disabled."
 msgstr ""
 
-#: main.php:86
+#: main.php:95
 msgid "Forwarding is currently enabled."
 msgstr ""
 
@@ -97,69 +137,81 @@ msgstr ""
 msgid "Forwards Summary"
 msgstr ""
 
-#: lib/Driver/ldap.php:188 lib/Driver/ldap.php:234
-msgid "Incorrect Password"
+#: lib/Driver/ldap.php:424
+msgid "Internal LDAP error.  Details have been logged for the administrator."
 msgstr ""
 
-#: templates/main/main.inc:79
+#: lib/Driver/ldap.php:266
+msgid ""
+"Internal error while searching LDAP.  Details have been logged for the "
+"administrator."
+msgstr ""
+
+#: templates/main/main.inc:65
 msgid "Keep a copy in your local mailbox?"
 msgstr ""
 
-#: lib/Driver/forwards.php:160 lib/Driver/qmail.php:150
-msgid "Maybe you didn't have a forward enabled?"
+#: lib/Driver/forwards.php:106
+msgid "Maybe you didn't have a vacation notice installed?"
 msgstr ""
 
-#: lib/Driver/mdaemon.php:36 lib/Driver/mdaemon.php:106
+#: lib/Driver/mdaemon.php:32 lib/Driver/mdaemon.php:97
 msgid "Mdaemon path not found"
 msgstr ""
 
-#: lib/Driver/mdaemon.php:81 lib/Driver/mdaemon.php:130
+#: lib/Driver/mdaemon.php:77 lib/Driver/mdaemon.php:120
 msgid "Not able to create semaphore file"
 msgstr ""
 
-#: main.php:92 templates/main/main.inc:58
+#: main.php:112 templates/main/main.inc:44
 msgid "Set or Remove E-Mail Forwards"
 msgstr ""
 
-#: templates/main/main.inc:73
+#: templates/main/main.inc:59
 msgid "Set/install a forward to:"
 msgstr ""
 
-#: templates/main/main.inc:94
+#: templates/main/main.inc:80
 msgid "Submit"
 msgstr ""
 
-#: lib/Driver/forwards.php:49 lib/Driver/ldap.php:46 lib/Driver/qmail.php:47
-msgid "The module is not properly configured!"
+#: lib/Driver/plesk.php:252
+msgid ""
+"The Plesk driver requires the Horde_DOM package from Horde 3.2 or later. See "
+"http://pear.horde.org/index.php?package=Horde_DOM"
 msgstr ""
 
-#: templates/main/main.inc:89
-msgid "Then submit the form so that your forward can be updated."
+#: lib/Driver/customsql.php:147
+msgid "The forwarding cannot be disabled. Check the password."
 msgstr ""
 
-#: templates/main/main.inc:64
-msgid ""
-"This form lets you install (or remove) e-mail forwarding for your account."
+#: lib/Driver/plesk.php:286
+msgid "The forwards application is not properly configured."
+msgstr ""
+
+#: lib/Driver/forwards.php:223 lib/Driver/ldap.php:628
+msgid "The module is not properly configured!"
 msgstr ""
 
-#: lib/Driver/customsql.php:287 lib/Driver/sql.php:333
-msgid "Unable to connect to SQL server."
+#: templates/main/main.inc:75
+msgid "Then submit the form so that your forward can be updated."
 msgstr ""
 
-#: templates/main/main.inc:84
-msgid "Unset/remove a forward"
+#: templates/main/main.inc:50
+msgid ""
+"This form lets you install (or remove) e-mail forwarding for your account."
 msgstr ""
 
-#: lib/Driver/ldap.php:268
-msgid "User not found."
+#: templates/main/main.inc:70
+msgid "Unset/remove the forward"
 msgstr ""
 
-#: main.php:34
+#: main.php:35
 #, php-format
 msgid "You can't change Forwards for user %s"
 msgstr ""
 
-#: main.php:41
+#: main.php:43
 msgid "You must give your password"
 msgstr ""
 
@@ -171,14 +223,14 @@ msgstr ""
 msgid "You must provide your password"
 msgstr ""
 
-#: main.php:29
+#: main.php:30
 msgid "You must specify the mode (set or remove)"
 msgstr ""
 
-#: main.php:58
+#: main.php:60
 msgid "You must supply an e-mail address!"
 msgstr ""
 
-#: templates/main/main.inc:91
+#: templates/main/main.inc:77
 msgid "Your password:"
 msgstr ""
diff --git a/po/fr_FR.po b/po/fr_FR.po
index 4776017..1f8c024 100644
--- a/po/fr_FR.po
+++ b/po/fr_FR.po
@@ -1,6 +1,6 @@
 # translation of fr_FR.po to Français
 # forwards module translations
-# Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+# Copyright 2003, 2004 Free Software Foundation, Inc.
 # Daniel Huhardeaux <daniel.huhardeaux at tootai.com>
 # Pierre Lachance <pl at pierrelachance.net>, 2003, 2004.
 #
diff --git a/po/gl_ES.po b/po/gl_ES.po
index cb04d16..6c2e729 100644
--- a/po/gl_ES.po
+++ b/po/gl_ES.po
@@ -8,7 +8,7 @@
 # Universidade de Santiago de Compostela
 #
 # Revisada y corregida por:
-# 
+#
 # Servicio de normalizacion linguistica <snlusc at usc.es>
 # Universidade de Santiago de Compostela
 #
diff --git a/po/hu_HU.po b/po/hu_HU.po
index bfd420e..6d1a78e 100644
--- a/po/hu_HU.po
+++ b/po/hu_HU.po
@@ -1,5 +1,5 @@
 # Hungarian translations for horde package.
-# Copyright (C) 2005 Horde Project
+# Copyright 2005-2009 The Horde Project
 # This file is distributed under the same license as the horde package.
 # Automatically generated, 2005.
 #
diff --git a/po/it_IT.po b/po/it_IT.po
index 2cc7a5b..65c3094 100644
--- a/po/it_IT.po
+++ b/po/it_IT.po
@@ -1,203 +1,190 @@
 # Traduzione in italiano del modulo forwards
-# Copyright (C) 2002 Horde Project.
+# Copyright 2002-2009 The Horde Project.
 # Alessio Ciregia <alessio at ifc.cnr.it>, 2002.
-#
+# Fabio Pedretti <fabio.pedretti at ing.unibs.it>, 2007
 msgid ""
 msgstr ""
-"Project-Id-Version: 0.1\n"
+"Project-Id-Version: 3.0.1\n"
 "Report-Msgid-Bugs-To: dev at lists.horde.org\n"
-"POT-Creation-Date: 2004-08-30 14:10+0200\n"
-"PO-Revision-Date: 2002-08-13 10:32+0200\n"
-"Last-Translator: Alessio Ciregia <alessio at ifc.cnr.it>\n"
+"POT-Creation-Date: 2006-07-31 18:12+0200\n"
+"PO-Revision-Date: 2007-10-31 13:48+0100\n"
+"Last-Translator: Fabio Pedretti <fabio.pedretti at ing.unibs.it>\n"
 "Language-Team: Italian <i18n at lists.horde.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-1\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: templates/main/main.inc:22
+#: templates/main/main.inc:63
 msgid ""
 "An e-mail forward lets you redirect your mail to another address (or a comma "
 "separated list of addresses if you wish). You can even forward to another "
 "address and keep a copy in your local mailbox."
 msgstr ""
-"Un <I>e-mail forwarder</I> ti permette di redirigere la posta su un altro "
-"indirizzo (o una serie di indirizzi separati da una virgola). <BR>Puoi anche "
-"redirigere la posta verso un altro indirizzo e allo stesso tempo mantenere "
-"una copia nella mailbox locale."
+"Un inoltro e-mail ti permette di redirigere la posta su un altro indirizzo "
+"(o una serie di indirizzi separati da una virgola). Puoi anche redirigere la "
+"posta verso un altro indirizzo e allo stesso tempo mantenere una copia nella "
+"tua casella locale."
 
-#: lib/Driver.php:166
-#, fuzzy
+#: lib/Driver.php:163
 msgid "Can't parse your email address"
-msgstr "Avvisa su aggiornamenti"
+msgstr "Impossibile analizzare l'indirizzo e-mail"
 
-#: lib/Driver/ldap.php:83 lib/Driver/ldap.php:130
-#, fuzzy
+#: lib/Driver/ldap.php:86 lib/Driver/ldap.php:133
 msgid "Check your password"
-msgstr "Cambia la tua password"
+msgstr "Controlla la tua password"
 
-#: lib/Driver/forwards.php:94 lib/Driver/forwards.php:149
-#: lib/Driver/forwards.php:192 lib/Driver/qmail.php:89
-#: lib/Driver/qmail.php:140 lib/Driver/qmail.php:184
-#, fuzzy
+#: lib/Driver/forwards.php:97 lib/Driver/forwards.php:153
+#: lib/Driver/forwards.php:198 lib/Driver/forwards.php:265
+#: lib/Driver/qmail.php:91 lib/Driver/qmail.php:143 lib/Driver/qmail.php:189
 msgid "Check your username and password"
-msgstr "Devi inserire il tuo nome utente e la password"
+msgstr "Controlla nome utente e password"
 
-#: lib/Driver/ldap.php:186 lib/Driver/ldap.php:231 lib/Driver/ldap.php:318
+#: lib/Driver/ldap.php:187 lib/Driver/ldap.php:233 lib/Driver/ldap.php:319
 msgid "Could not bind to ldap server"
-msgstr ""
+msgstr "Impossibile eseguire il bind sul server ldap"
 
-#: lib/Driver/ldap.php:304
+#: lib/Driver/ldap.php:305
 msgid "Could not connect to ldap server"
 msgstr "Impossibile connettersi al server ldap"
 
 #: lib/Block/summary.php:37
-#, fuzzy
 msgid "Failed to create a forwards driver"
-msgstr "Impossibile connettersi al server SMB."
+msgstr "Impossibile creare un modulo di inoltro"
 
-#: main.php:68
-#, fuzzy, php-format
+#: main.php:73
+#, php-format
 msgid "Failure in removing forward: %s"
-msgstr "Rimozione del forward fallita : "
+msgstr "Rimozione dell'inoltro fallita: %s"
 
-#: main.php:58
-#, fuzzy, php-format
+#: main.php:63
+#, php-format
 msgid "Failure in setting forward: %s"
-msgstr "Impostazione del forward fallita : "
+msgstr "Impostazione dell'inoltro fallita: %s"
 
-#: templates/main/main.inc:46
+#: templates/main/main.inc:88
 msgid ""
 "For your protection and safety, you must identify yourself with your login "
 "password to verify this change."
 msgstr ""
 "Per sicurezza, devi identificarti con la tua password di login per "
-"verificare la tua identit&agrave."
+"verificare la tua identità."
 
-#: lib/Block/summary.php:42
-#, fuzzy
+#: lib/Block/summary.php:51
+msgid "Forward is active, unable to retrieve additional details."
+msgstr "L'inoltro è attivo, impossibile recuperare ulteriori dettagli."
+
+#: lib/Block/summary.php:47
 msgid "Forward is active."
-msgstr "Sondaggio e' attivo"
+msgstr "L'inoltro è attivo."
 
-#: lib/Block/summary.php:40
-#, fuzzy
+#: lib/Block/summary.php:41
 msgid "Forward is not active."
-msgstr "Condivisione cartelle non abilitato."
+msgstr "L'inoltro non è attivo."
 
-#: main.php:66
+#: main.php:71
 msgid "Forward removed!"
-msgstr "Forward rimosso!"
+msgstr "Inoltro rimosso!"
 
-#: main.php:56
+#: main.php:61
 msgid "Forward set!"
-msgstr "Forward impostato!"
+msgstr "Inoltro impostato!"
 
-#: main.php:83
-#, fuzzy
+#: main.php:88
 msgid "Forwarding is currently disabled."
-msgstr "Condivisione cartelle non abilitato."
+msgstr "L'inoltro è correntemente disabilitato."
 
-#: main.php:81
-#, fuzzy
+#: main.php:86
 msgid "Forwarding is currently enabled."
-msgstr "Condivisione cartelle non abilitato."
+msgstr "L'inoltro è correntemente abilitato."
 
 #: lib/Block/summary.php:3
-#, fuzzy
 msgid "Forwards Summary"
-msgstr "Riassunto Discussione"
-
-#: templates/menu/menu.inc:10
-msgid "Help"
-msgstr "Aiuto"
+msgstr "Sommario inoltro"
 
-#: lib/Driver/ldap.php:187 lib/Driver/ldap.php:232
+#: lib/Driver/ldap.php:188 lib/Driver/ldap.php:234
 msgid "Incorrect Password"
 msgstr "Password Errata"
 
-#: templates/main/main.inc:38
-#, fuzzy
+#: templates/main/main.inc:79
 msgid "Keep a copy in your local mailbox?"
-msgstr "Mantieni una copia nella tua mailbox locale (default <b>no</b>)"
+msgstr "Mantenere una copia nella casella locale?"
 
-#: lib/Driver/forwards.php:156 lib/Driver/qmail.php:147
+#: lib/Driver/forwards.php:160 lib/Driver/qmail.php:150
 msgid "Maybe you didn't have a forward enabled?"
-msgstr ""
+msgstr "Forse non avevi abilitato l'inoltro?"
 
-#: lib/Driver/mdaemon.php:38 lib/Driver/mdaemon.php:108
-#, fuzzy
+#: lib/Driver/mdaemon.php:36 lib/Driver/mdaemon.php:106
 msgid "Mdaemon path not found"
-msgstr "Contatto non trovato."
+msgstr "Percorso di mdaemon non trovato"
 
-#: lib/Driver/mdaemon.php:83 lib/Driver/mdaemon.php:132
-#, fuzzy
+#: lib/Driver/mdaemon.php:81 lib/Driver/mdaemon.php:130
 msgid "Not able to create semaphore file"
-msgstr "Non era possibile creare il file VFS."
+msgstr "Impossibile creare il file semaforo"
 
-#: main.php:86 templates/main/main.inc:17
+#: main.php:92 templates/main/main.inc:58
 msgid "Set or Remove E-Mail Forwards"
-msgstr "E-Mail Forwards - Impostazione o rimozione"
+msgstr "Impostazione o rimozione di un inoltro e-mail"
 
-#: templates/main/main.inc:32
-#, fuzzy
+#: templates/main/main.inc:73
 msgid "Set/install a forward to:"
-msgstr "Imposta/installa il forward"
+msgstr "Imposta l'inoltro a:"
 
-#: templates/main/main.inc:52
+#: templates/main/main.inc:94
 msgid "Submit"
-msgstr "Submit"
+msgstr "Applica"
 
-#: lib/Driver/forwards.php:47 lib/Driver/ldap.php:46 lib/Driver/qmail.php:46
-#, fuzzy
+#: lib/Driver/forwards.php:49 lib/Driver/ldap.php:46 lib/Driver/qmail.php:47
 msgid "The module is not properly configured!"
-msgstr "Mnemo non &egrave; correttamente configurato"
+msgstr "Il modulo non è configurato correttamente!"
 
-#: templates/main/main.inc:47
+#: templates/main/main.inc:89
 msgid "Then submit the form so that your forward can be updated."
-msgstr " Quindi clicca su submit affinch&egrave il forward venga impostato."
+msgstr "Quindi applica il modulo affinchè l'inoltro venga impostato."
 
-#: templates/main/main.inc:23
+#: templates/main/main.inc:64
 msgid ""
 "This form lets you install (or remove) e-mail forwarding for your account."
 msgstr ""
-"Questo form ti permette di installare (o rimuovere) l'e-mail forwarding per "
+"Questo modulo ti permette di installare (o rimuovere) l'inoltro e-mail per "
 "il tuo account."
 
-#: lib/Driver/customsql.php:270 lib/Driver/sql.php:301
+#: lib/Driver/customsql.php:287 lib/Driver/sql.php:333
 msgid "Unable to connect to SQL server."
 msgstr "Impossibile connettersi al server SQL."
 
-#: lib/Block/summary.php:47
-#, fuzzy
-msgid "Unable to retrieve forwarding information"
-msgstr "Impossibile cambiare a %s."
-
-#: templates/main/main.inc:43
+#: templates/main/main.inc:84
 msgid "Unset/remove a forward"
-msgstr "Rimuovi il forward"
+msgstr "Rimuovi l'inoltro"
 
 #: lib/Driver/ldap.php:268
 msgid "User not found."
 msgstr "Utente non trovato."
 
-#: main.php:33
+#: main.php:34
 #, php-format
 msgid "You can't change Forwards for user %s"
-msgstr "Non puoi cambiare Forwards per l'utente %s"
+msgstr "Non puoi cambiare l'inoltro per l'utente %s"
 
-#: main.php:39
+#: main.php:41
 msgid "You must give your password"
 msgstr "Devi fornire la tua password"
 
-#: main.php:28
-#, fuzzy
+#: templates/main/main.inc:11
+msgid "You must provide a forwarding address to set"
+msgstr "Devi fornire un indirizzo da impostare per l'inoltro"
+
+#: templates/main/main.inc:7
+msgid "You must provide your password"
+msgstr "Devi fornire la tua password"
+
+#: main.php:29
 msgid "You must specify the mode (set or remove)"
-msgstr "Devi specificare lo username da rimuovere."
+msgstr "Devi specificare il modo (imposta o rimuovi)"
 
-#: main.php:53
-#, fuzzy
+#: main.php:58
 msgid "You must supply an e-mail address!"
-msgstr "Devi specificare un indirizzo e-mail"
+msgstr "Devi specificare un indirizzo e-mail!"
 
-#: templates/main/main.inc:50
+#: templates/main/main.inc:91
 msgid "Your password:"
 msgstr "La tua password:"
diff --git a/po/nn_NO.po b/po/nn_NO.po
index a303de4..f73cea1 100644
--- a/po/nn_NO.po
+++ b/po/nn_NO.po
@@ -1,8 +1,8 @@
 # Forwards Norwegian Nynorsk translation
-# Copyright (C) 2002 Per-Stian Vatne
+# Copyright 2002 Per-Stian Vatne
 # This file is distributed under the same license as the Forwards package.
 # Per-Stian Vatne <psv at orsta.org>, 2002.
-# 
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: Forwards 0.0.1-cvs\n"
@@ -15,9 +15,9 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 
 msgid ""
-"An e-mail forward lets you redirect your mail to another address (or a "
-"comma separated list of addresses if you wish). You can even forward to "
-"another address and keep a copy in your local mailbox."
+"An e-mail forward lets you redirect your mail to another address (or a comma "
+"separated list of addresses if you wish). You can even forward to another "
+"address and keep a copy in your local mailbox."
 msgstr ""
 "Vidaresending av e-post lar deg omdirigere e-posten din til ei anna adresse "
 "(eller ei kommaseparert liste av adresser, om du ønskjer). Du kan også "
diff --git a/po/pl_PL.po b/po/pl_PL.po
index f8c422e..cbd7838 100644
--- a/po/pl_PL.po
+++ b/po/pl_PL.po
@@ -1,6 +1,6 @@
 # Polish translations for horde package
 # Polskie t³umaczenia dla pakietu horde.
-# Copyright (C) 2004 Piotr Kuczynski <pkuczynski at hypode.pl>
+# Copyright 2004 Piotr Kuczynski <pkuczynski at hypode.pl>
 # This file is distributed under the same license as the horde package.
 #
 msgid ""
diff --git a/po/pt_BR.po b/po/pt_BR.po
index 5cdd802..ac21207 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -1,191 +1,191 @@
-# TRADUÇãO PARA O PORTUGUÊS DO MÓDULO FORWARDS
-# Copyright (C) 2002 Horde Project.
+# Tradução para o Português do módulo Forwards.
+# Copyright 2002-2009 The Horde Project.
 # João César Marigonda <joao at webnow.com.br>, 2002.
+# GRACO - Gestores da Rede Academica de Computacão - DCC/UFBa <graco at dcc.ufba.br>, 2008.
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: forward\n"
-"POT-Creation-Date: 2002-02-00 09:15-0600\n"
-"PO-Revision-Date: 0000-00-00 00:03+0000\n"
-"Last-Translator: João César Marigonda <joao at webnow.com.br>\n"
+"Project-Id-Version: Forwards 3.1\n"
+"POT-Creation-Date: 2008-02-23 15:25-0600\n"
+"PO-Revision-Date: 2008-02-25 01:16+0100\n"
+"Last-Translator: GRACO <graco at dcc.ufba.br>\n"
 "Language-Team: Português Brasileiro <i18n at lists.horde.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=iso-8859-1\n"
 "Content-Transfer-Encoding: 8-bit\n"
 
+#: templates/main/main.inc:63
 msgid ""
-"An e-mail forward let's you redirect your mail to another address (or a "
-"comma separated list of addresses if you wish). You can even forward to "
-"another address and keep a copy in your local mailbox."
+"An e-mail forward lets you redirect your mail to another address (or a comma "
+"separated list of addresses if you wish). You can even forward to another "
+"address and keep a copy in your local mailbox."
 msgstr ""
-"Um redirecionamento de e_mail permite que as mensagens recebidas sejam "
-"encaminhadas para outro endereço (ou uma lista deles, separada por vírgula). "
-"É possível inclusive manter uma cópia das mensagens em sua conta local. "
-
-msgid ""
-"As an administrator, you can set forwards for yourself or for others (if you "
-"know their username and password)."
-msgstr ""
-"Como administrador, você pode definir redirecionamentos para si e para "
-"outros (se conhecidos o nome de usuário e a senha)."
-
-msgid "Could not create file"
-msgstr "Não foi possível criar o arquivo"
-
-msgid "Could not login - check password"
-msgstr "Não foi possível efetuar login - confira a senha"
-
-msgid "Could not login -- check password!"
-msgstr "Não foi possível efetuar login - confira a senha"
-
-msgid "Could not set forwarding!"
-msgstr "Não foi possível definir o redirecionamento"
-
-msgid "Could not write to file"
-msgstr "Não foi possível escrever no arquivo"
-
-msgid "Error"
-msgstr "Erro"
-
-msgid "Failure in removing forward : "
-msgstr "Falha ao remover arquivo de redirecionamento: "
-
-msgid "Failure in setting forward : "
-msgstr "Falha ao definir redirecionamento: "
-
-msgid "File open failed - File exists"
-msgstr "Falha na abertura de arquivo - Arquivo já existe"
-
+"O redirecionamento de e-mail permite que as mensagens recebidas sejam "
+"encaminhadas para outro endereço (ou uma lista deles, separada por "
+"vírgula),  sendo possível manter uma cópia destas mensagens em sua caixa de "
+"entrada neste servidor. "
+
+#: lib/Driver.php:163
+msgid "Can't parse your email address"
+msgstr "Não foi possível checar seu endereço de email"
+
+#: lib/Driver/ldap.php:86 lib/Driver/ldap.php:133
+msgid "Check your password"
+msgstr "Confira sua senha"
+
+#: lib/Driver/forwards.php:97 lib/Driver/forwards.php:153
+#: lib/Driver/forwards.php:198 lib/Driver/forwards.php:265
+#: lib/Driver/qmail.php:91 lib/Driver/qmail.php:143 lib/Driver/qmail.php:189
+msgid "Check your username and password"
+msgstr "Confira seu usuário e senha"
+
+#: lib/Driver/ldap.php:187 lib/Driver/ldap.php:233 lib/Driver/ldap.php:319
+msgid "Could not bind to ldap server"
+msgstr "Náo foi possível autenticar-se no servidor ldap"
+
+#: lib/Driver/ldap.php:305
+msgid "Could not connect to ldap server"
+msgstr "Não foi possível conectar ao servidor ldap"
+
+#: lib/Block/summary.php:37
+msgid "Failed to create a forwards driver"
+msgstr "Falha ao criar o driver de redirecionamento"
+
+#: main.php:73
+#, php-format
+msgid "Failure in removing forward: %s"
+msgstr "Falha ao remover o redirecionamento: %s"
+
+#: main.php:63
+#, php-format
+msgid "Failure in setting forward: %s"
+msgstr "Falha ao configurar o redirecionamento: %s"
+
+#: templates/main/main.inc:88
 msgid ""
 "For your protection and safety, you must identify yourself with your login "
 "password to verify this change."
 msgstr ""
 "Para sua proteção e segurança, você deve identificar-se com seu login e "
-"senha para confirmar a modificação. "
+"senha para confirmar a alterção."
 
+#: lib/Block/summary.php:51
+msgid "Forward is active, unable to retrieve additional details."
+msgstr "Redirecionamento ativo, não foi possível obter detalhes adicionais."
+
+#: lib/Block/summary.php:47
+msgid "Forward is active."
+msgstr "Redirecionamento ativo."
+
+#: lib/Block/summary.php:41
+msgid "Forward is not active."
+msgstr "Redirecionamento desativado."
+
+#: main.php:71
 msgid "Forward removed!"
 msgstr "Redirecionamento removido!"
 
+#: main.php:61
 msgid "Forward set!"
 msgstr "Redirecionamento definido!"
 
-msgid "Forwards module is not properly configured"
-msgstr "O módulo de redirecionamento não foi devidamente configurado"
-
-msgid "Help"
-msgstr "Ajuda"
+#: main.php:88
+msgid "Forwarding is currently disabled."
+msgstr "O redirecionamento está desabilitado."
 
-msgid "Keep a copy in your mailbox (default <b>no</b>)"
-msgstr "Manter uma cópia na conta local (Padrão: <b>não</b>)"
+#: main.php:86
+msgid "Forwarding is currently enabled."
+msgstr "O redirecionamento está habilitado."
 
-msgid "Language"
-msgstr "Idioma"
+#: lib/Block/summary.php:3
+msgid "Forwards Summary"
+msgstr "Estado do redirecionamento"
 
-msgid "Logout"
-msgstr "Desconectar"
+#: lib/Driver/ldap.php:188 lib/Driver/ldap.php:234
+msgid "Incorrect Password"
+msgstr "Senha incorreta"
 
-msgid "Message"
-msgstr "Mensagem"
+#: templates/main/main.inc:79
+msgid "Keep a copy in your local mailbox?"
+msgstr "Manter uma cópia na conta local?"
 
-msgid "Note:"
-msgstr "Nota:"
+#: lib/Driver/forwards.php:160 lib/Driver/qmail.php:150
+msgid "Maybe you didn't have a forward enabled?"
+msgstr "Será que você não tinha um redirecionamento ativado?"
 
-msgid "Problem?"
-msgstr "Problema?"
+#: lib/Driver/mdaemon.php:36 lib/Driver/mdaemon.php:106
+msgid "Mdaemon path not found"
+msgstr "Caminho para mdaemon não encontrado"
 
-msgid "Select your preferred language:"
-msgstr "Selecione o idioma:"
-
-msgid "Server connection failed"
-msgstr "Conexão com servidor falhou"
+#: lib/Driver/mdaemon.php:81 lib/Driver/mdaemon.php:130
+msgid "Not able to create semaphore file"
+msgstr "Não foi possível criar o arquivo semaphore"
 
+#: main.php:92 templates/main/main.inc:58
 msgid "Set or Remove E-Mail Forwards"
-msgstr "Define ou remove redirecionamento de e_mail"
-
-msgid "Set the language that menu items, explanations, and help are in."
-msgstr "Define o idioma dos ítens do menu, das explicações e da ajuda."
+msgstr "Defina ou remova o redirecionamento de e-mail"
 
-msgid "Set/install a forward"
-msgstr "Define/instala redirecionamento"
-
-msgid "Some of Forwards module's configuration files are missing:"
-msgstr "Faltam arquivos de configuração do módulo de redirecionamento:"
+#: templates/main/main.inc:73
+msgid "Set/install a forward to:"
+msgstr "Defina um redirecionamento para:"
 
+#: templates/main/main.inc:94
 msgid "Submit"
 msgstr "Enviar"
 
-msgid "Success"
-msgstr "Sucesso"
+#: lib/Driver/forwards.php:49 lib/Driver/ldap.php:46 lib/Driver/qmail.php:47
+msgid "The module is not properly configured!"
+msgstr "O modulo não está corretamente configurado!"
 
+#: templates/main/main.inc:89
 msgid "Then submit the form so that your forward can be updated."
 msgstr ""
 "Em seguida envie o formulário para que o redirecionamento seja atualizado."
-"<br>"
-
-msgid ""
-"This file controls the default preferences for Forwards module, and also "
-"controls which preferences users can alter."
-msgstr ""
-"Este arquivo controla as preferências padrão do módulo de redirecionamento, "
-"como também aquelas que podem ser personalizadas."
-
-msgid ""
-"This file controls the stylesheet that is used to set colors and fonts in "
-"addition to or overriding Horde defaults."
-msgstr ""
-"Este arquivo controla os estilos utilizados para cores e fontes, em "
-"sobreposição ou adição aos definidos pelo Horde."
-
-msgid ""
-"This form let's you install (or remove) e-mail forwarding for your account."
-msgstr ""
-"Este formulário permite instalar (ou remover) redirecionamentos para sua "
-"conta."
 
+#: templates/main/main.inc:64
 msgid ""
-"This form uses strong encryption to protect your password while in transmit "
-"to the web server."
+"This form lets you install (or remove) e-mail forwarding for your account."
 msgstr ""
-"Este formulário utiliza criptografia forte para proteger sua senha, "
-"enquantoenviada ao servidor web."
+"Este formulário permite que você instale (ou remova) redirecionamento de e-"
+"mail para sua conta."
 
-msgid ""
-"This is the main Forwards module configuration file. It contains paths and "
-"options for all Forwards module scripts."
-msgstr ""
-"Este é o principal arquivo de configuração do redirecionamento. Contém "
-"diretórios e opções para todos os scripts do módulo Forwards."
+#: lib/Driver/customsql.php:287 lib/Driver/sql.php:333
+msgid "Unable to connect to SQL server."
+msgstr "Impossível conectar ao servidor SQL."
 
+#: templates/main/main.inc:84
 msgid "Unset/remove a forward"
-msgstr "Apagar/remover redirecionamento"
+msgstr "Desabilite/remova o redirecionamento."
 
-msgid "Warning"
-msgstr "Aviso"
-
-msgid "You can not set Forwards  for other user"
-msgstr "Você não pode definir redirecionamento para outro usuário"
+#: lib/Driver/ldap.php:268
+msgid "User not found."
+msgstr "Usuário não encontrado."
 
+#: main.php:34
 #, c-format
 msgid "You can't change Forwards for user %s"
 msgstr "Você não pode modificar redirecionamentos para o usuário %s"
 
+#: main.php:41
 msgid "You must give your password"
 msgstr "Você deve fornecer uma senha"
 
-msgid "You must give your userid"
-msgstr "Você deve fornecer seu nome de usuário"
-
-msgid "You must specify the mode"
-msgstr "Você deve especificar o modo"
+#: templates/main/main.inc:11
+msgid "You must provide a forwarding address to set"
+msgstr "Você deve fornecer um endereço para definir o redirecionamento"
 
-msgid "You must supply an e-mail address"
-msgstr "Você deve fornecer um endereço de e_mail"
+#: templates/main/main.inc:7
+msgid "You must provide your password"
+msgstr "Você deve fornecer sua senha"
 
-msgid "Your Information"
-msgstr "Seus dados"
+#: main.php:29
+msgid "You must specify the mode (set or remove)"
+msgstr "Você deve escolher uma opção (definir ou remover)"
 
-msgid "Your Userid:"
-msgstr "Seu userid:"
+#: main.php:58
+msgid "You must supply an e-mail address!"
+msgstr "Você deve fornecer um endereço de e-mail"
 
+#: templates/main/main.inc:91
 msgid "Your password:"
 msgstr "Sua senha:"
diff --git a/po/pt_PT.po b/po/pt_PT.po
index 5cdd802..f82beae 100644
--- a/po/pt_PT.po
+++ b/po/pt_PT.po
@@ -1,5 +1,5 @@
 # TRADUÇãO PARA O PORTUGUÊS DO MÓDULO FORWARDS
-# Copyright (C) 2002 Horde Project.
+# Copyright 2002-2009 The Horde Project.
 # João César Marigonda <joao at webnow.com.br>, 2002.
 #
 msgid ""
diff --git a/po/ro_RO.po b/po/ro_RO.po
index 795f764..d57a0ec 100644
--- a/po/ro_RO.po
+++ b/po/ro_RO.po
@@ -1,9 +1,8 @@
 # FORWARDS MODULE ROMANIAN TRANSLATION
-# Copyright (C) 2003 Horde Project.
+# Copyright 2003-2009 The Horde Project.
 # Eugen Hoanca <eugenh at urban-grafx.ro>, 2003.
 # Marius Dragulescu <mariusd at urban-grafx.ro>, 2003.
 #
-
 msgid ""
 msgstr ""
 "Project-Id-Version: Forwards 2.2\n"
@@ -16,15 +15,14 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 
 msgid ""
-"An e-mail forward lets you redirect your mail to another address (or a "
-"comma separated list of addresses if you wish). You can even forward to "
-"another address and keep a copy in your local mailbox."
+"An e-mail forward lets you redirect your mail to another address (or a comma "
+"separated list of addresses if you wish). You can even forward to another "
+"address and keep a copy in your local mailbox."
 msgstr ""
 "O inaintare de e-mailuri permite redirectarea mailurilor catre o alta adresa "
 "sau catre o lista de adrese separate prin virgula.Se poate inainta si catre "
 "alta adresa cu pastrarea unei copii locale."
 
-
 msgid "Could not create file"
 msgstr "Creare fisier imposibila"
 
@@ -59,7 +57,6 @@ msgstr ""
 "Pentru securitatea personala, trebuie sa te identifici prin username si "
 "parola pentru a verifica schimbarile."
 
-
 msgid "Forward removed!"
 msgstr "Inaintare eliminata!"
 
@@ -121,13 +118,12 @@ msgstr ""
 "Acest fisier contine atat preferintele implicite ale modulului Forwards, cat "
 "si alte preferinte."
 
-
 msgid ""
 "This file controls the stylesheet that is used to set colors and fonts in "
 "addition to or overriding Horde defaults."
 msgstr ""
-"Acest fisier determina schema de ulori si fonturi utilizate ce vor inlocui"
-"setarile implicite furnizate de Horde."
+"Acest fisier determina schema de ulori si fonturi utilizate ce vor "
+"inlocuisetarile implicite furnizate de Horde."
 
 msgid ""
 "This form lets you install (or remove) e-mail forwarding for your account."
diff --git a/po/ru_RU.po b/po/ru_RU.po
index ed2c24e..24aae13 100644
--- a/po/ru_RU.po
+++ b/po/ru_RU.po
@@ -1,5 +1,5 @@
 # Russian translations for Forwards package
-# Copyright (C) 2006 Horde Project
+# Copyright 2006-2009 The Horde Project
 # This file is distributed under the same license as the Forwards package.
 # Automatically generated, 2006.
 #
diff --git a/po/forwards.pot b/po/tr_TR.po
similarity index 50%
copy from po/forwards.pot
copy to po/tr_TR.po
index 232a782..49bcc3f 100644
--- a/po/forwards.pot
+++ b/po/tr_TR.po
@@ -1,20 +1,20 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR Horde Project
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
+# Turkish translations for Forwards package
+# Yöneltme paketi için Türkçe çeviriler.
+# Copyright 2008-2009 The Horde Project
+# This file is distributed under the same license as the Ýmp package.
+# horde-tr at metu.edu.tr, 2007-2008.
 #
-#, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
+"Project-Id-Version: Forwards 3.0-cvs\n"
 "Report-Msgid-Bugs-To: dev at lists.horde.org\n"
-"POT-Creation-Date: 2006-07-31 18:12+0200\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
-"Language-Team: LANGUAGE <LL at li.org>\n"
+"POT-Creation-Date: 2008-04-15 12:57+0300\n"
+"PO-Revision-Date: 2006-08-09 17:14+0200\n"
+"Last-Translator: Emre Sezginer <horde-tr at horde.org>\n"
+"Language-Team: Turkish <dev at lists.horde.org>\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CHARSET\n"
-"Content-Transfer-Encoding: 8bit\n"
+"Content-Type: text/plain; charset=iso-8859-9\n"
+"Content-Transfer-Encoding: 8-bit\n"
 
 #: templates/main/main.inc:63
 msgid ""
@@ -22,163 +22,167 @@ msgid ""
 "separated list of addresses if you wish). You can even forward to another "
 "address and keep a copy in your local mailbox."
 msgstr ""
+"Eposta yöneltme, gelen epostalarýnýzýn bir baþka adrese ya da virgül ile "
+"ayrýlmýþ birden fazla adrese ulaþtýrýlmasýný saðlar. Hatta, gelen "
+"mesajlarýnýzýn bir kopyasýný Gelen Kutunuzda tutup, bir kopyasýný da baþka "
+"bir adrese yöneltebilirsiniz."
 
 #: lib/Driver.php:163
 msgid "Can't parse your email address"
-msgstr ""
+msgstr "Eposta adresiniz ayrýþtýrýlamadý"
 
 #: lib/Driver/ldap.php:86 lib/Driver/ldap.php:133
 msgid "Check your password"
-msgstr ""
+msgstr "Þifrenizi kontrol ediniz"
 
-#: lib/Driver/forwards.php:97 lib/Driver/forwards.php:153
-#: lib/Driver/forwards.php:198 lib/Driver/forwards.php:265
-#: lib/Driver/qmail.php:91 lib/Driver/qmail.php:143 lib/Driver/qmail.php:189
+#: lib/Driver/forwards.php:256 lib/Driver/qmail.php:215
 msgid "Check your username and password"
-msgstr ""
+msgstr "Kullanýcý adý ve þifrenizi kontrol ediniz"
 
 #: lib/Driver/ldap.php:187 lib/Driver/ldap.php:233 lib/Driver/ldap.php:319
 msgid "Could not bind to ldap server"
-msgstr ""
+msgstr "ldap sunucu ile bað kurulamadý"
 
 #: lib/Driver/ldap.php:305
 msgid "Could not connect to ldap server"
-msgstr ""
+msgstr "ldap sunucuya baðlanýlamadý"
 
 #: lib/Block/summary.php:37
 msgid "Failed to create a forwards driver"
-msgstr ""
+msgstr "Yöneltme sürücüsü oluþturulamadý"
 
-#: main.php:73
+#: main.php:75
 #, php-format
 msgid "Failure in removing forward: %s"
-msgstr ""
+msgstr "Yöneltme kaldýrýlýrken hata oluþtu: %s"
 
-#: main.php:63
+#: main.php:65
 #, php-format
 msgid "Failure in setting forward: %s"
-msgstr ""
+msgstr "\"Ilet\" ayarlanýrken hata oluþtu: %s"
 
 #: templates/main/main.inc:88
 msgid ""
 "For your protection and safety, you must identify yourself with your login "
 "password to verify this change."
-msgstr ""
+msgstr "Güvenliðiniz için, bu deðiþimi, þifrenizi girerek onaylamalýsýnýz. "
 
 #: lib/Block/summary.php:51
 msgid "Forward is active, unable to retrieve additional details."
-msgstr ""
+msgstr "Yöneltme faal. Ek detaylý bilgi alýnamadý."
 
 #: lib/Block/summary.php:47
 msgid "Forward is active."
-msgstr ""
+msgstr "Yöneltme faal."
 
 #: lib/Block/summary.php:41
 msgid "Forward is not active."
-msgstr ""
+msgstr "Yöneltme faal deðil."
 
-#: main.php:71
+#: main.php:73
 msgid "Forward removed!"
-msgstr ""
+msgstr "Yöneltme iptal edildi!"
 
-#: main.php:61
+#: main.php:63
 msgid "Forward set!"
-msgstr ""
+msgstr "Yöneltme ayarlandý!"
 
-#: main.php:88
+#: main.php:90
 msgid "Forwarding is currently disabled."
-msgstr ""
+msgstr "Yöneltme þu anda etkin deðil."
 
-#: main.php:86
+#: main.php:88
 msgid "Forwarding is currently enabled."
-msgstr ""
+msgstr "Yöneltme þu anda etkin."
 
 #: lib/Block/summary.php:3
 msgid "Forwards Summary"
-msgstr ""
+msgstr "Yöneltme Özeti"
 
 #: lib/Driver/ldap.php:188 lib/Driver/ldap.php:234
 msgid "Incorrect Password"
-msgstr ""
+msgstr "Hatalý Þifre"
 
 #: templates/main/main.inc:79
 msgid "Keep a copy in your local mailbox?"
-msgstr ""
+msgstr "Bir kopya gelen kutunuzda kalsýn mý?"
 
-#: lib/Driver/forwards.php:160 lib/Driver/qmail.php:150
+#: lib/Driver/forwards.php:130 lib/Driver/qmail.php:122
 msgid "Maybe you didn't have a forward enabled?"
-msgstr ""
+msgstr "Yöneltmeyi aktif hale getirmemiþ olabilirsiniz"
 
 #: lib/Driver/mdaemon.php:36 lib/Driver/mdaemon.php:106
 msgid "Mdaemon path not found"
-msgstr ""
+msgstr "Mdaemon yolu bulunamadý"
 
 #: lib/Driver/mdaemon.php:81 lib/Driver/mdaemon.php:130
 msgid "Not able to create semaphore file"
-msgstr ""
+msgstr "Ýþaret dosyasý yaratýlamadý"
 
-#: main.php:92 templates/main/main.inc:58
+#: main.php:94 templates/main/main.inc:58
 msgid "Set or Remove E-Mail Forwards"
-msgstr ""
+msgstr "Eposta Yöneltmeyi Etkin Kýlma Ya da Kaldýrma"
 
 #: templates/main/main.inc:73
 msgid "Set/install a forward to:"
-msgstr ""
+msgstr "Yöneltme adresi:"
 
 #: templates/main/main.inc:94
 msgid "Submit"
-msgstr ""
+msgstr "Gönder"
 
-#: lib/Driver/forwards.php:49 lib/Driver/ldap.php:46 lib/Driver/qmail.php:47
+#: lib/Driver/forwards.php:50 lib/Driver/qmail.php:48 lib/Driver/ldap.php:46
 msgid "The module is not properly configured!"
-msgstr ""
+msgstr "Yöneltme modülü doðru yapýlandýrýlmamýþ!"
 
 #: templates/main/main.inc:89
 msgid "Then submit the form so that your forward can be updated."
-msgstr ""
+msgstr "Daha sonra yöneltmeyi güncellemek için \"gönder\" tuþuna týklayýn "
 
 #: templates/main/main.inc:64
 msgid ""
 "This form lets you install (or remove) e-mail forwarding for your account."
 msgstr ""
+"Bu form, hesabýnýz için eposta yöneltmeyi etkin kýlmak ya da kaldýrmak için "
+"kullanýlýr."
 
-#: lib/Driver/customsql.php:287 lib/Driver/sql.php:333
+#: lib/Driver/sql.php:332 lib/Driver/customsql.php:287
 msgid "Unable to connect to SQL server."
-msgstr ""
+msgstr "SQL sunucuya baðlantý kurulamadý."
 
 #: templates/main/main.inc:84
 msgid "Unset/remove a forward"
-msgstr ""
+msgstr "Yöneltmeyi iptal et/kaldýr"
 
 #: lib/Driver/ldap.php:268
 msgid "User not found."
-msgstr ""
+msgstr "kullanýcý bulunamadý."
 
-#: main.php:34
+#: main.php:36
 #, php-format
 msgid "You can't change Forwards for user %s"
-msgstr ""
+msgstr "%s kullanýcýsý için yöneltmeyi deðiþtiremezsiniz"
 
-#: main.php:41
+#: main.php:43
 msgid "You must give your password"
-msgstr ""
+msgstr "Þifrenizi girmelisiniz"
 
 #: templates/main/main.inc:11
 msgid "You must provide a forwarding address to set"
-msgstr ""
+msgstr "Yöneltilecek adresi girmelisiniz"
 
 #: templates/main/main.inc:7
 msgid "You must provide your password"
-msgstr ""
+msgstr "Þifrenizi girmelisiniz"
 
-#: main.php:29
+#: main.php:31
 msgid "You must specify the mode (set or remove)"
-msgstr ""
+msgstr "Ya yöneltmeyi ya da yöneltmeyi iptal etmeyi seçmelisiniz"
 
-#: main.php:58
+#: main.php:60
 msgid "You must supply an e-mail address!"
-msgstr ""
+msgstr "Bir eposta adresi belirtmelisiniz!"
 
 #: templates/main/main.inc:91
 msgid "Your password:"
-msgstr ""
+msgstr "Þifreniz:"
diff --git a/po/zh_TW.po b/po/zh_TW.po
index d53a1c5..e89ed5e 100644
--- a/po/zh_TW.po
+++ b/po/zh_TW.po
@@ -1,12 +1,12 @@
 # Forwards module translations
-# Copyright (C) 2002 David Chang. ±i¨}¤å,¥xÆW
+# Copyright 2002 David Chang. ±i¨}¤å,¥xÆW
 # David Chang <david at tmv.gov.tw>, 2002.
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: forwards H3 (3.0)\n"
+"Project-Id-Version: forwards H3 (3.1-cvs)\n"
 "Report-Msgid-Bugs-To: dev at lists.horde.org\n"
-"POT-Creation-Date: 2007-02-06 11:17+0800\n"
+"POT-Creation-Date: 2007-01-25 15:09+0800\n"
 "PO-Revision-Date: 2002-07-04 11:20+080\n"
 "Last-Translator: David Chang <david at tmv.gov.tw>\n"
 "Language-Team: Traditional Chinese <i18n at lists.horde.org>\n"
@@ -50,12 +50,12 @@ msgstr "
 msgid "Failed to create a forwards driver"
 msgstr "µLªk«Ø¥ß¤@­Ó¦Û°ÊÂà«HªºÅX°Êµ{¦¡"
 
-#: main.php:73
+#: main.php:75
 #, php-format
 msgid "Failure in removing forward: %s"
 msgstr "¨ú®ø¦Û°ÊÂà«H®É¥¢±Ñ: %s"
 
-#: main.php:63
+#: main.php:65
 #, php-format
 msgid "Failure in setting forward: %s"
 msgstr "³]©w¦Û°ÊÂà«H®É¥¢±Ñ: %s"
@@ -78,19 +78,19 @@ msgstr "
 msgid "Forward is not active."
 msgstr "¦Û°ÊÂà«H¥\¯à©|¥¼±Ò¥Î."
 
-#: main.php:71
+#: main.php:73
 msgid "Forward removed!"
 msgstr "¤w¨ú®ø¦Û°ÊÂà«H¥\¯à!"
 
-#: main.php:61
+#: main.php:63
 msgid "Forward set!"
 msgstr "¤w±Ò¥Î¦Û°ÊÂà«H¥\¯à!"
 
-#: main.php:88
+#: main.php:90
 msgid "Forwarding is currently disabled."
 msgstr "¦Û°ÊÂà«H¥\¯à¥Ø«e¤w°±¥Î."
 
-#: main.php:86
+#: main.php:88
 msgid "Forwarding is currently enabled."
 msgstr "¦Û°ÊÂà«H¥\¯à¥Ø«e¤w±Ò¥Î."
 
@@ -118,7 +118,7 @@ msgstr "
 msgid "Not able to create semaphore file"
 msgstr "µLªk«Ø¥ß¼Ð»xÀÉ"
 
-#: main.php:92 templates/main/main.inc:58
+#: main.php:94 templates/main/main.inc:58
 msgid "Set or Remove E-Mail Forwards"
 msgstr "³]©w©Î²¾°£¹q¤l¶l¥ó¦Û°ÊÂà«H"
 
@@ -143,7 +143,7 @@ msgid ""
 "This form lets you install (or remove) e-mail forwarding for your account."
 msgstr "³o¥÷ªí³æÅý§A¯à°÷¬°§Aªº¹q¤l¶l¥ó³]©w(©Î²¾°£)¦Û°ÊÂà«H."
 
-#: lib/Driver/customsql.php:288 lib/Driver/sql.php:333
+#: lib/Driver/customsql.php:287 lib/Driver/sql.php:333
 msgid "Unable to connect to SQL server."
 msgstr "µLªk³sµ²¦Ü SQL ¦øªA¾¹."
 
@@ -155,12 +155,12 @@ msgstr "
 msgid "User not found."
 msgstr "§ä¤£¨ì¨Ï¥ÎªÌ."
 
-#: main.php:34
+#: main.php:36
 #, php-format
 msgid "You can't change Forwards for user %s"
 msgstr "§A¤£¯àÅܧó¨Ï¥ÎªÌ %s ªº¦Û°ÊÂà«H¥\¯à"
 
-#: main.php:41
+#: main.php:43
 msgid "You must give your password"
 msgstr "§A¥²¶·¿é¤J§Aªº±K½X"
 
@@ -172,11 +172,11 @@ msgstr "
 msgid "You must provide your password"
 msgstr "§A¥²¶·¿é¤J§Aªº±K½X"
 
-#: main.php:29
+#: main.php:31
 msgid "You must specify the mode (set or remove)"
 msgstr "§A¥²¶·«ü©w¼Ò¦¡ (³]©w©Î²¾°£)"
 
-#: main.php:58
+#: main.php:60
 msgid "You must supply an e-mail address!"
 msgstr "§A¥²¶·´£¨Ñ¤@­Ó E-mail ¦ì§}!"
 
diff --git a/templates/common-header.inc b/templates/common-header.inc
index 44fa84b..2c62553 100644
--- a/templates/common-header.inc
+++ b/templates/common-header.inc
@@ -6,7 +6,7 @@ if (isset($language)) {
 }
 ?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
-<!-- Forwards: Copyright 2000-2007, The Horde Project. Forwards is under a Horde license. -->
+<!-- Forwards: Copyright 2000-2009 The Horde Project.  Forwards is under a Horde license. -->
 <!--   Horde Project: http://www.horde.org/ | Forwards: http://www.horde.org/forwards/    -->
 <!--                  Horde Licenses: http://www.horde.org/licenses/                      -->
 <?php echo !empty($language) ? '<html lang="' . strtr($language, '_', '-') . '">' : '<html>' ?>
diff --git a/templates/main/main.inc b/templates/main/main.inc
index 5b7e581..2154a4b 100644
--- a/templates/main/main.inc
+++ b/templates/main/main.inc
@@ -3,9 +3,9 @@
 
 function submit_form()
 {
-    if (document.forwards.oldpassword.value == "") {
+    if (document.forwards.password.value == "") {
         alert('<?php echo addslashes(_("You must provide your password")) ?>');
-        document.forwards.oldpassword.focus();
+        document.forwards.password.focus();
         return false;
     } else if (document.forwards.where.value == "" && document.forwards.mode.value == "set") {
         alert('<?php echo addslashes(_("You must provide a forwarding address to set")) ?>');
@@ -28,29 +28,15 @@ function setFocus()
  <span class="leftFloat">
 <?php
 require_once 'Horde/Menu.php';
-$menu = &new Menu(HORDE_MENU_MASK_ALL & ~HORDE_MENU_MASK_PREFS);
+$menu = new Menu(HORDE_MENU_MASK_ALL & ~HORDE_MENU_MASK_PREFS);
 echo $menu->render();
 ?>
  </span>
 </div>
 
 <?php
-
 // Show notifications.
 $notification->notify(array('listeners' => 'status'));
-
-// Get the horde password so we can try to check for existing
-// forwards.
-$hordePassword = Auth::getCredential('password');
-
-// Check for existing forwards.
-if ($isForwarding = $driver->isEnabledForwarding($user, $realm, $hordePassword)) {
-    $current_target = $driver->currentTarget($user, $realm, $hordePassword);
-    $current_keeplocal = $driver->isKeepLocal($user, $realm, $hordePassword);
-} else {
-    $current_target = '';
-    $current_keeplocal = '';
-}
 ?>
 <table class="light">
  <tr>
@@ -69,7 +55,7 @@ if ($isForwarding = $driver->isEnabledForwarding($user, $realm, $hordePassword))
    <br />
    <form method="post" action="<?php echo Horde::url('main.php', false, -1, true) ?>" name="forwards">
    <?php echo Util::formInput() ?>
-   <input type="radio" name="mode" value="set" checked="checked" />
+   <input type="radio" name="mode" value="set"<?php if ($enabled != 'Y') echo ' checked="checked"' ?> />
    <?php echo _("Set/install a forward to:") ?>&nbsp;
    <input type="text" name="where" value="<?php echo $current_target ?>" size="63" maxlength="150" /><br />
 
@@ -80,8 +66,8 @@ if ($isForwarding = $driver->isEnabledForwarding($user, $realm, $hordePassword))
    </blockquote>
 <?php endif; ?>
 
-   <input type="radio" name="mode" value="unset" />
-   <?php echo _("Unset/remove a forward") ?>
+   <input type="radio" name="mode" value="unset"<?php if ($enabled == 'Y') echo ' checked="checked"' ?> />
+   <?php echo _("Unset/remove the forward") ?>
 
    <br /><br />
 <?php if ($conf['enabled']['authenticate']): ?>
@@ -89,7 +75,7 @@ if ($isForwarding = $driver->isEnabledForwarding($user, $realm, $hordePassword))
    <?php echo _("Then submit the form so that your forward can be updated.") ?>
    <br />
    <?php echo _("Your password:") ?> &nbsp;
-   <input type="password" name="oldpassword" size="16" maxlength="32" />&nbsp;
+   <input type="password" name="password" size="16" maxlength="32" />&nbsp;
 <?php endif; ?>
    <input class="button" type="submit" name="submit" value="<?php echo _("Submit") ?>" onclick="return submit_form();" />
    </form>
diff --git a/themes/graphics/favicon.ico b/themes/graphics/favicon.ico
index 598571d..5503b23 100644
Binary files a/themes/graphics/favicon.ico and b/themes/graphics/favicon.ico differ
diff --git a/themes/graphics/forwards.png b/themes/graphics/forwards.png
index 74c8427..0df5ae9 100644
Binary files a/themes/graphics/forwards.png and b/themes/graphics/forwards.png differ

-- 
Debian Horde Packages repository: sork-forwards-h3 package



More information about the pkg-horde-hackers mailing list