liuyuqi 8 years ago
commit
cc1b06bce7
100 changed files with 8327 additions and 0 deletions
  1. 52 0
      ADDITIONS/README.TXT
  2. BIN
      ADDITIONS/change_password.tgz
  3. 112 0
      ADDITIONS/cleanupdirs.pl
  4. 40 0
      ADDITIONS/convert-passwd-to-postfixadmin.pl
  5. 8 0
      ADDITIONS/cyrus/Changelog
  6. 7 0
      ADDITIONS/cyrus/README-ES.txt
  7. 7 0
      ADDITIONS/cyrus/README.txt
  8. 36 0
      ADDITIONS/cyrus/cyrus-mailbox-postcreation.pl
  9. 36 0
      ADDITIONS/cyrus/cyrus-mailbox-postdelete.pl
  10. 33 0
      ADDITIONS/cyrus/cyrus-mailbox-postedit.pl
  11. 31 0
      ADDITIONS/cyrus/cyrus.conf
  12. 77 0
      ADDITIONS/delete-mailq-by-domain.pl
  13. 141 0
      ADDITIONS/fetchmail.pl
  14. 231 0
      ADDITIONS/import_users_from_csv.py
  15. 124 0
      ADDITIONS/mailbox_remover.pl
  16. 167 0
      ADDITIONS/mkeveryone.pl
  17. 111 0
      ADDITIONS/pfa_maildir_cleanup.pl
  18. 62 0
      ADDITIONS/postfixadmin-domain-postdeletion.sh
  19. 61 0
      ADDITIONS/postfixadmin-mailbox-postcreation.sh
  20. 77 0
      ADDITIONS/postfixadmin-mailbox-postdeletion.sh
  21. 151 0
      ADDITIONS/quota_usage.pl
  22. 38 0
      ADDITIONS/squirrelmail-plugin/INSTALL
  23. 40 0
      ADDITIONS/squirrelmail-plugin/LICENSE.txt
  24. 70 0
      ADDITIONS/squirrelmail-plugin/README
  25. 44 0
      ADDITIONS/squirrelmail-plugin/common.php
  26. 22 0
      ADDITIONS/squirrelmail-plugin/config.php.sample
  27. 20 0
      ADDITIONS/squirrelmail-plugin/debian/README.Debian
  28. 27 0
      ADDITIONS/squirrelmail-plugin/debian/changelog
  29. 1 0
      ADDITIONS/squirrelmail-plugin/debian/conffiles
  30. 19 0
      ADDITIONS/squirrelmail-plugin/debian/control
  31. 11 0
      ADDITIONS/squirrelmail-plugin/debian/copyright
  32. 4 0
      ADDITIONS/squirrelmail-plugin/debian/docs
  33. 1 0
      ADDITIONS/squirrelmail-plugin/debian/files
  34. 3 0
      ADDITIONS/squirrelmail-plugin/debian/postfixadmin-squirrelmail.dirs
  35. 5 0
      ADDITIONS/squirrelmail-plugin/debian/postinst
  36. 56 0
      ADDITIONS/squirrelmail-plugin/debian/rules
  37. 102 0
      ADDITIONS/squirrelmail-plugin/functions.inc.php
  38. 27 0
      ADDITIONS/squirrelmail-plugin/index.php
  39. 6 0
      ADDITIONS/squirrelmail-plugin/locale/build.sh
  40. BIN
      ADDITIONS/squirrelmail-plugin/locale/cs_CZ/LC_MESSAGES/postfixadmin.mo
  41. 132 0
      ADDITIONS/squirrelmail-plugin/locale/cs_CZ/LC_MESSAGES/postfixadmin.po
  42. BIN
      ADDITIONS/squirrelmail-plugin/locale/da_DK/LC_MESSAGES/postfixadmin.mo
  43. 127 0
      ADDITIONS/squirrelmail-plugin/locale/da_DK/LC_MESSAGES/postfixadmin.po
  44. BIN
      ADDITIONS/squirrelmail-plugin/locale/de_DE/LC_MESSAGES/postfixadmin.mo
  45. 127 0
      ADDITIONS/squirrelmail-plugin/locale/de_DE/LC_MESSAGES/postfixadmin.po
  46. BIN
      ADDITIONS/squirrelmail-plugin/locale/hu_HU/LC_MESSAGES/postfixadmin.mo
  47. 135 0
      ADDITIONS/squirrelmail-plugin/locale/hu_HU/LC_MESSAGES/postfixadmin.po
  48. 129 0
      ADDITIONS/squirrelmail-plugin/locale/it_IT/LC_MESSAGES/postfixadmin.po
  49. BIN
      ADDITIONS/squirrelmail-plugin/locale/nl_NL/LC_MESSAGES/postfixadmin.mo
  50. 131 0
      ADDITIONS/squirrelmail-plugin/locale/nl_NL/LC_MESSAGES/postfixadmin.po
  51. BIN
      ADDITIONS/squirrelmail-plugin/locale/pl_PL/LC_MESSAGES/postfixadmin.mo
  52. 132 0
      ADDITIONS/squirrelmail-plugin/locale/pl_PL/LC_MESSAGES/postfixadmin.po
  53. BIN
      ADDITIONS/squirrelmail-plugin/locale/pt_BR/LC_MESSAGES/postfixadmin.mo
  54. 127 0
      ADDITIONS/squirrelmail-plugin/locale/pt_BR/LC_MESSAGES/postfixadmin.po
  55. 127 0
      ADDITIONS/squirrelmail-plugin/po/postfixadmin.po
  56. 128 0
      ADDITIONS/squirrelmail-plugin/postfixadmin_changepass.php
  57. 165 0
      ADDITIONS/squirrelmail-plugin/postfixadmin_forward.php
  58. 157 0
      ADDITIONS/squirrelmail-plugin/postfixadmin_vacation.php
  59. 61 0
      ADDITIONS/squirrelmail-plugin/setup.php
  60. 2 0
      ADDITIONS/squirrelmail-plugin/version
  61. 185 0
      ADDITIONS/virtualmaildel.php
  62. 987 0
      CHANGELOG.TXT
  63. 39 0
      DOCUMENTS/BACKUP_MX.txt
  64. 214 0
      DOCUMENTS/DOVECOT.txt
  65. 36 0
      DOCUMENTS/FAQ.txt
  66. 50 0
      DOCUMENTS/HORDE.txt
  67. 17 0
      DOCUMENTS/LANGUAGE.txt
  68. 26 0
      DOCUMENTS/POSTFIXADMIN.txt
  69. 176 0
      DOCUMENTS/POSTFIX_CONF.txt
  70. 44 0
      DOCUMENTS/SECURITY.txt
  71. 16 0
      DOCUMENTS/SUPERADMIN.txt
  72. 111 0
      DOCUMENTS/UPGRADE.txt
  73. 2 0
      DOCUMENTS/screenshots/README.txt
  74. BIN
      DOCUMENTS/screenshots/postfixadmin-admin-create-alias.jpg
  75. BIN
      DOCUMENTS/screenshots/postfixadmin-admin-create-domain.jpg
  76. BIN
      DOCUMENTS/screenshots/postfixadmin-admin-create-mailbox.jpg
  77. BIN
      DOCUMENTS/screenshots/postfixadmin-admin-domain-list.jpg
  78. BIN
      DOCUMENTS/screenshots/postfixadmin-admin-virtual-list.jpg
  79. BIN
      DOCUMENTS/screenshots/postfixadmin-inital-welcome.jpg
  80. BIN
      DOCUMENTS/screenshots/postfixadmin-mail-admin-login.jpg
  81. BIN
      DOCUMENTS/screenshots/postfixadmin-user-change-forward.jpg
  82. BIN
      DOCUMENTS/screenshots/postfixadmin-user-overview.jpg
  83. BIN
      DOCUMENTS/screenshots/postfixadmin-user-vacation.jpg
  84. 281 0
      GPL-LICENSE.TXT
  85. 174 0
      INSTALL.TXT
  86. 46 0
      LICENSE.TXT
  87. 512 0
      VIRTUAL_VACATION/FILTER_README
  88. 222 0
      VIRTUAL_VACATION/INSTALL.TXT
  89. 22 0
      VIRTUAL_VACATION/index.php
  90. 22 0
      VIRTUAL_VACATION/tests/asterisk-email.txt
  91. 55 0
      VIRTUAL_VACATION/tests/facebook.txt
  92. 43 0
      VIRTUAL_VACATION/tests/mail-myself.txt
  93. 110 0
      VIRTUAL_VACATION/tests/mailing-list.txt
  94. 105 0
      VIRTUAL_VACATION/tests/spam.txt
  95. 21 0
      VIRTUAL_VACATION/tests/teodor-smtp-envelope-headers.txt
  96. 43 0
      VIRTUAL_VACATION/tests/test-email.txt
  97. 63 0
      VIRTUAL_VACATION/tests/test.sh
  98. 723 0
      VIRTUAL_VACATION/vacation.pl
  99. 140 0
      backup.php
  100. 102 0
      broadcast-message.php

+ 52 - 0
ADDITIONS/README.TXT

@@ -0,0 +1,52 @@
+#
+# Postfix Admin ADDITIONS
+#
+
+BEFORE YOU START
+----------------
+
+**** ALL THESE SCRIPTS ARE CREATED BY THIRD PARTIES ****
+     **** THEY ARE AS IS, USE AT YOUR OWN RISK! ****
+
+ADDITIONS
+---------
+
+In this directory you will find additional scripts that are build by others.
+
+- change_password.tgz
+by George Vieira <george at citadelcomputer dot com dot au>
+SquirrelMail plugin to change your passwor
+
+- cleanupdirs.pl
+by jared bell <jared at beol dot net>
+Displays a list of mailboxes that need to be deleted
+
+- mailbox_remover.pl
+by Petr Znojemsky
+Deletes all unused mailboxes
+
+- mkeveryone.pl
+by Joshua Preston
+Generate an 'everybody' alias for a domain.
+
+- pfa_maildir_cleanup.pl
+by Stephen Fulton <sfulton at esoteric dot ca>
+Deletes all unused mailboxes
+
+- postfixadmin-0.3-1.4.tar.gz
+by Florian Kimmerl <info at spacekoeln dot de>
+The Postfixadmin SquirrelMail plugin let users change their virtual alias,
+vacation status/message and password.
+
+- virtualmaildel.php
+by George Vieira <george at citadelcomputer dot com dot au>
+Deletes all unused mailboxes
+
+- postfixadmin-mailbox-postcreation.sh
+- postfixadmin-mailbox-postdeletion.sh
+- postfixadmin-domain-postdeletion.sh
+by Troels Arvin <troels@arvin.dk>
+Examples of scripts relevant to the optional 
+$CONF['mailbox_postcreation_script'],
+$CONF['mailbox_postdeletion_script'] and
+$CONF['domain_postdeletion_script']  configuration options.

BIN
ADDITIONS/change_password.tgz


+ 112 - 0
ADDITIONS/cleanupdirs.pl

@@ -0,0 +1,112 @@
+#!/usr/bin/perl -w
+
+################################################################################
+#
+# cleanupdirs 1.2 by jared bell <jared@beol.net>
+#
+# display/remove maildir & domains directory tree's not listed in the postfix
+# mysql database. currently setup for use with postfixadmin, but can be
+# adapted. edit settings where it says 'change settings as needed.' by default
+# this program will display a list of directories which need deleted, nothing
+# is actually deleted. to change this behavior, look into the command line
+# arguments.
+#
+# command line arguments:
+#   --delete
+#       force automatic deletion of directories. instead of displaying a list
+#       of deleted directories, they will be logged in the specified logfile.
+#   --print
+#       display deleted directories as well as log them. only valid when
+#       '--delete' has been specified.
+#
+# settings:
+#   $root_path = "/home/vmail";
+#       if maildir is '/home/vmail/domain.tld/user' then '/home/vmail' is the
+#       $root_path. if your maildirs are '/home/vmail/user@domain.tld' then
+#       this program will need to be modified in order to work right.
+#   $logfile = "/var/log/removed_maildirs.log";
+#       the logfile to use when $delete_old_dirs is set to 1
+#   $db_* = "*";
+#       sets the host, port, database, user and pass to your mysql server
+#
+# version history:
+#   1.2 - removed uneeded settings. added '--print' command line argument
+#   1.1 - added '--delete' command line argument
+#   1.0 - initial release
+#
+################################################################################
+
+use strict;
+use DBI;
+use File::Path;
+use Getopt::Long;
+
+### change settings as needed, see notes above #################################
+our $root_path = "/home/vmail";
+our $logfile = "/var/log/removed_maildirs.log";
+our $db_hostname = "localhost";
+our $db_port = "3306"; # this script currently supports MySQL only
+our $db_database = "postfix";
+our $db_username = "someuser";
+our $db_password = "somepass";
+
+# instead of changing this script, you can put your settings to /etc/mail/postfixadmin/cleanupdirs.conf
+# just use perl syntax there to fill the variables listed above (without the "our" keyword). Example:
+# $db_username = 'mail';
+if (-f "/etc/mail/postfixadmin/cleanupdirs.conf") {
+	require "/etc/mail/postfixadmin/cleanupdirs.conf";
+}
+
+################################################################################
+
+### begin program ##############################################################
+my(@dirs_to_delete, $logfile_open);
+my $delete_old_dirs = 0; # do not delete by default, use cmdline to change this
+my $print_also = 0; # also print items when deleting, use cmdline to change this
+GetOptions ('delete' => \$delete_old_dirs, 'print' => \$print_also);
+my $conn_info = "DBI:mysql:database=$db_database;hostname=$db_hostname;port=$db_port";
+my $dbh = DBI->connect($conn_info, $db_username, $db_password)
+  or die $DBI::errstr;
+opendir DOMAINDIR, $root_path
+  or die "Unable to access directory '$root_path' ($!)";
+foreach my $domain_dir (sort readdir DOMAINDIR) {
+  next if $domain_dir =~ /^\./; # skip dotted dirs
+  next if (! -d "$root_path/$domain_dir"); # skip everything that is not a directory
+  my $full_domain_dir = "$root_path/$domain_dir";
+  opendir USERDIR, $full_domain_dir
+    or die "Unable to access directory '$full_domain_dir' ($!)";
+  foreach my $user_dir (sort readdir USERDIR) {
+    next if $user_dir =~ /^\./; # skip dotted dirs
+    push @dirs_to_delete, "$full_domain_dir/$user_dir"
+      if &check_dir("SELECT maildir FROM mailbox WHERE maildir = ?",
+        "$domain_dir/$user_dir/"); # end slash needed for checkdir
+  }
+  push @dirs_to_delete, $full_domain_dir
+    if &check_dir("SELECT domain FROM domain WHERE domain = ?", $domain_dir);
+}
+closedir USERDIR;
+closedir DOMAINDIR;
+$dbh->disconnect;
+if (@dirs_to_delete) {
+  foreach my $to_delete (@dirs_to_delete) {
+    if ($delete_old_dirs == 1) {
+      $logfile_open = open LOGFILE, ">> $logfile"
+        or die "Unable to append logfile '$logfile' ($!)"
+          unless $logfile_open;
+      rmtree $to_delete;
+      print LOGFILE localtime() . " Deleting directory '$to_delete'\n";
+      print localtime() . " Deleting directory '$to_delete'\n"
+        if $print_also;
+    } else {
+      print localtime() . " Need to delete directory '$to_delete'\n";
+    }
+  }
+}
+close LOGFILE if $logfile_open;
+sub check_dir {
+  my($query, $dir) = @_;
+  my $sth = $dbh->prepare($query);
+  my $num_rows = $sth->execute($dir);
+  $sth->finish;
+  ($num_rows eq "0E0") ? 1 : 0;
+}

+ 40 - 0
ADDITIONS/convert-passwd-to-postfixadmin.pl

@@ -0,0 +1,40 @@
+#!/usr/bin/perl -w
+#
+# Postfix Admin 
+# 
+# LICENSE 
+# This source file is subject to the GPL license that is bundled with  
+# this package in the file LICENSE.TXT. 
+# 
+# Further details on the project are available at http://postfixadmin.sf.net 
+# 
+# @version $Id: convert-passwd-to-postfixadmin.pl 1558 2013-11-10 15:57:32Z christian_boltz $ 
+# @license GNU GPL v2 or later. 
+#
+#
+# Really crude attempt at taking all users from a local 
+# passwd file (/etc/shadow) and creating postfixadmin mailboxes for them.
+#
+# The script outputs some SQL, which you need to then insert into your database
+# as appropriate.
+#
+# Notes:
+#  1) Change $mydomain and $true as required.
+#  2) Ideally it should parse /etc/passwd, or call the getpw()? function and
+#     populate someone's name if known.
+#  3) There's plenty of room for improvement.
+#
+# Original author: David Goodwin <david at palepurple-co-uk> - 2007/10/05.
+#
+use strict;
+
+open(FH, '</etc/shadow') or die ('Cannot open shadow file; you need to be root - ' . $!);
+my $mydomain = "test.com";
+my $true = "t"; # t for pgsql; 1 for mysql
+foreach(<FH>) { 
+    my ($username, $password) = split(':', $_);
+    next if $password eq '!';
+    next if $password eq '*';
+    my $maildir = "$username\@$mydomain/";
+    print "insert into mailbox (username, password, domain, active, maildir) values ('$username', '$password', '$mydomain', $true, '$maildir');\n";
+}

+ 8 - 0
ADDITIONS/cyrus/Changelog

@@ -0,0 +1,8 @@
+
+Version 0.1 -- 26/10/2009
+---------------------------
+
+  * Public Release.
+  * Postcreation, Postdeletion and Postedit hooks.
+
+

+ 7 - 0
ADDITIONS/cyrus/README-ES.txt

@@ -0,0 +1,7 @@
+
+Configuración
+-------------
+
+ - Edita el fichero cyrus.conf y modifica las variables $cyrus_*. El usuario debe tener permisos sobre todas las cuentas.
+ - Edita los ficheros cyrus-*.pl y cambia la ruta de cyrus.conf (linea require '/path/to/cyrus.conf';)
+

+ 7 - 0
ADDITIONS/cyrus/README.txt

@@ -0,0 +1,7 @@
+
+Configuration
+-------------
+
+ - Edit cyrus.conf and set $cyrus_* variables correctly. User must have permission over all accounts.
+ - Edit cyrus-*.pl and change path to cyrus.conf (require '/path/to/cyrus.conf'; line)
+

+ 36 - 0
ADDITIONS/cyrus/cyrus-mailbox-postcreation.pl

@@ -0,0 +1,36 @@
+#!/usr/bin/perl 
+
+# Cyrus Mailbox creation
+#
+# Iñaki Rodriguez (irodriguez@virtualminds.es / irodriguez@ackstorm.es)
+# 
+#  LICENSE
+#  This source file is subject to the GPL license that is bundled with
+#  this package in the file LICENSE.TXT.
+#
+# (26/10/2009) 
+
+use Cyrus::IMAP::Admin;
+require '/etc/mail/postfixadmin/cyrus.conf';
+use strict;
+use vars qw($cyrus_user $cyrus_password $cyrus_host);
+
+my %opts;
+
+my $mailbox = mailbox_name($ARGV[0]);
+
+my $client = Cyrus::IMAP::Admin->new($cyrus_host);
+die_on_error($client);
+
+$opts{-user} = $cyrus_user;
+$opts{-password} = $cyrus_password;
+
+$client->authenticate(%opts);
+die_on_error($client);
+
+$client->create($mailbox);
+die_on_error($client);
+
+$client->setquota($mailbox,'STORAGE',scalar $ARGV[3]) if ($ARGV[3] > 0);
+die_on_error($client);
+

+ 36 - 0
ADDITIONS/cyrus/cyrus-mailbox-postdelete.pl

@@ -0,0 +1,36 @@
+#!/usr/bin/perl 
+
+# Cyrus Mailbox deletion
+#
+# Iñaki Rodriguez (irodriguez@virtualminds.es / irodriguez@ackstorm.es)
+# 
+#  LICENSE
+#  This source file is subject to the GPL license that is bundled with
+#  this package in the file LICENSE.TXT.
+#
+# (26/10/2009) 
+
+use Cyrus::IMAP::Admin;
+require '/etc/mail/postfixadmin/cyrus.conf';
+use strict;
+use vars qw($cyrus_user $cyrus_password $cyrus_host);
+
+my %opts;
+
+my $mailbox = mailbox_name($ARGV[0]);
+
+my $client = Cyrus::IMAP::Admin->new($cyrus_host);
+die_on_error($client);
+
+$opts{-user} = $cyrus_user;
+$opts{-password} = $cyrus_password;
+
+$client->authenticate(%opts);
+die_on_error($client);
+
+$client->setacl($mailbox,$cyrus_user => 'all');
+die_on_error($client);
+
+$client->deletemailbox($mailbox);
+die_on_error($client);
+

+ 33 - 0
ADDITIONS/cyrus/cyrus-mailbox-postedit.pl

@@ -0,0 +1,33 @@
+#!/usr/bin/perl 
+
+# Cyrus Mailbox edition
+#
+# Iñaki Rodriguez (irodriguez@virtualminds.es / irodriguez@ackstorm.es)
+#
+#  LICENSE
+#  This source file is subject to the GPL license that is bundled with
+#  this package in the file LICENSE.TXT.
+#
+# (26/10/2009)
+
+use Cyrus::IMAP::Admin;
+require '/etc/mail/postfixadmin/cyrus.conf';
+use strict;
+use vars qw($cyrus_user $cyrus_password $cyrus_host);
+
+my %opts;
+
+my $mailbox = mailbox_name($ARGV[0]);
+
+my $client = Cyrus::IMAP::Admin->new($cyrus_host);
+die_on_error($client);
+
+$opts{-user} = $cyrus_user;
+$opts{-password} = $cyrus_password;
+
+$client->authenticate(%opts);
+die_on_error($client);
+
+$client->setquota($mailbox,'STORAGE',scalar $ARGV[3]) if ($ARGV[3] > 0);
+die_on_error($client);
+

+ 31 - 0
ADDITIONS/cyrus/cyrus.conf

@@ -0,0 +1,31 @@
+#!/usr/bin/perl
+
+# Config
+
+$cyrus_user = 		'cyrus';
+$cyrus_password =	'cyruspass';
+$cyrus_host =		'localhost';
+
+# unixhierarchysep => 1 (yes) / 0 (no)
+$unixhierarchysep =	1;
+
+# Common routines
+
+sub mailbox_name {
+	my $mailbox = shift;
+	
+	if($unixhierarchysep) {
+	        $mailbox = 'user/'.$ARGV[0];
+	} else {
+        	$mailbox = 'user.'.$ARGV[0];
+	}
+
+	return $mailbox;
+}
+
+sub die_on_error {
+	my $cyradm = shift;
+	if($cyradm->error) { die $cyradm->error; }
+}
+1;
+

+ 77 - 0
ADDITIONS/delete-mailq-by-domain.pl

@@ -0,0 +1,77 @@
+#!/usr/bin/perl
+
+
+use strict;
+use warnings;
+use Getopt::Long;
+
+
+$ENV{'PATH'} = "/sbin:/bin:/usr/sbin:/usr/bin";
+
+my ($domain);
+my $list = 0;
+
+(help()) if (!$ARGV[0]);
+GetOptions ('l' => \$list, 'd=s' => \$domain) or (help());
+
+
+(list_queue()) if ($list == 1);
+
+(delete_queue()) if ($domain);
+
+
+sub delete_queue {
+my $ids = `postqueue -p`;
+my @ids = split /\n/, $ids;
+
+for my $id (@ids) {
+        next if $id =~ /^[\s\(-]/;
+        chomp $id;
+        next unless $id;
+        $id =~ s/(.*?)\**\s.*/$1/;
+        #print "$id\n";
+        my $match = `postcat -q $id | grep '$domain'`;
+        next unless $match;
+        #print "Deleting ID: $id\n";
+        my $saida = `postsuper -d $id`;
+        print $saida;
+}
+
+}
+
+
+
+
+sub list_queue {
+my %hash_mail = ();
+my @queue = `postqueue -p`;
+my($queue,$key,$total);
+
+
+foreach $queue(@queue) {
+        chomp $queue;
+        if ( $queue =~ /^\s+.*\@(.*)/ ) {
+                $hash_mail{$1}++;
+        }
+}
+print"\nTOTAL\tTO\n";
+print"-----
+----------------------------------------------------------------\n";
+foreach $key (reverse sort { $hash_mail{$a} <=> $hash_mail{$b}} keys
+%hash_mail) {
+        $total += $hash_mail{$key};
+        print"$hash_mail{$key} - $key\n";
+}
+print"\n$total -> TOTAL QUEUE\n";
+
+}
+
+
+sub help {
+print "Usage $0 -l	            To list a row of E-mail
+Usage $0 -d domain.com   To delete the mensgens the Domain\n"; 
+}
+
+
+
+

+ 141 - 0
ADDITIONS/fetchmail.pl

@@ -0,0 +1,141 @@
+#!/usr/bin/perl
+
+use DBI;
+use MIME::Base64;
+# use Data::Dumper;
+use File::Temp qw/ mkstemp /;
+use Sys::Syslog;
+# require liblockfile-simple-perl
+use LockFile::Simple qw(lock trylock unlock);
+
+######################################################################
+########## Change the following variables to fit your needs ##########
+
+# database settings
+
+# database backend - uncomment one of these
+our $db_type = 'Pg';
+#my $db_type = 'mysql';
+
+# host name
+our $db_host="127.0.0.1";
+# database name
+our $db_name="postfix";
+# database username
+our $db_username="mail";
+# database password
+our $db_password="CHANGE_ME!";
+
+# instead of changing this script, you can put your settings to /etc/mail/postfixadmin/fetchmail.conf
+# just use perl syntax there to fill the variables listed above (without the "our" keyword). Example:
+# $db_username = 'mail';
+if (-f "/etc/mail/postfixadmin/fetchmail.conf") {
+	require "/etc/mail/postfixadmin/fetchmail.conf";
+}
+
+
+#################### Don't change anything below! ####################
+######################################################################
+
+openlog("fetchmail-all", "pid", "mail");
+
+sub log_and_die {
+	my($message) = @_;
+  syslog("err", $message);
+  die $message;
+}
+
+# read options and arguments
+
+$configfile = "/etc/fetchmail-all/config";
+
+@ARGS1 = @ARGV;
+
+while ($_ = shift @ARGS1) {
+    if (/^-/) {
+        if (/^--config$/) {
+            $configfile = shift @ARGS1
+        }
+    }
+}
+
+$run_dir="/var/run/fetchmail";
+
+# use specified config file
+if (-e $configfile) {
+    do $configfile;
+}
+
+if($db_type eq "Pg" || $db_type eq "mysql") {
+	$dsn = "DBI:$db_type:database=$db_name;host=$db_host";
+} else {
+	log_and_die "unsupported db_type $db_type";
+}
+
+$lock_file=$run_dir . "/fetchmail-all.lock";
+
+$lockmgr = LockFile::Simple->make(-autoclean => 1, -max => 1);
+$lockmgr->lock($lock_file) || log_and_die "can't lock ${lock_file}";
+
+# database connect
+$dbh = DBI->connect($dsn, $db_username, $db_password) || log_and_die "cannot connect the database";
+
+if($db_type eq "Pg") {
+	$sql_cond = "active = 1 AND date_part('epoch',now())-date_part('epoch',date)";
+} elsif($db_type eq "mysql") {
+	$sql_cond = "active = 't' AND unix_timestamp(now())-unix_timestamp(date)";
+}
+
+$sql = "
+	SELECT id,mailbox,src_server,src_auth,src_user,src_password,src_folder,fetchall,keep,protocol,mda,extra_options,usessl, sslcertck, sslcertpath, sslfingerprint
+	FROM fetchmail
+	WHERE $sql_cond  > poll_time*60
+	";
+
+my (%config);
+map{
+	my ($id,$mailbox,$src_server,$src_auth,$src_user,$src_password,$src_folder,$fetchall,$keep,$protocol,$mda,$extra_options,$usessl,$sslcertck,$sslcertpath,$sslfingerprint)=@$_;
+
+	syslog("info","fetch ${src_user}@${src_server} for ${mailbox}");
+
+	$cmd="user '${src_user}' there with password '".decode_base64($src_password)."'";
+	$cmd.=" folder '${src_folder}'" if ($src_folder);
+	$cmd.=" mda ".$mda if ($mda);
+
+#	$cmd.=" mda \"/usr/local/libexec/dovecot/deliver -m ${mailbox}\"";
+	$cmd.=" is '${mailbox}' here";
+
+	$cmd.=" keep" if ($keep);
+	$cmd.=" fetchall" if ($fetchall);
+	$cmd.=" ssl" if ($usessl);
+	$cmd.=" sslcertck" if($sslcertck);
+	$cmd.=" sslcertpath $sslcertpath" if ($sslcertck && $sslcertpath);
+	$cmd.=" sslfingerprint \"$sslfingerprint\"" if ($sslfingerprint);
+	$cmd.=" ".$extra_options if ($extra_options);
+
+	$text=<<TXT;
+set postmaster "postmaster"
+set nobouncemail
+set no spambounce
+set properties ""
+set syslog
+
+poll ${src_server} with proto ${protocol}
+	$cmd
+
+TXT
+
+  ($file_handler, $filename) = mkstemp( "/tmp/fetchmail-all-XXXXX" ) or log_and_die "cannot open/create fetchmail temp file";
+  print $file_handler $text;
+  close $file_handler;
+
+  $ret=`/usr/bin/fetchmail -f $filename -i $run_dir/fetchmail.pid`;
+
+  unlink $filename;
+
+  $sql="UPDATE fetchmail SET returned_text=".$dbh->quote($ret).", date=now() WHERE id=".$id;
+  $dbh->do($sql);
+}@{$dbh->selectall_arrayref($sql)};
+
+$lockmgr->unlock($lock_file);
+closelog();

+ 231 - 0
ADDITIONS/import_users_from_csv.py

@@ -0,0 +1,231 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Script takes a CSV list of users and does a 'bulk' insertion into mysql.
+#
+# Copyright (C) 2009 Simone Piccardi
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or (at
+# your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+#
+
+import csv
+import getopt
+import sys
+import re
+import time
+import random, string
+from datetime import datetime
+from crypt import crypt
+try:
+    import MySQLdb 
+except ImportError ,e:
+    print 'Cannot import the needed MySQLdb module, you must install it'
+    print 'on Debian systems just use the command'
+    print '   apt-get install python-mysqldb'
+
+def usage():
+    print "Usage: inspostadmusers.py [options] users.csv"
+    print "       -h        print this help"
+    print "       -t        test run, do not insert, just print"
+    print "       -u        DB user"
+    print "       -p        DB password"
+    print "       -D        DB name"
+    print "       -H        DB host"
+    print "       -q        Quota in Mb (0 => no limit)"
+    print "       -n        char in seed"
+    print "       -d        debug info on"
+    print "       -A        create default alias for each domain"
+    print
+    print "the users.csv file must contains the user list with a line"
+    print "for each user, first line should be a title line with at least"
+    print "the following column names: "
+    print " * user     - user part of the email (like user in user@domain.com)"
+    print " * password - cleartext password"
+    print " * domain   - domain name (like 'domain.com')"
+    print " * name     - full user name ('Name Surname')"
+    print
+    print "the 'name' column is optional, other columns will be ignored"
+    print
+    print "Known restrictions:"
+    print "* this script only works with MySQL"
+    print "* mailbox paths are hardcoded to domain/username/"
+
+
+# option parsing
+try:
+    opts, args = getopt.getopt(sys.argv[1:], 'u:p:d:D:H:htdA')
+    optval={}
+    for opt, val in opts:
+        if opt == "-h":
+            usage()
+            sys.exit(0)
+        else:
+            optval[opt]=val
+except getopt.GetoptError:
+    usage()
+    sys.exit(2)
+
+#
+# Setup DB connection
+#
+MYSQLDB="postfixadmin"
+MYSQLUSER="postfixadmin"
+MYSQLPASSWORD=""
+MYSQLHOST="localhost"
+
+# settings by command line options
+if optval.has_key('-u'):
+    MYSQLUSER = optval['-u']
+if optval.has_key('-p'):
+    MYSQLPASSWORD = optval['-p']
+if optval.has_key('-D'):
+    MYSQLDB = optval['-D']
+if optval.has_key('-H'):
+    MYSQLHOST = optval['-H']
+
+if optval.has_key('-q'):
+    quota = optval['-q']
+else:
+    quota = 0
+
+if optval.has_key('-n'):
+    seed_len = optval['-n']
+else:
+    seed_len = 8
+
+# check arguments, only the user list file must be present
+if len(args) !=1:
+    print 'Need just one argument'
+    usage()
+    sys.exit(1)
+
+# MySQL connection (skipped in test run)
+if optval.has_key('-t'):
+    print "Test Run"
+else:
+    try:
+        connection = MySQLdb.connect(host=MYSQLHOST, user=MYSQLUSER, 
+                                     db=MYSQLDB, passwd=MYSQLPASSWORD)
+    except MySQLdb.MySQLError, e:
+        print "Database connection error"
+        print e
+        sys.exit(1)
+ 
+    cursor = connection.cursor()
+
+#
+# Main body
+#
+NOW = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+
+# read and convert CSV data
+lista = csv.DictReader(open(args[0]))
+
+def gen_seed(seed_len, chars):
+    return '$1$'+''.join([random.choice(chars) for _ in xrange(seed_len)])+'$'
+
+def insert_record(cursor,table,record):
+    columns = record.keys()
+    query = "INSERT INTO " + table + "(" + ','.join(columns) + ") VALUES (" + ','.join(len(columns)*['%s']) + ")"
+    try:
+        cursor.execute(query, record.values())
+        return 0
+    except MySQLdb.MySQLError, e:
+        print "Database insertion error"
+        print e
+        print "Record was:"
+        print record.values()
+        print "Query was:"
+        print query
+
+# defining default values for tables (mailbox, alias and domain)
+mailbox = {
+    'created': NOW, 
+    'modified': NOW,
+    'active': 1,
+    'quota': quota
+    }
+aliases = {
+    'created':  NOW,
+    'modified': NOW,
+    'active':   1
+    }
+domain = {
+    'description': "",
+    'aliases': 0,
+    'mailboxes': 0,
+    'quota': 0,
+    'transport': 'virtual',
+    'backupmx': 0,
+    'created': NOW,
+    'modified': NOW,
+    'active': 1
+}
+
+# list of default alias
+def_alias = ['abuse','hostmaster','postmaster','webmaster'] 
+
+domain_list = {}
+chars = string.letters + string.digits
+
+# loop over the CSV 
+for row in lista:
+    # create domain if it does not exists
+    if domain_list.has_key(row["domain"]):
+        if optval.has_key('-d'):
+            print "Domain " + row["domain"] + "already exixts"
+    else:
+        domain_list[row["domain"]] = 1
+        domain['domain'] = row["domain"]
+        if optval.has_key('-t'):
+            print "Inserting domain"
+            print domain
+        else:
+            insert_record(cursor,'domain',domain)
+            if optval.has_key('-A'):
+                for i in def_alias:
+                    aliases['address']= i+'@'+row["domain"]
+                    aliases['goto']= aliases['address']
+                    aliases['domain'] = row["domain"]
+                    if optval.has_key('-t'):
+                        print "Inserting alias"
+                        print aliases
+                    else:
+                        insert_record(cursor,'alias',aliases)
+
+    # build query data for mailbox table
+    mailbox['username']=row["user"]+'@'+row["domain"]
+    encpass=crypt(row["password"], gen_seed(seed_len,chars))
+    mailbox['password'] = encpass
+    mailbox['name'] = row["name"]
+    mailbox['maildir'] = row["domain"]+'/'+row["user"]+'/'
+    mailbox['local_part'] =row["user"]
+    mailbox['domain'] = row["domain"]
+
+    # build query data for alias table
+    aliases['address']= mailbox['username']
+    aliases['goto']= mailbox['username']
+    aliases['domain'] = row["domain"]
+
+    # inserting data for mailbox (and relate alias)
+    if optval.has_key('-t'):
+        print "Inserting mailbox"
+        print mailbox
+        print aliases
+    else:
+        insert_record(cursor,'mailbox',mailbox)
+        insert_record(cursor,'alias',aliases)
+
+
+sys.exit(0)

+ 124 - 0
ADDITIONS/mailbox_remover.pl

@@ -0,0 +1,124 @@
+#!/usr/bin/perl
+#
+# by Petr Znojemsky (c) 2004
+# Mailbox remover 0.1a 23/10/2004 - the very first version for MySQL
+# removes maildirs from disk when they are not found in a database
+#
+# Added subdir support and pause --- Alan Batie 2007
+# Lists directories to be deleted then pauses for 5 seconds for chance to abort
+# $Id: mailbox_remover.pl 211 2007-11-11 23:36:46Z christian_boltz $
+#
+# All your maildirs or other directories could be accidentally removed.
+# Use it at own risk. No warranties!
+
+use strict;
+use DBI;
+use File::Path;
+
+##########
+# Set these variables according to your configuration
+
+# when mailboxes are removed, save their tarballs here
+my $archdir="/var/archive/mailboxes";
+
+# expected to support z option, tweak invocation if you want different
+my $archcmd="/usr/bin/tar";
+
+# trailing slash not needed
+my $maildir_path="/var/mail";
+# find out if we need to check subdirs for mailboxes or just maildir_path
+# $CONF['domain_path'] = 'YES';
+my $pfadmin_config="/usr/local/www/postfixadmin/config.inc.php";
+
+# database information
+my $host="localhost";
+my $port="3306";
+my $userid="dbuser";
+my $passwd="dbpw";
+my $db="dbname";
+############
+
+my $connectionInfo="DBI:mysql:database=$db;$host:$port";
+# make connection to database
+my $dbh = DBI->connect($connectionInfo,$userid,$passwd);
+# prepare and execute query
+my $query = "SELECT maildir FROM mailbox";
+my $sth = $dbh->prepare($query);
+$sth->execute();
+
+# assign fields to variables
+my ($db_maildir, %db_maildirs);
+$sth->bind_columns(\$db_maildir);
+
+# load up directory list
+while($sth->fetch()) {
+    $db_maildirs{$db_maildir} = 1;
+}
+
+$sth->finish();
+# disconnect from database
+$dbh->disconnect;
+
+# 
+# find out if we need to check subdirs for mailboxes or just maildir_path
+# $CONF['domain_path'] = 'YES';
+#
+my $use_subdirs = 0;
+open(CONFIG, "<$pfadmin_config") || die "Can't open '$pfadmin_config': $!\n";
+while(<CONFIG>) {
+    if (/\$CONF\['domain_path'\] *= *'([^']*)'/) {
+	$use_subdirs = ($1 =~ /yes/i);
+    }
+}
+close(CONFIG);
+
+# store maildir list to %directories
+# key is path, value is username to use in archive file
+my %directories;
+opendir(DIR, $maildir_path) || die "Cannot open dir $maildir_path: $!\n";
+foreach my $name (readdir(DIR)) {
+    next if ($name eq '.' || $name eq '..' || ! -d "$maildir_path/$name");
+
+    if ($use_subdirs) {
+	opendir(SUBDIR, "$maildir_path/$name") || die "Cannot open dir $maildir_path/$name: $!\n";
+	foreach my $subname (readdir(SUBDIR)) {
+	    next if ($subname eq '.' || $subname eq '..' || ! -d "$maildir_path/$name/$subname");
+	    # db entry has trailing slash...
+	    if (!defined($db_maildirs{"$name/$subname/"})) {
+	        print "marking $maildir_path/$name/$subname for deletion.\n";
+		$directories{"$name/$subname"} = "$name-$subname";
+	    }
+	}
+	closedir(SUBDIR);
+    } else {
+	# db entry has trailing slash...
+	if (!defined($db_maildirs{"$name/"})) {
+	    print "marking $maildir_path/$name for deletion.\n";
+	    $directories{"$name"} = $name;
+	}
+    }
+}
+closedir(DIR);
+
+print "Ctrl-C in 5 seconds to abort before removal starts...\n";
+sleep 5;
+
+my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
+# yyyymmddhhmm
+my $tstamp = sprintf("%04d%02d%02d%02d%02d", $year+1900, $mon+1, $mday, $hour, $min);
+
+# compare two arrays and erase maildirs not found in database
+chdir $maildir_path || die "Can't change to maildir '$maildir_path': $!\n";;
+my @args;
+foreach my $maildir (keys(%directories)) {
+    my $archive = "$archdir/$directories{$maildir}-$tstamp.tgz";
+    # quick permissions check
+    open(TOUCH, ">$archive") || die "Can't create archive file $archive: $!\n";
+    close(TOUCH);
+    print "Archiving $maildir\n";
+    @args = ($archcmd, "cvzf", $archive, $maildir);
+	system(@args) == 0 or die "Creating archive for $maildir failed: $?"
+
+    rmtree($maildir);
+    print localtime() . " $maildir has been deleted.\n";
+}

+ 167 - 0
ADDITIONS/mkeveryone.pl

@@ -0,0 +1,167 @@
+#!/usr/bin/perl
+#
+# Generate an 'everybody' alias for a domain.
+#
+# Create the file /etc/mkeveryone.conf
+# chmod 640 /etc/mkeveryone.conf
+# Example of mkeveryone.conf
+#
+# userid=postfix
+# passwd=postfix
+# db=postfix
+# host=localhost
+# port=3306
+# domain=domain.tld
+# target=everybody@domain.tld
+# ignore=vacation@domain.tld
+# ignore=spam@domain.tld
+# ignore=newsletter@domain.tld
+# ignore=root@domain.tld
+#
+# Save this file in, for example, /usr/local/sbin/mkeveryone.pl
+# chmod 750 /usr/local/sbin/mkeveryone.pl
+#
+# Run the script!
+#
+use DBI;
+use Time::Local;
+use POSIX qw(EAGAIN);
+use Fcntl;
+use IO;
+use IO::File;
+
+my $timeNow=time();
+
+my $DATFILE     = "/etc/mkeveryone.conf";
+my $FILEHANDLE  = "";
+
+# database information
+my $db="postfix";
+my $host="localhost";
+my $port="3306";
+my $userid="postfix";
+my $passwd="postfix";
+my $domain="domain.tld";
+my $target="everyone@$domain";
+my @ignore;
+my @dest;
+
+open (FILEHANDLE, $DATFILE);
+
+while ( $LINE = <FILEHANDLE> ) {
+
+       if ( length $LINE > 0 ) {
+       chomp $LINE;
+
+           $RETURNCODE = 0;
+
+           SWITCH: {
+
+               $LINE =~ /^ignore/i and do {
+                   $LINE =~ s/^ignore// && $LINE =~ s/=// && $LINE =~ s/^ //g;
+                   @ignore = (@ignore,$LINE);
+                };
+
+               $LINE =~ /^userid/i and do {
+                   # Userid found.";
+                   $LINE =~ s/^userid// && $LINE =~ s/=// && $LINE =~ s/^ //g;
+                   $userid = $LINE;
+               };
+
+               $LINE =~ /^passwd/i and do {
+                   # Passwd found.";
+                   $LINE =~ s/^passwd// && $LINE =~ s/=// && $LINE =~ s/^ //g;
+                   $passwd = $LINE;
+               };
+
+               $LINE =~ /^db/i and do {
+                   # Database found.";
+                   $LINE =~ s/^db// && $LINE =~ s/=// && $LINE =~ s/^ //g;
+                   $db = $LINE;
+               };
+
+               $LINE =~ /^host/i and do {
+                   # Database host found.";
+                   $LINE =~ s/^host// && $LINE =~ s/=// && $LINE =~ s/^ //g;
+                   $host = $LINE;
+               };
+
+               $LINE =~ /^port/i and do {
+                   # Database host found.";
+                   $LINE =~ s/^port// && $LINE =~ s/=// && $LINE =~ s/^ //g;
+                   $port = $LINE;
+               };
+
+               $LINE =~ /^target/i and do {
+                   # Database host found.";
+                   $LINE =~ s/^target// && $LINE =~ s/=// && $LINE =~ s/^ //g;
+                   $target = $LINE;
+               };
+
+               $LINE =~ /^domain/i and do {
+                   # Database host found.";
+                   $LINE =~ s/^domain// && $LINE =~ s/=// && $LINE =~ s/^ //g;
+                   $domain = $LINE;
+               };
+          }
+       }
+}
+
+print "Connecting to database $db on $host:$port...\n\r";
+
+print "Target email address is $target...\n\r";
+
+my $connectionInfo="DBI:mysql:database=$db;$host:$port";
+
+# make connection to database
+$dbh = DBI->connect($connectionInfo,$userid,$passwd);
+
+# Delete the old message...prepare and execute query
+$query = "SELECT username FROM mailbox WHERE domain='$domain';";
+$sth = $dbh->prepare($query);
+$sth->execute();
+
+# assign fields to variables
+$sth->bind_columns(\$username);
+
+my $ign="false";
+while($sth->fetch()) {
+  $ign = "false";
+
+  foreach $ignored ( @ignore ) {
+     if ( $username eq $ignored ){
+          $ign = "true";
+          }
+  }
+
+  if ( $ign eq "false" ) {
+       @dest = (@dest,$username);
+  }
+}
+
+# Delete the old aliases...prepare and execute query
+$query = "DELETE FROM alias WHERE address='$target';";
+$sth = $dbh->prepare($query);
+$sth->execute();
+
+print "Record deleted from the database.\r\n";
+
+$sth->finish();
+
+$goto = join(",",@dest);
+print "$goto\n\r\n\r";
+
+
+# Insert the new message...prepare and execute query
+$query = "INSERT INTO alias (address,goto,domain,created,modified) VALUES ('$target','$goto','$domain',now(),now());";
+
+$sth = $dbh->prepare($query);
+$sth->execute();
+
+print "Record added to the database.\r\n";
+
+$sth->finish();
+
+# disconnect from databse
+$dbh->disconnect;
+

+ 111 - 0
ADDITIONS/pfa_maildir_cleanup.pl

@@ -0,0 +1,111 @@
+#!/usr/bin/perl
+#
+##
+## pfa_maildir_cleanup.pl
+##
+## (c) 2004 by Stephen Fulton (sfulton@esoteric.ca)
+##
+## based on a script by Petr Znojemsky (thanks!) 
+##
+## Simple script to remove maildirs/domains not listed in a MySQL database.
+## Set up for use with those using PostfixAdmin, but can be adapted.
+##
+## Edit the variables between the ##EDIT## to match your setup.
+##
+## USE AT YOUR OWN RISK. I ASSUME NO RESPONSIBILITY.
+##
+
+use DBI;
+use File::Path;
+
+##EDIT## 
+
+$root_path = "/home/mail";
+$logfile = "/var/log/removed_maildirs.log";
+
+$db_host = "localhost";
+$db_database = "database";
+$db_user = "username";
+$db_password = 'password';
+
+##END EDIT##
+
+
+$connectionInfo = "DBI:mysql:database=$db_database;$db_host:3306";
+
+## Read a list of domain directories in the root path /remote/mail1
+
+opendir(DIRHANDLE, $root_path) || die "Cannot access directory $maildir_path: $!";
+
+my @directories = ();
+
+foreach $directory (sort readdir(DIRHANDLE)) {
+   push (@directories, $directory);
+}
+
+closedir(DIRHANDLE);
+
+## Strip the "." and ".." from the directories array
+
+($dot, $doubledot, @directories) = @directories;
+
+## For each of the domain directories..
+
+foreach $domain_dir (@directories) {
+   $complete_domain_path = "$root_path/$domain_dir";
+
+   ## Get a list of user directories within each domain directory...
+
+   opendir(DOMAINHANDLE, $complete_domain_path) || die "Cannot access directory $complete_domain_path: $!";
+
+   my @user_directories = ();
+
+   foreach $dir (sort readdir(DOMAINHANDLE)) {
+      push(@user_directories, $dir);
+   }
+   close(DOMAINHANDLE);
+
+   ## Now remove any "." or ".." directory entries and construct a domain/maildir variable
+   ## valid for one iteration of loop.
+
+   foreach $user_directory (@user_directories) {
+      if( not($user_directory eq '..') && not($user_directory eq '.') ) {
+         $short_user_dir = "$domain_dir/$user_directory/";
+
+         ## Here is where the $short_user_dir is compared against the DB entry.
+
+         $dbh = DBI->connect($connectionInfo,$db_user,$db_password);
+         $user_query = "SELECT maildir FROM mailbox WHERE maildir = '$short_user_dir'";
+         $sth = $dbh->prepare($user_query);
+         $rows = $sth->execute();
+
+         ## If there are no rows that match, then directory is orphaned and can
+         ## be deleted.
+
+         if($rows == 0) {
+            $maildir_path = "$root_path/$short_user_dir";
+            open(INFO, ">>$logfile") || die "Cannot write to the logfile: $logfile.";
+            rmtree($maildir_path);
+            print INFO localtime()." Maildir ".$maildir_path." has been deleted.\n";
+            (INFO);
+         }
+         $sth->finish;
+         $dbh->disconnect;
+      }
+   }
+
+   $dbh2 = DBI->connect($connectionInfo,$db_user,$db_password);
+   $domain_query = "SELECT domain FROM domain WHERE domain = '$domain_dir'";
+   $sth2 = $dbh2->prepare($domain_query);
+   $domain_rows = $sth2->execute();
+
+   if($domain_rows == 0) {
+      open(INFO, ">>$logfile") || die "Cannot write to the logfile: $logfile.";
+      rmtree($complete_domain_path);
+      print INFO localtime()." Domain directory ".$complete_domain_path." has been deleted.\n";
+      close(INFO);
+   }
+
+$sth2->finish;
+$dbh2->disconnect;
+}

+ 62 - 0
ADDITIONS/postfixadmin-domain-postdeletion.sh

@@ -0,0 +1,62 @@
+#!/bin/sh
+
+# Example script for removing a Maildir domain top-level folder
+# from a Courier-IMAP virtual mail hierarchy.
+
+# The script only looks at argument 1, assuming that it 
+# indicates the relative name of a domain, such as
+# "somedomain.com". If $basedir/somedomain.com exists, it will
+# be removed.
+
+# The script will not actually delete the directory. I moves it
+# to a special directory which may once in a while be cleaned up
+# by the system administrator.
+
+# This script should be run as the user which owns the maildirs. If 
+# the script is actually run by the apache user (e.g. through PHP),
+# then you could use "sudo" to grant apache the rights to run
+# this script as the relevant user.
+# Assume this script has been saved as
+# /usr/local/bin/postfixadmin-domain-postdeletion.sh and has been
+# made executable. Now, an example /etc/sudoers line:
+# apache ALL=(courier) NOPASSWD: /usr/local/bin/postfixadmin-domain-postdeletion.sh
+# The line states that the apache user may run the script as the
+# user "courier" without providing a password.
+
+
+# Change this to where you keep your virtual mail users' maildirs.
+basedir=/var/spool/maildirs
+
+# Change this to where you would like deleted maildirs to reside.
+trashbase=/var/spool/deleted-maildirs
+
+if [ `echo $1 | fgrep '..'` ]; then
+    echo "First argument contained a double-dot sequence; bailing out."
+    exit 1
+fi
+
+if [ ! -e "$trashbase" ]; then
+    echo "trashbase '$trashbase' does not exist; bailing out."
+    exit 1
+fi
+
+trashdir="${trashbase}/`date +%F_%T`_$1"
+domaindir="${basedir}/$1"
+
+if [ ! -e "$domaindir" ]; then
+    echo "Directory '$domaindir' does not exits; nothing to do."
+    exit 0;
+fi
+if [ ! -d "$domaindir" ]; then
+    echo "'$domaindir' is not a directory; bailing out."
+    exit 1
+fi
+if [ -e "$trashdir" ]; then
+    echo "Directory '$trashdir' already exits; bailing out."
+    exit 1;
+fi
+
+mv $domaindir $trashdir
+
+exit $?
+

+ 61 - 0
ADDITIONS/postfixadmin-mailbox-postcreation.sh

@@ -0,0 +1,61 @@
+#!/bin/sh
+
+# Example script for adding a Maildir to a Courier-IMAP virtual mail
+# hierarchy.
+
+# The script only looks at argument 3, assuming that it 
+# indicates the relative name of a maildir, such as
+# "somedomain.com/peter/".
+
+# This script should be run as the user which owns the maildirs. If 
+# the script is actually run by the apache user (e.g. through PHP),
+# then you could use "sudo" to grant apache the rights to run
+# this script as the relevant user.
+# Assume this script has been saved as
+# /usr/local/bin/postfixadmin-mailbox-postcreation.sh and has been
+# made executable. Now, an example /etc/sudoers line:
+# apache ALL=(courier) NOPASSWD: /usr/local/bin/postfixadmin-mailbox-postcreation.sh
+# The line states that the apache user may run the script as the
+# user "courier" without providing a password.
+
+
+# Change this to where you keep your virtual mail users' maildirs.
+basedir=/var/spool/maildirs
+
+if [ ! -e "$basedir" ]; then
+    echo "$0: basedir '$basedir' does not exist; bailing out."
+    exit 1
+fi
+
+if [ `echo $3 | fgrep '..'` ]; then
+    echo "$0: An argument contained a double-dot sequence; bailing out."
+    exit 1
+fi
+
+maildir="${basedir}/$3"
+parent=`dirname "$maildir"`
+if [ ! -d "$parent" ]; then
+    if [ -e "$parent" ]; then
+        echo "$0: strange - directory '$parent' exists, but is not a directory; bailing out."
+        exit 1
+    else
+        mkdir -p "${parent}"
+        if [ $? -ne 0 ]; then
+            echo "$0: mkdir -p '$parent' returned non-zero; bailing out."
+            exit 1
+        fi
+    fi
+fi
+
+if [ -e "$maildir" ]; then
+    echo "$0: Directory '$maildir' already exists! bailing out"
+    exit 1
+fi
+
+maildirmake "$maildir"
+if [ ! -d "$maildir" ]; then
+    echo "$0: maildirmake didn't produce a directory; bailing out."
+    exit 1
+fi
+
+exit 0

+ 77 - 0
ADDITIONS/postfixadmin-mailbox-postdeletion.sh

@@ -0,0 +1,77 @@
+#!/bin/sh
+
+# Example script for removing a Maildir from a Courier-IMAP virtual mail
+# hierarchy.
+
+# The script looks at arguments 1 and 2, assuming that they 
+# indicate username and domain, respectively.
+
+# The script will not actually delete the maildir. I moves it
+# to a special directory which may once in a while be cleaned up
+# by the system administrator.
+
+# This script should be run as the user which owns the maildirs. If 
+# the script is actually run by the apache user (e.g. through PHP),
+# then you could use "sudo" to grant apache the rights to run
+# this script as the relevant user.
+# Assume this script has been saved as
+# /usr/local/bin/postfixadmin-mailbox-postdeletion.sh and has been
+# made executable. Now, an example /etc/sudoers line:
+# apache ALL=(courier) NOPASSWD: /usr/local/bin/postfixadmin-mailbox-postdeletion.sh
+# The line states that the apache user may run the script as the
+# user "courier" without providing a password.
+
+
+# Change this to where you keep your virtual mail users' maildirs.
+basedir=/var/spool/maildirs
+
+# Change this to where you would like deleted maildirs to reside.
+trashbase=/var/spool/deleted-maildirs
+
+
+if [ ! -e "$trashbase" ]; then
+    echo "trashbase '$trashbase' does not exist; bailing out."
+    exit 1
+fi
+
+if [ `echo $1 | fgrep '..'` ]; then
+    echo "First argument contained a double-dot sequence; bailing out."
+    exit 1
+fi
+if [ `echo $2 | fgrep '..'` ]; then
+    echo "First argument contained a double-dot sequence; bailing out."
+    exit 1
+fi
+
+subdir=`echo "$1" | sed 's/@.*//'`
+
+maildir="${basedir}/$2/${subdir}"
+trashdir="${trashbase}/$2/`date +%F_%T`_${subdir}"
+
+parent=`dirname "$trashdir"`
+if [ ! -d "$parent" ]; then
+    if [ -e "$parent" ]; then
+        echo "Strainge - directory '$parent' exists, but is not a directory."
+        echo "Bailing out."
+        exit 1
+    else
+        mkdir -p "$parent"
+        if [ $? -ne 0 ]; then
+            echo "mkdir -p '$parent' returned non-zero; bailing out."
+            exit 1
+        fi
+    fi
+fi
+
+if [ ! -e "$maildir" ]; then
+    echo "maildir '$maildir' does not exist; nothing to do."
+    exit 1
+fi
+if [ -e "$trashdir" ]; then
+    echo "trashdir '$trashdir' already exists; bailing out."
+    exit 1
+fi
+
+mv $maildir $trashdir
+
+exit $?

+ 151 - 0
ADDITIONS/quota_usage.pl

@@ -0,0 +1,151 @@
+#!/usr/bin/perl
+# vim:ts=4:sw=4:et
+# Virtual quota_usage 0.3
+# Contributed to Postfixadmin by Jose Nilton <jniltinho@gmail.com> 
+#
+# See also : http://www.russelldare.net/media/perl/dirsizeSource.pdf
+# License: GPL v2.
+
+# Usage:
+# perl quota_usage.pl --list 
+# perl quota_usage.pl --list --addmysql 
+#                                      for add mysql database postfix 
+#
+# Requirements - the following perl modules are required:
+# DBD::Pg or DBD::mysql; perl perl-DBD-mysql perl-DBD (may be named differently depending on your platform).
+#           and the 'du' binary in $ENV{'PATH'} (see below).
+#
+# You will need to modify the postfix DATABASE to add a quota_usage column. 
+# Mysql:
+# 	ALTER TABLE mailbox ADD quota_usage INT(11) NOT NULL DEFAULT '0' AFTER modified, 
+# 	ADD quota_usage_date DATE NOT NULL DEFAULT '0000-00-00' AFTER quota_usage;
+# PostgreSQL:
+# 	ALTER TABLE mailbox ADD COLUMN quota_usage INTEGER NOT NULL DEFAULT 0;
+# 	ALTER TABLE mailbox ADD COLUMN quota_usage_date DATE NOT NULL DEFAULT current_date;
+#
+
+use strict;
+use warnings;
+use File::Path;
+use DBI;
+use Getopt::Long;
+
+##EDIT## 
+my $db_host 	= 'localhost';
+my $db_database = 'postfix';
+my $db_user 	= 'postfix';
+my $db_password = '123456';
+my $root_path 	= '/home/vmail';
+# Pg or mysql
+my $db_type     = 'mysql'; 
+##END EDIT##
+
+(help()) if (!$ARGV[0]);
+
+$ENV{'PATH'} = "/sbin:/bin:/usr/sbin:/usr/bin";
+my($domain_dir, $full_domain_dir, $user_dir, $usage, $email, $sql, $dbh);
+
+my $list = 0;
+my $insert_db = 0;
+my $total_mailbox = 0;
+my $total_domain = 0;
+GetOptions ('l|list' => \$list, 'i|addmysql' => \$insert_db, 'help|h|man' => \&help) or (help());
+
+
+(list_quota_usage()) if ($list == 1 || $insert_db == 1 );
+
+
+
+sub list_quota_usage {
+    opendir(DOMAINDIR, $root_path) or die ("Unable to access directory '$root_path' ($!)");
+
+    if($insert_db == 1){
+        $dbh = DBI->connect("DBI:$db_type:database=$db_database;host=$db_host", $db_user, $db_password) or die ("cannot connect the database");
+        execSql("UPDATE mailbox set quota_usage = 0");
+    }
+
+    foreach $domain_dir (sort readdir DOMAINDIR) {
+        next if $domain_dir =~ /^\./;                    # skip dotted dirs
+        $full_domain_dir = "$root_path/$domain_dir"; #print "$full_domain_dir\n";
+        $total_domain++;            
+
+        opendir(USERDIR, $full_domain_dir) or die ("Unable to access directory '$full_domain_dir' ($!)");
+        foreach $user_dir (sort readdir USERDIR) {
+            next if $user_dir =~ /^\./; # skip dotted dirs
+            $email = "$user_dir\@$domain_dir";
+            $total_mailbox++;
+
+            my $i = `du -0 --summarize $full_domain_dir/$user_dir`;
+            ($usage) = split(" ", $i);
+
+            if ($usage < 100) {
+                $usage = 0;
+            } elsif ($usage < 1000) {
+                $usage = 1;
+            } else {
+                $usage = $usage + 500;
+                $usage = int $usage / 1000;
+            }
+            if($insert_db == 1){execSql("UPDATE mailbox set quota_usage = $usage, quota_usage_date = CAST(NOW() AS DATE) WHERE username = '$email'");}
+            print_list() if ($list == 1);
+
+        }
+    }
+    close(DOMAINDIR);
+    close(USERDIR);
+
+    (print_total()) if ($list == 1);
+
+}
+
+
+
+
+
+sub execSql {
+    my $sql = shift;
+    my $ex;
+    $ex = $dbh->do($sql) or die ("error when running $sql");
+}
+
+
+
+sub print_total{
+    print "---------------------------------------------------------\n";
+    print "TOTAL DOMAIN\t\t\t\tTOTAL MAILBOX\n";
+    print "---------------------------------------------------------\n";
+    print "$total_domain\t\t\t\t\t\t$total_mailbox\n";
+}
+
+
+
+sub print_list {
+format STDOUT_TOP =
+Report of Quota Used
+---------------------------------------------------------
+EMAIL                                         QUOTA USED
+---------------------------------------------------------
+.
+
+
+format = 
+@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<         @<<<<<<<<<<
+$email,                                           "$usage MB"                         
+.
+
+    write;
+}
+
+
+
+
+
+sub help {
+    print "$0 [options...]\n";
+    print "-l|--list                     List quota used\n";
+    print "-i|--addmysql                 For insert quota used in database mysql\n";
+
+}
+
+
+

+ 38 - 0
ADDITIONS/squirrelmail-plugin/INSTALL

@@ -0,0 +1,38 @@
+Installing the postfixadmin Plugin
+======================================
+
+Requirements:
+=============
+
+ - PHP 5.[234].* with php5-xmlrpc installed (if available; it should be available by default anyway)
+ - http access to a local/remote postfixadmin interface 
+ - Zend Framework (1.12.x) - needs adding to the include path within common.php, 
+   or installing in a system include path directory (e.g. /usr/share/php)
+   (e.g. from within the directory containing this file ...
+	wget https://packages.zendframework.com/releases/ZendFramework-1.12.3/ZendFramework-1.12.3-minimal.tar.gz 
+	tar -zxf ZendFramework-1.12.3-minimal.tar.gz
+	mv ZendFramework-1.12.3-minimal/library/Zend .    )
+   NOTE: This plugin is _not compatible_ with Zend Framework version 2.x.
+
+Installation :
+==============
+
+- Copy this code into the Squirrelmail plugins directory - your life will be easiest if it's in a directory called 'postfixadmin'
+- Install Zend Framework (see above under Requirements for example)
+- Edit config.php and specify the remote URL for the Postfixadmin XmlRpc service. 
+- Edit common.php and (if you need to) change the include path(s) so they are correct.
+- Edit the remote Postfixadmin's XmlRpc service config file and ensure 'xmlrpc_enabled' is set to boolean true.
+- Enable the plugin through 'squirrelmail-configure' or 'config/conf.pl'.  
+   Choose option 8 and move the plugin from the "Available Plugins"
+   category to the "Installed Plugins" category.  Save and exit.
+
+Security :
+==========
+
+- The XmlRpc client needs to get the user's mailbox password before it will be able to connect to the
+  XmlRpc server (postfixadmin). The plugin prompts the user for their mailbox password, and caches it in their session
+  ($_SESSION['password']). This password is then sent once on every page load to the remote XmlRpc server.
+
+- You should consider doing any of the following :
+ - Using https if the server and client are on seperate servers. This will probably require a signed certificate etc, and may require changes to the Zend_XmlRpc_Client's HttpClient.
+ - Using something like stunnel to encrypt traffic between server(s).

+ 40 - 0
ADDITIONS/squirrelmail-plugin/LICENSE.txt

@@ -0,0 +1,40 @@
+
+2007/03/29 :
+    Before I (David Goodwin) customised this plugin, it contained the following within all
+    files as a header. 
+
+    /****************************************************************************************
+
+        Author ......... Florian Kimmerl
+        Contact ........ info@spacekoeln.de
+        Home Site ...... http://www.spacekoeln.de/
+        Program ........ postfixadmin
+        Purpose ........ Allows you to change your postfixadmin settings within squirrelmail
+
+        *************************************************************************************
+
+        The Original Code is Postfix Admin.
+        The Initial Developer of the Original Code is Mischa Peters .
+        Portions created by Mischa Peters are Copyright (c) 2002, 2003, 2004.
+        All Rights Reserved.
+        Contributor(s):
+        This project includes work by Mischa Peters and others that is:
+        Copyright (c) 2002,2003,2004 Mischa Peters
+        All rights reserved.
+
+    ****************************************************************************************/
+
+    
+    Contacting the author provided no success, so I took over maintainership.
+
+    Please note:
+
+    1) Changes made by myself (David Goodwin) will be licensed under the GPL
+    2) PostfixAdmin has itself been relicensed under the GPL; however this took place _after_
+       this plugin was written.
+    3) Squirrelmail itself is released under http://squirrelmail.org/wiki/SquirrelMailGPL (GPL)
+
+
+The GNU public license can be found online at :
+
+    http://www.gnu.org/licenses/gpl.txt

+ 70 - 0
ADDITIONS/squirrelmail-plugin/README

@@ -0,0 +1,70 @@
+Squirrelmail Plugin Postfixadmin
+********************************
+
+The Postfixadmin SquirrelMail plugin let users change their virtual alias,
+vacation status/message and password if you are using the great postfixadmin
+tool from http://high5.net/postfixadmin
+
+Version 0.4.3   2007/08/14
+
+Postfixadmin - Postfixadmin+MySQL/PgSQL plugin for Squirrelmail
+
+
+Author: Florian Kimmerl <info@spacekoeln.de>
+Author: Sam Brookes <sam at pale purple.co.uk>
+    - Initial conversion to MDB2
+    - Fix SQL Injections etc
+Author: David Goodwin <david at pale purple.co.uk>
+    - Subsequent tidyup + testing etc
+Author: Krzysztof 'Mad Max' Laska - <madmax at riders.pl>
+    - Polish Translation.
+
+
+
+The Initial Developer of the Original postfixadmin Code is Mischa Peters.
+Portions created by Mischa Peters are Copyright (c) 2002, 2003, 2004.
+All Rights Reserved.
+
+REQUIREMENTS
+
+o SquirrelMail 1.4x
+
+o A working Mail-System "Virtual Domains and Users with postfix+Courier-IMAP+MySQL" (or PostgreSQL) See http://high5.net/howto/
+
+o POSTFIXADMIN version 2.2.0 or higher. See http://sf.net/projects/postfixadmin
+
+o This plugin only uses the postfixadmin database
+
+o Pear MDB2 database abstraction layer - see http://pear.php.net 
+
+o PHP installation with register globals TURNED OFF (huraren on IRC reports that the MDB2 driver isn't happy with it turned on)
+
+INSTALLATION
+
+See the included file INSTALL
+
+BUGS
+
+o Probably vulnerable to cross site scripting, certainly when setting the vacation message.
+
+o There may be some remaining SQL injection holes.
+
+TODO
+
+-Code Cleanup
+-Tranlation
+
+
+TRANSLATIONS
+
+Translations are welcome! Send the *.po-File to: david@NO.codepoets.SPAM.co.uk
+
+
+ACKNOWLEDGMENTS
+
+Thanks to the SquirrelMail team for building such a great app and
+for all the work they do to keep it running.
+
+Thanks to high5.net for writing the great Postfixadmin tool
+
+

+ 44 - 0
ADDITIONS/squirrelmail-plugin/common.php

@@ -0,0 +1,44 @@
+<?php
+// vim:ts=4:sw=4:et
+ini_set('include_path', get_include_path() . ':' . dirname(__FILE__));
+
+@include_once('Zend/Version.php');
+if(!class_exists('Zend_Version', false)) {
+	die("Zend Framework not found. Please check the INSTALL File.");
+}
+chdir("..");
+
+
+if (!defined('SM_PATH')) 
+{
+    define('SM_PATH','../');
+}
+include_once(dirname(__FILE__)  . '/config.php');
+include_once(dirname(__FILE__) . '/functions.inc.php');
+include_if_exists(dirname(__FILE__) . '/../include/validate.php');
+if (file_exists(dirname(__FILE__) . '/../include/validate.php')) 
+{
+    include_once(dirname(__FILE__) . '/include/validate.php');
+}
+else { 
+    include_if_exists(SM_PATH . 'src/validate.php');
+}
+include_once(SM_PATH . 'functions/page_header.php');
+include_once(SM_PATH . 'functions/display_messages.php');
+include_once(SM_PATH . 'functions/imap.php');
+include_if_exists(SM_PATH . 'functions/array.php');
+if (file_exists(SM_PATH . 'src/load_prefs.php'))
+{
+    include_once(SM_PATH . 'src/load_prefs.php');
+}
+else {
+    include_if_exists(SM_PATH . 'include/load_prefs.php');
+}
+// overwrite squirrelmail's content type to utf8...
+header("Content-Type: text/html; charset=utf8");
+
+
+//global $VACCONFMESSAGE;
+bindtextdomain('postfixadmin', dirname(__FILE__) . '/postfixadmin/locale');
+textdomain('postfixadmin');
+

+ 22 - 0
ADDITIONS/squirrelmail-plugin/config.php.sample

@@ -0,0 +1,22 @@
+<?php
+
+$CONF = array();
+$CONF['xmlrpc_url'] = 'http://postfixadmin.local/postfixadmin/xmlrpc.php';
+
+// Virtual Vacation
+// If you use virtual vacation for you mailbox users set this to 'true'.
+// NOTE: Make sure that you install the vacation module!!
+
+//$AllowVacation = true;    // true or false
+global $AllowVacation;
+$AllowVacation = true;
+
+// Change Password
+// Enables user to change the POP3/IMAP Password.
+//$AllowChangePass = true;    // true or false
+global $AllowChangePass;
+$AllowChangePass = true;
+
+// Minimum password length - set to Zero to not care, otherwise the number of 
+// characters a password must be longer than.
+$CONF['min_password_length'] = 5;

+ 20 - 0
ADDITIONS/squirrelmail-plugin/debian/README.Debian

@@ -0,0 +1,20 @@
+Squirrelmail PostfixAdmin Plugin for Debian
+===========================================
+
+After installing the package, you will need to :
+
+1) Edit the config.inc.php file to point to the PostfixAdmin server.
+
+2) Ensure the xmlrpc interface is available and enabled on the Postfixadmin server
+
+3) Run the squirrelmail-configure script.
+
+Where to get help
+=================
+
+See http://squirrelmail-postfixadmin.palepurple.co.uk
+
+Try also : david [at] pale purple dot co dot uk
+
+Or #postfixadmin on irc.freenode.net might be a good bet.
+

+ 27 - 0
ADDITIONS/squirrelmail-plugin/debian/changelog

@@ -0,0 +1,27 @@
+squirrelmail-postfixadmin (2.3.0) stable; urgency=low
+
+  * Using XMLRPC backend (no SQL here)
+
+ -- David Goodwin <david.goodwin@palepurple.co.uk>  Mon, 01 Feb 2010 09:56:00 +0000
+
+squirrelmail-postfixadmin (2.2.0) stable; urgency=low
+
+  * Changed DB backend to use prepared statements
+  * Changed vacation handling to match that of Postfixadmin (vacation.active
+    etc)
+  * Changed vacation page to support UTF8
+
+ -- David Goodwin <david.goodwin@palepurple.co.uk>  Wed, 20 Aug 2008 15:25:00 +0000
+
+squirrelmail-postfixadmin (2.1.1-1) stable; urgency=low
+
+  * Add NL language support
+  * Better db error logging (e.g. if wrong mdb2 driver specified etc)
+
+ -- David Goodwin <david.goodwin@palepurple.co.uk>  Wed, 12 Dec 2007 16:00:00 +0000
+
+squirrelmail-postfixadmin (2.1.0-1) stable; urgency=low
+
+  * Initial release.
+
+ -- David Goodwin <david.goodwin@palepurple.co.uk>  Thu,  8 Nov 2007 20:00:00 +0000

+ 1 - 0
ADDITIONS/squirrelmail-plugin/debian/conffiles

@@ -0,0 +1 @@
+/etc/squirrelmail/plugins/postfixadmin-config.php

+ 19 - 0
ADDITIONS/squirrelmail-plugin/debian/control

@@ -0,0 +1,19 @@
+Source: squirrelmail-postfixadmin
+Section: mail
+Priority: optional
+Maintainer: David Goodwin <david.goodwin@palepurple.co.uk>
+Standards-Version: 3.6.1
+
+Package: squirrelmail-postfixadmin
+Architecture: all
+Depends: squirrelmail, php-pear
+Suggests: postfixadmin
+Description: Plugin for Squirrelmail to integrate with Postfixadmin
+ Postfixadmin is a web based interface for managing mail domains 
+ and users. This package integrates Squirrelmail with it. 
+ Users can change their password, forwarding and vacation settings
+ from within Squirrelmail when this package is installed, and 
+ enabled through the ./squirrelmail-configure command.
+ .
+ For further information see 
+ http://squirrelmail-postfixadmin.palepurple.co.uk

+ 11 - 0
ADDITIONS/squirrelmail-plugin/debian/copyright

@@ -0,0 +1,11 @@
+This package was debianized by David Goodwin <david@palepurple.co.uk>
+2007/11/08
+
+It was downloaded from: http://squirremail-postfixadmin.palepurple.co.uk
+
+Upstream Author(s): n/a
+
+Copyright:
+    Copyright (C) 2007+ by David Goodwin <david@palepurple.co.uk>
+
+License: GPL v2+

+ 4 - 0
ADDITIONS/squirrelmail-plugin/debian/docs

@@ -0,0 +1,4 @@
+LICENSE.txt
+README
+INSTALL
+debian/README.Debian

+ 1 - 0
ADDITIONS/squirrelmail-plugin/debian/files

@@ -0,0 +1 @@
+squirrelmail-postfixadmin_2.2.0_all.deb mail optional

+ 3 - 0
ADDITIONS/squirrelmail-plugin/debian/postfixadmin-squirrelmail.dirs

@@ -0,0 +1,3 @@
+usr/share/squirrelmail/plugins/postfixadmin
+usr/share/doc/squirrelmail-postfixadmin
+etc/squirrelmail/plugins

+ 5 - 0
ADDITIONS/squirrelmail-plugin/debian/postinst

@@ -0,0 +1,5 @@
+#!/bin/sh
+
+echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+echo "WARNING: You need to read /usr/share/doc/squirrelmail-postfixadmin/README.Debian!"
+echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

+ 56 - 0
ADDITIONS/squirrelmail-plugin/debian/rules

@@ -0,0 +1,56 @@
+#!/usr/bin/make -f
+# debian/rules makefile for squirrelmail
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+build: build-stamp
+build-stamp:
+	dh_testdir
+
+clean:
+	dh_testdir
+	dh_testroot
+	dh_clean
+
+install: build
+	$(checkdir)
+	dh_testdir
+	dh_testroot
+	dh_clean -k
+	dh_installdirs
+	dh_install
+	mkdir -p debian/tmp/usr/share/squirrelmail/plugins/postfixadmin
+	cp -a *.php version debian/tmp/usr/share/squirrelmail/plugins/postfixadmin
+	cp -a locale debian/tmp/usr/share/squirrelmail/plugins/postfixadmin
+	cp -a po debian/tmp/usr/share/squirrelmail/plugins/postfixadmin
+	mkdir -p debian/tmp/etc/squirrelmail/plugins/
+	cp -a *.sample debian/tmp/etc/squirrelmail/plugins/postfixadmin-config.php
+	mkdir -p debian/tmp/DEBIAN
+	cp debian/postinst debian/tmp/DEBIAN/postinst
+	chmod 555 debian/tmp/DEBIAN/postinst
+	ln -s /etc/squirrelmail/plugins/postfixadmin-config.php debian/tmp/usr/share/squirrelmail/plugins/postfixadmin/config.php
+	find debian/tmp -name .svn | xargs -r rm -r
+
+# Build architecture-independent files here.
+binary-indep: build install
+	dh_testdir
+	dh_testroot
+	dh_installdebconf	
+	dh_installdocs -X.svn
+	dh_installexamples
+	dh_installman
+	dh_installcron
+	dh_link
+	dh_compress
+	dh_fixperms -X/var
+	dh_installdeb
+	dh_gencontrol
+	dh_md5sums
+	dh_builddeb
+
+# Build architecture-dependent files here.
+binary-arch:
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install

+ 102 - 0
ADDITIONS/squirrelmail-plugin/functions.inc.php

@@ -0,0 +1,102 @@
+<?php
+/**
+ * Postfixadmin (http://postfixadmin.sf.net) integration with Squirrelmail.
+ * See http://squirrelmail-postfixadmin.palepurple.co.uk
+ * @author David Goodwin and many others
+ */
+
+
+function do_header() {
+    global $color;
+    displayPageHeader($color, 'None');
+}
+
+function do_footer() {
+    echo "</body></html>";
+}
+
+function _display_password_form() {
+    bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
+    textdomain('postfixadmin');
+    do_header('Postfixadmin Squirrelmail - Login');
+    echo _('The PostfixAdmin plugin needs your current mailbox password');
+    echo "<form action='' method='post'>";
+    echo _('Password for');
+    echo " " . $_SESSION['username'] . " :"; 
+    echo "<input type='password' name='password' value=''>";
+    echo "<input type='submit' value='" . _('Submit') . "'></form>";
+    do_footer();
+}
+
+/**
+ * This returns a Zend_XmlRpc_Client instance - unless we can't log you in...
+ */
+function get_xmlrpc() {
+    global $CONF;
+    require_once('Zend/XmlRpc/Client.php');
+    $client = new Zend_XmlRpc_Client($CONF['xmlrpc_url']);
+    $http_client = $client->getHttpClient();
+    $http_client->setCookieJar();
+
+    $login_object = $client->getProxy('login');
+
+    if(empty($_SESSION['password'])) {
+        if(empty($_POST['password'])) {
+            _display_password_form();
+            exit(0);
+        }
+        else {
+            try {
+                $success = $login_object->login($_SESSION['username'], $_POST['password']);
+            }
+            catch(Exception $e) {
+                //var_dump($client->getHttpClient()->getLastResponse()->getBody());
+                error_log("Failed to login to xmlrpc instance - " . $e->getMessage());
+                die('Failed to login to xmlrpc instance');
+            }
+            if($success) {
+                $_SESSION['password'] = $_POST['password'];
+                // reload the current page as a GET request.
+                header("Location: {$_SERVER['REQUEST_URI']}");
+                exit(0);
+            }
+            else {
+                _display_password_form();
+                exit(0);
+            }
+        }
+    }
+    else {
+        $success = $login_object->login($_SESSION['username'], $_SESSION['password']);
+    }
+
+    if(!$success) {
+        unset($_SESSION['password']);
+        die("Invalid details cached... refresh this page and re-enter your mailbox password");
+    }
+    return $client;
+}
+
+function include_if_exists($filename) {
+    if(file_exists($filename)) {
+        include_once($filename);
+    }
+    return;
+}
+global $optmode;
+$optmode = 'display';
+
+//
+// check_email
+// Action: Checks if email is valid and returns TRUE if this is the case.
+// Call: check_email (string email)
+//
+function check_email($email) {
+    $return = filter_var($email, FILTER_VALIDATE_EMAIL);
+    if($return === false) {
+        return false;
+    }
+    return true;
+}
+
+

+ 27 - 0
ADDITIONS/squirrelmail-plugin/index.php

@@ -0,0 +1,27 @@
+<?php
+
+/****************************************************************************************
+
+    Author ......... Florian Kimmerl
+    Contact ........ info@spacekoeln.de
+    Home Site ...... http://www.spacekoeln.de/
+    Program ........ postfixadmin
+    Version ........ 0.3-1.4
+    Purpose ........ Allows you to change your postfixadmin settings within squirrelmail
+
+ /**
+ * index.php
+ *
+ * Copyright (c) 1999-2003 The SquirrelMail Project Team
+ * Licensed under the GNU GPL. For full terms see the file COPYING.
+ *
+ * This file simply takes any attempt to view source files and sends those
+ * people to the login screen. At this point no attempt is made to see if
+ * the person is logged or not.
+ *
+ *
+****************************************************************************************/
+
+header("Location: ../../index.php");
+
+?>

+ 6 - 0
ADDITIONS/squirrelmail-plugin/locale/build.sh

@@ -0,0 +1,6 @@
+#!/bin/bash
+
+for f in $(find . -name postfixadmin.po)
+do
+    msgfmt -o $(dirname $f)/postfixadmin.mo $f
+done

BIN
ADDITIONS/squirrelmail-plugin/locale/cs_CZ/LC_MESSAGES/postfixadmin.mo


+ 132 - 0
ADDITIONS/squirrelmail-plugin/locale/cs_CZ/LC_MESSAGES/postfixadmin.po

@@ -0,0 +1,132 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 2004-01-29 17:35+0100\n"
+"PO-Revision-Date: 2007-07-20 20:46+0100\n"
+"Last-Translator: Michael Heca <michael.heca@gmail.com>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-2\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: setup.php
+msgid "Forwarding"
+msgstr "Pøesmìrování"
+
+msgid "Here you can create and edit E-Mail forwards."
+msgstr "Zde mù¾ete vytvoøit a nastavit pøesmìrování"
+
+msgid "Set an OUT OF OFFICE message or auto responder for your mail."
+msgstr "Zde mù¾ete nastavit automatickou odpovìd, pokud nebudete k zasti¾ení."
+
+msgid "Change your mailbox password."
+msgstr "Zmìnít heslo k Va¹emu e-mailovému úètu"
+
+#: postfixadmin_changepass.php
+msgid "Alias"
+msgstr "Úèet"
+
+msgid "Change Password"
+msgstr "Zmìnit heslo"
+
+msgid "Change your login password"
+msgstr "Zmìnít heslo k Va¹emu e-mailovému úètu"
+
+#: postfixadmin_forward.php
+msgid "Edit Alias"
+msgstr "Editace adresy pro pøesmìrování"
+
+msgid "Edit an alias* for your domain.<br />One entry per line."
+msgstr "Editace pøesmìrování pro Vá¹ úèet. <br/> Ka¾dá adresa na novém øádku."
+
+msgid "The email address that you have entered is not valid:"
+msgstr "Zadaná e-mailová adresa je chybná:"
+
+msgid "Unable to locate alias!"
+msgstr "Neni mo¾né nalézt úèet!"
+
+msgid "Unable to modify the alias!"
+msgstr "Není mo¾né zmìnit úèet!"
+
+msgid "*Additional forward-aliase always recieve messages BBC!"
+msgstr "Dal¹í aliasy dostanou e-mail jako BBC!"
+
+msgid "Alias successfully changend!"
+msgstr "Pøesmìrování bylo zmìnìno!"
+
+msgid "To remove an alias, simply delete it's line from the text box."
+msgstr "Pro odstranení pøesmìrování sma¾te v¹echny øádky v textovém boxu."
+
+#: postfixadmin_vacation.php
+msgid "Auto Response"
+msgstr "Automatická odpovìï"
+
+msgid "Going Away"
+msgstr "Jsem mimo"
+
+msgid "Coming Back"
+msgstr "Jsem zpìt"
+
+msgid "Options"
+msgstr "Nastavení"
+
+msgid "Out of Office"
+msgstr "Mimo kanceláø"
+
+msgid "Subject"
+msgstr "Pøedmìt"
+
+msgid "Body"
+msgstr "Tìlo mailu"
+
+msgid "Your auto response has been removed!"
+msgstr "Va¹e automatická odpovìï byla odstranìna!"
+
+msgid "Your auto response has been set!"
+msgstr "Va¹e automatická odpovìï byla nastavena!"
+
+msgid "You already have an auto response configured!"
+msgstr "U¾ máte nastavenu automatickou odpovìï!"
+
+#: postfixadmin_changepass.php:81
+#: postfixadmin_changepass.php:87
+msgid "The passwords that you supplied don't match!<br />Or are empty!"
+msgstr "Zadaná hesla nejsou stejná a nebo jsou prázdná!"
+
+#: postfixadmin_forward.php:70
+#: postfixadmin_forward.php:152
+msgid "To"
+msgstr "Komu"
+
+#: postfixadmin_changepass.php:101
+msgid "Unable to change your password!"
+msgstr "Není mo¾né zmìnit heslo!"
+
+#: postfixadmin_changepass.php:75
+msgid "You didn't supply your current password!"
+msgstr "Stávající heslo neodpovídá!"
+
+#: postfixadmin_changepass.php:96
+msgid "Your password has been changed!"
+msgstr "Va¹e heslo bylo zmìnìno!"
+
+msgid "Password current"
+msgstr "Stávající heslo"
+
+msgid "Password new"
+msgstr "Nové heslo"
+
+msgid "Password new again"
+msgstr "Nové heslo znovu"
+
+msgid "Please sign out and log back again with your new password!"
+msgstr "Prosím odhla¹te se a pøihla¹te se s novým heslem!"
+
+msgid "I will be away from <date> until <date>. For urgent matters you can contact <contact person>."
+msgstr "Nebudy k zasti¾ení od <date> do <date>. Pro naléhané po¾adavky prosím kontaktujte <contact person>."
+

BIN
ADDITIONS/squirrelmail-plugin/locale/da_DK/LC_MESSAGES/postfixadmin.mo


+ 127 - 0
ADDITIONS/squirrelmail-plugin/locale/da_DK/LC_MESSAGES/postfixadmin.po

@@ -0,0 +1,127 @@
+# Danish translation for Squirrelmail Plugin Postfixadmin.
+# Copyright (C) 2004 Florian Kimmerl, 2007 David Goodwin
+# This file is distributed under the same license as the Squirrelmail Plugin Postfixadmin package.
+# Jesper R. Meyer <jrm@upthere.dk>, 2007.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: 0.4.3\n"
+"POT-Creation-Date: 2004-01-29 17:35+0100\n"
+"PO-Revision-Date: 2007-11-09 16:07+0100\n"
+"Last-Translator: JESPER MEYER <jrm@upthere.dk>\n"
+"Language-Team: DANISH <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: setup.php
+msgid "Forwarding"
+msgstr "Videresending"
+
+msgid "Here you can create and edit E-Mail forwards."
+msgstr "Her kan du oprette og ændre email-videresendinger."
+
+msgid "Set an OUT OF OFFICE message or auto responder for your mail."
+msgstr "Tilføj en 'ikke tilstede' besked eller et autosvar til din emailadresse."
+
+msgid "Change your mailbox password."
+msgstr "Ændre adgangskoden til din postboks"
+
+#: postfixadmin_changepass.php
+msgid "Alias"
+msgstr "Alias"
+
+msgid "Change Password"
+msgstr "Ændre adgangskode"
+
+msgid "Change your login password"
+msgstr "Ændre din login-adgangskode"
+
+#: postfixadmin_forward.php
+msgid "Edit Alias"
+msgstr "Rediger alias"
+
+msgid "Edit an alias* for your domain.<br />One entry per line."
+msgstr "Rediger et alias* for dit domæne.<br />En modtager pr. linje."
+
+msgid "The email address that you have entered is not valid:"
+msgstr "Emailadressen du angav er ugyldig"
+
+msgid "Unable to locate alias!"
+msgstr "Aliaset eksistere ikke!"
+
+msgid "Unable to modify the alias!"
+msgstr "Kunne ikke ændre aliaset!"
+
+msgid "*Additional forward-aliase always recieve messages BBC!"
+msgstr "*Eksta vidersendingsalias modtager altid meddelelser BCC!"
+
+msgid "Alias successfully changend!"
+msgstr "Alias ændret!"
+
+#: postfixadmin_vacation.php
+msgid "Auto Response"
+msgstr "Autosvar"
+
+msgid "Going Away"
+msgstr "Tager afsted"
+
+msgid "Coming Back"
+msgstr "Kommer tilbage"
+
+msgid "Options"
+msgstr "Indstillinger"
+
+msgid "Out of Office"
+msgstr "Ikke tilstede"
+
+msgid "Subject"
+msgstr "Emne"
+
+msgid "Body"
+msgstr "Meddelelse"
+
+msgid "Your auto response has been removed!"
+msgstr "Autosvar er fjernet!"
+
+msgid "Your auto response has been set!"
+msgstr "Autosvar er aktiveret!"
+
+msgid "You already have an auto response configured!"
+msgstr "Du har allerede et autosvar indstillet!"
+
+#: postfixadmin_changepass.php:81 postfixadmin_changepass.php:87
+msgid "The passwords that you supplied don't match!<br />Or are empty!"
+msgstr "Adgangskoderne er ikke ens!<br />Eller er tomme!"
+
+#: postfixadmin_forward.php:70 postfixadmin_forward.php:152
+msgid "To"
+msgstr "Til"
+
+#: postfixadmin_changepass.php:101
+msgid "Unable to change your password!"
+msgstr "Kan ikke ændre adgangskoden!"
+
+#: postfixadmin_changepass.php:75
+msgid "You didn't supply your current password!"
+msgstr "Du glemte at skrive din nuværende adgangskode!"
+
+#: postfixadmin_changepass.php:96
+msgid "Your password has been changed!"
+msgstr "Din adgangskode er ændret!"
+
+msgid "Password current"
+msgstr "Nuværende adgangskode"
+
+msgid "Password new"
+msgstr "Ny adgangskode"
+
+msgid "Password new again"
+msgstr "Ny adgangskode (igen)"
+
+msgid "Please sign out and log back again with your new password!"
+msgstr "Log af og log ind igen med din nye adgangskode!"
+
+msgid "I will be away from <date> until <date>. For urgent matters you can contact <contact person>."
+msgstr "Jeg er ikke tilstede i perioden <dato> til <dato>. I nødstilfælde kan <kontaktperson> kontaktes."

BIN
ADDITIONS/squirrelmail-plugin/locale/de_DE/LC_MESSAGES/postfixadmin.mo


+ 127 - 0
ADDITIONS/squirrelmail-plugin/locale/de_DE/LC_MESSAGES/postfixadmin.po

@@ -0,0 +1,127 @@
+# postfixadmin - Plugin for Squirrelmail.
+# Copyright (C) 2004 FLORIAN KIMMERL
+# This file is distributed under the same license as the PACKAGE package.
+# Florian Kimmerl <info@spacekoeln.de>, 2004.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: 0.3-1.4\n"
+"POT-Creation-Date: 2004-01-28 16:32+0100\n"
+"PO-Revision-Date: 2004-01-28 16:32+0100\n"
+"Last-Translator: FLORIAN KIMMERL <info@spacekoeln.de>\n"
+"Language-Team: GERMAN <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: setup.php
+msgid "Forwarding"
+msgstr "Weiterleitungen"
+
+msgid "Here you can create and edit E-Mail forwards."
+msgstr "Hier können Sie E-Mail-Weiterleitungen erstellen und bearbeiten."
+
+msgid "Set an OUT OF OFFICE message or auto responder for your mail."
+msgstr "Hier können Sie den Abwesenheits-Assistenten konfigurieren."
+
+msgid "Change your mailbox password."
+msgstr "Hier können Sie Passwort ändern. Nach der Änderung müssen Sie sich neu anmelden!"
+
+#: postfixadmin_changepass.php
+msgid "Alias"
+msgstr "E-Mail"
+
+msgid "Change Password"
+msgstr "Passwort ändern"
+
+msgid "Change your login password"
+msgstr "Ändern Sie Ihr Zugangspasswort für POP3/IMAP"
+
+#: postfixadmin_forward.php
+msgid "Edit Alias"
+msgstr "E-Mail Weiterleitungen bearbeiten"
+
+msgid "Edit an alias* for your domain.<br />One entry per line."
+msgstr "Bearbeiten Sie hier Ihre E-Mail Weiterleitungen*.<br />Ein Eintrag pro Zeile."
+
+msgid "The email address that you have entered is not valid:"
+msgstr "Die angegebene E-Mail-Adresse ist ungültig:"
+
+msgid "Unable to locate alias!"
+msgstr "Ihre Weiterleitungen können nicht angefordert werden! Versuchen Sie es später erneut."
+
+msgid "Unable to modify the alias!"
+msgstr "Ihre Weiterleitungen können nicht modifiziert werden! Versuchen Sie es später erneut."
+
+msgid "*Additional forward-aliase always recieve messages BBC!"
+msgstr "*Zusätzliche Weiterleitungen erhalten alle Nachrichten als Kopie (BCC)!"
+
+msgid "Alias successfully changend!"
+msgstr "Weiterleitungen wurden erfolgreich geändert!"
+
+#: postfixadmin_vacation.php
+msgid "Auto Response"
+msgstr "Abwesenheits-Assistent"
+
+msgid "Going Away"
+msgstr "Ich bin weg"
+
+msgid "Coming Back"
+msgstr "Ich bin zurück"
+
+msgid "Options"
+msgstr "Optionen"
+
+msgid "Out of Office"
+msgstr ""
+
+msgid "Subject"
+msgstr "Betreff"
+
+msgid "Body"
+msgstr "Nachrichtentext"
+
+msgid "Your auto response has been removed!"
+msgstr "Iher Abwesenheits-Nachricht wurde deaktiviert!"
+
+msgid "Your auto response has been set!"
+msgstr "Ihre Abwesenheits-Nachricht wurde aktiviert!"
+
+msgid "You already have an auto response configured!"
+msgstr "Ihre Abwesenheits-Nachricht ist bereits aktiviert!"
+
+msgid "back"
+msgstr "zurück"
+
+#: postfixadmin_changepass.php:81 postfixadmin_changepass.php:87
+msgid "The passwords that you supplied don't match!<br />Or are empty!"
+msgstr "Die beiden neuen Passwörter stimmen nicht überein!<br />Oder die Felder wurden nicht ausgefüllt!"
+
+#: postfixadmin_forward.php:70 postfixadmin_forward.php:152
+msgid "To"
+msgstr "An"
+
+#: postfixadmin_changepass.php:101
+msgid "Unable to change your password!"
+msgstr "Ihr Passwort kann nicht geändert werden!"
+
+#: postfixadmin_changepass.php:75
+msgid "You didn't supply your current password!"
+msgstr "Ihr aktuelles Passwort wurde nicht angegeben oder ist falsch!"
+
+#: postfixadmin_changepass.php:96
+msgid "Your password has been changed!"
+msgstr "Ihr Passwort wurde ergolgreich geändert!"
+
+msgid "Password current"
+msgstr "Passwort aktuell"
+
+msgid "Password new"
+msgstr "Passwort neu"
+
+msgid "Password new again"
+msgstr "Passwort neu nochmal"
+
+msgid "Please sign out and log back again with your new password!"
+msgstr "Bitte melden Sie sich hier ab und loggen sich mit Ihrem neuen Passwort erneut ein! "

BIN
ADDITIONS/squirrelmail-plugin/locale/hu_HU/LC_MESSAGES/postfixadmin.mo


+ 135 - 0
ADDITIONS/squirrelmail-plugin/locale/hu_HU/LC_MESSAGES/postfixadmin.po

@@ -0,0 +1,135 @@
+# postfixadmin - Plugin for Squirrelmail.
+# Copyright (C) 2004 FLORIAN KIMMERL
+# This file is distributed under the same license as the PACKAGE package.
+# Florian Kimmerl <info@spacekoeln.de>, 2004.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: 0.3-1.4\n"
+"POT-Creation-Date: 2004-01-28 16:32+0100\n"
+"PO-Revision-Date: 2004-01-28 16:32+0100\n"
+"Last-Translator: FLORIAN KIMMERL <info@spacekoeln.de>\n"
+"Language-Team: HUNGARIAN <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-2\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: setup.php
+msgid "Forwarding"
+msgstr "Levéltovábbítás"
+
+msgid "Here you can create and edit E-Mail forwards."
+msgstr "Itt tudod létrehozni és szerkeszteni az E-mail továbbításokat."
+
+msgid "Set an OUT OF OFFICE message or auto responder for your mail."
+msgstr "Itt lehet beállítani az automatikus válasz levél szövegét, ha az ember távol van."
+
+msgid "Change your mailbox password."
+msgstr "Itt tudod megváltoztatni a belépéshez szükséges jelszót."
+
+#: postfixadmin_changepass.php
+msgid "Alias"
+msgstr "E-mail"
+
+msgid "Change Password"
+msgstr "Jelszó megváltoztatása"
+
+msgid "Change your login password"
+msgstr "Bejelentkezési jelszó megváltoztatása"
+
+#: postfixadmin_forward.php
+msgid "Edit Forward"
+msgstr "Levéltovábbítás szerkesztése"
+
+msgid "Edit Alias"
+msgstr "Levéltovábbítás szerkesztése"
+
+msgid "The email address that you have entered is not valid:"
+msgstr "Az E-mail cím amit beírtál hibás:"
+
+msgid "Unable to locate alias!"
+msgstr "Hiba az e-mail címmel."
+
+msgid "Unable to modify the alias!"
+msgstr "A módosítás sikertelen!"
+
+msgid "Alias successfully changed!"
+msgstr "A módosítás sikeres!"
+
+#: postfixadmin_vacation.php
+msgid "Auto Response"
+msgstr "Automatikus válasz"
+
+msgid "Going Away"
+msgstr "Házonkívül vagyok"
+
+msgid "Coming Back"
+msgstr "Visszajöttem"
+
+msgid "Options"
+msgstr "Opciók"
+
+msgid "Out of Office"
+msgstr "Házonkívül"
+
+msgid "Subject"
+msgstr "Tárgy"
+
+msgid "Body"
+msgstr "Levéltörzs"
+
+msgid "Your auto response has been removed!"
+msgstr "Az automatikus válasz törölve lett!"
+
+msgid "Your auto response has been set!"
+msgstr "Az automatikus válasz be lett állítva!"
+
+msgid "You already have an auto response configured!"
+msgstr "Már létezik egy automatikus válasz!"
+
+#: postfixadmin_changepass.php:81 postfixadmin_changepass.php:87
+msgid "The passwords that you supplied don't match!<br />Or are empty!"
+msgstr "A jelszavak nem egyeznek!<br />Vagy üresen hagytad a mezõket!"
+
+#: postfixadmin_changepass.php:101
+msgid "Unable to change your password!"
+msgstr "A jelszó megváltoztatása sikertelen!"
+
+#: postfixadmin_changepass.php:75
+msgid "You didn't supply your current password!"
+msgstr "Az aktuális jelszó nem megfelelõ!"
+
+#: postfixadmin_changepass.php:96
+msgid "Your password has been changed!"
+msgstr "A jelszó változtatása sikeres volt!"
+
+msgid "Password current"
+msgstr "Aktuális jelszó"
+
+msgid "Password new"
+msgstr "Új jelszó"
+
+msgid "Password new again"
+msgstr "Új jelszó mégegyszer"
+
+msgid "Please sign out and log back again with your new password!"
+msgstr "Kérjük, jelentkezzen ki, majd újra be az új jelszavával!"
+
+msgid "I will be away from <date> until <date>. For urgent matters you can contact <contact person>."
+msgstr "Házonkívül leszek <date> és <date> között. Sürgõs esetben értesítendõ: <contact person>."
+
+msgid "One copy always goes to"
+msgstr "Egy másolat mindig ide"
+
+msgid "Another copy also goes to"
+msgstr "További másolatok ide"
+
+msgid "Enter an email address (or addresses) where you would like an additional copy of messages addressed to you sent.<br> Enter only one address per line."
+msgstr "Sorolja fel azokat az e-mail címeket, amelyekre az Önhöz érkezõ leveleket továbbítani szeretné.<br>Soronként csak egy címet adjon meg!"
+
+msgid "A copy of each message will go to both your mailbox and the forwarded address(es)."
+msgstr "Minden Önnek címzett levél meg fog érkezni a saját postafiókjába és a továbbított e-mail címekre is."
+
+msgid "To remove a Forward, simply delete its line from the text box."
+msgstr "Ahhoz, hogy töröljön egy továbbítást, ki kell törölnie az adott sort a felsorolásból."

+ 129 - 0
ADDITIONS/squirrelmail-plugin/locale/it_IT/LC_MESSAGES/postfixadmin.po

@@ -0,0 +1,129 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 2004-01-29 17:35+0100\n"
+"PO-Revision-Date: 2010-02-19 11:30+0100\n"
+"Last-Translator: valentina <ruggiolona@tiscali.it>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: setup.php
+msgid "Forwarding"
+msgstr "Inoltro E-MAIL"
+
+msgid "Here you can create and edit E-Mail forwards."
+msgstr "Qui puoi creare e modificare l'inoltro dell' E-MAIL."
+
+msgid "Set an OUT OF OFFICE message or auto responder for your mail."
+msgstr "Imposta un messaggio OUT OF OFFICE / ASSENTE o un risponditore automatico per la tua mail."
+
+msgid "Change your mailbox password."
+msgstr "Modifica la tua password di accesso alla mail"
+
+#: postfixadmin_changepass.php
+msgid "Alias"
+msgstr "Alias"
+
+msgid "Change Password"
+msgstr "Modifica password"
+
+msgid "Change your login password"
+msgstr "Modifica la tua password di accesso"
+
+#: postfixadmin_forward.php
+msgid "Edit Alias"
+msgstr "Modifica Alias"
+
+msgid "Edit an alias* for your domain.<br />One entry per line."
+msgstr "Modifica un Alias per il tuo dominio.<br />Un record per linea."
+
+msgid "The email address that you have entered is not valid:"
+msgstr "L'indirizzo email che hai inserito non è corretto:"
+
+msgid "Unable to locate alias!"
+msgstr "Impossibile trovare l'alias!"
+
+msgid "Unable to modify the alias!"
+msgstr "Impossibile modificare l'alias!"
+
+msgid "*Additional forward-aliase always recieve messages BBC!"
+msgstr "* L'inoltro ad un alias aggiuntivo comporta l'invio del messaggio in BCC!"
+
+msgid "Alias successfully changend!"
+msgstr "Alias modificato correttamente!"
+
+#: postfixadmin_vacation.php
+msgid "Auto Response"
+msgstr "Risponditore automatico"
+
+msgid "Going Away"
+msgstr "Going Away"
+
+msgid "Coming Back"
+msgstr "Coming Back"
+
+msgid "Options"
+msgstr "Opzioni"
+
+msgid "Out of Office"
+msgstr "Out of Office/Assente"
+
+msgid "Subject"
+msgstr "Oggetto"
+
+msgid "Body"
+msgstr "Messaggio"
+
+msgid "Your auto response has been removed!"
+msgstr "Il risponditore automatico è stato disattivato!"
+
+msgid "Your auto response has been set!"
+msgstr "Il risponditore automatico è stato configurato!"
+
+msgid "You already have an auto response configured!"
+msgstr "Hai gia configurato il risponditore automatico !"
+
+#: postfixadmin_changepass.php:81
+#: postfixadmin_changepass.php:87
+msgid "The passwords that you supplied don't match!<br />Or are empty!"
+msgstr "Le password inserite non coincidono!<br />O i campi sono vuoti!"
+
+#: postfixadmin_forward.php:70
+#: postfixadmin_forward.php:152
+msgid "To"
+msgstr "A"
+
+#: postfixadmin_changepass.php:101
+msgid "Unable to change your password!"
+msgstr "Impossibile modificare la password"
+
+#: postfixadmin_changepass.php:75
+msgid "You didn't supply your current password!"
+msgstr "Non hai indicato la password attuale!"
+
+#: postfixadmin_changepass.php:96
+msgid "Your password has been changed!"
+msgstr "La tua password è stata modificata!"
+
+msgid "Password current"
+msgstr "Password attuale"
+
+msgid "Password new"
+msgstr "Nuova password"
+
+msgid "Password new again"
+msgstr "Insierisci nuovamente la nuova password"
+
+msgid "Please sign out and log back again with your new password!"
+msgstr "Per favore fai log out e riaccedi alla tua mail con la nuova password!"
+
+msgid "I will be away from <date> until <date>. For urgent matters you can contact <contact person>."
+msgstr "Mi dispiace sarò assente dal <date> al <date>. Per richieste urgenti vi prego di contattare <nome e indirizzo email>.    I will be away from <date> until <date>. For urgent matters you can contact <contact person>."
+

BIN
ADDITIONS/squirrelmail-plugin/locale/nl_NL/LC_MESSAGES/postfixadmin.mo


+ 131 - 0
ADDITIONS/squirrelmail-plugin/locale/nl_NL/LC_MESSAGES/postfixadmin.po

@@ -0,0 +1,131 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: postfixadmin-squirrelmail 2.1.0\n"
+"POT-Creation-Date: 2007-11-16 17:35+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Johan <johan@double-l.nl>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-2\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: setup.php
+msgid "Forwarding"
+msgstr "Doorsturen"
+
+msgid "Here you can create and edit E-Mail forwards."
+msgstr "Hier kunt u uw doorstuur adres bewerken"
+
+msgid "Set an OUT OF OFFICE message or auto responder for your mail."
+msgstr "Configureer hier uw automatisch beantwoorden"
+
+msgid "Change your mailbox password."
+msgstr "Verander uw wachtwoord"
+
+#: postfixadmin_changepass.php
+msgid "Alias"
+msgstr "Alias"
+
+msgid "Change Password"
+msgstr "Verander wachtwoord"
+
+msgid "Change your login password"
+msgstr "Verander uw login wachtwoord"
+
+#: postfixadmin_forward.php
+msgid "Edit Forwards"
+msgstr "Bewerk aliassen"
+
+msgid "Edit an alias* for your email address.<br />One entry per line."
+msgstr "Bewerk uw alias(sen) voor uw emailadres.<br />1 alias per regel."
+
+msgid "The email address that you have entered is not valid:"
+msgstr "Het ingevoerde adres is geen geldig adres"
+
+msgid "Unable to locate alias!"
+msgstr "Niet in staat opgeven alias te vinden!"
+
+msgid "Unable to modify the alias!"
+msgstr "Niet in staat de alias aan te passen"
+
+msgid "*Additional forward-aliases always receive messages BBC!"
+msgstr "Aliassen ontvangen altijd per BCC! "
+
+msgid "To remove an alias, simply delete its line from the text box."
+msgstr "Verwijder de regel om de alias(sen) te verwijderen."
+
+msgid "Alias successfully changed!"
+msgstr "Alias succesvol aangepast"
+
+#: postfixadmin_vacation.php
+msgid "Auto Response"
+msgstr "Automatisch beantwoorden"
+
+msgid "Going Away"
+msgstr "Ik ben weg, schakel Out of Office IN"
+
+msgid "Coming Back"
+msgstr "Ik ben terug, schakel Out of Office UIT"
+
+msgid "Options"
+msgstr "Opties"
+
+msgid "Out of Office"
+msgstr "Out of office"
+
+msgid "Subject"
+msgstr "Onderwerp"
+
+msgid "Body"
+msgstr "Tekst"
+
+msgid "Your auto response has been removed!"
+msgstr "Uw automatisch beantwoorden is verwijderd!"
+
+msgid "Your auto response has been set!"
+msgstr "Uw automatisch beantwoorden is geactiveerd!"
+
+msgid "You already have an auto response configured!"
+msgstr "Automatisch beantwoorden is al geconfigureerd!"
+
+#: postfixadmin_changepass.php:81 postfixadmin_changepass.php:87
+msgid "The passwords that you supplied don't match!<br />Or are empty!"
+msgstr "De wachtwoorden komen niet overeen!<br />Of er is geen wachtwoord opgegeven!"
+
+#: postfixadmin_forward.php:70 postfixadmin_forward.php:152
+msgid "To"
+msgstr "Aan"
+
+#: postfixadmin_changepass.php:101
+msgid "Unable to change your password!"
+msgstr "Niet in staat uw wachtwoord te wijzigen!"
+
+#: postfixadmin_changepass.php:75
+msgid "You didn't supply your current password!"
+msgstr "U moet uw huidige wachtwoord opgeven!"
+
+#: postfixadmin_changepass.php:96
+msgid "Your password has been changed!"
+msgstr "Uw wachtwoord is gewijzigd!"
+
+msgid "Password current"
+msgstr "Huidig wachtwoord"
+
+msgid "Password new"
+msgstr "Nieuw wachtwoord"
+
+msgid "Password new again"
+msgstr "Nieuw wachtwoord nogmaals"
+
+msgid "Please sign out and log back again with your new password!"
+msgstr "Log uit en opnieuw in met het nieuwe wachtwoord"
+
+msgid "I will be away from <date> until <date>. For urgent matters you can contact <contact person>."
+msgstr "Ik ben niet aanwezig van <datum> tot <datum>. Voor dringende zaken kunt u contact opnemen met <Contact persoon>."
+

BIN
ADDITIONS/squirrelmail-plugin/locale/pl_PL/LC_MESSAGES/postfixadmin.mo


+ 132 - 0
ADDITIONS/squirrelmail-plugin/locale/pl_PL/LC_MESSAGES/postfixadmin.po

@@ -0,0 +1,132 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 2004-01-29 17:35+0100\n"
+"PO-Revision-Date: 2007-07-20 20:46+0100\n"
+"Last-Translator: Krzysztof Laska <krzysiek@dip.pl>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-2\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: setup.php
+msgid "Forwarding"
+msgstr "Przekazywanie"
+
+msgid "Here you can create and edit E-Mail forwards."
+msgstr "Tutaj mo¿esz ustawiæ i edytowaæ opcje przekazywania wiadomo¶ci"
+
+msgid "Set an OUT OF OFFICE message or auto responder for your mail."
+msgstr "Ustaw wiadomo¶æ wysy³an± nadawcom podczas Twojej nieobecno¶ci (Vacation)"
+
+msgid "Change your mailbox password."
+msgstr "Zmieñ has³o do swojego konta pocztowego"
+
+#: postfixadmin_changepass.php
+msgid "Alias"
+msgstr "Konto"
+
+msgid "Change Password"
+msgstr "Zmieñ has³o"
+
+msgid "Change your login password"
+msgstr "Zmieñ has³o do swojego konta pocztowego"
+
+#: postfixadmin_forward.php
+msgid "Edit Alias"
+msgstr "Edytuj adresy do przekazywania"
+
+msgid "Edit an alias* for your domain.<br />One entry per line."
+msgstr "Edytuj forward* dla swojego konta. <br/> Ka¿dy adres w nowym wierszu."
+
+msgid "The email address that you have entered is not valid:"
+msgstr "Adres e-mail jaki poda³e¶ jest niepoprawny:"
+
+msgid "Unable to locate alias!"
+msgstr "Nie mo¿na zlokalizowaæ aliasu!"
+
+msgid "Unable to modify the alias!"
+msgstr "Nie mo¿na zmodyfikowaæ aliasu!"
+
+msgid "*Additional forward-aliase always recieve messages BBC!"
+msgstr "*Wszystkie dodatkowe adresy zawsze odbieraj± wiadomo¶ci przesy³ane jako BCC! Ca³a poczta jest przekazywana i nie jest przechowywana na koncie podstawowym!"
+
+msgid "Alias successfully changend!"
+msgstr "Zmiana zachowana!"
+
+msgid "To remove an alias, simply delete it's line from the text box."
+msgstr "¯eby wy³±czyæ forward na dane konto po prostu usuñ liniê z adresem na który nie chcesz ju¿ przekazywaæ poczty."
+
+#: postfixadmin_vacation.php
+msgid "Auto Response"
+msgstr "Autoodpowied¼"
+
+msgid "Going Away"
+msgstr "W³±cz autoodpowied¼"
+
+msgid "Coming Back"
+msgstr "Wy³±cz autoodpowied¼"
+
+msgid "Options"
+msgstr "Opcje"
+
+msgid "Out of Office"
+msgstr "Autoodpowied¼"
+
+msgid "Subject"
+msgstr "Temat"
+
+msgid "Body"
+msgstr "Tre¶æ"
+
+msgid "Your auto response has been removed!"
+msgstr "Twoja autoodpowied¼ zosta³a wy³±czona!"
+
+msgid "Your auto response has been set!"
+msgstr "Twoja autoodpowied¼ zosta³a w³±czona!"
+
+msgid "You already have an auto response configured!"
+msgstr "Masz ju¿ skonfigurowan± autoodpowied¼!"
+
+#: postfixadmin_changepass.php:81
+#: postfixadmin_changepass.php:87
+msgid "The passwords that you supplied don't match!<br />Or are empty!"
+msgstr "Has³a które poda³e¶ nie pasuj± lub s± puste!"
+
+#: postfixadmin_forward.php:70
+#: postfixadmin_forward.php:152
+msgid "To"
+msgstr "Do"
+
+#: postfixadmin_changepass.php:101
+msgid "Unable to change your password!"
+msgstr "Nie mo¿na zmieniæ has³a!"
+
+#: postfixadmin_changepass.php:75
+msgid "You didn't supply your current password!"
+msgstr "Nie poda³e¶ aktualnego has³a!"
+
+#: postfixadmin_changepass.php:96
+msgid "Your password has been changed!"
+msgstr "Twoje has³o zosta³o zmienione!"
+
+msgid "Password current"
+msgstr "Bie¿±ce has³o"
+
+msgid "Password new"
+msgstr "Nowe has³o"
+
+msgid "Password new again"
+msgstr "Powtórz nowe has³o"
+
+msgid "Please sign out and log back again with your new password!"
+msgstr "Wyloguj siê i zaloguj z nowym has³em!"
+
+msgid "I will be away from <date> until <date>. For urgent matters you can contact <contact person>."
+msgstr "Nie bêdê odbieraæ poczty pomiêdzy <data> a <data>. W sprawach pilnych proszê kontaktowaæ siê z <osoba kontaktowa>"
+

BIN
ADDITIONS/squirrelmail-plugin/locale/pt_BR/LC_MESSAGES/postfixadmin.mo


+ 127 - 0
ADDITIONS/squirrelmail-plugin/locale/pt_BR/LC_MESSAGES/postfixadmin.po

@@ -0,0 +1,127 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 2004-01-29 17:35+0100\n"
+"PO-Revision-Date: 2008-10-16 20:30+3\n"
+"Last-Translator: Julio Covolato <julio@psi.com.br>\n"
+"Language-Team: BRAZILIAN PORTUGUESE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: setup.php
+msgid "Forwarding"
+msgstr "Encaminhar"
+
+msgid "Here you can create and edit E-Mail forwards."
+msgstr "Aqui Voc&ecirc; pode criar e editar alias."
+
+msgid "Set an OUT OF OFFICE message or auto responder for your mail."
+msgstr "Configurar mensagem de f&eacute;rias para seu email."
+
+msgid "Change your mailbox password."
+msgstr "Troque a senha de seu email."
+
+#: postfixadmin_changepass.php
+msgid "Alias"
+msgstr ""
+
+msgid "Change Password"
+msgstr "Mudar Senha"
+
+msgid "Change your login password"
+msgstr "Mude sua senha de login"
+
+#: postfixadmin_forward.php
+msgid "Edit Alias"
+msgstr "Editar Alias"
+
+msgid "Edit an alias* for your domain.<br />One entry per line."
+msgstr "Editar um alias* para seu dom&iacute;nio.<br /> Uma entrada por linha."
+
+msgid "The email address that you have entered is not valid:"
+msgstr "Este endere&ccedil;o de email informado n&atilde;o &eacute; v&aacute;lido:"
+
+msgid "Unable to locate alias!"
+msgstr "Alias n&atilde;o encontrado!"
+
+msgid "Unable to modify the alias!"
+msgstr "Imposs&iacute;vel modificar o alias!"
+
+msgid "*Additional forward-aliase always recieve messages BBC!"
+msgstr "*Alias adicionais sempre recebem mensagens em BCC"
+
+msgid "Alias successfully changend!"
+msgstr "Alias alterado com sucesso!"
+
+#: postfixadmin_vacation.php
+msgid "Auto Response"
+msgstr "Auto resposta"
+
+msgid "Going Away"
+msgstr "Ativar"
+
+msgid "Coming Back"
+msgstr "Desativar"
+
+msgid "Options"
+msgstr "Op&ccedil;&otilde;es"
+
+msgid "Out of Office"
+msgstr "Fora do escrit&oacute;rio"
+
+msgid "Subject"
+msgstr "Assunto"
+
+msgid "Body"
+msgstr "Mensagem"
+
+msgid "Your auto response has been removed!"
+msgstr "Sua auto resporta foi removida!"
+
+msgid "Your auto response has been set!"
+msgstr "Sua auto resposta foi ativada!"
+
+msgid "You already have an auto response configured!"
+msgstr "Voc&ecirc; ainda tem uma auto resposta ativa"
+
+#: postfixadmin_changepass.php:81 postfixadmin_changepass.php:87
+msgid "The passwords that you supplied don't match!<br />Or are empty!"
+msgstr "A senha digitada n&atilde;o confere!<br />Ou est&aacute; vazia"
+
+#: postfixadmin_forward.php:70 postfixadmin_forward.php:152
+msgid "To"
+msgstr "Para"
+
+#: postfixadmin_changepass.php:101
+msgid "Unable to change your password!"
+msgstr "Imposs&iacute;vel alterar a sua senha!"
+
+#: postfixadmin_changepass.php:75
+msgid "You didn't supply your current password!"
+msgstr "Voc&ecirc; n&atilde;o forneceu a sua senha atual!"
+
+#: postfixadmin_changepass.php:96
+msgid "Your password has been changed!"
+msgstr "Sua senha foi alterada com sucesso!"
+
+msgid "Password current"
+msgstr "senha atual"
+
+msgid "Password new"
+msgstr "Nova senha"
+
+msgid "Password new again"
+msgstr "Confirme a nova senha"
+
+msgid "Please sign out and log back again with your new password!"
+msgstr "Por favor, saia e entre novamente no webmail com a nova senha"
+
+msgid "I will be away from <date> until <date>. For urgent matters you can contact <contact person>."
+msgstr "Estarei fora do escrit&oacute;rio entre os dias <data> e <data> do m&ecirc;s de <m&ecirc;s>.<br /> Qualquer mensagem urgente, favor enviar para o email <email>."

+ 127 - 0
ADDITIONS/squirrelmail-plugin/po/postfixadmin.po

@@ -0,0 +1,127 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 2004-01-29 17:35+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: setup.php
+msgid "Forwarding"
+msgstr ""
+
+msgid "Here you can create and edit E-Mail forwards."
+msgstr ""
+
+msgid "Set an OUT OF OFFICE message or auto responder for your mail."
+msgstr ""
+
+msgid "Change your mailbox password."
+msgstr ""
+
+#: postfixadmin_changepass.php
+msgid "Alias"
+msgstr ""
+
+msgid "Change Password"
+msgstr ""
+
+msgid "Change your login password"
+msgstr ""
+
+#: postfixadmin_forward.php
+msgid "Edit Alias"
+msgstr ""
+
+msgid "Edit an alias* for your domain.<br />One entry per line."
+msgstr ""
+
+msgid "The email address that you have entered is not valid:"
+msgstr ""
+
+msgid "Unable to locate alias!"
+msgstr ""
+
+msgid "Unable to modify the alias!"
+msgstr ""
+
+msgid "*Additional forward-aliase always recieve messages BBC!"
+msgstr ""
+
+msgid "Alias successfully changend!"
+msgstr ""
+
+#: postfixadmin_vacation.php
+msgid "Auto Response"
+msgstr ""
+
+msgid "Going Away"
+msgstr ""
+
+msgid "Coming Back"
+msgstr ""
+
+msgid "Options"
+msgstr ""
+
+msgid "Out of Office"
+msgstr ""
+
+msgid "Subject"
+msgstr ""
+
+msgid "Body"
+msgstr ""
+
+msgid "Your auto response has been removed!"
+msgstr ""
+
+msgid "Your auto response has been set!"
+msgstr ""
+
+msgid "You already have an auto response configured!"
+msgstr ""
+
+#: postfixadmin_changepass.php:81 postfixadmin_changepass.php:87
+msgid "The passwords that you supplied don't match!<br />Or are empty!"
+msgstr ""
+
+#: postfixadmin_forward.php:70 postfixadmin_forward.php:152
+msgid "To"
+msgstr ""
+
+#: postfixadmin_changepass.php:101
+msgid "Unable to change your password!"
+msgstr ""
+
+#: postfixadmin_changepass.php:75
+msgid "You didn't supply your current password!"
+msgstr ""
+
+#: postfixadmin_changepass.php:96
+msgid "Your password has been changed!"
+msgstr ""
+
+msgid "Password current"
+msgstr ""
+
+msgid "Password new"
+msgstr ""
+
+msgid "Password new again"
+msgstr ""
+
+msgid "Please sign out and log back again with your new password!"
+msgstr ""
+
+msgid "I will be away from <date> until <date>. For urgent matters you can contact <contact person>."
+msgstr ""

+ 128 - 0
ADDITIONS/squirrelmail-plugin/postfixadmin_changepass.php

@@ -0,0 +1,128 @@
+<?php
+require_once(dirname(__FILE__) . '/common.php');
+
+$xmlrpc = get_xmlrpc();
+$user = $xmlrpc->getProxy('user');
+
+global $username;
+
+do_header();
+
+$USERID_USERNAME = $username;
+$tmp = preg_split ('/@/', $USERID_USERNAME);
+$USERID_DOMAIN = $tmp[1];
+
+
+$stMessage = '';
+$tMessage = '';
+$pPassword_admin_text = '';
+$pPassword_password_current_text = '';
+$pPassword_password_text = '';
+$error = 0;
+
+if ($_SERVER['REQUEST_METHOD'] == "POST")
+{
+    //$pPassword_password_text = _("pPassword_password_text");
+    $fPassword_current = $_POST['fPassword_current'];
+    $fPassword = $_POST['fPassword'];
+    $fPassword2 = $_POST['fPassword2'];
+    $username = $USERID_USERNAME;
+
+    if(!$user->login($_SESSION['username'], $_POST['fPassword_current'])) {
+        $error = 1;
+        bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
+        textdomain('postfixadmin');
+        $pPassword_password_current_text = _("You didn't supply your current password!");
+        bindtextdomain('squirrelmail', SM_PATH . 'locale');
+        textdomain('squirrelmail');
+    }
+    $min_length = 0;
+    if(isset($CONF['min_password_length'])) {
+        $min_length = $CONF['min_password_length'];
+    }
+    if (empty ($fPassword) or ($fPassword != $fPassword2) or ($min_length > 0 && strlen($fPassword) < $min_length)) {
+        $error = 1;
+        bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
+        textdomain('postfixadmin');
+        if(empty($fPassword)) {
+            $pPassword_password_text .= _("The passwords that you supplied are empty!");
+        }
+        if($fPassword != $fPassword2) {
+            $pPassword_password_text .= _("The passwords that you supplied don't match!");
+        }
+        if($min_length > 0 && strlen($fPassword) < $min_length) {
+            $pPassword_password_text .= _("The password you supplied is too short!");
+        }
+        bindtextdomain('squirrelmail', SM_PATH . 'locale');
+        textdomain('squirrelmail');
+    }
+
+    if ($error != 1) {
+        $success = $user->changePassword($fPassword_current, $fPassword);
+
+        if ($success) {
+            bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
+            textdomain('postfixadmin');
+            $tMessage = _("Your password has been changed!");
+            $stMessage = _("Please sign out and log back again with your new password!");
+            bindtextdomain('squirrelmail', SM_PATH . 'locale');
+            textdomain('squirrelmail');
+        }
+        else {
+            bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
+            textdomain('postfixadmin');
+            $tMessage = _("Unable to change your password!");
+            bindtextdomain('squirrelmail', SM_PATH . 'locale');
+            textdomain('squirrelmail');
+        }
+    }
+}
+bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
+textdomain('postfixadmin');
+echo "<table bgcolor=\"$color[0]\" align=\"center\" width=\"95%\" cellpadding=\"1\" cellspacing=\"0\" border=\"0\">
+    <tr>
+    <td align=\"center\"><b>". _("Options") ." - ". _("Change Password")." </b>
+    <table align=\"center\" width=\"100%\" cellpadding=\"5\" cellspacing=\"0\" border=\"0\">
+    <tr><td bgcolor=\"$color[4]\" align=\"center\"><br>
+    <table align=\"center\" width=\"95%\" cellpadding=\"4\" cellspacing=\"0\" border=\"0\"><tr>
+    <td bgcolor=\"$color[3]\" align=\"center\"><b>" ._("Change your login password") ."\n
+    </b></td>
+    </tr>
+    <tr>
+    <td bgcolor=\"$color[0]\" align=\"center\"><form name=\"mailbox\" method=\"post\">
+    <b>$tMessage<b><font color=red><br>
+    <a href=\"../../src/signout.php\" target=\"_top\">$stMessage</a>
+    ".$pPassword_admin_text."\n
+    ".$pPassword_password_current_text."\n
+    ".$pPassword_password_text."\n
+    </b><table width=\"95%\" border=\"0\" cellspacing=\"0\" cellpadding=\"2\">
+    <tr>
+    <td width=\"37%\"><b>". _("Alias") . ":\n</td>
+    <td width=\"63%\">{$_SESSION['username']}</td>
+    </tr>
+    <tr>
+    <td><b>". _("Password current"). ":\n</td>
+    <td><input type=\"password\" name=\"fPassword_current\" size=\"30\" /></td>
+    </tr>
+    <tr>
+    <td><b>". _("Password new"). ":\n</td>
+    <td><input type=\"password\" name=\"fPassword\" size=\"30\" /></td>
+    </tr>
+    <tr>
+    <td><b>". _("Password new again"). ":\n</td>
+    <td><input type=\"password\" name=\"fPassword2\" size=\"30\" /></td>
+    </tr>
+    <tr>
+    <td>&nbsp;</td>
+    <td><input type=\"submit\" name=\"submit\" value=\"" ._("Change Password") . "\" /></td>
+    <td>&nbsp;</td>
+    </tr>
+    </table>
+    <TT></TT></FORM></td>
+    </tr><tr><td bgcolor=\"$color[4]\" align=\"left\">&nbsp;</td>
+    </tr></table><BR>
+    </td>
+    </tr></table></td></tr></table>";
+bindtextdomain('squirrelmail', SM_PATH . 'locale');
+textdomain('squirrelmail');
+?>

+ 165 - 0
ADDITIONS/squirrelmail-plugin/postfixadmin_forward.php

@@ -0,0 +1,165 @@
+<?php
+
+require_once(dirname(__FILE__) . '/common.php');
+
+
+
+$USERID_USERNAME = $username;
+$tmp = preg_split ('/@/', $USERID_USERNAME);
+$USERID_LOCALPART = $tmp[0];
+$USERID_DOMAIN = $tmp[1];
+
+$xmlrpc = get_xmlrpc();
+$alias = $xmlrpc->getProxy('alias');
+do_header();
+// Normal page request (GET)
+if ($_SERVER['REQUEST_METHOD'] == "GET")
+{
+    $row = $alias->get();
+    if($row === false) {
+        bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
+        textdomain('postfixadmin');
+        $tMessage = _("Unable to locate alias!");
+        bindtextdomain('squirrelmail', SM_PATH . 'locale');
+        textdomain('squirrelmail');
+        exit(0);
+    }
+}
+
+if ($_SERVER['REQUEST_METHOD'] == "POST")
+{
+    $pEdit_alias_goto = _("To");
+
+    $fGoto = $_POST['fGoto'];
+
+    // reform string into a list...
+    $goto = preg_replace ('/\r\n/', ',', $fGoto);
+    $goto = preg_replace ('/[\s]+/i', '', $goto);
+    $goto = preg_replace ('/\,*$/', '', $goto);
+    $array = preg_split ('/,/', $goto);
+    $error = 0;
+    // check that we have valid addresses in the list
+
+    foreach($array as $key => $email_address) 
+    {
+        if (empty($email_address))
+        {
+            unset($array[$key]);	
+            continue;
+        }
+        if (!check_email($email_address)) 
+        {
+            $error = 1;
+            $tGoto = $goto;
+            bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
+            textdomain('postfixadmin');
+            $tMessage = _("The email address that you have entered is not valid:") . " $email_address</font>";
+            bindtextdomain('squirrelmail', SM_PATH . 'locale');
+            textdomain('squirrelmail');
+        }
+    }
+    if ($error != 1) {
+        $flag = 'forward_and_store'; // goto = $USERID_USERNAME;
+        $success = $alias->update($array, $flag);
+        if(!$success) {
+            bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
+            textdomain('postfixadmin');
+            $tMessage = _("Unable to modify the alias!");
+            bindtextdomain('squirrelmail', SM_PATH . 'locale');
+            textdomain('squirrelmail');
+        }
+        else {
+
+            bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
+            textdomain('postfixadmin');
+            echo "<p align=center><b>". _("Alias successfully changed!"). "\n</b></p>";
+            bindtextdomain('squirrelmail', SM_PATH . 'locale');
+            textdomain('squirrelmail');
+            echo "<p align=center><a href=\"javascript:history.go(-1)\">". _("Click here to go back") ."</a></p>";
+            exit;
+        }
+    }
+}
+bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
+textdomain('postfixadmin');
+
+if(!isset($tMessage)) {
+    $tMessage = '';
+}
+echo "<table bgcolor=\"$color[0]\" align=\"center\" width=\"95%\" cellpadding=\"1\" cellspacing=\"0\" border=\"0\">
+<tr>
+<td align=\"center\" bgcolor=\"$color[0]\" colspan=\"2\">
+<b>". _("Options") ." - ". _("Edit Alias"). " </b>
+<table align=\"center\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">
+<tr>
+<td bgcolor=\"$color[4]\" align=\"center\">
+<table align=\"center\" width=\"100%\">
+<tr>
+<td align=\"left\">". _("Edit an alias* for your email address.<br />One entry per line."). " </td>
+</tr>
+<tr>
+<td align=\"left\">". _("*Additional forward-aliases always receive messages BCC!"). "\n
+</tr>
+<tr>
+<td align=\"left\">" . _("To remove an alias, simply delete its line from the text box.") . "</td>
+</tr>
+</table>
+<table align=\"center\" width\"95%\" cellpadding=\"5\" cellspacing=\"1\">
+<form name=\"mailbox\" method=\"post\">
+<tr>
+<td bgcolor=\"$color[3]\" align=\"center\"><b>". _("Edit Forwards"). "</b>
+</td>
+</tr>
+<tr>
+<td bgcolor=\"$color[5]\" align=\"center\">$tMessage
+<table cellpadding=\"5\" cellspacing=\"1\">
+<tr>
+<th align=\"left\">". _("Alias"). ":\n
+</th>
+<td align=\"left\">" . $_SESSION['username'] . "</td>
+</tr>
+<tr>
+<th>&nbsp;</th>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<th align=\"left\" valign=\"top\">". _("To"). ":\n</th>
+<td>
+<textarea rows=\"8\" cols=\"50\" name=\"fGoto\">";
+bindtextdomain('squirrelmail', SM_PATH . 'locale');
+textdomain('squirrelmail');
+$aliases = $alias->get();
+foreach($aliases as $address) {
+    if ($address == "" || $address == NULL) { continue; }
+    print "$address\n";
+}
+bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
+textdomain('postfixadmin');
+echo "
+</textarea>
+</td>
+</tr>
+<tr>
+<th>&nbsp;</th>
+<td>&nbsp;</td>
+</tr>
+<tr>
+<th>&nbsp;</th>
+<td align=\"left\"colspan=\"2\">
+<input type=\"submit\" name=\"submit\" value=\"" . _("Edit Alias") . "\">
+</td>
+</tr>
+</table>
+</td>
+</tr>
+</table>
+</form>
+</td>
+</tr>
+</table>
+</td></tr>
+</table>
+";
+bindtextdomain('squirrelmail', SM_PATH . 'locale');
+textdomain('squirrelmail');
+?>

+ 157 - 0
ADDITIONS/squirrelmail-plugin/postfixadmin_vacation.php

@@ -0,0 +1,157 @@
+<?php
+
+require_once(dirname(__FILE__) . '/common.php');
+
+$xmlrpc = get_xmlrpc();
+$vacation = $xmlrpc->getProxy('vacation');
+
+$VACCONFTXT = _("I will be away from <date> until <date>. For urgent matters you can contact <contact person>.");
+bindtextdomain('squirrelmail', SM_PATH . 'locale');
+textdomain('squirrelmail');
+$VACCONF = <<<EOM
+$VACCONFTXT
+EOM;
+
+do_header();
+
+$USERID_USERNAME = $username;
+$tmp = preg_split ('/@/', $USERID_USERNAME);
+$USERID_DOMAIN = $tmp[1];
+
+if ($_SERVER['REQUEST_METHOD'] == "GET")
+{
+    $details = $vacation->getDetails();
+    if($vacation->checkVacation()) {
+
+        bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
+        textdomain('postfixadmin');
+        $tMessage = _("You already have an auto response configured!");
+        bindtextdomain('squirrelmail', SM_PATH . 'locale');
+        textdomain('squirrelmail');
+        bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
+        textdomain('postfixadmin');
+        echo "<table bgcolor=\"#b8cbdc\" align=\"center\" width=\"95%\" cellpadding=\"1\" cellspacing=\"0\" border=\"0\"><tr>
+            <td align=\"center\"><b>". _("Options") ." - ". _("Auto Response") ."</b>
+            <table align=\"center\" width=\"100%\" cellpadding=\"5\" cellspacing=\"0\" border=\"0\">
+            <tr><td bgcolor=\"$color[4]\" align=\"center\"><br>
+            <table align=\"center\" width=\"70%\" cellpadding=\"4\" cellspacing=\"0\" border=\"0\"><tr>
+            <td bgcolor=\"$color[3]\" align=\"center\"><b>". _("Auto Response") ."\n
+            </b></td></tr><tr>
+            <td bgcolor=\"$color[0]\" align=\"center\"><form name=\"vacation\" method=\"post\">
+            <table width=\"95%\" border=\"0\" cellspacing=\"0\" cellpadding=\"2\">
+            <tr>
+            <td><center>$tMessage<p></center></td>
+            </tr>
+            <tr>
+            <td> <div align=\"center\">
+            <input type=\"submit\" name=\"fBack\" value=\"" . _("Coming Back"). "\" />
+            </div></td>
+            </tr>
+            </table>
+            <TT></TT></FORM>
+            </td>
+            </tr><tr><td bgcolor=\"$color[4]\" align=\"left\">&nbsp;</td>
+            </tr></table><BR></td></tr></table></td></tr></table>";
+        bindtextdomain('squirrelmail', SM_PATH . 'locale');
+        textdomain('squirrelmail');
+    }
+    else
+    {
+        $tSubject = "Out of Office";
+        $tSubject = $details['subject'];
+        $VACCONF = $details['body'];
+
+        $tMessage = '';
+        bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
+        textdomain('postfixadmin');
+        echo "<table bgcolor=\"$color[0]\" align=\"center\" width=\"95%\" cellpadding=\"1\" cellspacing=\"0\" border=\"0\">
+            <tr>
+            <td align=\"center\"><b>". _("Options") ." - ". _("Auto Response") ." </b>
+            <table align=\"center\" width=\"100%\" cellpadding=\"5\" cellspacing=\"0\" border=\"0\">
+            <tr><td bgcolor=\"$color[4]\" align=\"center\"><br>
+            <table align=\"center\" width=\"70%\" cellpadding=\"4\" cellspacing=\"0\" border=\"0\"><tr>
+            <td bgcolor=\"$color[3]\" align=\"center\"><b>" . _("Auto Response") ."\n
+            </b></td></tr><tr>
+            <td bgcolor=\"$color[0]\" align=\"center\"><form name=\"vacation\" method=\"post\">$tMessage
+            <table width=\"95%\" border=\"0\" cellspacing=\"0\" cellpadding=\"2\"><tr>
+            <td width=\"23%\">". _("Subject") .":\n</td>
+            <td width=\"2%\">&nbsp;</td>
+            <td width=\"69%\"><input type=\"text\" name=\"fSubject\" value=\"" . $tSubject . "\" /></td>
+            <td width=\"2%\">&nbsp;</td>
+            <td width=\"4%\">&nbsp;</td>
+            </tr><tr>
+            <td>". _("Body") .":\n</td>
+            <td>&nbsp;</td>
+            <td><textarea rows=\"10\" cols=\"80\" name=\"fBody\">$VACCONF\n
+            </textarea></td><td>&nbsp;</td><td>&nbsp;</td></tr><tr><td>&nbsp;</td><td>&nbsp;</td>
+            <td><input type=\"submit\" name=\"fAway\" value=\"" . _("Going Away") . "\" /></td>
+            <td>&nbsp;</td><td>&nbsp;</td></tr>
+            </table><TT></TT></FORM></td>
+            </tr><tr><td bgcolor=\"$color[4]\" align=\"left\">&nbsp;</td>
+            </tr></table><BR></td></tr></table></td></tr></table>";
+        bindtextdomain('squirrelmail', SM_PATH . 'locale');
+        textdomain('squirrelmail');
+    }
+}
+
+if ($_SERVER['REQUEST_METHOD'] == "POST")
+{
+    $fBack = null;
+    $fAway = null;
+    foreach(array('fBack', 'fAway', 'fSubject', 'fBody') as $key) {
+        $$key = null;
+        if(isset($_POST[$key])) {
+            $$key = $_POST[$key];
+        }
+    }
+    
+    if (!empty($fBack))
+    {
+        $success = $vacation->remove();
+
+        if(!$success)
+        {
+            bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
+            textdomain('postfixadmin');
+            $tMessage = _("Unable to update your auto response settings!");
+            echo "<p>This may signify an error; please contact support (1)</p>";
+            bindtextdomain('squirrelmail', SM_PATH . 'locale');
+            textdomain('squirrelmail');
+        }
+        else
+        {
+            bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
+            textdomain('postfixadmin');
+            echo "<p align=center><b>". _("Your auto response has been removed!") ."</b></p>";
+            bindtextdomain('squirrelmail', SM_PATH . 'locale');
+            textdomain('squirrelmail');
+
+        }
+    }
+
+    if (!empty ($fAway))
+    {
+        // add record into vacation
+        $success = $vacation->setAway($fSubject, $fBody);
+
+        if(!$success) {
+            $error = 1;
+            bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
+            textdomain('postfixadmin');
+            $tMessage = _("Unable to update your auto response settings!");
+            bindtextdomain('squirrelmail', SM_PATH . 'locale');
+            textdomain('squirrelmail');
+        }
+        else
+        {
+            bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
+            textdomain('postfixadmin');
+            echo "<p align=center><b>". _("Your auto response has been set!") ."</b></p>";
+            bindtextdomain('squirrelmail', SM_PATH . 'locale');
+            textdomain('squirrelmail');
+
+        }
+    }
+}
+
+?>

+ 61 - 0
ADDITIONS/squirrelmail-plugin/setup.php

@@ -0,0 +1,61 @@
+<?php
+// vim:ts=4:sw=4:et
+include_once(SM_PATH . 'functions/i18n.php');
+
+function squirrelmail_plugin_init_postfixadmin() {
+    include(dirname(__FILE__) . '/config.php');
+    global $squirrelmail_plugin_hooks;
+
+    $squirrelmail_plugin_hooks['optpage_register_block']['postfixadmin'] = 'postfixadmin_optpage_register_block';
+
+}
+
+function postfixadmin_version(){
+    return '2.3.0';
+}
+
+function postfixadmin_optpage_register_block () {
+    // Gets added to the user's OPTIONS page.
+    global $optpage_blocks;
+    global $AllowVacation;
+    global $AllowChangePass;
+
+    //  if ( !soupNazi() ) {
+
+    bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
+    textdomain('postfixadmin');
+    $optpage_blocks[] = array (
+        'name' => _("Forwarding"),
+        'url'  => '../plugins/postfixadmin/postfixadmin_forward.php',
+        'desc' => _("Here you can create and edit E-Mail forwards."),
+        'js'   => FALSE
+    );
+    bindtextdomain('squirrelmail', SM_PATH . 'locale');
+    textdomain('squirrelmail');
+
+    bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
+    textdomain('postfixadmin');
+    if($AllowVacation) {
+        $optpage_blocks[] = array(
+            'name' => _("Auto Response"),
+            'url'  => '../plugins/postfixadmin/postfixadmin_vacation.php',
+            'desc' => _("Set an OUT OF OFFICE message or auto responder for your mail."),
+            'js'   => false
+        );
+        bindtextdomain('squirrelmail', SM_PATH . 'locale');
+        textdomain('squirrelmail');
+    }
+    bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
+    textdomain('postfixadmin');
+    if($AllowChangePass) {
+        $optpage_blocks[] = array(
+            'name' => _("Change Password"),
+            'url'  => '../plugins/postfixadmin/postfixadmin_changepass.php',
+            'desc' => _("Change your mailbox password."),
+            'js'   => false
+        );
+        bindtextdomain('squirrelmail', SM_PATH . 'locale');
+        textdomain('squirrelmail');
+    }
+}
+?>

+ 2 - 0
ADDITIONS/squirrelmail-plugin/version

@@ -0,0 +1,2 @@
+postfixadmin
+2.3.0

+ 185 - 0
ADDITIONS/virtualmaildel.php

@@ -0,0 +1,185 @@
+<?php
+//
+// Virtual Mail Delete
+// by George Vieira <george at citadelcomputer dot com dot au>
+//
+// You can run this from your crontab with something like
+//
+// 0 4 * * * *    vmail    php -q virtualmaildel.php >/dev/null
+
+	//
+	// Setup location of postfixadmin config files. Needed to login to mysql
+	//
+	$conf		= '/home/httpd/mail/admin/config.inc.php';
+
+	//
+	// Where's the homedir accounts stored. (GET THIS RIGHT OTHERWISE IT THINK NONE EXIST AND DELETES ALL)
+	//
+	$homedir	= '/home/virtual';
+
+	//
+	// Make sure everything is everything before continuing
+	//
+	if ( ! file_exists( $conf ) )
+		die( "Cannot find config file $conf\n" );
+
+	if ( ! is_dir( $homedir ) )
+		die( "Cannot find home directory for virtual mailboxes in $homedir\n" );
+
+	//
+	// Load mysql authentication from postfixadmin
+	//
+	include( $conf );
+
+	//
+	// Recursive Delete Function
+	//
+	function deldir($dir)
+	{
+		$current_dir = opendir($dir);
+		while($entryname = readdir($current_dir))
+		{
+			if(is_dir("$dir/$entryname") and ($entryname != "." and $entryname!=".."))
+			{
+				deldir("${dir}/${entryname}");
+			}
+			elseif($entryname != "." and $entryname!="..")
+			{
+				unlink("${dir}/${entryname}");
+			}
+		}
+		closedir($current_dir);
+		@rmdir(${dir});
+	}
+
+// --- Main Start ---
+
+	//
+	// Get list of directories
+	//
+	$fr = opendir( $homedir );
+	while ( ($domain = readdir($fr)) !== false)
+	{
+		//
+		// Check if it's a dir
+		//
+		if ( $domain != "." and $domain != ".." and filetype($homedir .'/'. $domain) == "dir" )
+		{
+			//
+			// Open the (assumed) DOMAIN directory
+			//
+			$ff = opendir( $homedir .'/'. $domain );
+			while ( ($user = readdir($ff)) !== false)
+			{
+				//
+				// Check for directories assuming it's a user account
+				//
+				if ( $user!="." and $user!=".." and filetype($homedir .'/'. $domain .'/'. $user) == "dir" )
+				{
+					//
+					// if the dir 'new' exists inside then it's an account
+					//
+					if ( file_exists($homedir .'/'. $domain .'/'. $user .'/'. "new") )
+					{
+						$dir[$domain][$user] = "";
+					}
+					else
+					{
+						//
+						// Alert that the dir doesn't have a 'new' dir, possibly not an account. Leave it.
+						//
+						echo "UNKNOWN  : " . $homedir ."/". $domain ."/". $user ."/new NOT FOUND. Possibly not an account. Leaving untouched\n";
+					}
+				}
+			} 
+		}
+	} 
+	//
+	// OK, got an array of accounts from the dir, Now connect to the DB and check them
+	//
+	$conx = mysql_connect( $CONF['database_host'],$CONF['database_user'],$CONF['database_password'] );
+	//
+	// Is there a problem connecting?
+	//
+	if ( $conx != false )
+	{
+		//
+		// Select the database
+		//
+		mysql_select_db( $CONF['database_name'] , $conx) or die ("Can't access database postfix : " . mysql_error()); 
+
+		//
+		// Select all mailboxes to verify against dirs listed in array
+		//
+		$query = "SELECT * FROM mailbox";
+		$result = mysql_query( $query );
+
+		//
+		// Query the mailbox table
+		//
+		if ( $result != false )
+		{
+			//
+			// Fetch the list of results
+			//
+			while ( $row = mysql_fetch_assoc( $result ) )
+			{
+				//
+				// Pull apart the maildir field, needed to figure out the directory structure to compare
+				//
+				$strip = explode("/",$row['maildir']);
+				//
+				// Unset the array if it exists. This stops it being erased later.
+				//
+				unset( $dir[ $strip[0] ][ $strip[1] ] );
+			}
+			//
+			// If there are results. unset the domain too.
+			//
+			if ( count($dir[$strip[0]])==0 and mysql_num_rows($result)>0 )
+				unset( $dir[$strip[0]] );
+		}
+		else
+			die( "Failed SELECT in mailboxes\n" );
+	}
+	else
+		die( 'Cannot connect to the database!\n' );
+
+	//
+	// OK, time to clean up. All known users/domains have been removed from the list.
+	//
+
+	//
+	// If the array still exists (incase nothing there)
+	//
+	if ( is_array($dir) )
+	{
+		//
+		// Go through each dir
+		//
+		foreach ( $dir as $key => $value )
+		{
+			//
+			// Is this a user array?
+			//
+			if ( is_array( $value) )
+			{
+				//
+				// Go through and nuke the folders
+				//
+				foreach ( $value as $user => $value2 )
+				{
+					//
+					// Nuke.. need any more explanations?
+					//
+					echo "REMOVING : " . $homedir."/".$key."/".$user."\n" ;
+					deldir( $homedir."/".$key."/".$user ) ;
+				}
+			}
+		}
+	}
+	//
+	// And we are outta here....
+	//
+	echo "Cleanup process completed\n";
+?>

+ 987 - 0
CHANGELOG.TXT

@@ -0,0 +1,987 @@
+# Postfix Admin
+#
+# LICENSE
+# This source file is subject to the GPL license that is bundled with
+# this package in the file LICENSE.TXT.
+#
+# Further details on the project are available at http://postfixadmin.sf.net
+#
+# Last update:
+# $Id: CHANGELOG.TXT 1801 2015-09-26 13:11:20Z christian_boltz $
+
+Version 3.0 beta3 (2.93) - 2015/09/26 - SVN r1802
+-------------------------------------------------
+
+  Summary of major changes:
+  - add list.php and list.tpl for displaying lists
+    - based on *Handler $struct, which means list view can now be customized with
+      $CONF[*_struct_hook] functions (columns with display_in_list and non-empty
+      label will be displayed)
+    - add CSV export
+    - replaces list-domain.php, list-admin.php and fetchmail.php (including their
+      *.tpl files) and the alias and alias domain lists in list-virtual
+    - improved / more detailed search support by using URL parameters
+      (list.php?search[field]=value, optionally also ?searchmode[field]=< -
+      no pretty search form yet, limited to fields the user/admin can access)
+    - only display search input box if search fields are specified in *handler
+      (that effectively means no search box for admin, domain and fetchmail listings)
+    - can also be used for users (non-admins)
+  - add FetchmailHandler (replaces fetchmail.php and its template), which also
+    means postfixadmin-cli can configure fetchmail jobs now
+  - add $CONF['fetchmail_struct_hook']
+  - remove unused $CONF['users_domain_controle']
+
+  PFAHandler:
+  - new field types:
+    - enma - associative array (value => displayed value), must be specified in
+      the "options" column
+    - html - raw HTML, used for mailbox status markers which include HTML tags
+    - b64p - passwords stored as base64, used by FetchmailHandler
+    - vtxt, vnum - "virtual", read-only text/integer
+    - quot - formatted quota ("5/10", read-only)
+  - automatically skip quot, vtxt and vnum fields in store()
+  - add handling of users (non-admins), including permission checks
+  - add and use $this->label_field and $this->label for nicer messages
+  - add $this->order_by to allow ordering by any field(s)
+  - add getMsg() function (needed by list.php)
+  - add $msg['can_create'] (true by default, false will hide the 'create' button)
+  - add $is_superadmin to make admin vs. superadmin easier to handle
+  - add $can_edit and $can_delete (only available in edit/delete mode, set by
+    init() based on the '_can_edit' and '_can_delete' from database query)
+  - add $searchfields[] (list of fields to search by default, $search[_])
+  - add $this->msg['show_simple_search'] (true if $searchfields is non-empty)
+  - split off build_select_query() (also used for pagebrowser) from read_from_db()
+    and add support for $search['_'] (searching in $searchfields[])
+  - read_from_db(), getList(): add $searchmode parameter (_before_ $limit and
+    $offset!) to be able to use query different query modes, not only "="
+  - add getPagebrowser() (returns an array of pagebrowser keys)
+
+  AdminHandler:
+  - switch to using list.php (replaces list-admin.php)
+
+  DomainHandler:
+  - reduce required permissions to 'admin', restrict write operations to superadmins
+  - add optical quota indicators for aliases, mailboxes and domain quota
+  - fix counting of aliases for domains without any mailbox
+  - use list.php for displaying domain list (replaces list-domain.php)
+
+  MailboxHandler:
+  - check_quota(): deny creating an unlimited mailbox if domain quota is set
+  - storemore(): store maildir in the correct variable to fix running
+    mailbox_postedit script (bug#342)
+
+  AliasHandler:
+  - read_from_db_postprocess(): disable _can_edit and _can_delete for default
+    aliases if special_alias_control is off and not superadmin
+  - add 'status' column, move gen_show_status handling for aliases from
+    list-virtual into AliasHandler db_read_from_db_potprocess()
+  - change getList() to work with empty $condition
+  - add getPagebrowser() to filter out mailboxes
+
+  edit.php:
+  - Newer PHP versions (noticed with 5.6.6) don't include empty fields in
+    $_POST, which broke changing a field to empty. Make sure all !isset()
+    fields are set to ''.
+  - for not-set bool values, set $values instead of the (wrong) $inp_values
+  - add user (non-admin) mode
+
+  delete.php:
+  - allow users (non-admins) to use delete.php (not used in PostfixAdmin yet)
+
+  list-virtual:
+  - use AliasHandler, AliasdomainHandler and list.tpl for aliases and alias
+    domains (the mailbox list still uses the old code)
+  - replace $alias_pagebrowser_query and the create_page_browser() call
+    with $handler->getPagebrowser()
+  - adjust search to use ?search[_]=...
+  - drop $check_alias_owner variable and check_alias_owner() call
+    (replaced by the code added in AliasHandler)
+
+  misc:
+  - translation updates: cs (patch#126), pl (by marcin-github), sv (patch#128)
+  - add CliScheme.php to display the database scheme (for usage in upgrade.php)
+  - error_log() a warning if nameserver queries in check_domain() take more than 2
+    seconds in total
+  - add functions db_quota_text() and db_quota_percent() to generate SQL queries
+    for used quota ("x/y" and percentage)
+  - pacol(): replace $not_in_db with $multiopt - the remaining parameters can be
+    specified as associative array (backwards-compatible). Also add $linkto parameter
+  - db_where_clause(): add $additional_raw_where and $searchmode parameters,
+    split query into WHERE and HAVING
+  - delete no longer used check_alias_owner() function
+  - display "view log" menu entry only if logging is enabled (patch#127)
+  - smarty.inc.php assign(): additionally provide the unsanitized values as RAW_$key
+  - setup.php: after creating a superadmin, display a note that the setup is done
+    and it's possible to login now
+  - setup.php: stop relying on subversion keyword for database upgrades
+  - explictly set session_cache_limiter to nocache (bug#347)
+  - fetchmail.pl: honor the (newly added) active column
+  - change fetchmail.date field to date (no auto-update) (bug#351)
+  - several small changes and fixes at various places - too many to list them here
+
+Version 3.0 beta2 (2.92) - 2014/10/28 - SVN r1706
+-------------------------------------------------
+
+  - AliasHandler: don't clean goto field when making alias inactive (bug#316)
+  - list-virtual: display quota even if $CONF[used_quotas] == NO (bug#307)
+  - vacation.pl: fix postgresql queries in vacation.pl (bug#315)
+  - fix query in AliasHandler getList() which caused an empty list and breaks
+    deletion of aliases in MariaDB (bug#313, bug#325)
+  - fetchmail.pl: fix ssl extra options (cert check, cert path, fingerprint)
+  - fix logging (run setup.php to fix old log entries) (bug#317)
+  - fetchmail.php: change error_reporting() to exclude E_NOTICE (bug#322)
+  - translation updates: fr (patch#123), nl (patch#122)
+  - $CONF[default_aliases] can now use the new domain as alias target (patch#124)
+  - check that vacation start/end date are not in the past (patch#122)
+  - update vacation INSTALL.TXT with more secure locations
+  - update Smarty to 3.1.21
+
+Version 3.0 beta1 (2.91) - 2014/05/06 - SVN r1670
+-------------------------------------------------
+
+  Summary of major changes:
+  - new command-line interface "postfixadmin-cli"
+  - major rewrite:
+    - move lots of code into *Handler classes, which are used by web and
+      command-line interface
+    - replace various edit-*.php and create-*.php with a generic editform
+      (edit.php/editform.tpl)
+    - this also means it's easy to customize forms, add fields etc.
+      (see $CONF['*_struct_hook'])
+    - lots of code cleanup, remove/merge lots of duplicated code and templates
+    - use smarty for templates
+  - add ability to choose activation date, end date and reply interval for
+    vacation message
+  - various enhancements everywhere
+  - redesign login page, list and edit pages (goodbye, green!) and make them wider
+  - several new config options and changed defaults
+  - NOTE: changes from the 2.3.x releases also apply to this version
+
+  new config options:
+  - $CONF['language_hook']
+    Hook function to override or add translations to $PALANG.
+    Example hook function included (commented out).
+  - $CONF['password_validation'] - array with regular expressions to check
+    if a password is valid/good enough.
+    The default configuration enforces:
+    - minimum length 5 characters/digits/whatever
+    - at least 2 characters
+    - at least 2 digits
+  - $CONF['*_struct_hook'] - make $struct in the *Handler classes customizeable
+  - $CONF['vacation_choice_of_reply'] - list of reply interval options
+  - $CONF['domain_quota'] - total quota per domain
+  - $CONF['theme_custom_css'] - to add some custom CSS without editing the
+    default CSS file
+  - $CONF['motd_*'] - replaces motd*.txt
+
+  changed config defaults (with their new default value):
+  - $CONF['database_type'] = 'mysqli';
+  - $CONF['dovecotpw'] = "/usr/sbin/doveadm pw";
+    $CONF['new_quota_table'] = 'YES'; (for dovecot 2)
+  - $CONF['domain_path'] = 'YES'; $CONF['domain_in_mailbox'] = 'NO';
+    (results in domain.tld/username/ maildirs)
+  - $CONF['alias_control'] = 'YES'; $CONF['alias_control_admin'] = 'YES';
+  - $CONF['backup'] = 'NO';
+  - $CONF['show_status']='YES'; $CONF['show_status_key']='YES';
+    $CONF['show_undeliverable']='YES'; $CONF['show_popimap']='YES';
+    $CONF['show_undeliverable_exceptions'] - "gmail.com" removed
+  - $CONF[*_post*_script] - add empty defaults
+  - $CONF['admin_email'] = ''
+    IMPORTANT: If set, this will be used as mail sender for all mails
+    (2.3.x used the currently logged in admin's username in most cases).
+    $CONF['admin_email'] = '' will match the 2.3.x behaviour.
+
+  removed config options:
+  - $CONF['min_password_length'] - now handled in /.{5}/ in
+    $CONF['password_validation']
+  - $CONF['postfix_admin_url'] - relative paths are now used everywhere
+
+  list-virtual.php:
+  - display percentage of quota usage
+  - display alias domains less confusing (using From/To)
+  - list-virtual can now display only mailboxes, only aliases or only alias
+    domains - or all in one page as in 2.3
+  - extreme speedup of page browser in list-virtual if a large number of
+    mailboxes or aliases exist
+  - include search support (replaces search.php and brings various bug fixes
+    for free)
+  - fix: delivery to mailbox with a recipient delimiter (mailbox+foo@domain)
+    was marked as "forward only"
+  - fix: don't mark mailboxes with vacation active as undeliverable
+  - fix: undeliverable targets were not flagged if another target pointed to a
+    domain in $CONF[show_undeliverable_exceptions]
+
+  fetchmail.php, fetchmail.pl:
+  - add sslcertck, sslcertpath, sslfingerprint fields/check
+    (sslcertpath and sslfingerprint require $CONF[fetchmail_extra_options]
+    because they don't have input validation)
+
+  functions.inc.php
+  - allowed_quota: if $CONF[quota] == NO, just return 0 (unlimited)
+  - authentification_get_username() - honor POSTFIXADMIN_SETUP to avoid
+    a redirect to login.php after creating an admin with setup.php and to
+    get "SETUP.PHP" for db_log()
+  - check_domain(), check_email(): instead of calling flash_error(),
+    return string with error message - or empty string if everything is ok
+  - check_email():
+    - replace $CONF[vacation_domain] only at the end of the mail address
+    - don't trim() mail address to avoid that aliases starting with a space are
+      allowed. This fixes http://sourceforge.net/p/postfixadmin/bugs/210/
+  - check_language(): remove things like ";q=0.8" before checking if
+    a language exists
+  - check_owner():
+    - escape_string() $username and $domain to prevent SQL injections
+  - db_pgsql() - new function to replace lots of
+    "if ($CONF[database_type] == 'pgsql')) checks
+  - db_delete(): allow to specify additional conditions for the WHERE clause
+  - db_get_boolean(): allow 0 and 1 as parameters, not only boolean true/false
+  - db_log():
+    - allow log actions create_admin and edit_admin
+    - add edit_admin_state and delete_admin as comment/reminder that they
+      should also be logged
+  - db_query(): error_log() failed query
+  - db_where_clause($condition, $struct) - new function to create a WHERE clause
+    (bool values are converted with db_get_boolean() based on $struct)
+  - _flash_string():
+    - also accept an array of messages, not only a string
+    - html-escape messages to fix XSS if the message contains user-supplied input
+  - generate_password(): make generated password always 8 chars long
+    (instead of $CONF['min_password_length'])
+  - get_domain_properties(): use DomainHandler (function result mostly
+    unchanged, only difference: instead of quota_sum in bytes it now
+    returns total_quota in MB)
+  - list_domains_for_admin():
+    - rewrite to work for superadmins also (will list all domains now
+      instead of "ALL"), which means we can drop the admin vs. superadmin
+      check at various places
+  - pacrypt():
+    - no longer escape_string() the result. This fixes
+      http://sourceforge.net/p/postfixadmin/bugs/218/
+    - for 'system' encryption, use full hashed password as salt
+      https://sourceforge.net/p/postfixadmin/bugs/2/
+    - dovecot:*:
+      - add support for dovecot *-CRYPT passwords (needs dovecot >= 2.1)
+      - allow "." in dovecot method (to allow a suffix like ".b64")
+      - Also, the {METHOD} part is no longer removed (passwords without
+        {METHOD} still work)
+  - remove_from_array() - new function
+  - safesession() - new function (like safeget(), but for $_SESSION)
+  - smtp_mail(): error_log() the error message if fsockopen() fails
+  - table_by_key() now always prepends $CONF['database_prefix']
+    NOTE: If you have/had an incomplete database_tables array and use
+    $CONF['database_prefix'], you might need to rename the affected tables
+    manually (add the database_prefix in their name).
+  - moved several functions to the *Handler classes
+  - deleted no longer used functions:
+    - admin_exist()
+    - authentication_is_admin()
+    - authentication_is_user()
+    - boolconf() (moved to Config::bool())
+    - check_string()
+    - create_admin()
+    - check_alias() (moved to AliasHandler->create_allowed())
+    - db_boolean_to_int()
+    - domain_exist()
+    - get_admin_properties()
+    - get_mailbox_properties()
+  - get rid of global $table_* variables, use table_by_key() instead
+
+  PFAHandler.php:
+  - parent class for all *Handler classes
+  - contains code shared between all classes
+
+  AdminHandler.php:
+  - Handler class for admins
+  - for now, set the superadmin column and add "ALL" in domain_admins to
+    keep the database backwards-compatible with 2.3.x
+
+  AdminpasswordHandler.php:
+  - used for the "change password" form for admins
+
+  DomainHandler.php
+  - handler class for domains
+  - delete(): do not allow to delete a domain if it is an alias domain target
+
+  AliasdomainHandler.php:
+  - handler class for alias domains
+  - alias domains can now be edited
+
+  AliasHandler.php:
+  - rewrite based on PFAHandler
+  - we even get a "deliver to local mailbox" checkbox :-)
+  - only allow @domain as target if $this->id is a catchall
+  - remove deprecated functions:
+    - get()
+    - hasStoreAndForward()
+    - update()
+    - is_mailbox_alias()
+    - is_vacation_address()
+    - hasAliasRecord()
+
+  MailboxHandler (previously named UserHandler in 2.3):
+  - rewrite based on PFAHandler
+  - drop old __construct(), view() and change_pass()
+  - replace check of old password in change_pw() with $this->login
+  - delete(): also cleanup fetchmail, quota and quota2 tables
+  - always check password with validate_password()
+  - always display correct available quota (using allowed_quota())
+  - do not escape the password coming from $_POST. Fixes
+    http://sourceforge.net/p/postfixadmin/bugs/218/
+
+  VacationHandler:
+  - rewrite based on PFAHandler (not useable yet)
+  - add ability to choose activation date, end date and reply interval for
+    vacation message - http://sourceforge.net/p/postfixadmin/patches/111/
+
+  vacation.pl:
+  - allow to use original subject in vacation reply subject ("Re: $SUBJECT")
+    http://sourceforge.net/p/postfixadmin/patches/117/
+  - encode subject - https://sourceforge.net/p/postfixadmin/bugs/272/ ,
+    https://sourceforge.net/p/postfixadmin/patches/119/
+  - add a friendly from address to vacation messages ($friendly_from)
+  - make error handling if we cannot send the reply more robust
+  - add $smtp_client config option to specify the helo name
+  - added custom noreply detection ($noreply_pattern, $custom_noreply_pattern)
+
+  Config.php
+  - new class to store $CONF
+  - also used to store $PALANG texts (Config::Lang())
+  - contains functions to read config entries in various ways (bool etc.)
+
+  edit.php
+  - generic edit page for everything (admins, domains, mailboxes, aliases, ...)
+  - use ?table= parameter to decide what will be edited (basically $tableHandler)
+  - read handler-specific configuration from $handler->webformConfig()
+    and use it at various places
+  - always redirect to edit.php?table=$table after adding an item to
+    ensure correct initialization for next item
+  - call $handler->mergeId if $id_field is editable, but not displayed
+    in form (usecase: merge localpart + domain to address)
+  - set $form_fields and $id_field later (after $hander->init()) - needed
+    for AliasHandler to decide if goto_mailbox should be displayed
+  - only set $values if a field is editable and displayed in the form
+
+  editform.tpl:
+  - generic edit form template, uses $struct to render the form
+  - implement handling of 'list' fields (<select> with multiple choices
+    allowed)
+  - also include alternative implementation with checkboxes (commented out)
+
+  upgrade.php
+  - _pgsql_field_exists(), _mysql_field_exists():
+    Those functions are always called with the expanded table name - don't
+    expand it twice. (The better solution would be to change all calling
+    code to provide non-expanded tablenames, but that's more work.)
+  - change {BIGINT} to include "NOT NULL DEFAULT 0"
+  - upgrade_1283(): add a "superadmin" column to the admin table
+    This is the first step to get rid of the "ALL" dummy domain.
+  - upgrade_1284(): migrate the ALL domain to the superadmin column
+    Note: The ALL domain is not (yet) deleted to stay backwards-compatible
+    for now (will be done in a later upgrade function)
+  - change {BOOLEAN} to include "default false"
+
+  login.php
+  - when login.php is requested, logout the current admin/user
+    https://sourceforge.net/p/postfixadmin/bugs/284/
+  - this also means login.php is now used for logout
+  - error_log() failed login attemps
+    https://sourceforge.net/p/postfixadmin/feature-requests/111/
+
+  delete.php, editactive.php:
+  - require token for CSRF protection, see
+    https://sourceforge.net/p/postfixadmin/bugs/269/
+
+  xmlrpc.php:
+  - adopt to *Handler syntax
+  - setAway(): add (optional) new parameters for interval_time, activeFrom and
+    activeUntil - https://sourceforge.net/p/postfixadmin/patches/113/
+  - change $_SESSION['username'] to $_SESSION['sessid']['username']
+
+  *.lang:
+  - get rid of several duplicate texts
+  - removed HTML tags from $PALANG texts
+  - several translation updates
+
+  documentation updates:
+  - SECURITY.TXT: add note about templates_c directory
+  - DOCUMENTS/POSTFIX_CONF.TXT is now executable and can generate the
+    mysql_*.cf maps for postfix
+  - update DOCUMENTS/DOVECOT.TXT for dovecot 2.x
+
+  squirrelmail plugin:
+  - various bugfixes
+  - documentation update
+
+  Debian packaging:
+  - Changed source format to 3.0 (quilt)
+  - simplified the DB credential patch and removing ucf registrations on package
+    purge...
+  - control: added php5-cli dependency
+  - rules:
+    - some permission fixes to postfixadmin-cli scripts
+    - New target prep: Create a needed tar.gz file to build a non-nativ .dpkg
+    - New target build-package: Call this target to build a shiny new .dpkg file
+  - postfixadmin.docs: removed redundant changelog file
+  - debian/postfixadmin.postrm: Call wwwconfig scripts only if they are existing
+
+Version 2.3.7 - 2014/02/20 - SVN r1651 (postfixadmin-2.3 branch)
+----------------------------------------------------------------
+  - SECURITY: fix SQL injection in show_gen_status()
+  - lt.lang, da.lang translation update
+  - when enabling/disabling a mailbox, also update the corresponding alias
+  - fix creating superadmin in setup.php with MariaDB (more strict SQL)
+  - don't trim() mail address to avoid that aliases starting with a space are
+    allowed. This fixes http://sourceforge.net/p/postfixadmin/bugs/210/ and
+    https://sourceforge.net/p/postfixadmin/feature-requests/113/
+  - update regex in check_domain() to support new, longer TLDs like .international
+  - mark vacation_notification.notified field as latin1 to avoid overlong index
+  - vacation.pl: encode subject
+  - vacation.pl: disable use of TLS by default due to a bug in Mail::Sender 0.8.22
+    (you can re-enable it with $smtp_tls_allowed)
+
+Version 2.3.6 - 2013/01/02 - SVN r1417 (postfixadmin-2.3 branch)
+----------------------------------------------------------------
+
+  - display domain and mailbox description with correct encoding
+  - fix footer link
+  - focus username input field in login form
+  - fix double inclusion of config.inc.php in setup.php
+  - fix bool and date handling in fetchmail
+
+Version 2.3.5 - 2012/01/16 - SVN r1335 (postfixadmin-2.3 branch)
+----------------------------------------------------------------
+
+  - fix SQL injection in pacrypt() (if $CONF[encrypt] == 'mysql_encrypt')
+  - fix SQL injection in backup.php - the dump was not mysql_escape()d,
+    therefore users could inject SQL (for example in the vacation message)
+    which will be executed when restoring the database dump.
+    WARNING: database dumps created with backup.php from 2.3.4 or older might
+             contain malicious SQL. Double-check before using them!
+  - fix XSS with $_GET[domain] in templates/menu.php and edit-vacation
+  - fix XSS in some create-domain input fields
+  - fix XSS in create-alias and edit-alias error message
+  - fix XSS (by values stored in the database) in fetchmail list view,
+    list-domain and list-virtual
+  - create-domain: fix SQL injection (only exploitable by superadmins)
+  - add missing $LANG['pAdminDelete_admin_error']
+  - don't mark mailbox targets with recipient delimiter as "forward only"
+  - wrap hex2bin with function_exists() - PHP 5.3.8 has it as native function
+
+Version 2.3.4 - 2011/09/16 - SVN r1180 (postfixadmin-2.3 branch)
+----------------------------------------------------------------
+
+  - generate more secure random passwords
+  - squirrelmail plugin: fix typo in variable name
+  - list-domain: fix SELECT query to work with PgSQL even when using custom fields
+  - create-domain: force domain name to lowercase to avoid problems with PgSQL
+    foreign keys
+  - fix vacation.pl to log to "mail" syslog facility
+  - error_log() dovecotpw error messages
+
+Version 2.3.3 - 2011/03/14 - SVN r1010 (postfixadmin-2.3 branch)
+----------------------------------------------------------------
+
+  - create-alias: allow multiple alias targets
+  - create-alias, edit-alias: prevent input data loss on validation errors
+  - list-virtual: fix displaying of 'modified' column for aliases when using
+    postgres
+  - replaced deprecated split() with preg_split() or explode()
+  - functions.inc.php: better error messages when database functions are missing
+  - create domain: fixed typo in variable name that broke the default value for
+    default aliases
+  - postgres: changed mailbox.quota, domain.quota and domain.maxquota fields
+    to bigint to allow mailboxes >4 GB (run setup.php to upgrade your database)
+  - vacation.pl logged literal $variable instead of the variable content at two
+    places
+  - edit-vacation: log enabling/disabling vacation if done by admins
+  - POSTFIX_CONF.txt: fixed filename for quota map
+  - config.inc.php: removed double $CONF['database_prefix']
+  - config.inc.php: fixed comments about domain_post* script parameters
+  - updated INSTALL.TXT and UPGRADE.TXT
+  - sk translation update
+  - some more minor fixes
+
+Version 2.3.2 - 2010/08/24 - SVN r860 (postfixadmin-2.3 branch)
+---------------------------------------------------------------
+
+  - SUMMARY: PostfixAdmin 2.3.2 is a bugfix-only release for Postfix Admin 2.3.1
+  - SECURITY: attackers could find out if a admin exists (login pre-filled the
+    username after "only" a wrong password was entered)
+  - SECURITY: fix sql injection in list-domain (only exploitable by superadmins)
+  - alias targets in users/edit-alias are now validated
+  - invalid alias targets in users/edit-alias are shown to the user again
+    instead of dropping them
+  - fix dovecot:* password encryption (was broken in 2.3.1)
+  - fix displaying used quota for dovecot <= 1.1 (was broken in 2.3.1)
+  - when deleting a domain that is an alias domain (on the "from" side), the
+    alias domain is deleted
+
+Version 2.3.1 - 2010/07/09 - SVN r847 (postfixadmin-2.3 branch)
+---------------------------------------------------------------
+
+  - SUMMARY: PostfixAdmin 2.3.1 is a bugfix-only release for Postfix Admin 2.3.
+    The only visible change is displaying the alias target for mailboxes which
+    was a longstanding issue/"missing feature".
+    The ADDITIONS directory contains some new scripts.
+  - SECURITY: users could bypass checking the old password when changing the
+    password by entering a too short new password. Fortunately only
+    "exploitable" by authentificated users.
+  - merge in changes to /debain (thanks normes) from trunk
+  - display alias targets for mailboxes (if $CONF['special_alias_control'] = YES)
+  - add hook for custom maildir path generation
+  - add import_users_from_csv.py script (by Simone Piccardi)
+  - add mailbox_post* scripts for cyrus
+  - handle dovecot passwords without any tempfile (prevents safe_mode issues)
+  - fix MySQL 6.0 compatibility
+  - fix quota display (for dovecot >= 1.2)
+  - fix short open tags ("<?")
+  - translation updates and fixes
+  - documentation updates and fixes
+  - document commandline parameters for $CONF[*_script] options in config.inc.php
+  - list-virtual: added error message if the check_owner query returns more
+    than one result (can happen with pre-2.3 databases and prevents access for
+    superadmins)
+  - add in_array() check to avoid that superadmins can enter invalid domains
+  - fix delete link for alias domains (when on target domain)
+  - delete values from quota and quota2 table when deleting a mailbox
+  - fix hardcoded table names in list-domain.php
+  - fixed edit-alias.php not to drop alias to the mailbox if
+    special_alias_control = NO
+  - fix alias handling for mailboxes (special_alias_control vs.
+    alias_control_admin confusion)
+  - fix typo in upgrade.php that broke index creation and deletion when using
+    non-default table names
+  - fix creating 'ALL' domain (dummy for superadmins) when using non-default
+    table names
+  - fix: db_query did not return number of SELECTed rows if query starts with
+    with whitespace
+  - check for $CONF['encrypt'] = 'dovecot:md5-crypt' (postfixadmin login not
+    working because dovecotpw uses a new salt each time), recommend
+    internal md5crypt instead
+  - replaced terribly outdated, broken squirrelmail plugin with a fresh version.
+    Note: The new plugin version requires the Zend framework.
+
+Version 2.3 - 2009/10/24 - SVN r739
+-----------------------------------
+
+  - automatically create quota tables for dovecot (both 1.0/1.1 and >= 1.2)
+  - list-virtual can now handle both table formats
+  - fixed upgrade.php for MySQL 6.0 compability
+  - changed vacation.pl syslog facility from "user" to "mail"
+  - added config option for postregsql database port
+  - added config option to enable/disable XMLRPC interface (default: off)
+  - Fix check/query for alias with enabled vacation in vacation.pl
+  - Fix db_get_boolean() to return t/f for postgresql, not true/false
+  - Fix missing quoting for boolean values in SQL queries at various places
+  - Allow SHA courier-authlib passwords
+  - various small bug fixes
+  - fixed SVN revision for 2.3rc7 in changelog (was r691, should be r694)
+
+Version 2.3rc7 - 2009/07/27 - SVN r694
+--------------------------------------
+
+  - Fix bug with confd-link.sh debian thing (breakage on Lenny with wwwconfig-common 0.1.2)
+  - Fix crypt() issue (see https://sourceforge.net/tracker/?func=detail&aid=2814820&group_id=191583&atid=937964 )
+
+Version 2.3rc6 - 2009/07/20 - SVN r689
+--------------------------------------
+
+  - Updates to vacation.pl
+  - PHP 5.3 compatibility
+  - Easier dependencies for .debs - should work on Lenny/Ubuntu etc without issue now.
+
+Version 2.3rc5 - 2009/05/20 - SVN r658
+--------------------------------------
+
+  - Improvements to the setup process
+  - Far better Debian packaging (we hope!) which should make installation much, much easier.
+  - Various bug fixes
+  - Performance enhancements (or we fixed the regressions ...) in domain listing etc.
+
+Version 2.3rc4 - 2009/04/18 - SVN r632
+--------------------------------------
+
+  - *Security fix* - on upgrade setup.php is restored; allowing a malicious
+    user to create their own superadmin account. We've removed the requirement to delete
+    setup.php, and instead a new config parameter (setup_password) is used to protect access
+    to this page. Password is encrypted, and setup.php can be used to generate the initial value.
+  - Fix undefined variables problem(s)
+  - Fix PostgreSQL date timestamp issues...
+
+Version 2.3rc3 - 2009/04/06 - SVN r611
+--------------------------------------
+
+  - Minor improvements to the Debian packaging, expect more soon
+  - Assorted bug fixes
+  - Partial support for per-user fetchmail.pl support
+
+Version 2.3rc2 - 2009/02/03 - SVN r593
+--------------------------------------
+
+  - Refactor /users (see /model) and provide XmlRpc interface for remote mail clients
+     (e.g. squirrelmail-postfixadmin)
+  - Add dovecotpw support - see:
+     https://sourceforge.net/tracker/index.php?func=detail&aid=2607332&group_id=191583&atid=937966
+  - Add unit tests for model/ directory (see /tests)
+  - Add additional scripts to ADDITIONS
+  - Documentation updates
+  - Various language updates
+  - added ADDITIONS/delete-mailq-by-domain.pl (by Jose Nilton)
+  - added ADDITIONS/quota_usage.pl (by Jose Nilton) - produces report of quota usage
+  - added support for courier authlib authentication flavors ($CONF['authlib_default_flavor'])
+
+
+Version 2.3 Beta - 2009/01/15 - SVN r527
+-----------------------------------------
+
+  - added support for domain aliases (from lenix) (can be disabled with $CONF['alias_domain'])
+    Important: If you update from a previous version, you'll have to adapt your postfix
+    configuration (see DOCUMENTS/POSTFIX_CONF.txt) - or just disable alias domain support,
+    your postfix configuration will continue to work
+  - updated postfix example configuration for domain aliases and to use the new mysql map format
+  - vacation.pl:
+    - add option for re-notification after definable timeout (patch from Luxten)
+      (default stays on "notify once")
+    - force usage of envelope from/to, better checks for mailinglists, spam etc.
+      If in doubt, do not send a vacation reply (patch from Lutxen)
+    - added a small test suite
+    - use Log4Perl
+    - allow to enter the configuration in /etc/mail/postfixadmin/vacation.conf
+      instead of editing vacation.pl directly
+    - bump version number of vacation.pl
+  - added domain-postcreation script support
+  - added dovecot quota support (documentation + viewing in postfixadmin)
+  - enhanced mailbox table to make it easier for people to customise where mailboxes live
+    (new column "local_part")
+  - enhanced fetchmail.pl script (file locking, syslog logging, configuration file etc)
+  - added clear error message for non-resolvable domains when creating mailboxes or aliases
+  - check for non-resolvable domains on domain creation
+  - new option $CONF['create_mailbox_subdirs_prefix'] for compatibility with more IMAP servers
+  - added support for mysql encrypt() password encrpytion
+  - fix "illegal mix of collations" problem in MySQL by explicitely setting the charset everywhere
+  - fix: cleanup vacation_notification table when disabling vacation
+  - fix: config and fetchmail tables now honor $CONF['database_tables']
+  - fix: several table names were hardcoded in database creation/update
+  - fix: "unlimited" and "disabled" for quota and limits were crossed at several places
+  - fix: honor $CONF['default_transport'] even if $CONF['transport'] = "no" (patch by fabiobon)
+  - fix: transport field is no longer emptied on domain edit if editing transport is disabled
+  - show links to create mailboxes or alias even on disabled domains
+  - added support for fetchmail's "ssl" option
+  - superadmin can now setup fetchmail for all users, not only for himself
+  - force username to be lowercase - this helps some IMAP clients apparently
+  - the "probably undeliverable" marker now honors catchall targets
+  - on mailbox creation, show password if $CONF['generate_password'] == 'YES', but
+    do not show it if it was _not_ autogenerated and $CONF['show_password'] == 'NO'
+  - dropped $CONF['show_custom_count']. PHP can count ;-)
+  - dropped obsolete VIRTUAL_VACATION/mail-filter script
+  - translation updates
+  - several small bugfixes
+
+
+Version 2.2.1.1 - 2008/07/23 - SVN r412
+---------------------------------------
+
+  - fixed version number in functions.inc.php ;-)
+
+
+Version 2.2.1 - 2008/07/21 - SVN r408
+-------------------------------------
+
+  - added quota parameter to mailbox_postcreation hook
+  - new hook to update the quota after editing a mailbox ($CONF['mailbox_postedit_script'])
+  - fixed subfolder creation order and timing
+  - allow smtp server to be specified in vacation.pl
+  - fixed MySQL charset issues
+  - several small bugfixes
+  - Norwegian (bokmal) translation added
+  - several translation updates
+
+
+Version 2.2.0 - 2008/04/29
+--------------------------
+
+  <Far more changes than those listed here; thanks to all the community who have provided
+   patches and time to help us get here!>
+  - Unicode support for vacation messages
+  - More language translations
+  - Merged the two vacation scripts (PostgreSQL version won :) )
+  - Added setup.php/upgrade.php scripts to handle upgrades
+    - See also new 'config' database table
+  - Added support for 'fetchmail' so mail from a remote server can be retrieved.
+  - Many, many bug fixes
+
+  - Added: Feature to show status of aliases/mailboxes (GregC)
+  - Fixed: Many admin/*.php files merged with /*.php
+  - Fixed: 'alias' instead of '$table_alias' being used by some .php files (GregC)
+  - Fixed: Overview no longer lists alias entries for mailboxes (GregC)
+  - Changed: Added exit buttons to several edit options. (GregC)
+  - Fixed: user options are a little more idiot-proof, templates are consistent (GregC)
+  - Changed: Users can view and edit their vacation config (GregC)
+  - Added: Slovakian language posted on SourceForge by eszabo
+  - Changed: searches include mailbox.name matches (GregC)
+  - Fixed: function check_email will ignore vacation_domain if vacation==YES (GregC)
+  - Changed: applied patches from Christian Boltz posted at
+    http://www.cboltz.de/tmp/postfixadmin-3.patch, referenced at
+    https://sourceforge.net/tracker/index.php?func=detail&aid=1696647&group_id=191583&atid=937966 (GregC)
+  - Added: main.php to admin dirctory (GregC)
+  - Added: Item "Main" on admin menu (GregC)
+  - Changed: Edit-vacation now edits for admins/superadmins (GregC)
+  - Added: Do not store local copy when forward mail. (Mihau) [24]
+  - Added: Virtual Vacation for PostgreSQL. (Tarvin)
+  - Added: Virtual Vacation 3.2 (Thanx David)
+  - Added: SUBJECT tag for Virtual Vacation.
+  - Added: Dovecot setup document for Postfix Admin. (Thanx Massimo)
+  - Added: SquirrelMail plugin to change_password.
+  - Changed: Starting to merge /admin in root. (Mihau)
+  - Changed: Moved some TXT files to DOCUMENTS.
+  - Changed: Updated tw.lang. (Thanx Bruce)
+  - Fixed: Usage of mysql_real_escape_string(). (Mihau)
+  - Fixed: Calculating of quotas. (Mihau)
+  - Fixed: Password generation when creating a new account. (Mihau)
+  - Fixed: PostgreSQL patches. (Tarvin)
+  - Fixed: Adding of multiple aliases. (Mihau)
+  - Fixed: CSS Menu width. (Mihau)
+  - Fixed: Overview when upgrading from 2.0.4. (Mihau)
+  - Fixed: smtp_mail() to wait for response from server.
+  - Fixed: pacrypt() so system works properly. (Thanx Npaufler)
+  - Fixed: quoting an email address when sending mail in vacation.pl. (Thanx Marc)
+  - Fixed: vacation.pl has a clean exit when it encounters an error. (Thanx Brian)
+  - Fixed: descriptions for quota={-1|0} in admin section (Mihau)
+
+
+Version 2.1.0 -- 2005/01/07
+---------------------------
+  - Added: Traditional Chinese language. (Thanx Bruce)
+  - Added: Traditional Bulgarian language. (Thanx Plamen)
+  - Added: Macedonian language. (Thanx Damjan)
+  - Added: Estonian language. (Thanx Peeter)
+  - Added: Slovenian language. (Thanx Nejc)
+  - Added: Check for update link in footer.
+  - Added: Additional language strings. Check LANGUAGE.TXT
+  - Added: Transport support. (read postfix transport for more information)
+  - Added: Additional language string for transport support.
+  - Added: MySQL 4.1 support.
+  - Added: PostgreSQL support. (Big Thanx WhiteFox!)
+  - Added: Setup Checker script. (Thanx Fenrir)
+  - Added: Database prefix. (Thanx Decramy)
+  - Added: Template tags. (Thanx Nelson)
+  - Added: admin/domain/alias/mailbox in delete dialog box.
+  - Added: $CONF['postfix_admin_url'] variable.
+  - Added: $CONF['postfix_admin_path'] variable.
+  - Added: $CONF['vacation_domain'] variable.
+  - Added: $CONF['welcome_text'] variable.
+  - Added: $CONF['special_alias_control'] variable. (Thanx Mihau)
+  - Added: Virtual Vacation 3.1 (Thanx David)
+  - Added: ADDITIONS directory with third party scripts and plugins.
+  - Added: Search function for aliases and mailboxes.
+  - Changed: Postfix Admin has now it's own license.
+  - Changed: New menu and color scheme. (Thanx Nelson)
+  - Changed: Disable number and unlimited number for aliases/mailboxes/quota.
+  - Changed: Virtual Vacation to have it's own transport. (Big Thanx Npaufler!)
+  - Changed: Removed the welcome text for a new mailbox from the language files.
+  - Changed: backup.php to be a more secure. (Thanx John)
+  - Fixed: Cleaned up stylesheet.
+  - Fixed: Default quota multiplier.
+  - Fixed: All POST/GET strings are escaped.
+  - Fixed: Corrected smtp_mail() to wait for result. (Thanx Patrice)
+  - Fixed: Pagination with alias_control switched on.
+  - Fixed: Swedish language. (Thanx Bjorne)
+  - Fixed: Polish language. (Thanx Piotr)
+  - Fixed: Minor Virtual Vacation bugs. (Thanx David)
+  - Fixed: check_quota().
+  - Fixed: Minor encode_header() issue. (Thanx Matthew)
+  - Fixed: edit-alias.php when running with magic_quotes_gpc = off
+
+
+Version 2.0.5 -- 2004/08/21
+---------------------------
+  - Added: Chinese language. (Thanx Matthew)
+  - Added: Catalan language. (Thanx Jaume)
+  - Added: Czech language. (Thanx Jakub)
+  - Added: Dynamic language detection.
+  - Added: Header in header.tpl to set charset header from language file.
+  - Added: More subroutines and alias checking for Vacation. (Thanx David)
+  - Added: Domain pass-through with certain pages.
+  - Added: Backup MX option for domain.
+  - Added: Log contains IP address of admin.
+  - Added: Pagination for alias/mailbox listing.
+  - Added: 2 additional language strings to support Backup MX.
+  - Added: Support for motd.txt (Domain Admins only).
+  - Added: Support for motd-admin.txt (Site Admins only).
+  - Added: Support for motd-users.txt (Users only).
+  - Added: Optional hostname for vacation.
+  - Added: generate_password() to generating random passwords for mailboxes.
+  - Changed: dk -> da, se -> sv, no-nn -> nn
+  - Changed: All email addresses are now converted to lowercase, strtolower().
+  - Changed: Moved onMouseOver to the CSS stylesheet.
+  - Changed: Moved font color to the CSS styleheet.
+  - Changed: PHP mail() is replaced by an internal function, smtp_mail().
+  - Changed: mysql_fetch_array() replaced with internal function db_array().
+  - Changed: mysql_fetch_assoc() replaced with internal function db_assoc().
+  - Changed: mysql_fetch_row() replaced with internal function db_row().
+  - Changed: Quota multiplier is now a configuration option.
+  - Fixed: Login didn't check for active flag.
+  - Fixed: Minor html table errors.
+  - Fixed: Row count by using COUNT(*).
+  - Fixed: Locked down subdirectories.
+  - Fixed: Create admin properly populates the domain_admins table.
+  - Fixed: Cleaned up stylesheet.css.
+  - Fixed: Delete mailbox properly removes vacation entries.
+
+
+Version 2.0.4  -- 2004/02/26
+----------------------------
+  - Added: Euskara language. (Thanx Julen)
+  - Added: Hungarian language. (Thanx Christian)
+  - Added: Icelandic language. (Thanx Gestur)
+  - Added: Italian language. (Thanx Stucchi)
+  - Added: Norwegian - Nynorsk language. (Thanx Paul)
+  - Added: Polish language. (Thanx Jarek)
+  - Added: Portuguese - Brazil language. (Thanx Roberto)
+  - Added: Rusian language. (Thanx Paul)
+  - Added: Turkish language (Thanx Onuryalazi)
+  - Added: Encode a string according to RFC 1522 for use in headers if it
+    contains 8-bit characters. (Thanx Evgeniy)
+  - Added: One click active change of mailbox/domain/admin. (Thanx Marcin)
+  - Changed: Header in header.tpl to read charset header from language file.
+  - Fixed: Some form values are now parsed through htmlspecialchars().
+    (Thanx Marcin)
+  - Fixed: admin/delete.php ignored $CONF['vacation'].
+  - Fixed: More minor fixes to Virtual Vacation.
+
+
+Version 2.0.3  -- 2004/01/14
+----------------------------
+  - Added: Site Admin email address.
+  - Added: Danish language. (Thanx Lars)
+  - Added: Dutch language. (Thanx Mourik)
+  - Added: Faroese language. (Thanx Danial)
+  - Added: Finnish language. (Thanx Palo)
+  - Added: French language. (Thanx Kuthz)
+  - Added: Swedish language. (Thanx Slite)
+  - Added: Ignoring of MAILER-DAEMON type emails for Vacation.
+  - Fixed: Minor issues regarding mail().
+  - Fixed: Minor issues regarding crypt().
+  - Fixed: Strip issue of email address for Vacation.
+
+
+Version 2.0.2  -- 2004/01/06
+----------------------------
+  - Added: German language. (Thanx Tobias)
+  - Added: Spanish language. (Thanx Alvaro)
+  - Fixed: The body was not included using sendmail.php.
+  - Fixed: Undefined variables.
+  - Fixed: Minor HTML cleanup.
+
+
+Version 2.0.1  -- 2004/01/04
+----------------------------
+  - Fixed: The language variable caused a problem on some systems.
+
+
+Version 2.0.0  -- 2004/01/03
+----------------------------
+  - Added: The ability for one domain admin to maintain multiple domains.
+  - Added: Domain to domain forwarding.
+  - Added: Mailboxes can now be activated or deactivated.
+  - Added: Configurable welcome message for new mailboxes.
+  - Added: Optional sending of welcome message.
+  - Added: Create alias "To" defaults to current domain.
+  - Added: Logging of admin / user actions.
+  - Added: Limit for aliases and/or mailboxes per domain.
+  - Added: Disable aliases and/or mailboxes per domain.
+  - Added: Max quota per mailbox per domain.
+  - Added: Multi-Language support.
+  - Added: Statistics overview for all domains.
+  - Added: User .forwarding for mailbox users.
+  - Added: Logo for Postfix Admin (Thanx Andrew).
+  - Added: Extra MySQL debugging capabilities.
+  - Added: Clear text password support.
+  - Added: PHP crypt() support.
+  - Changed: Separated logic and SQL from content.
+  - Changed: config.inc.php doesn't point to example.com anymore.
+  - Changed: Virtual Vacation no longer requires procmail.
+  - Changed: Complete re-write.
+
+
+Version 1.5.4  -- 2003/06/16
+----------------------------
+  - Added: Option for "Back to".
+  - Added: Option for Vacation module.
+  - Added: Table declaration for the use of Quota in the INSTALL.TXT.
+    This requires an additional local delivery agent.
+    Quotas are not supported by Postfix!
+  - Changed: The word "View" to "List".
+
+
+Version 1.5.3  -- 2003/06/06
+----------------------------
+  - Fixed: Even more minor bugs in regards to declaration of variables.
+    (Thanx Aquilante and Kyle_m)
+
+
+Version 1.5.2  -- 2003/06/05
+----------------------------
+  - Fixed: Minor bugs in regards to declaration of variables.
+
+
+Version 1.5.1  -- 2003/06/04
+----------------------------
+  - Added: Optional mailbox per domain directory structure. (Thanx Jim)
+  - Added: Option to completely control the stored aliases. (Thanx Alex)
+  - Changed: config.inc.php is renamed to config.inc.php.sample. (Thanx Alex)
+  - Fixed: $PHP_SELF in config.inc.php and my_lib.php. (Thanx Jim)
+
+
+Version 1.5.0  -- 2003/05/28
+----------------------------
+  - Added: Support for "Back to Main Site"
+  - Added: config.inc.php as the main configuration file.
+  - Added: Drop down box for domain selection when adding a new admin.
+  - Added: Resend of test email to newly created mailbox.
+  - Added: Mailbox and Aliases count for domainview.
+  - Added: Change description of domain without deleting the complete
+    domain.
+  - Added: Change name of mailbox user without deleting the mailbox.
+  - Added: Expire headers for unnecessary reloads. (Thanx Alex)
+  - Fixed: Code clean up.
+  - Fixed: Minor bugs and cosmetic fixes.
+  - Fixed: Modified check_string() to check numbers and returns false if not
+    matched. (Thanx btaber)
+  - Fixed: Correct session handling in login.php (Thanx Yen-Wei Liu)
+  - Fixed: Correct deletion of RFC822 email addresses. (Thanx Yen-Wei Liu)
+  - Removed: Completely removed the site_lib.php.
+  - Removed: my_lib.php from the admin directory.
+  - Removed: Symlink to index.php.
+
+
+Version 1.4.0  -- 2003/04/07
+----------------------------
+  - Added: When deleting a domain, all aliases and mailboxes for that domain
+    are also deleted from the database.
+  - Added: Add standard aliases for every domain that is created.
+    These aliases can point to the main "local" administrator.
+    The aliases are configured in the config.php in the admin directory.
+  - Changed: The layout of my_lib.php and site_lib.php have been changed.
+  - Changed: Modifying an alias is now done with TEXTAREA for more
+    flexibility.
+  - Fixed: Minor bugs and cosmetic fixes.
+
+
+Version 1.3.8a -- 2003/03/31
+----------------------------
+  - Fixed: After deletion of a domain it would not return to the correct page.
+
+
+Version 1.3.8  -- 2003/03/25
+----------------------------
+  - Added: Admin password change. No longer needed to delete and re-enter
+    the admin user for a specific domain.
+
+
+Version 1.3.7  -- 2002/12/24
+----------------------------
+  - Initial public release of Postfix Admin.
+
+
+# vim: set expandtab softtabstop=2 tabstop=2 shiftwidth=2:

+ 39 - 0
DOCUMENTS/BACKUP_MX.txt

@@ -0,0 +1,39 @@
+#
+# Postfix Admin
+# by Mischa Peters <mischa at high5 dot net>
+# Copyright (c) 2002 - 2005 High5!
+# Licensed under GPL for more info check GPL-LICENSE.TXT
+#
+
+Please follow these steps if your mailserver is used as a backup MX for some
+(or all) of your domains.
+
+Note: The setup described in this file only checks the domain, not the full
+mail address. 
+You should use "reject_unverified_recipient" in your postfix config or setup
+"relay_recipient_maps" with a list of valid mail adresses on the primary mx
+to avoid that your backup MX accepts mails for non-existing recipient adresses.
+Without this, your backup MX might become a backscatter source.
+
+1. Modify main.cf
+-----------------
+In order for Postfix to use MySQL for relay_domains add the following
+to your main.cf
+
+relay_domains = proxy:mysql:/usr/local/etc/postfix/mysql_relay_domains_maps.cf
+
+
+2. mysql_relay_domains_maps.cf
+------------------------------
+You will need to put this into a text file for postfix to pickup.
+
+user = postfix
+password = password
+hosts = localhost
+dbname = postfix
+query = SELECT domain FROM domain WHERE domain = '%s' AND backupmx = '1'
+
+
+3. Restart Postfix
+-------------------
+When you are done make sure to restart Postfix so the changes take effect.

+ 214 - 0
DOCUMENTS/DOVECOT.txt

@@ -0,0 +1,214 @@
+#
+# Dovecot configuration for Postfix Admin
+# Originally written by: Massimo <AndyCapp> Danieli
+# Revised by: Sampsa Hario <shario> for Dovecot v1.0
+# Revised by: David Goodwin <david@palepurple.co.uk> for Dovecot 2.1.x  (2014/01/02)
+#
+
+More complete Dovecot documentation:
+
+http://wiki.dovecot.org/Quota
+http://wiki.dovecot.org/Quota/Dict
+http://www.opensourcehowto.org/how-to/mysql/mysql-users-postfixadmin-postfix-dovecot--squirrelmail-with-userprefs-stored-in-mysql.html
+
+
+Here are the relevant parts of Dovecot v2.1.x configuration for Postfixadmin setup.
+
+Please refer to Dovecot documentation for complete information.
+
+The setup gets userdb and passdb info from MySQL as well as quotas, and 
+uses dict backend to store used quotas as key=value pairs so that they can
+be viewed real-time in Postfixadmin.
+
+
+1. Dovecot setup
+-----------------
+
+A basic /etc/dovecot/dovecot.conf is as follows, this was generated using 'dovecot -n' on a vanilla install and then
+changing to talk to a PostgreSQL or MySQL database. 
+
+# BEGIN /etc/dovecot/dovecot.conf:
+# Change this to where your mail root is, this needs to match whatever structure postfix expects....
+
+mail_location = maildir:/var/mail/vmail/%u/
+
+namespace inbox {
+  inbox = yes
+  location = 
+  mailbox Drafts {
+    special_use = \Drafts
+  }
+  mailbox Junk {
+    special_use = \Junk
+  }
+  mailbox Sent {
+    special_use = \Sent
+  }
+  mailbox "Sent Messages" {
+    special_use = \Sent
+  }
+  mailbox Trash {
+    special_use = \Trash
+  }
+  prefix = 
+}
+
+protocols = "imap pop3"
+# change to 'no' if you don't have ssl cert/keys, and comment out ssl_cert/ssl_key
+ssl = yes 
+ssl_cert = </etc/dovecot/private/dovecot.pem
+ssl_key = </etc/dovecot/private/dovecot.pem
+
+# login is for outlook express smtpd auth
+auth_mechanisms = plain login
+
+# If you're having trouble, try uncommenting these :
+#auth_debug = yes
+#auth_debug_passwords = yes
+
+userdb { 
+    driver = sql
+    args = /etc/dovecot/dovecot-sql.conf 
+}
+
+passdb { 
+    driver = sql
+    args = /etc/dovecot/dovecot-sql.conf 
+}
+
+# Uncomment this if you want Postfix to be able to do smtpd auth through dovecot
+# At a minimum Postfix probably needs : smtpd_sasl_type = dovecot 
+# And additionally: smtpd_sasl_path = private/auth
+#service auth {
+#    unix_listener /var/spool/postfix/private/auth {
+#        mode = 0660
+#        user = postfix
+#        group = postfix
+#    }
+#    user = postfix
+#    group = postfix
+#}
+
+# Needs to match Postfix virtual_uid_maps
+first_valid_uid = 1001 
+
+# allow plaintext auth (change to 'yes' to block plaintext passwords)
+disable_plaintext_auth = no
+
+#END
+
+
+2. Dovecot *sql setup
+----------------------
+
+Below you'll find the relevant part of dovecot-sql.conf file regarding our
+setup. 
+
+Things you will probably need to change are db connection settings (connect=)
+and the default_pass_scheme.
+
+#BEGIN /etc/dovecot/dovecot-sql.conf
+
+connect = host=localhost dbname=postfix user=postfix password=postfix
+# Use either 
+driver = mysql
+# Or 
+# driver = pgsql
+
+# Default password scheme - change to match your Postfixadmin setting.
+# depends on your $CONF['encrypt'] setting:
+# md5crypt  -> MD5-CRYPT
+# md5       -> PLAIN-MD5
+# cleartext -> PLAIN
+default_pass_scheme = MD5-CRYPT
+
+# Query to retrieve password. user can be used to retrieve username in other
+# formats also.
+
+password_query = SELECT username AS user,password FROM mailbox WHERE username = '%u' AND active='1'
+
+# Query to retrieve user information, note uid matches dovecot.conf AND Postfix virtual_uid_maps parameter.
+user_query = SELECT maildir, 1001 AS uid, 1001 AS gid FROM mailbox WHERE username = '%u' AND active='1'
+
+
+# MYSQL :
+user_query = SELECT CONCAT('/var/vmail/mail/', maildir) AS home, 1001 AS uid, 1001 AS gid, 
+	CONCAT('*:bytes=', quota) AS quota_rule FROM mailbox WHERE username = '%u' AND active='1'
+# PostgreSQL : (no Quota though) :
+# user_query = SELECT '/var/vmail/mail/' || maildir AS home, 1001 as uid, 1001 as gid FROM mailbox WHERE username = '%u' AND active = '1'
+
+#END /etc/dovecot/dovecot-sql.conf
+
+
+
+
+
+3. Dovecot v1.0 quota support (optional)
+----------------------------------------
+
+Please note that you need to use Dovecot's own local delivery agent to
+enforce and update quotas. Then you can view real-time used quotas in
+Postfixadmin.
+
+Add to dovecot.conf:
+
+## IMAP quota
+protocol imap {
+  quota = dict:storage=200000 proxy::quota
+}
+
+## POP quota
+protocol pop3 {
+  mail_plugins = quota
+}
+
+## Local Delivery Agent
+protocol lda {
+  mail_plugins = quota
+}
+
+## Dictionary DB proxy
+dict {
+  quota = mysql:/etc/dovecot-dict-quota.conf
+}
+
+## Default quota values
+plugin {
+quota = dict:storage=200000 proxy::quota
+}
+
+
+Change dovecot-sql.conf to return quota values:
+
+for MySQL:
+user_query = SELECT maildir, 1001 AS uid, 1001 AS gid, CONCAT('dict:storage=',floor(quota/1000),' proxy::quota') as quota FROM mailbox WHERE username = '%u' AND active='1'
+
+for PostgreSQL:
+user_query = SELECT maildir, 1001 AS uid, 1001 AS gid, 'dict:storage=' || floor(quota/1000) || '::proxy::quota' as quota FROM mailbox WHERE username = '%u' AND active='1'
+
+
+Create file dovecot-dict-quota.conf:
+
+driver = mysql
+connect = host=localhost dbname=postfix user=postfix password=postfix
+default_pass_scheme = MD5-CRYPT
+table = quota
+select_field = current
+where_field = path
+username_field = username
+
+
+Create database in Mysql:
+(This is automatically done by postfixadmin's setup.php)
+
+Enable quota support in Postfixadmin config.inc.php:
+
+$CONF['used_quotas'] = 'YES';
+$CONF['quota'] = 'YES';
+
+Note: The above text describes the configuration for dovecot 1.0 & 1.1 quota table format.
+
+If you use dovecot 1.2 or newer, 
+- use the 'quota2' table (also created by setup.php)
+- set $CONF['new_quota_table'] = 'YES'
+

+ 36 - 0
DOCUMENTS/FAQ.txt

@@ -0,0 +1,36 @@
+Frequently Asked Questions:
+
+
+1) Why isn't PostfixAdmin creating my mailbox?
+
+ - PostfixAdmin is only a web interface for storing configuration settings. 
+   It does not (by default!) have the ability to create mail folders on disk. 
+   In a normal setup, sending the 'Welcome' email accomplishes this task - 
+   as Courier/Cyrus/etc do it (and have permission to do so)
+
+
+2) I've deleted the mailbox from PostfixAdmin, yet it still exists on disk? Why?
+
+ - This is related to #1 above - namely, PostfixAdmin (which is a php web 
+   application) does not have permission to modify the mailbox files on disk.
+   You need to either manually remove the directories 
+   (e.g. rm -Rf /var/spool/mail/vmail/something@example.org) 
+   or install the postfixadmin-mailbox-postdeletion.sh script (See ADDITIONS/)
+   and modify config.inc.php appropriately.
+
+
+3) How do I have to setup sudo to run the $CONF['*_script'] scripts?
+
+ - run   visudo   to edit the sudo configuration file
+ - add a line like this for every script you want to run:
+      wwwrun  ALL = (courier) NOPASSWD: /usr/local/bin/postfixadmin-mailbox-postcreation.sh
+   (replace usernames and path according to your setup)
+
+
+4) I try and create a mailbox, but it keeps saying "Invalid email address"... ?
+
+ - Postfixadmin, by default, attempts to verify an email address is valid, partly by
+   checking that the domain exists. For most people this works as expected, but
+   if it doesn't for you, try editing $CONF['emailcheck_resolve_domain'] to 'NO' in 
+   config.inc.php and try again.
+

+ 50 - 0
DOCUMENTS/HORDE.txt

@@ -0,0 +1,50 @@
+Horde integration with Postfixadmin 
+
+This is taken from the following thread :
+
+https://sourceforge.net/forum/forum.php?thread_id=1869141&forum_id=676076
+
+Namely :
+
+"Hi, people, I was wondering if anyone was using PA with Horde3. I want my users to be able to change teir password from inside Horde, so I was wondering if anyone has implemented a custom hook or defined a SQL query to make the password change possible. "
+
+
+Solution :
+
+"Hi, 
+ 
+that works for me without any hook - with the SQL driver. I connect through IP to localhost. You can also try socket connection... 
+ 
+my horde/passwd/config/backends.php looks like: 
+ 
+$backends['sql'] = array ( 
+'name' => 'Mail SQL Server', 
+'preferred' => '', 
+'password policy' => array( 
+'minLength' => 3, 
+'maxLength' => 8, 
+'maxSpace' => 0, 
+'minUpper' => 1, 
+'minLower' => 1, 
+'minNumeric' => 1, 
+'minSymbols' => 1 
+), 
+'driver' => 'sql', 
+'params' => array( 
+'phptype' => 'mysql', 
+'hostspec' => '127.0.0.1', 
+'port' => '3306', 
+'protocol' => 'tcp', 
+'username' => 'postfix', 
+'password' => 'yourpostfixdbpassword', 
+'encryption' => 'crypt-md5', 
+'database' => 'postfix', 
+'table' => 'mailbox', 
+'user_col' => 'username', 
+'pass_col' => 'password', 
+'show_encryption' => false 
+) 
+); "
+
+Thanks to 'Kope' for the solution, and of course Luis Hernán Otegui (slimshady76) for asking the question.
+

+ 17 - 0
DOCUMENTS/LANGUAGE.txt

@@ -0,0 +1,17 @@
+#
+# Postfix Admin
+# by Mischa Peters <mischa at high5 dot net>
+# Copyright (c) 2002 - 2005 High5!
+# Licensed under GPL for more info check GPL-LICENSE.TXT
+#
+
+If you want to contribute a translation, please follow these easy steps:
+- download your language file from SVN
+  http://postfixadmin.svn.sourceforge.net/viewvc/postfixadmin/trunk/languages/
+- search for lines with '# XXX' comments and
+  - translate the line
+  - remove the '# XXX'
+  Note: The file is utf-8 encoded. You can also use htmlentities.
+- post your translation to the Sourceforge tracker
+  http://sourceforge.net/tracker/?group_id=191583&atid=937966
+

+ 26 - 0
DOCUMENTS/POSTFIXADMIN.txt

@@ -0,0 +1,26 @@
+---------------------------------------
+  The different parts of PostfixAdmin
+
+
+Postfix Admin has a concept of a "global" administrator (think 'root') and 
+domain administrators.  When you install PostfixAdmin, the setup.php file 
+will ask you to create the global administrators account. Using this global
+account, you can (if you so wish) create domain administrators who are 
+limited to making changes within the domains you specify for them.
+
+Historically when you logged in as the 'global' (or superadmin) user, you'd
+access /admin; with version 2.2.0, this 'functionality' was removed (as there
+was excessive code duplication) and everyone uses the same login.php script.
+
+
+Needless to say, as a global administrator, you can do all kinds of bad things -
+like deleting domains and stopping delivery of mail to a particular mailbox. So
+- take care, and if you're unsure take semi-regular backups.
+
+
+If you login, and you are not an administrator (i.e. you are a 'regular' user
+who just has a mailbox on the server), then you will only see functionality to 
+modify your own account - e.g. change password, edit forward records and specify 
+whether you are on vacation (out of office) or not.
+
+

+ 176 - 0
DOCUMENTS/POSTFIX_CONF.txt

@@ -0,0 +1,176 @@
+#!/bin/bash
+content="
+
+  Postfix configuration for use with PostfixAdmin
+
+-----------------------
+
+  Your installation of Postfix MUST support either MySQL or Postgres
+lookup tables.  You can verify that with 'postconf -m'
+
+Its generally recommended to use proxy as well (which should also appear in
+postconf -m)  Three main.cf variables are involved:
+
+virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf
+virtual_alias_maps =
+   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf,
+   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf,
+   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf
+virtual_mailbox_maps =
+   proxy:mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf,
+   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf
+
+# if you let postfix store your mails directly (without using maildrop, dovecot deliver etc.)
+virtual_mailbox_base = /var/mail/vmail
+# or whereever you want to store the mails
+
+# Additional for quota support
+virtual_create_maildirsize = yes
+virtual_mailbox_extended = yes
+virtual_mailbox_limit_maps = mysql:/etc/postfix/sql/mysql_virtual_mailbox_limit_maps.cf
+virtual_mailbox_limit_override = yes
+virtual_maildir_limit_message = Sorry, the user's maildir has overdrawn his diskspace quota, please try again later.
+virtual_overquota_bounce = yes
+
+Where you chose to store the .cf files doesn't really matter, but they will
+have database passwords stored in plain text so they should be readable only
+by user postfix, or in a directory only accessible to user postfix.
+
+This isn't necessarily all you need to do to Postfix to get up and
+running.  Also, additional changes are needed for the vacation
+autoreply features.
+
+-------------------------
+
+  Contents of the files
+
+These are examples only, you will likely have to and want to make some
+customizations.  You will also want to consider the config.inc.php
+settings for domain_path and domain_in_mailbox.  These examples
+use values of domain_path=YES and domain_in_mailbox=NO
+
+You can create these files (with your values for user, password, hosts and
+dbname) automatically by executing this file (sh POSTFIX_CONF.txt).
+Please note that the generated files are for use with MySQL. 
+
+If you are using PostgreSQL, you'll need to do some changes to the queries:
+- PostgreSQL uses a different implementation for boolean values, which means 
+  you'll need to change  active='1'  to  active='t'  in all queries
+- PostgreSQL does not have a concat() function, instead use e.g. 
+  .... alias.address = '%u' || '@' || alias_domain.target_domain AND ....
+ 
+
+mysql_virtual_alias_maps.cf:
+user = postfix
+password = password
+hosts = localhost
+dbname = postfix
+query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
+#expansion_limit = 100
+
+mysql_virtual_alias_domain_maps.cf:
+user = postfix
+password = password
+hosts = localhost
+dbname = postfix
+query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('%u', '@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'
+
+mysql_virtual_alias_domain_catchall_maps.cf:
+# handles catch-all settings of target-domain
+user = postfix
+password = password
+hosts = localhost
+dbname = postfix
+query  = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'
+
+(See above note re Concat + PostgreSQL)
+
+mysql_virtual_domains_maps.cf:
+user = postfix
+password = password
+hosts = localhost
+dbname = postfix
+query          = SELECT domain FROM domain WHERE domain='%s' AND active = '1'
+#query          = SELECT domain FROM domain WHERE domain='%s'
+#optional query to use when relaying for backup MX
+#query           = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '0' AND active = '1'
+#expansion_limit = 100
+
+mysql_virtual_mailbox_maps.cf:
+user = postfix
+password = password
+hosts = localhost
+dbname = postfix
+query           = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'
+#expansion_limit = 100
+
+mysql_virtual_alias_domain_mailbox_maps.cf:
+user = postfix
+password = password
+hosts = localhost
+dbname = postfix
+query = SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = CONCAT('%u', '@', alias_domain.target_domain) AND mailbox.active = 1 AND alias_domain.active='1'
+
+
+(See above note re Concat + PostgreSQL)
+
+# For quota support
+
+mysql_virtual_mailbox_limit_maps.cf:
+user = postfix
+password = password
+hosts = localhost
+dbname = postfix
+query = SELECT quota FROM mailbox WHERE username='%s' AND active = '1'
+
+-------------------------
+
+  More information - HowTo docs that use PostfixAdmin
+
+http://postfix.wiki.xs4all.nl/index.php?title=Virtual_Users_and_Domains_with_Courier-IMAP_and_MySQL
+http://wiki.dovecot.org/HowTo/DovecotLDAPostfixAdminMySQL
+
+" # end content
+
+# generate config files out of this file
+# to do this, run   sh POSTFIX_CONF.txt
+
+POSTFIX_CONF="$0"
+
+map_files="`sed -n '/^mysql.*cf:/ s/://p' < \"$0\"`"
+
+tmpdir="`mktemp -d /tmp/postfixadmin-XXXXXX`" || { echo "Error: could not create tempdir" >&2 ; exit 1; }
+echo $tmpdir
+
+echo 'Database host? (often localhost)'
+read hosts
+test -z "$hosts" && hosts=localhost
+
+echo 'Database name?'
+read dbname
+test -z "$dbname" && { echo "Error: you did not enter a database name" >&2 ; exit 1; }
+
+echo Database user?
+read user
+test -z "$user" && { echo "Error: you did not enter a database username" >&2 ; exit 1; }
+
+echo Database password?
+read password
+test -z "$password" && { echo "Error: you did not enter a database password" >&2 ; exit 1; }
+
+for file in $map_files ; do
+	(
+		echo "# $file"
+		sed -n "/$file:/,/^$/ p" < "$POSTFIX_CONF" | sed "
+			1d ; # filename
+			s/^user =.*/user = $user/ ;
+			s/^password =.*/password = $password/ ;
+			s/^hosts =.*/hosts = $hosts/ ;
+			s/^dbname =.*/dbname = $dbname/ ;
+		"
+	) > "$tmpdir/$file"
+done
+
+echo "Config files have been written to $tmpdir. Please check their content and move them to /etc/postfix/sql/."
+echo "Do not forget to edit /etc/postfix/main.cf as described in $POSTFIX_CONF."
+

+ 44 - 0
DOCUMENTS/SECURITY.txt

@@ -0,0 +1,44 @@
+Security and PostfixAdmin
+-------------------------
+
+While the developers of PostfixAdmin believe the software to be 
+secure, there is no guarantee that it will continue to do be so
+in the future - especially as new types of exploit are discovered.
+(After all, this software is without warranty!)
+
+In the event you do discover a vulnerability in this software,
+please report it to the development mailing list, or contact 
+one of the developers directly.
+
+
+
+
+DATABASE USER SECURITY
+----------------------
+
+You may wish to consider the following :
+
+ 1. Postfix only requires READ access to the database tables.
+ 2. The virtual vacation support (if used) only needs to WRITE to 
+    the vacation_notification table (and read alias and vacation).
+ 3. PostfixAdmin itself needs to be able to READ and WRITE to 
+    all the tables.
+ 4. PostfixAdmin's setup.php additionally needs permissions to CREATE
+    and ALTER tables in the PostfixAdmin database. For PostgreSQL, also
+	permissions for CREATE FUNCTION and CREATE TRIGGER are needed.
+	In other words: setup.php needs all permissions on the PostfixAdmin
+	database.
+
+Using the above, you can improve security by creating separate 
+database user accounts for each of the above roles, and limit 
+the permissions available to them as appropriate.
+
+
+FILE SYSTEM SECURITY
+--------------------
+
+PostfixAdmin does not require write support on the underlying 
+filesystem with the following exceptions:
+- the templates_c directory where Smarty caches the templates
+- PHP's session.save_path to store session files
+

+ 16 - 0
DOCUMENTS/SUPERADMIN.txt

@@ -0,0 +1,16 @@
+------------------------------------
+  Recreating a superadmin account
+
+
+When you run setup.php you will be required to enter a super user name and password. 
+This user will be able to login and modify any domain or setting. Hence, superadmin!.
+
+With that login you can create new superadmins (and you should delete or change the
+password of  admin@domain.tld). If that user is no longer there or you didn't use
+the .TXT files, you could add another manually from the database. 
+
+In case you forgot your superadmin username or password, you can create a new
+superadmin account using setup.php.
+
+If you also have forgotten your setup password, you can use setup.php to configure
+a new setup password.

+ 111 - 0
DOCUMENTS/UPGRADE.txt

@@ -0,0 +1,111 @@
+#
+# Postfix Admin
+# by Mischa Peters <mischa at high5 dot net>
+# Copyright (c) 2002 - 2005 High5!
+# Licensed under GPL for more info check GPL-LICENSE.TXT
+#
+
+REQUIRED!!
+----------
+- You are using Postfix 2.0 or higher.
+- You are using Apache 1.3.27 / Lighttpd 1.3.15 or higher.
+- You are using PHP 5.1.2 or higher.
+- You are using MySQL 3.23 or higher OR PostgreSQL v7.4+
+
+
+READ THIS FIRST!
+----------------
+
+This document describes upgrading from an older PostfixAdmin version
+(>= v1.5x)
+
+It's recommend that you install Postfix Admin in a new folder and not
+on-top of the old install!! (At the very least, make sure you have backups of 
+the database and relevant filesystem!)
+
+When upgrading Postfix Admin, make sure you backup your database before
+running upgrade.php.
+
+
+1. Backup the Database
+----------------------
+When you install from a previous version make sure you backup your database
+first. There are a lot of changes in the database structure since Postfix Admin
+1.5.4.
+
+  $ mysqldump -a -u root -p > /tmp/postfixadmin-backup.sql
+or
+  $ pg_dump -ad -u postfix postfix > /tmp/postfixadmin-backup.sql
+
+
+2. Unarchive new Postfix Admin
+------------------------------
+Make sure that you are in your WWW directory and then unarchive the
+Postfix Admin archive (whatever the filename is):
+
+  $ tar -zxvf postfixadmin-X.X.tgz
+
+
+3. Change permissions
+----------------------
+Since the database password is stored in the config.inc.php it's a good idea
+to have change the permissions for Postfix Admin.
+
+  $ cd /usr/local/www/postfixadmin
+  $ find -type f -print0 | xargs -0 chmod 640
+  $ find -type f -print0 | xargs -0 chown root:www
+
+(the last command assumes your Apache is running with group "www")
+
+Since version 2.4 we use smarty templates. That means the templates_c directory
+needs to be writeable for your webserver.
+
+  $ chown -R www-data templates_c/
+
+(if your Apache runs as user "www-data")
+
+
+4. Configure
+------------
+Check the config.inc.php file. There you can specify settings that are
+relevant to your setup.
+
+Comparing config.inc.php with your previous using "diff" might save you some
+time.
+
+You can use a config.local.php file to contain your local settings. These will override any 
+defined in config.inc.php - and save some time when upgrading to a new version of PostfixAdmin ;-)
+
+5. Run setup.php
+----------------------------------------
+
+Access setup.php through a web browser.
+
+It will attempt to upgrade your database, and also allow you to create a superadmin user.
+(In case the database upgrade fails, you can run setup.php?debug=1 to see the last executed query.)
+
+From version 2.3, you need to specify a setup_password in config.inc.php - 
+setup.php should guide you through this process. If you do not have a setup_password, type one
+into the form, and setup.php will echo out the hashed value (which needs to go into config.inc.php).
+The setup_password removes the requirement for you to delete setup.php, and also closes a security hole.
+
+Since version 2.2 of Postfixadmin, setup.php can perform the needed database 
+updates automatically .
+
+If you update from 2.1 or older, also create a superadmin account using setup.php.
+
+Note that admin/ has been merged into the main directory. Login with the
+superadmin account to setup domains and domain admins.
+
+6. Upgrade your postfix config
+------------------------------
+
+Since version 2.3, PostfixAdmin supports alias domains ($CONF['alias_domain']).
+If you want to use them, you have to add some queries to your postfix config -
+see POSTFIX_CONF for details.
+
+
+7. Done
+-------
+This is all that is needed. Fire up your browser and go to the site that you
+specified to host Postfix Admin.

+ 2 - 0
DOCUMENTS/screenshots/README.txt

@@ -0,0 +1,2 @@
+Random Screenshots taken on 2007/09/25, using a version of Postfixadmin from subversion.
+

BIN
DOCUMENTS/screenshots/postfixadmin-admin-create-alias.jpg


BIN
DOCUMENTS/screenshots/postfixadmin-admin-create-domain.jpg


BIN
DOCUMENTS/screenshots/postfixadmin-admin-create-mailbox.jpg


BIN
DOCUMENTS/screenshots/postfixadmin-admin-domain-list.jpg


BIN
DOCUMENTS/screenshots/postfixadmin-admin-virtual-list.jpg


BIN
DOCUMENTS/screenshots/postfixadmin-inital-welcome.jpg


BIN
DOCUMENTS/screenshots/postfixadmin-mail-admin-login.jpg


BIN
DOCUMENTS/screenshots/postfixadmin-user-change-forward.jpg


BIN
DOCUMENTS/screenshots/postfixadmin-user-overview.jpg


BIN
DOCUMENTS/screenshots/postfixadmin-user-vacation.jpg


+ 281 - 0
GPL-LICENSE.TXT

@@ -0,0 +1,281 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+

+ 174 - 0
INSTALL.TXT

@@ -0,0 +1,174 @@
+#
+# Postfix Admin
+# by Mischa Peters <mischa at high5 dot net>
+# Copyright (c) 2002 - 2005 High5!
+# Licensed under GPL for more info check GPL-LICENSE.TXT
+#
+
+REQUIRED!!
+----------
+- You are using Postfix 2.0 or higher.
+- You are using Apache 1.3.27 / Lighttpd 1.3.15 or higher.
+- You are using PHP 5.1.2 or higher.
+- You are using MySQL 3.23 or higher (5.x recommended) OR PostgreSQL 7.4 (or higher)
+
+
+READ THIS FIRST!
+----------------
+When this is an upgrade from a previous version of Postfix Admin, please read 
+DOCUMENTS/UPGRADE.TXT also!
+
+If you need to setup Postfix to be able to handle Virtual Domains and Virtual
+Users check out:
+
+  - the PostfixAdmin documentation in the DOCUMENTS/ directory
+  - our wiki at http://sourceforge.net/apps/mediawiki/postfixadmin/
+
+There are also lots of HOWTOs around the web. Be warned that many of them 
+(even those listed below) may be outdated or incomplete. 
+Please stick to the PostfixAdmin documentation, and use those HOWTOs only if
+you need some additional information that is missing in the PostfixAdmin 
+DOCUMENTS/ folder.
+  - http://codepoets.co.uk/postfixadmin-postgresql-courier-squirrelmail-debian-etch-howto-tutorial (Debian+Courier+PostgreSQL+Postfix+Postfixadmin)
+  - http://bliki.rimuhosting.com/space/knowledgebase/linux/mail/postfixadmin+on+debian+sarge (Postfix+MySQL+Postfixadmin+Dovecot)
+  - http://en.gentoo-wiki.com/wiki/Virtual_mail_server_using_Postfix,_Courier_and_PostfixAdmin (Postfix+MySQL+Postfixadmin+Courier)
+
+
+1. Unarchive new Postfix Admin
+------------------------------
+Make sure that you are in your WWW directory and then unarchive the
+Postfix Admin archive (whatever the filename is):
+
+  $ tar -zxvf postfixadmin-$version.tgz
+
+
+2. Setup a Database
+-------------------
+
+With your chosen/preferred database server (i.e. MySQL or PostgreSQL), 
+you need to create a new database. A good name for this could be :
+
+  postfix
+
+The mechanics of creating the database vary depending on which server 
+you are using. Most users will find using phpMyAdmin or phpPgAdmin the
+easiest route.
+
+If you wish to use the command line, you'll need to do something like :
+
+For MySQL:
+  CREATE DATABASE postfix;
+  CREATE USER 'postfix'@'localhost' IDENTIFIED BY 'choose_a_password';
+  GRANT ALL PRIVILEGES ON `postfix` . * TO 'postfix'@'localhost';
+
+For PostgreSQL:
+  CREATE USER postfix WITH PASSWORD 'whatever';
+  CREATE DATABASE postfix OWNER postfix ENCODING 'unicode';
+
+
+3. Configure PostfixAdmin so it can find the database
+-----------------------------------------------------
+
+Create a config.local.php file for your local configuration:
+
+<?php
+$CONF['database_type'] = 'mysqli';
+$CONF['database_user'] = 'postfix';
+$CONF['database_password'] = 'postfixadmin';
+$CONF['database_name'] = 'postfix';
+
+$CONF['configured'] = true;
+?>
+
+See config.inc.php for all available config options and their default value.
+
+You can also edit config.inc.php instead of creating a config.local.php,
+but this will make updates harder and is therefore not recommended.
+
+The most important settings are those for your database server.
+
+You must also change the line that says :
+
+$CONF['configured'] = false;
+
+to
+
+$CONF['configured'] = true;
+
+
+PostfixAdmin does not require write access to any files except the templates_c 
+directory (smarty cache). You can therefore leave the files owned as root (or
+another user); as long as the web server user (e.g. www-data) can read them, it
+will be fine.
+For templates_c/, allow write access (only) for the web server user (e. g. www-data).
+The easiest way to do this is   chown -R www-data templates_c
+
+The next 'step', is optional. Only do it, if other non-trusted users have access 
+to your user:
+
+    Depending on your environment, you may want to protect the database username
+    and password stored in config.inc.php - if so, you could move them into the 
+    Apache configuration file (which can be set to be visible only by root) using 
+    something like the following in your VirtualHost definition :
+
+    SetEnv DB_USER "postfix"
+    SetEnv DB_PASS "opensesame"
+
+    config.inc.php would then be able to access these through :
+
+    $CONF['database_user'] = $_SERVER['DB_USER']
+
+
+4. Check settings, and create Admin user
+----------------------------------------
+
+Hit http://yourserver.tld/postfixadmin/setup.php in a web browser.
+
+You should see a list of 'OK' messages. 
+
+The setup.php script will attempt to create the database structure 
+(or upgrade it if you're coming from a previous version). 
+
+Assuming everything is OK you can specify a password (which you'll 
+need to use setup.php again in the future); when you submit the form, 
+the hashed value (which you need to enter into config.inc.php is echoed 
+out - with appropriate instructions on what to do with it).
+
+create the admin user using the form displayed.
+
+5. Use PostfixAdmin
+-------------------
+
+This is all that is needed. Fire up your browser and go to the site that you
+specified to host Postfix Admin.
+
+6. Integration with Postfix, Dovecot etc.
+-----------------------------------------
+
+Now that PostfixAdmin is working, you need to do some configuration in Postfix,
+Dovecot etc. so that they use the domains, mailboxes and aliases you setup in
+PostfixAdmin.
+
+The files in the DOCUMENTS/ directory explain which settings you need to
+do/change.
+
+7. XMLRPC Integration (OPTIONAL!)
+--------------------------------
+
+See ADDITIONS/squirrelmail-plugin
+See xmlrpc.php - only a subset of Postfixadmin's functionality is currently exposed.
+See config.inc.php - see xmlrpc_enabled key (defaults to off).
+
+You'll need to install a copy of the Zend Framework (version 1.12.x) within Postfixadmin
+or your PHP include_path (see header within xmlrpc.php).
+NOTE: The XMLRPC interface is _not compatible_ with Zend Framework version 2.x.
+You'll need to enable the xmlrpc link (see config.inc.php)
+
+8. More information
+-------------------
+As of March 2007, PostfixAdmin moved to SourceForge.  For the
+forum posts and source updates, see:
+
+https://sourceforge.net/projects/postfixadmin
+
+There is also #postfixadmin on irc.freenode.net.

+ 46 - 0
LICENSE.TXT

@@ -0,0 +1,46 @@
+
+    Postfix Admin is a Web Based Management tool created for Postfix. It is
+    a PHP based application that handles Postfix Style Virtual Domains and
+    Users that are stored in MySQL.
+    Copyright (c) 2005 High5! (Mischa Peters and others)
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Postfix Admin version 2.1.1, Copyright (c) 2005 High5! (Mischa Peters & Contributors)
+    Postfix Admin comes with ABSOLUTELY NO WARRANTY.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions.
+
+    High5!, hereby disclaims all copyright interest in the program
+    `Postfix Admin' (which makes passes at Postfix, PHP and MySQL) written
+    by Wietse Venema, PHP Group and MYSQL AB.
+
+    Contributors: Mihau, Tarvin, SteveB, DJTremors, WhiteFox, David Osborn, 
+                  David Goodwin (GingerDog), Christian Boltz (cboltz) and GregC and others.
+
+
+Postfix Admin uses some libraries that come with a different license.
+
+a) libraries shipped with PostfixAdmin 
+- the Smarty templating engine is licensed under the GNU LESSER GENERAL PUBLIC 
+  LICENSE Version 3 (see smarty/COPYING.lib)
+- the CLI (commandline interface) is based on CakePHP which is licensed under
+  the MIT license.
+
+b) libraries not shipped with PostfixAdmin
+- the XMLRPC interface and the squirrelmail plugin use the Zend Framework which is
+  licensed under the New BSD License (3-clause), see http://framework.zend.com/license
+- PHPUnit (used in tests/) is licensed under the BSD License (3-clause).
+

+ 512 - 0
VIRTUAL_VACATION/FILTER_README

@@ -0,0 +1,512 @@
+Introduction
+============
+
+This is a very first implementation of Postfix content filtering.
+A Postfix content filter receives unfiltered mail from Postfix and
+does one of the following:
+
+- re-injects the mail back into Postfix, perhaps after changing content
+- rejects the mail (by sending a suitable status code back to
+  Postfix) so that it is returned to sender.
+- sends the mail somewhere else
+
+This document describes two approaches to content filtering: simple
+and advanced. Both filter all the mail by default.
+
+At the end are examples that show how to filter only mail from
+users, about using different filters for different domains that
+you provide MX service for, and about selective filtering on the 
+basis of message envelope and/or header/body patterns.
+
+Simple content filtering example
+================================
+
+The first example is simple to set up.  It uses a shell script that
+receives unfiltered mail from the Postfix pipe delivery agent, and
+that feeds filtered mail back into the Postfix sendmail command.
+
+Only mail arriving via SMTP will be content filtered.
+
+                  ..................................
+                  :            Postfix             :
+Unfiltered mail----->smtpd \                /local---->Filtered mail
+                  :         -cleanup->queue-       :
+               ---->pickup /                \smtp----->Filtered mail
+               ^  :                        |       :
+               |  :                         \pipe-----+
+               |  ..................................  |
+               |                                      |
+               |                                      |
+               +-Postfix sendmail<----filter script<--+
+
+Mail is filtered by a /some/where/filter program. This can be a
+simple shell script like this:
+
+    #!/bin/sh
+
+    # Localize these.
+    INSPECT_DIR=/var/spool/filter
+    SENDMAIL="/usr/sbin/sendmail -i"
+
+    # Exit codes from <sysexits.h>
+    EX_TEMPFAIL=75
+    EX_UNAVAILABLE=69
+
+    # Clean up when done or when aborting.
+    trap "rm -f in.$$" 0 1 2 3 15
+
+    # Start processing.
+    cd $INSPECT_DIR || { echo $INSPECT_DIR does not exist; exit $EX_TEMPFAIL; }
+
+    cat >in.$$ || { echo Cannot save mail to file; exit $EX_TEMPFAIL; }
+
+    # filter <in.$$ || { echo Message content rejected; exit $EX_UNAVAILABLE; }
+
+    $SENDMAIL "$@" <in.$$
+
+    exit $?
+
+The idea is to first capture the message to file and then run the
+content through a third-party content filter program.
+
+- If the mail cannot be captured to file, mail delivery is deferred
+  by terminating with exit status 75 (EX_TEMPFAIL). Postfix will
+  try again after some delay.
+
+- If the content filter program finds a problem, the mail is bounced
+  by terminating with exit status 69 (EX_UNAVAILABLE).  Postfix
+  will return the message to the sender as undeliverable.
+
+- If the content is OK, it is given as input to the Postfix sendmail
+  command, and the exit status of the filter command is whatever
+  exit status the Postfix sendmail command produces. Postfix will
+  deliver the message as usual.
+
+I suggest that you run this script by hand until you are satisfied
+with the results. Run it with a real message (headers+body) as
+input:
+
+    % /some/where/filter -f sender recipient... <message-file
+
+Once you're satisfied with the content filtering script:
+
+1 - Create a dedicated local user account called "filter".  This
+    user handles all potentially dangerous mail content - that is
+    why it should be a separate account. Do not use "nobody", and
+    most certainly do not use "root" or "postfix".  The user will
+    never log in, and can be given a "*" password and non-existent
+    shell and home directory.
+
+2 - Create a directory /var/spool/filter that is accessible only
+    to the "filter" user. This is where the content filtering script
+    is supposed to store its temporary files.
+
+3 - Define the content filter in the Postfix master file:
+
+    /etc/postfix/master.cf:
+      filter    unix  -       n       n       -       -       pipe
+        flags=Rq user=filter argv=/somewhere/filter -f ${sender} -- ${recipient}
+
+To turn on content filtering for mail arriving via SMTP only, append
+"-o content_filter=filter:dummy" to the master.cf entry that defines
+the Postfix SMTP server:
+
+    /etc/postfix/master.cf:
+        smtp      inet     ...stuff...      smtpd
+            -o content_filter=filter:dummy
+
+The content_filter configuration parameter accepts the same syntax
+as the right-hand side in a Postfix transport table.  Execute
+"postfix reload" to complete the change.
+
+To turn off content filtering, edit the master.cf file, remove the
+"-o content_filter=filter:dummy" text from the entry that defines
+the Postfix SMTP server, and execute another "postfix reload".
+
+With the shell script as shown above you will lose a factor of four
+in Postfix performance for transit mail that arrives and leaves
+via SMTP. You will lose another factor in transit performance for
+each additional temporary file that is created and deleted in the
+process of content filtering.  The performance impact is less for
+mail that is submitted or delivered locally, because such deliveries
+are already slower than SMTP transit mail.
+
+Simple content filter limitations
+=================================
+
+The problem with content filters like the one above is that they
+are not very robust. The reason is that the software does not talk
+a well-defined protocol with Postfix. If the filter shell script
+aborts because the shell runs into some memory allocation problem,
+the script will not produce a nice exit status as defined in the
+file /usr/include/sysexits.h.  Instead of going to the deferred
+queue, mail will bounce.  The same lack of robustness can happen
+when the content filtering software itself runs into a resource
+problem.
+
+Advanced content filtering example
+===================================
+
+The second example is more complex, but can give much better
+performance, and is less likely to bounce mail when the machine
+runs into a resource problem.  This approach uses content filtering
+software that can receive and deliver mail via SMTP.
+
+Some Anti-virus software is built to receive and deliver mail via
+SMTP and is ready to use as an advanced Postfix content filter.
+For non-SMTP capable content filtering software, Bennett Todd's
+SMTP proxy implements a nice PERL/SMTP content filtering framework.
+See: http://bent.latency.net/smtpprox/
+
+The example given here filters all mail, including mail that arrives
+via SMTP and mail that is locally submitted via the Postfix sendmail
+command.
+
+You can expect to lose about a factor of two in Postfix performance
+for transit mail that arrives and leaves via SMTP, provided that
+the content filter creates no temporary files. Each temporary file
+created by the content filter adds another factor to the performance
+loss.
+
+We will set up a content filtering program that receives SMTP mail
+via localhost port 10025, and that submits SMTP mail back into
+Postfix via localhost port 10026.
+
+      ..................................
+      :            Postfix             :
+   ----->smtpd \                /local---->
+      :         -cleanup->queue-       :
+   ---->pickup /    ^       |   \smtp----->
+      :             |       v          :
+      :           smtpd    smtp        :
+      :           10026     |          :
+      ......................|...........
+                    ^       |
+                    |       v
+                ....|............
+                :   |     10025 :
+                :   filter      :
+                :               :
+                .................
+
+To enable content filtering in this manner, specify in main.cf a
+new parameter:
+
+    /etc/postfix/main.cf:
+        content_filter = scan:localhost:10025
+
+This causes Postfix to add one extra content filtering record to
+each incoming mail message, with content scan:localhost:10025.
+The content filtering records are added by the smtpd and pickup
+servers.
+
+When a queue file has content filtering information, the queue
+manager will deliver the mail to the specified content filter
+regardless of its final destination.
+
+In this example, "scan" is an instance of the Postfix SMTP client
+with slightly different configuration parameters. This is how
+one would set up the service in the Postfix master.cf file:
+
+    /etc/postfix/master.cf:
+        scan      unix  -       -       n       -       10       smtp
+
+Instead of a limit of 10 concurrent processes, use whatever process
+limit is feasible for your machine.  Content inspection software
+can gobble up a lot of system resources, so you don't want to have
+too much of it running at the same time.
+
+The content filter can be set up with the Postfix spawn service,
+which is the Postfix equivalent of inetd. For example, to instantiate
+up to 10 content filtering processes on demand:
+
+    /etc/postfix/master.cf:
+        localhost:10025     inet  n      n      n      -      10     spawn
+            user=filter argv=/some/where/filter localhost 10026
+
+"filter" is a dedicated local user account.  The user will never
+log in, and can be given a "*" password and non-existent shell and
+home directory.  This user handles all potentially dangerous mail
+content - that is why it should be a separate account.
+
+In the above example, Postfix listens on port localhost:10025.  If
+you want to have your filter listening on port localhost:10025
+instead of Postfix, then you must run your filter as a stand-alone
+program.
+
+Note: the localhost port 10025 SMTP server filter should announce
+itself as "220 localhost...".  Postfix aborts delivery when it
+connects to an SMTP server that uses the same hostname as Postfix
+("host <servername> greeted me with my own hostname"), because that
+normally means you have a mail delivery loop problem.
+
+The example here assumes that the /some/where/filter command is a
+PERL script. PERL has modules that make talking SMTP easy. The
+command-line specifies that mail should be sent back into Postfix
+via localhost port 10026.
+
+The simplest content filter just copies SMTP commands and data
+between its inputs and outputs. If it has a problem, all it has to
+do is to reply to an input of `.' with `550 content rejected', and
+to disconnect without sending `.' on the connection that injects
+mail back into Postfix.
+
+The job of the content filter is to either bounce mail with a
+suitable diagnostic, or to feed the mail back into Postfix through
+a dedicated listener on port localhost 10026:
+
+    /etc/postfix/master.cf:
+        localhost:10026     inet  n      -      n      -      10      smtpd
+            -o content_filter= 
+            -o local_recipient_maps=
+            -o relay_recipient_maps=
+            -o myhostname=localhost.domain.tld
+            -o smtpd_helo_restrictions=
+            -o smtpd_client_restrictions=
+            -o smtpd_sender_restrictions=
+            -o smtpd_recipient_restrictions=permit_mynetworks,reject
+            -o mynetworks=127.0.0.0/8
+
+Warning for Postfix version 2 users: in this SMTP server after the
+content filter, do not override main.cf settings for virtual_alias_maps
+or virtual_alias_domains. That would cause mail to be rejected with
+"User unknown".
+
+This SMTP server has the same process limit as the "filter" master.cf
+entry.
+
+The "-o content_filter=" requests no content filtering for incoming
+mail.
+
+The "-o local_recipient_maps=" and "-o relay_recipient_maps=" avoid
+unnecessary table lookups.
+
+The "-o myhostname=localhost.domain.tld" avoids false alarms ("host
+<servername> greeted me with my own hostname") if your content
+filter is based on a proxy that simply relays SMTP commands.
+
+The "-o smtpd_xxx_restrictions" and "-o mynetworks=127.0.0.0/8"
+turn off UCE controls that would only waste time here.
+
+Squeezing out more performance
+==============================
+
+Many refinements are possible, such as running a specially-configured
+smtp delivery agent for feeding mail into the content filter, and
+turning off address rewriting before content filtering.
+
+As the example below shows, things quickly become very complex,
+because a lot of main.cf like information gets listed in the
+master.cf file. This makes the system hard to understand.
+
+Even worse, details change as Postfix evolves and different
+configuration parameters are implemented by different programs.
+
+If you need to squeeze out more performance, it is probably simpler
+to run multiple Postfix instances, one before and one after the
+content filter. That way, each instance can have simple main.cf
+and master.cf files, each instance can have its own mail queue,
+and the system will be easier to understand.
+
+As before, we will set up a content filtering program that receives
+SMTP mail via localhost port 10025, and that submits SMTP mail back
+into Postfix via localhost port 10026.
+
+      .......................................
+      :                Postfix              :
+   ----->smtpd \                            :
+      :         -pre-cleanup-\       /local---->
+   ---->pickup /              -queue-       :
+      :             -cleanup-/   |   \smtp----->
+      :     bounces/    ^        v          :
+      : and locally     |        v          :
+      :   forwarded   smtpd     scan        :
+      :    messages   10026      |          :
+      ...........................|...........
+                        ^        |
+                        |        v
+                    ....|.............
+                    :   |      10025 :
+                    :   filter       :
+                    :                :
+                    ..................
+
+To enable content filtering in this manner, specify in main.cf a
+new parameter:
+
+/etc/postfix/main.cf:
+    content_filter = scan:localhost:10025
+
+/etc/postfix/master.cf:
+#
+# These are the usual input "smtpd" and local "pickup" servers already
+# present in master.cf. We add an option to select a non-default
+# cleanup service (defined further below).
+#
+smtp      inet  n       -       n       -       -       smtpd
+    -o cleanup_service_name=pre-cleanup
+pickup    fifo  n       -       n       60      1       pickup
+    -o cleanup_service_name=pre-cleanup
+#
+# ------------------------------------------------------------------
+#
+# This is the cleanup daemon that handles messages in front of
+# the content filter. It does header_checks and body_checks (if
+# any), but does no virtual alias or canonical address mapping,
+# so that mail passes through your content filter with the original
+# recipient addresses mostly intact.
+#
+# Virtual alias or canonical address mapping happens in the second
+# cleanup phase after the content filter. This gives the content_filter
+# access to *largely* unmodified addresses for maximum flexibility.
+#
+# Some sites may specifically want to perform canonical or virtual
+# address mapping in front of the content_filter.  In that case you
+# still have to enable address rewriting in the after-filter cleanup
+# instance, in order to correctly process forwarded mail or bounced
+# mail.
+#
+pre-cleanup         unix  n      -      n      -       0      cleanup
+        -o canonical_maps=
+        -o sender_canonical_maps=
+        -o recipient_canonical_maps=
+        -o masquerade_domains=
+        -o virtual_alias_maps=
+#
+# ------------------------------------------------------------------
+#
+# This is the delivery agent that injects mail into the content
+# filter.  It is tuned for low concurrency, because most content
+# filters burn CPU and use lots of memory.  The process limit of 10
+# re-enforces the effect of $default_destination_concurrency_limit.
+# Even without an explicit process limit, the concurrency is bounded
+# because all messages heading into the content filter have the same
+# destination.
+#
+scan                unix  -      -      n      -      10      smtp
+#
+# ------------------------------------------------------------------
+#
+# This is the SMTP listener that receives filtered messages from
+# the content filter. It *MUST* clear the content_filter
+# parameter to avoid loops, and use a different hostname to avoid
+# triggering the Postfix SMTP loop detection code.
+#
+# This "smtpd" uses the normal cleanup service which is also used
+# for bounces and for internally forwarded mail.
+#
+# The parameters from mynetworks onward disable all access
+# control other than insisting on connections from one of the IP
+# addresses of the host. This is typically overkill, but can
+# reduce resource usage, if the default restrictions use lots of
+# tables.
+#
+localhost:10026     inet  n      -      n      -       -      smtpd
+    -o content_filter= 
+    -o myhostname=localhost.domain.tld
+    -o local_recipient_maps=
+    -o relay_recipient_maps=
+    -o mynetworks=127.0.0.0/8
+    -o mynetworks_style=host
+    -o smtpd_restriction_classes=
+    -o smtpd_client_restrictions=
+    -o smtpd_helo_restrictions=
+    -o smtpd_sender_restrictions=
+    -o smtpd_recipient_restrictions=permit_mynetworks,reject
+#
+# Do not override main.cf settings here for virtual_alias_maps or
+# virtual_mailbox_maps. This causes mail to be rejected with "User
+# unknown in virtual (alias|mailbox) recipient table".
+#
+# ------------------------------------------------------------------
+#
+# This is the normal cleanup daemon for use after content filtering.
+# No header or body checks, because those have already been taken
+# care of by the pre-cleanup service before the content filter.
+# 
+# The normal cleanup instance does all the virtual alias and canonical
+# address mapping that was disabled in the pre-cleanup instance before
+# the content filter. This rewriting must be done even when you didn't
+# disable address rewriting in the pre-cleanup instance, in order to
+# correctly process bounces and locally forwarded mail.
+#
+cleanup            unix  n      -      n      -       0      cleanup
+    -o header_checks=
+    -o mime_header_checks=
+    -o nested_header_checks=
+    -o body_checks=
+#
+# ------------------------------------------------------------------
+#
+# The normal "smtp" delivery agent for contrast with "scan".
+#
+smtp                unix  -      -      n      -      -       smtp
+
+The above example causes Postfix to add one content filtering record
+to each incoming mail message, with content scan:localhost:10025.
+You can use the same syntax as in the right-hand side of a Postfix
+transport table.  The content filtering records are added by the
+smtpd and pickup servers.
+
+The "scan" transport is a dedicated instance of the "smtp" delivery
+agent for injecting messages into the SMTP content filter. Using
+a dedicated "smtp" transport allows one to tune it for the specific
+task of delivering mail to a local content filter (low latency,
+low concurrency, throughput dependent on predictably low latency).
+
+See the previous example for setting up the content filter with
+the Postfix spawn service; you can of course use any server that
+can be run stand-alone outside the Postfix environment.
+
+Filtering mail from outside users only
+======================================
+
+The easiest approach is to configure ONE Postfix instance with TWO
+SMTP server addresses in master.cf:
+
+- One SMTP server address for inside users only that never invokes
+  content filtering.
+
+- One SMTP server address for outside users that always invokes
+  content filtering.
+
+/etc/postfix.master.cf:
+    # SMTP service for internal users only, no content filtering.
+    1.2.3.4:smtp        inet  n       -       n       -       -       smtpd
+        -o smtpd_client_restrictions=permit_mynetworks,reject
+    127.0.0.1:smtp      inet  n       -       n       -       -       smtpd
+        -o smtpd_client_restrictions=permit_mynetworks,reject
+
+    # SMTP service for external users, with content filtering.
+    1.2.3.5:smtp        inet  n       -       n       -       -       smtpd
+        -o content_filter=foo:bar
+
+Getting really nasty
+====================
+
+The above filtering configurations are static. Mail that follows
+a given path is either always filtered or it is never filtered. As
+of Postfix 2.0 you can also turn on content filtering on the fly.
+The Postfix UCE features allow you to specify a filtering action
+on the fly:
+
+    FILTER foo:bar
+
+You can do this in smtpd access maps as well as the cleanup server's
+header/body_checks.  This feature must be used with great care:
+you must disable all the UCE features in the after-filter smtpd
+and cleanup daemons or else you will have a content filtering loop.
+
+Limitations:
+
+- There can be only one content filter action per message.
+
+- FILTER actions from smtpd access maps and header/body_checks take
+  precedence over filters specified with the main.cf content_filter 
+  parameter.
+
+- Only the last FILTER action from smtpd access maps or from
+  header/body_checks takes effect.
+
+- The same content filter is applied to all the recipients of a
+  given message.

+ 222 - 0
VIRTUAL_VACATION/INSTALL.TXT

@@ -0,0 +1,222 @@
+######################################
+# Virtual Vacation for Postfix Admin #
+######################################
+#
+# Postfix Admin (Virtual Vacation)
+# Originally authored by Mischa Peters <mischa at high5 dot net>
+# Copyright (c) 2002 - 2005 High5!
+# Licensed under GPL for more info check GPL-LICENSE.TXT
+#
+
+REQUIRED!
+---------
+There are a bunch of Perl modules which need installing, depending on your 
+distribution these may be available through your package management tool, or
+will need installing through CPAN.
+
+A full list of required modules can be found in the source of vacation.pl.
+
+It obviously relies on Perl
+
+About Virtual Vacation
+----------------------
+The vacation script runs as service within Postfix's master.cf configuration file.
+Mail is sent to the vacation service via a transport table mapping.
+When users mark themselves as away on vacation, an alias is added to their account 
+sending a copy of all mail to them to the vacation service.
+
+e.g. mail to billy@goat.com will be delivered to 
+    billy@goat.com AND 
+    billy#goat.com@autoreply.goat.com
+
+Mail to @autoreply.goat.com is caught by the vacation.pl script and a reply 
+will be sent based on various settings. By default a reply is only sent once.
+
+
+Install Virtual Vacation
+------------------------
+
+1. Create a local account
+-------------------------
+
+Create a dedicated local user account called "vacation". 
+This user handles all potentially dangerous mail content - that is why it
+should be a separate account.
+
+Do not use "nobody", and most certainly do not use "root" or "postfix".  The
+user will never log in, and can be given a "*" password and non-existent
+shell and home directory.
+
+Also create a separate "vacation" group.
+
+This should look like this:
+
+#/etc/passwd
+vacation:*:65501:65501:Virtual Vacation:/nonexistent:/sbin/nologin
+
+#/etc/group
+vacation:*:65501:
+
+
+2. Create a log directory or log file
+-------------------------------------
+
+If you want to log to a file ($log_to_file), create a log directory or an 
+empty log file.
+
+This file or directory needs to be writeable for the "vacation" user.
+
+Note: If you are logging to syslog, you can skip this step.
+
+
+3. Install vacation.pl
+----------------------
+
+Create a directory /usr/lib/postfixadmin/ and copy the vacation.pl file to it:
+
+  $ mkdir /usr/lib/postfixadmin
+  $ cp vacation.pl /usr/lib/postfixadmin/vacation.pl
+  $ chown -R root:vacation /usr/lib/postfixadmin
+  $ chmod 750 /usr/lib/postfixadmin/ /usr/lib/postfixadmin/vacation.pl
+
+Which will then look something like:
+
+-rwxr-x---   1 root  vacation  3356 Dec 21 00:00 vacation.pl*
+
+
+4. Setup the transport type
+---------------------------
+Define the transport type in the Postfix master file:
+
+#/etc/postfix/master.cf:
+vacation    unix  -       n       n       -       -       pipe
+  flags=Rq user=vacation argv=/usr/lib/postfixadmin/vacation.pl -f ${sender} -- ${recipient}
+
+5. Setup the transport maps file
+--------------------------------
+
+Tell Postfix to use a transport maps file, so add the following to your
+Postfix main.cf:
+
+#/etc/postfix/main.cf:
+transport_maps = hash:/etc/postfix/transport
+
+Then add the transport definition to the newly created transport file.
+Obviously, change yourdomain.com to your own domain. This can be any
+arbitrary domain, and it is easiest if you just choose one that will be used
+for all your domains.
+
+#/etc/postfix/transport
+autoreply.yourdomain.com	vacation:
+
+(You may need to create an entry in /etc/hosts for your non-existant domain)
+
+Execute "postmap /etc/postfix/transport" to build the hashed database.
+
+Execute "postfix reload" to complete the change.
+
+
+
+
+6. Configure vacation.pl
+------------------------
+
+The perl vacation.pl script needs to know which database you are using, and also
+how to connect to the database.
+
+Namely :
+
+Change any variables starting with '$db_' and '$db_type' to either 'mysql' or 'pgsql'.
+
+Change the $vacation_domain variable to match what you entered in your /etc/postfix/transport 
+file.
+
+You can do this in two ways:
+
+a) edit vacation.pl directly (not recommended!)
+
+b) create /etc/postfixadmin/vacation.conf and enter your settings there
+
+   Just use perl syntax there to fill the config variables listed in vacation.pl
+   (without the "our" keyword). Example:
+   $db_username = 'mail';
+
+   To make sure nobody except vacation.pl can read your vacation.conf (including the
+   database password), run
+
+   $ chown root:vacation /etc/postfixadmin/vacation.conf
+   $ chmod 640 /etc/postfixadmin/vacation.conf
+
+
+7. Check the alias expansion
+----------------------------
+
+Depending on your setup, you may have multiple 'smtpd' service definitions within 
+your postfix master.cf file. This is especially the case if you are also using AMAVIS or
+another content filtering system when mail is re-injected into Postfix using the smtpd daemon.
+
+If you are, it's likely that alias expansion may happen more than once, in which case you 
+may see vacation-style responses duplicated. To suppress this behaviour, you need to add:
+
+  -o receive_override_options=no_address_mappings
+
+For example :
+
+smtp      inet  n       -       -       -       12       smtpd
+    -o content_filter=amavis:[127.0.0.50]:10024
+    -o receive_override_options=no_address_mappings
+
+127.0.0.1:10025 inet    n   -   -   -   - smtpd
+    -o smtpd_autorized_xforward_hosts=127.0.0.0/8
+    -o smtpd_client_restrictions=
+    -o smtpd_helo_restrictions=
+    -o smtpd_sender_restrictions=
+    -o smtpd_recipient_restrictions=permit_mynetworks,reject
+    -o mynetworks=127.0.0.0/8
+    -o receive_override_options=no_header_body_checks
+
+	^^^ Alias expansion occurs here, so we don't want it to happen again for the
+		first smtpd daemon (above). If you have per-user settings in amavis,
+		you might want to have no_address_mappings in the smtpd on port 10025
+		instead.
+
+
+8. Security
+-----------
+
+If security is an issue for you, read ../DOCUMENTS/Security.txt
+
+
+
+
+What do these files do?
+-----------------------
+When a user enables a vacation message on their account, the alias
+definition is changed so that in addition to delivering to their own
+mailbox, it also delivers to a dummy alias which calls the vacation.pl
+program. In other words, if joeuser@domain.com enables their vacation, the
+entry in the alias database table will deliver mail to
+joeuser@something.com, as well as
+joeuser#something.com@autoreply.yourdomain.com
+
+vacation.pl then checks the database to see wether a user is on holiday and
+what message to send back. Make sure that vacation.pl is able to communicate
+to your database. You have to specify the database, username and password for 
+it as described in the "Configure vacation.pl" section.
+
+NOTE: Make sure that the path to perl in vacation.pl is correct.
+
+
+I'm in trouble!
+---------------
+When something is not working there are a couple of files that you can have
+a look at. The most important one is your maillog (usually in /var/log/).
+
+Vacation.pl also has some debugging and logging capabilties. Check the top
+of vacation.pl.
+
+
+Done!
+-----
+When this is all in place you need to have a look at the Postfix Admin
+config.inc.php. Here you need to enable Virtual Vacation for the site.

+ 22 - 0
VIRTUAL_VACATION/index.php

@@ -0,0 +1,22 @@
+<?php
+// 
+// Postfix Admin 
+// by Mischa Peters <mischa at high5 dot net>
+// Copyright (c) 2002 - 2005 High5!
+// Licensed under GPL for more info check GPL-LICENSE.TXT
+//
+// File: index.php
+//
+// Template File: -none-
+//
+// Template Variables:
+//
+// -none-
+//
+// Form POST \ GET Variables:
+//
+// -none-
+//
+header ("Location: ../login.php");
+exit;
+?>

+ 22 - 0
VIRTUAL_VACATION/tests/asterisk-email.txt

@@ -0,0 +1,22 @@
+Return-Path: <www-data@palepurple.co.uk>
+X-Original-To: david@example.org
+Delivered-To: david@example.org
+Received: by mail.palepurple.co.uk (Postfix, from userid 33)
+	id 1942F894CF9; Fri,  1 Aug 2008 11:23:45 +0100 (BST)
+To: "" <david@example.org>
+Subject: New Phone call - annotate it!
+X-PHP-Script: admin.palepurple.co.uk/contacts/dispatch.php for 78.105.97.55
+From: "asterisk@example.org" <asterisk@example.org>
+Date: Fri, 01 Aug 2008 11:23:45 +0100
+Content-Type: text/plain; charset="iso-8859-1"
+Content-Transfer-Encoding: quoted-printable
+Content-Disposition: inline
+Message-Id: <20080801102345.1942F894CF9@mail.palepurple.co.uk>
+Content-Length: 250
+Lines: 5
+
+
+=0AVisit the following URL(s) to annotate these phone calls... :=0A=0A htt=
+ps://admin.palepurple.co.uk/contacts/phone_communication/browse.php=0Ahttp=
+s://admin.palepurple.co.uk/contacts/phone_communication/view.php?phone_com=
+munication_id=3D3532

+ 55 - 0
VIRTUAL_VACATION/tests/facebook.txt

@@ -0,0 +1,55 @@
+Return-Path: <notification+meynbxsa@facebookmail.com>
+X-Original-To: david@example.org
+Delivered-To: david@example.org
+Received: by mail.palepurple.co.uk (Postfix, from userid 1007)
+	id B735A894CF8; Mon,  4 Aug 2008 16:28:13 +0100 (BST)
+Received: from localhost (localhost [127.0.0.1])
+	by mail.palepurple.co.uk (Postfix) with ESMTP id 79230894CF9
+	for <david@example.org>; Mon,  4 Aug 2008 16:28:13 +0100 (BST)
+X-Virus-Scanned: by Amavis+SpamAssassin+ClamAV and more at palepurple.co.uk
+X-Spam-Score: -3.565
+X-Spam-Level: 
+X-Spam-Status: No, score=-3.565 tagged_above=-99 required=5 tests=[AWL=0.035,
+	BAYES_00=-2.599, RCVD_IN_DNSWL_LOW=-1, SPF_PASS=-0.001]
+Received: from mail.palepurple.co.uk ([127.0.0.50])
+	by localhost (oak.palepurple.co.uk [127.0.0.50]) (amavisd-new, port 10024)
+	with ESMTP id AajG3+FXGWMd for <david@example.org>;
+	Mon,  4 Aug 2008 16:28:10 +0100 (BST)
+Received: from mx-out.facebook.com (outmail003.ash1.tfbnw.net [69.63.184.103])
+	by mail.palepurple.co.uk (Postfix) with ESMTP id 36DD4894CF8
+	for <david@example.org>; Mon,  4 Aug 2008 16:28:09 +0100 (BST)
+Received: from www.new.facebook.com (intlb01-mip1.sctm.tfbnw.net [10.1.240.6])
+	by mx-out.facebook.com [email023.ash1.facebook.com] (8.13.7/8.13.6) with ESMTP id m74FS8Oa030908
+	for <david@example.org>; Mon, 4 Aug 2008 08:28:09 -0700
+X-Facebook: from zuckmail ([207.118.59.216]) 
+	by www.new.facebook.com with HTTP (ZuckMail);
+Date: Mon, 4 Aug 2008 08:28:08 -0700
+To: David Goodwin <david@example.org>
+From: Facebook <notification+meynbxsa@facebookmail.com>
+Reply-to: noreply <noreply@facebookmail.com>
+Subject: Mark Spencer also commented on Jon Masters's note...
+Message-ID: <dummycontentgoeshere27efe2cde474@www.new.facebook.com>
+X-Priority: 3
+X-Mailer: ZuckMail [version 1.00]
+X-Facebook-Notify: note_reply
+Errors-To: notification+meynbxsa@facebookmail.com
+MIME-Version: 1.0
+Content-Transfer-Encoding: 8bit
+Content-Type: text/plain; charset="UTF-8"
+Content-Length: 374
+Lines: 14
+
+Mark also commented on Jon Masters's note "Visiting the UK"
+
+To read all the comments, follow the link below:
+
+http://www.facebook.com/n/?note.php&note_id=whatever
+
+Thanks,
+The Facebook Team
+
+___
+Want to control which emails you receive from Facebook? Go to:
+http://www.facebook.com/editaccount.php?notifications&md=sheepmightfly
+
+

+ 43 - 0
VIRTUAL_VACATION/tests/mail-myself.txt

@@ -0,0 +1,43 @@
+Return-Path: <david@example.org>
+X-Original-To: david@example.org
+Delivered-To: david@example.org
+Received: by mail.palepurple.co.uk (Postfix, from userid 1007)
+	id 83AE0894CF8; Tue,  5 Aug 2008 20:15:53 +0100 (BST)
+Received: from localhost (localhost [127.0.0.1])
+	by mail.palepurple.co.uk (Postfix) with ESMTP id 4A249894CF9
+	for <david@example.org>; Tue,  5 Aug 2008 20:15:53 +0100 (BST)
+X-Virus-Scanned: by Amavis+SpamAssassin+ClamAV and more at palepurple.co.uk
+X-Spam-Score: -2.836
+X-Spam-Level: 
+X-Spam-Status: No, score=-2.836 tagged_above=-99 required=5 tests=[AWL=-0.237,
+	BAYES_00=-2.599]
+Received: from mail.palepurple.co.uk ([127.0.0.50])
+	by localhost (oak.palepurple.co.uk [127.0.0.50]) (amavisd-new, port 10024)
+	with ESMTP id gHB1TKpjKIKX for <david@example.org>;
+	Tue,  5 Aug 2008 20:15:50 +0100 (BST)
+Received: from irc.palepurple.co.uk (irc.palepurple.co.uk [89.16.169.131])
+	by mail.palepurple.co.uk (Postfix) with ESMTP id CAF82894CF8
+	for <david@example.org>; Tue,  5 Aug 2008 20:15:50 +0100 (BST)
+Received: by irc.palepurple.co.uk (Postfix, from userid 1000)
+	id 8869450146; Tue,  5 Aug 2008 20:15:50 +0100 (BST)
+Date: Tue, 5 Aug 2008 20:15:50 +0100
+From: David Goodwin <david@example.org>
+To: david@example.org, fred@example.org, barney@example.org, rover@example.org,
+    roger@example.org
+Subject: test email
+Message-ID: <20080805191549.GA27905@codepoets.co.uk>
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii
+Content-Disposition: inline
+X-GnuPG-Key-URL: http://codepoets.co.uk/files/pubkey.txt
+X-PGP-Key: 0x117957A6
+User-Agent: Mutt/1.5.13 (2006-08-11)
+Content-Length: 136
+Lines: 7
+
+hello world; this is in plain text only.
+
+-- 
+David Goodwin 
+
+[ http://www.codepoets.co.uk       ]

+ 110 - 0
VIRTUAL_VACATION/tests/mailing-list.txt

@@ -0,0 +1,110 @@
+Return-Path: <fw-general-return-20540-david=example.org@lists.zend.com>
+X-Original-To: david@example.org
+Delivered-To: david@example.org
+Received: by mail.palepurple.co.uk (Postfix, from userid 1007)
+	id A41BE894CF8; Tue,  5 Aug 2008 19:46:09 +0100 (BST)
+Received: from localhost (localhost [127.0.0.1])
+	by mail.palepurple.co.uk (Postfix) with ESMTP id 6786E894CF9
+	for <david@example.org>; Tue,  5 Aug 2008 19:46:09 +0100 (BST)
+X-Virus-Scanned: by Amavis+SpamAssassin+ClamAV and more at palepurple.co.uk
+X-Spam-Score: -2.478
+X-Spam-Level: 
+X-Spam-Status: No, score=-2.478 tagged_above=-99 required=5 tests=[AWL=0.545,
+	BAYES_00=-2.599, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-1,
+	SPF_HELO_NEUTRAL=0.576, SPF_PASS=-0.001]
+Received: from mail.palepurple.co.uk ([127.0.0.50])
+	by localhost (oak.palepurple.co.uk [127.0.0.50]) (amavisd-new, port 10024)
+	with ESMTP id F7C1kX6O4LsN for <david@example.org>;
+	Tue,  5 Aug 2008 19:46:01 +0100 (BST)
+Received: from www.zend.com (lists.zend.com [67.15.86.102])
+	by mail.palepurple.co.uk (Postfix) with SMTP id 83287894CF8
+	for <david@example.org>; Tue,  5 Aug 2008 19:46:01 +0100 (BST)
+Received: (qmail 28760 invoked by uid 505); 5 Aug 2008 18:45:46 -0000
+Mailing-List: contact fw-general-help@lists.zend.com; run by ezmlm
+Precedence: bulk
+List-Post: <mailto:fw-general@lists.zend.com>
+List-Help: <mailto:fw-general-help@lists.zend.com>
+List-Unsubscribe: <mailto:fw-general-unsubscribe@lists.zend.com>
+List-Subscribe: <mailto:fw-general-subscribe@lists.zend.com>
+Delivered-To: mailing list fw-general@lists.zend.com
+Received: (qmail 28753 invoked from network); 5 Aug 2008 18:45:46 -0000
+DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws;
+  s=s1024; d=yahoo.com;
+  h=Received:X-Mailer:Date:From:Subject:To:Cc:MIME-Version:Content-Type:Message-ID;
+  b=RX7cjkrkpdsfHOXg2TRzzF2P5UXe0S5UVRucVl9FdqyE070/mV2za8ehvsGVRTh11tjkhkzh9QJoijpzHTTyu8F4HUHHoql4wUS6zJJC/PgdcCpBVXf0Im4RkyXqhIOAndNk1d9tCPmUnKDjC6SvO6i0Xd5+CqFH9f+eaKzUFAI=;
+X-Mailer: YahooMailRC/1042.48 YahooMailWebService/0.7.218
+Date: Tue, 5 Aug 2008 11:45:44 -0700 (PDT)
+From: =?iso-8859-1?Q?P=E1draic_Brady?= <some.one@yahoo.com>
+To: Some one Else <someone.else@gmail.com>
+Cc: Zend Framework General <overthere@example.org>
+MIME-Version: 1.0
+Content-Type: multipart/alternative; boundary="0-283769398-1217961944=:498"
+Message-ID: <944272.498.qm@web55003.mail.re4.yahoo.com>
+X-pstn-neptune: 0/0/0.00/0
+X-pstn-levels:     (S:99.90000/99.90000 CV:99.0000 P:95.9108 M:97.0282 C:98.6951 )
+X-pstn-settings: 1 (0.1500:0.1500) cv gt3 gt2 gt1 p m c 
+X-pstn-addresses: from <some.one@yahoo.com> [638/31] 
+Subject: Re: [fw-general] Zend_Paginate how to integrate?
+Content-Length: 4072
+Lines: 60
+
+--0-283769398-1217961944=:498
+Content-Type: text/plain; charset=iso-8859-1
+Content-Transfer-Encoding: quoted-printable
+
+I do pretty much what Giorgio suggests and tie it into the Model as much as=
+ possible - fits into the concept of doing as little as possible in your co=
+ntrollers by pushing reusable code into Model (or other) objects if appropr=
+iate.=0A=0A P=E1draic Brady=0A=0Ahttp://blog.astrumfutura.com=0Ahttp://www.=
+patternsforphp.com=0AOpenID Europe Foundation=0A=0A=0A=0A=0A----- Original =
+Message ----=0AFrom: Giorgio Sironi <whatever@example.org>=0ATo=
+: Axel W=FCstemann <awu@xxxqbus.de>=0ACc: fw-general@xxlists.zend.com=0ASent: Tu=
+esday, August 5, 2008 7:20:48 PM=0ASubject: Re: [fw-general] Zend_Paginate =
+how to integrate?=0A=0A2008/8/5 Axel W=FCstemann <awuxxxx@qbus.de>:=0A> Yes, it=
+ seems to me a good idea to let reside the paginator in the model.=0A> What=
+ happens in the controller? How the view comes into play?=0A=0AThe controll=
+er simply calls the method prepareArticles with the right=0Apage (a param o=
+f request) and pass the paginator to the view, so the=0Aview script can use=
+ it for helpers like PaginationControl. Note that=0Abecause the paginator g=
+oes into the view, it return only=0Amultidimensional array and not objects.=
+=0A=0A-- =0AGiorgio Sironi=0APiccolo Principe & Ossigeno Scripter=0Ahttp://=
+www.sourceforge.net/projects/ossigeno=0A
+--0-283769398-1217961944=:498
+Content-Type: text/html; charset=iso-8859-1
+Content-Transfer-Encoding: quoted-printable
+
+<html><head><style type=3D"text/css"><!-- DIV {margin:0px;} --></style></he=
+ad><body><div style=3D"font-family:Courier New,courier,monaco,monospace,san=
+s-serif;font-size:10pt"><font style=3D"font-family: times new roman,new yor=
+k,times,serif;" size=3D"3">I do pretty much what Giorgio suggests and tie i=
+t into the Model as much as possible - fits into the concept of doing as li=
+ttle as possible in your controllers by pushing reusable code into Model (o=
+r other) objects if appropriate.</font><br><div>&nbsp;</div><span style=3D"=
+color: rgb(0, 0, 191);"><font style=3D"font-family: times new roman,new yor=
+k,times,serif;" size=3D"3"><span style=3D"font-weight: bold;">P=E1draic Bra=
+dy<br><br></span></font><span style=3D"font-style: italic;"><font style=3D"=
+font-family: times new roman,new york,times,serif;" size=3D"3"><a rel=3D"no=
+follow" target=3D"_blank" href=3D"http://blog.astrumfutura.com">http://blog=
+.astrumfutura.com</a><br><a rel=3D"nofollow" target=3D"_blank"
+ href=3D"http://www.patternsforphp.com">http://www.patternsforphp.com</a><b=
+r><a rel=3D"nofollow" target=3D"_blank" href=3D"http://www.openideurope.eu/=
+">OpenID Europe Foundation</a><br></font></span></span><div><br></div><div =
+style=3D"font-family: Courier New,courier,monaco,monospace,sans-serif; font=
+-size: 10pt;"><br><div style=3D"font-family: arial,helvetica,sans-serif; fo=
+nt-size: 10pt;">----- Original Message ----<br>From: Giorgio Sironi &lt;pic=
+coloprincipeazzurroxxxxx@gxxxmail.com&gt;<br>To: Axel W=FCstemann &lt;awuxx@qbus.de&g=
+t;<br>Cc: fw-general@xxxlists.zend.com<br>Sent: Tuesday, August 5, 2008 7:20:4=
+8 PM<br>Subject: Re: [fw-general] Zend_Paginate how to integrate?<br><br>=
+=0A2008/8/5 Axel W=FCstemann &lt;<a ymailto=3D"mailto:awuxxx@xxxqbus.de" href=3D"=
+mailto:awuxx@xxqbus.de">xxawu@qxxxbus.de</a>&gt;:<br>&gt; Yes, it seems to me a good=
+ idea to let reside the paginator in the model.<br>&gt; What happens in the=
+ controller? How the view comes into play?<br><br>The controller simply cal=
+ls the method prepareArticles with the right<br>page (a param of request) a=
+nd pass the paginator to the view, so the<br>view script can use it for hel=
+pers like PaginationControl. Note that<br>because the paginator goes into t=
+he view, it return only<br>multidimensional array and not objects.<br><br>-=
+- <br>Giorgio Sironi<br>Piccolo Principe &amp; Ossigeno Scripter<br><a href=
+=3D"http://www.sourceforge.net/projects/ossigeno" target=3D"_blank">http://=
+www.sourceforge.net/projects/ossigeno</a><br></div></div></div></body></htm=
+l>
+--0-283769398-1217961944=:498--

+ 105 - 0
VIRTUAL_VACATION/tests/spam.txt

@@ -0,0 +1,105 @@
+Return-Path: <mary@ccr.org>
+X-Original-To: david@codepoets.co.uk
+Delivered-To: david@codepoets.co.uk
+Received: by mail.palepurple.co.uk (Postfix, from userid 1007)
+	id A7BB7894CF8; Tue,  5 Aug 2008 19:32:19 +0100 (BST)
+Received: from localhost (localhost [127.0.0.1])
+	by mail.palepurple.co.uk (Postfix) with ESMTP id 673E4894CF9
+	for <david@codepoets.co.uk>; Tue,  5 Aug 2008 19:32:19 +0100 (BST)
+X-Quarantine-ID: <KOCPqIot+eWP>
+X-Virus-Scanned: by Amavis+SpamAssassin+ClamAV and more at palepurple.co.uk
+X-Spam-Flag: YES
+X-Spam-Score: 35.511
+X-Spam-Level: ***********************************
+X-Spam-Status: Yes, score=35.511 tagged_above=-99 required=5
+	tests=[BAYES_99=3.5, DIGEST_MULTIPLE=0.001, FH_HELO_EQ_D_D_D_D=0.001,
+	HELO_DYNAMIC_HCC=4.295, HELO_DYNAMIC_IPADDR2=4.395,
+	HTML_EXTRA_CLOSE=2.809, HTML_MESSAGE=0.001, PYZOR_CHECK=3.7,
+	RAZOR2_CF_RANGE_51_100=0.5, RAZOR2_CF_RANGE_E4_51_100=1.5,
+	RAZOR2_CF_RANGE_E8_51_100=1.5, RAZOR2_CHECK=0.5, RCVD_IN_PBL=0.905,
+	RDNS_DYNAMIC=0.1, TVD_RCVD_IP=1.931, URIBL_AB_SURBL=1.86,
+	URIBL_BLACK=1.955, URIBL_JP_SURBL=1.501, URIBL_OB_SURBL=1.5,
+	URIBL_RHS_DOB=1.083, URIBL_SC_SURBL=0.474, URIBL_WS_SURBL=1.5]
+X-Spam-Report:
+ *  3.5 BAYES_99 BODY: Bayesian spam probability is 99 to 100%
+ *      [score: 0.9982]
+ *  4.3 HELO_DYNAMIC_HCC Relay HELO'd using suspicious hostname (HCC)
+ *  4.4 HELO_DYNAMIC_IPADDR2 Relay HELO'd using suspicious hostname (IP addr
+ *       2)
+ *  0.0 FH_HELO_EQ_D_D_D_D Helo is d-d-d-d
+ *  1.9 TVD_RCVD_IP TVD_RCVD_IP
+ *  0.9 RCVD_IN_PBL RBL: Received via a relay in Spamhaus PBL
+ *      [189.31.157.78 listed in zen.spamhaus.org]
+ *  2.8 HTML_EXTRA_CLOSE BODY: HTML contains far too many close tags
+ *  0.0 HTML_MESSAGE BODY: HTML included in message
+ *  1.5 RAZOR2_CF_RANGE_E8_51_100 Razor2 gives engine 8 confidence level
+ *      above 50%
+ *      [cf: 100]
+ *  1.5 RAZOR2_CF_RANGE_E4_51_100 Razor2 gives engine 4 confidence level
+ *      above 50%
+ *      [cf: 100]
+ *  0.5 RAZOR2_CHECK Listed in Razor2 (http://razor.sf.net/)
+ *  0.5 RAZOR2_CF_RANGE_51_100 Razor2 gives confidence level above 50%
+ *      [cf: 100]
+ *  3.7 PYZOR_CHECK Listed in Pyzor (http://pyzor.sf.net/)
+ *  1.1 URIBL_RHS_DOB Contains an URI of a new domain (Day Old Bread)
+ *      [URIs: heartremember.com]
+ *  2.0 URIBL_BLACK Contains an URL listed in the URIBL blacklist
+ *      [URIs: heartremember.com]
+ *  1.9 URIBL_AB_SURBL Contains an URL listed in the AB SURBL blocklist
+ *      [URIs: heartremember.com]
+ *  1.5 URIBL_WS_SURBL Contains an URL listed in the WS SURBL blocklist
+ *      [URIs: heartremember.com]
+ *  1.5 URIBL_JP_SURBL Contains an URL listed in the JP SURBL blocklist
+ *      [URIs: heartremember.com]
+ *  1.5 URIBL_OB_SURBL Contains an URL listed in the OB SURBL blocklist
+ *      [URIs: heartremember.com]
+ *  0.5 URIBL_SC_SURBL Contains an URL listed in the SC SURBL blocklist
+ *      [URIs: heartremember.com]
+ *  0.0 DIGEST_MULTIPLE Message hits more than one network digest check
+ *  0.1 RDNS_DYNAMIC Delivered to trusted network by host with
+ *      dynamic-looking rDNS
+Received: from mail.palepurple.co.uk ([127.0.0.50])
+	by localhost (oak.palepurple.co.uk [127.0.0.50]) (amavisd-new, port 10024)
+	with ESMTP id KOCPqIot+eWP for <david@codepoets.co.uk>;
+	Tue,  5 Aug 2008 19:32:13 +0100 (BST)
+Received: from 189-31-157-78.gnace704.dsl.brasiltelecom.net.br (189-31-157-78.gnace704.dsl.brasiltelecom.net.br [189.31.157.78])
+	by mail.palepurple.co.uk (Postfix) with ESMTP id 02E02894CF8
+	for <postmaster@codepoets.co.uk>; Tue,  5 Aug 2008 19:32:11 +0100 (BST)
+Date: Tue, 05 Aug 2008 16:44:31 +0000
+Message-ID: <45605.clarke@shan>
+From: "ferd clarke" <mary@ccr.org>
+To: <postmaster@codepoets.co.uk>
+Subject: *** SPAM *** Super eustace proposition
+MIME-Version: 1.0
+Content-Type: multipart/alternative;
+	boundary="=_xjl52j6iKNOFLD"
+Content-Length: 628
+Lines: 26
+
+This is a multi-part message in MIME format.
+
+--=_xjl52j6iKNOFLD
+Content-Type: text/plain;
+	charset="iso-8859-1"
+Content-Transfer-Encoding: quoted-printable
+
+ view,  medicine todays best solution check out here
+--=_xjl52j6iKNOFLD
+Content-Type: text/html;
+	charset="iso-8859-1"
+Content-Transfer-Encoding: quoted-printable
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+<META http-equiv=3DContent-Type content=3D"text/html; =
+charset=3Diso-8859-1">
+</HEAD>
+<P> view,  medicine todays best solution <A =
+href=3D"http://heartremember.com">check out here</A></P>
+</BODY>
+</HTML>
+--=_xjl52j6iKNOFLD--
+
+

+ 21 - 0
VIRTUAL_VACATION/tests/teodor-smtp-envelope-headers.txt

@@ -0,0 +1,21 @@
+X-Original-To: david@example.org
+Delivered-To: david@example.org
+X-Virus-Scanned: amavisd-new at mx.ro 
+From: "Teodor Iacob" <david@example.org> 
+To: <david@example.org> 
+Subject: estsgf 
+Date: Mon, 19 Jan 2009 14:49:17 +0200 
+X-Mailer: Microsoft Office Outlook 11 
+X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.5579 
+Thread-Index: Acl6NFZyC+AImZ1WQSS0cPUO/Y2FqA== 
+X-BRO-MailScanner-Information: Please contact the ISP for more information 
+X-BRO-MailScanner-ID: n0JCoUwB014357 
+X-BRO-MailScanner: Found to be clean 
+X-MailScanner-From: david@example.org
+X-BRO-MailScanner-Watermark: 1232974231.00027@11VRmWFJ18WRflEdvrILlQ 
+ 
+dsgsgfsgfg 
+ 
+-- 
+ 
+Teodor Iacob 

+ 43 - 0
VIRTUAL_VACATION/tests/test-email.txt

@@ -0,0 +1,43 @@
+Return-Path: <david1@example.org>
+X-Original-To: david@example.org
+Delivered-To: david@example.org
+Received: by mail.palepurple.co.uk (Postfix, from userid 1007)
+	id 83AE0894CF8; Tue,  5 Aug 2008 20:15:53 +0100 (BST)
+Received: from localhost (localhost [127.0.0.1])
+	by mail.palepurple.co.uk (Postfix) with ESMTP id 4A249894CF9
+	for <david@example.org>; Tue,  5 Aug 2008 20:15:53 +0100 (BST)
+X-Virus-Scanned: by Amavis+SpamAssassin+ClamAV and more at palepurple.co.uk
+X-Spam-Score: -2.836
+X-Spam-Level: 
+X-Spam-Status: No, score=-2.836 tagged_above=-99 required=5 tests=[AWL=-0.237,
+	BAYES_00=-2.599]
+Received: from mail.palepurple.co.uk ([127.0.0.50])
+	by localhost (oak.palepurple.co.uk [127.0.0.50]) (amavisd-new, port 10024)
+	with ESMTP id gHB1TKpjKIKX for <david@example.org>;
+	Tue,  5 Aug 2008 20:15:50 +0100 (BST)
+Received: from irc.palepurple.co.uk (irc.palepurple.co.uk [89.16.169.131])
+	by mail.palepurple.co.uk (Postfix) with ESMTP id CAF82894CF8
+	for <david@example.org>; Tue,  5 Aug 2008 20:15:50 +0100 (BST)
+Received: by irc.palepurple.co.uk (Postfix, from userid 1000)
+	id 8869450146; Tue,  5 Aug 2008 20:15:50 +0100 (BST)
+Date: Tue, 5 Aug 2008 20:15:50 +0100
+From: David Goodwin <david1@example.org>
+To: "DG" <david@example.org>, "Fred@Work" <fred@example.org>, "Barney Rubble" 
+    <barney@example.org>, "Rover Dog" <rover@example.org>, roger@example.org
+Subject: test email
+Message-ID: <20080805191549.GA27905@codepoets.co.uk>
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii
+Content-Disposition: inline
+X-GnuPG-Key-URL: http://codepoets.co.uk/files/pubkey.txt
+X-PGP-Key: 0x117957A6
+User-Agent: Mutt/1.5.13 (2006-08-11)
+Content-Length: 136
+Lines: 7
+
+hello world; this is in plain text only.
+
+-- 
+David Goodwin 
+
+[ http://www.codepoets.co.uk       ]

+ 63 - 0
VIRTUAL_VACATION/tests/test.sh

@@ -0,0 +1,63 @@
+#!/bin/bash
+
+# This is an extremely simplistic test harness for the vacation functionality.
+# To judge success or failure you (unfortunately) need to tail -f the log file, which sucks a little,
+# but hey - it's better than no tests, right?
+
+# Original author: David Goodwin (hence all the palepurple.co.uk references!)
+# It would be nice if we could get some sort of status back from the vacation.pl script to indicate mail being sent, or not.
+
+
+
+export PGPASSWORD=gingerdog
+export PGUSER=dg
+export PGDATABASE=postfix
+export PGHOST=pgsqlserver
+
+
+echo "DELETE FROM vacation WHERE email = 'david@example.org'" | psql
+
+# First time around, there should be no vacation record for david@example.org, so these should all not cause mail to be sent.
+# some will trip up spam/mailing list protection etc though
+echo
+echo "NONE OF THESE SHOULD RESULT IN MAIL BEING SENT"
+echo 
+
+#echo "On: mailing-list.txt:"
+# cat mailing-list.txt | perl ../vacation.pl -t yes -f fw-general-return-20540-david=example.org@lists.zend.com -- david\#example.org@autoreply.example.org 
+echo "On: test-email.txt:"
+cat test-email.txt | perl ../vacation.pl -t yes -f david1@example.org -- david\#example.org@autoreply.example.org 
+echo "On: spam.txt:"
+cat spam.txt | perl ../vacation.pl -t yes -f mary@ccr.org -- david\#example.org@autoreply.example.org 
+echo "On: asterisk-email.txt:"
+cat asterisk-email.txt | perl ../vacation.pl -t yes -f www-data@palepurple.net -- david\#example.org@autoreply.example.org 
+# do not reply to facebook
+echo "On: facebook.txt:"
+cat facebook.txt | perl ../vacation.pl -t yes -f notification+meynbxsa@facebookmail.com -- david\#example.org@autoreply.example.org 
+# do not send yourself a vacation notice.
+echo "On: mail-myself.txt:"
+cat mail-myself.txt | perl ../vacation.pl -t yes -f david@example.org -- david\#example.org@autoreply.example.org 
+# do not send yourself a vacation notice.
+echo "On: teodor-smtp-envelope-headers.txt:"
+cat teodor-smtp-envelope-headers.txt | perl ../vacation.pl -t yes -f david@example.org -- david\#example.org@autoreply.example.org
+
+
+echo "INSERT INTO vacation (email, subject, body, created, active, domain) VALUES ('david@example.org', 'I am on holiday', 'Yeah, that is right', NOW(), true, 'example.org')" | psql 
+
+
+echo 
+echo "VACATION TURNED ON "
+echo 
+echo "Still ignore mailing list"
+cat mailing-list.txt | perl ../vacation.pl -t yes -f fw-general-return-20540-david=example.org@lists.zend.com -- david\#example.org@autoreply.example.org
+echo " * Should send vacation message for this *"
+cat test-email.txt | perl ../vacation.pl -t yes -f david1@example.org -- david\#example.org@autoreply.example.org
+echo " * Spam - no vacation message for this"
+cat spam.txt | perl ../vacation.pl -t yes -f mary@xxccr.org -- david\#example.org@autoreply.example.org
+echo " * OK - should send vacation message for this"
+cat asterisk-email.txt | perl ../vacation.pl -t yes -f www-data@palepurple.net -- david\#example.org@autoreply.example.org
+echo " * Facebook - should not send vacation message for"
+cat facebook.txt | perl ../vacation.pl -t yes -f notification+meynbxsa@facebookmail.com -- david\#example.org@autoreply.example.org
+echo " * Mailing myself - should not send vacation message"
+cat mail-myself.txt | perl ../vacation.pl -t yes -f david@example.org -- david\#example.org@autoreply.example.org
+echo

+ 723 - 0
VIRTUAL_VACATION/vacation.pl

@@ -0,0 +1,723 @@
+#!/usr/bin/perl -w
+#
+# Virtual Vacation 4.0r1
+#
+# $Revision: 1676 $
+# Originally by Mischa Peters <mischa at high5 dot net>
+#
+# Copyright (c) 2002 - 2005 High5!
+# Licensed under GPL for more info check GPL-LICENSE.TXT
+#
+# Additions:
+# 2004/07/13  David Osborn <ossdev at daocon.com>
+#             strict, processes domain level aliases, more
+#             subroutines, send reply from original to address
+#
+# 2004/11/09  David Osborn <ossdev at daocon.com>
+#             Added syslog support
+#             Slightly better logging which includes messageid
+#             Avoid infinite loops with domain aliases
+#
+# 2005-01-19  Troels Arvin <troels at arvin.dk>
+#             PostgreSQL-version.
+#             Normalized DB schema from one vacation table ("vacation")
+#             to two ("vacation", "vacation_notification"). Uses
+#             referential integrity CASCADE action to simplify cleanup
+#             when a user is no longer on vacation.
+#             Inserting variables into queries stricly by prepare()
+#             to try to avoid SQL injection.
+#             International characters are now handled well.
+#
+# 2005-01-21  Troels Arvin <troels at arvin.dk>
+#             Uses the Email::Valid package to avoid sending notices
+#             to obviously invalid addresses.
+#
+# 2007-08-15  David Goodwin <david at palepurple.co.uk>
+#             Use the Perl Mail::Sendmail module for sending mail
+#             Check for headers that start with blank lines (patch from forum)
+#
+# 2007-08-20  Martin Ambroz <amsys at trustica.cz>
+#             Added initial Unicode support
+#
+# 2008-05-09  Fabio Bonelli <fabiobonelli at libero.it>
+#             Properly handle failed queries to vacation_notification.
+#             Fixed log reporting.
+#
+# 2008-07-29  Patch from Luxten to add repeat notification after timeout. See:
+#             https://sourceforge.net/tracker/index.php?func=detail&aid=2031631&group_id=191583&atid=937966
+#
+# 2008-08-01  Luigi Iotti <luigi at iotti dot biz>
+#             Use envelope sender/recipient instead of using
+#             From: and To: header fields;
+#             Support to good vacation behavior as in
+#             http://www.irbs.net/internet/postfix/0707/0954.html
+#             (needs to be tested);
+#
+# 2008-08-04  David Goodwin <david at palepurple dot co dot uk>
+#             Use Log4Perl
+#             Added better testing (and -t option)
+#
+# 2009-06-29  Stevan Bajic <stevan at bajic.ch>
+#             Add Mail::Sender for SMTP auth + more flexibility
+#
+# 2009-07-07  Stevan Bajic <stevan at bajic.ch>
+#             Add better alias lookups
+#             Check for more heades from Anti-Virus/Anti-Spam solutions
+#
+# 2009-08-10  Sebastian <reg9009 at yahoo dot de>
+#             Adjust SQL query for vacation timeframe. It is now possible to set from/until date for vacation message.
+#
+# 2012-04-1   Nikolaos Topp <info at ichier.de>
+#             Add configuration parameter $smtp_client in order to get mails through
+#             postfix helo-checks, using check_helo_access whitelist without permitting 'localhost' default style stuff
+#
+# 2012-04-19  Jan Kruis <jan at crossreference dot nl>
+#             change SQL query for vacation into function.
+#             Add sub get_interval()
+#             Gives the user the option to set the interval time ( 0 = one reply, 1 = autoreply, > 1 = Delay reply ) 
+#             See https://sourceforge.net/tracker/?func=detail&aid=3508083&group_id=191583&atid=937966
+#
+# 2012-06-18  Christoph Lechleitner <christoph.lechleitner@iteg.at>
+#             Add capability to include the subject of the original mail in the subject of the vacation message.
+#             A good vacation subject could be: 'Re: $SUBJECT'
+#             Also corrected log entry about "Already informed ..." to show the $orig_from, not $email
+#
+
+# Requirements - the following perl modules are required:
+# DBD::Pg or DBD::mysql
+# Mail::Sender, Email::Valid MIME::Charset, Log::Log4perl, Log::Dispatch, MIME::EncWords and GetOpt::Std
+#
+# You may install these via CPAN, or through your package tool.
+# CPAN: 'perl -MCPAN -e shell', then 'install Module::Whatever'
+#
+# On Debian based systems :
+#   libmail-sender-perl
+#   libdbd-pg-perl
+#   libemail-valid-perl
+#   libmime-perl
+#   liblog-log4perl-perl
+#   liblog-dispatch-perl
+#   libgetopt-argvfile-perl
+#   libmime-charset-perl (currently in testing, see instructions below)
+#   libmime-encwords-perl (currently in testing, see instructions below)
+#
+# Note: When you use this module, you may start seeing error messages
+# like "Cannot insert a duplicate key into unique index
+# vacation_notification_pkey" in your system logs. This is expected
+# behavior, and not an indication of trouble (see the "already_notified"
+# subroutine for an explanation).
+#
+# You must also have the Email::Valid and MIME-tools perl-packages
+# installed. They are available in some package collections, under the
+# names 'perl-Email-Valid' and 'perl-MIME-tools', respectively.
+# One such package collection (for Linux) is:
+# http://dag.wieers.com/home-made/apt/packages.php
+#
+
+use DBI;
+use MIME::Base64;
+use MIME::EncWords qw(:all);
+use Email::Valid;
+use strict;
+use Mail::Sender;
+use Getopt::Std;
+use Log::Log4perl qw(get_logger :levels);
+use File::Basename;
+
+# ========== begin configuration ==========
+
+# IMPORTANT: If you put passwords into this script, then remember
+# to restrict access to the script, so that only the vacation user
+# can read it.
+
+# db_type - uncomment one of these
+our $db_type = 'Pg';
+#our $db_type = 'mysql';
+
+# leave empty for connection via UNIX socket
+our $db_host = '';
+
+# connection details
+our $db_username = 'user';
+our $db_password = 'password';
+our $db_name     = 'postfix';
+
+our $vacation_domain = 'autoreply.example.org';
+
+# smtp server used to send vacation e-mails
+our $smtp_server = 'localhost';
+our $smtp_server_port = 25;
+
+# this is the helo we [the vacation script] use on connection; you may need to change this to your hostname or something,
+# depending upon what smtp helo restrictions you have in place within Postfix. 
+our $smtp_client = 'localhost';
+
+# SMTP authentication protocol used for sending.
+# Can be 'PLAIN', 'LOGIN', 'CRAM-MD5' or 'NTLM'
+# see "perldoc Mail::Sender" (search for "auth") for more options and details
+# Leave it blank if you don't use authentication
+our $smtp_auth = undef;
+# username used to login to the server
+our $smtp_authid = 'someuser';
+# password used to login to the server
+our $smtp_authpwd = 'somepass';
+
+# This specifies the mail 'from' name which is shown to recipients of vacation replies.
+# If you leave it empty, the vacation mail will contain: 
+# From: <original@recipient.domain>
+# If you specify something here you'd instead see something like :
+# From: Some Friendly Name <original@recipient.domain>
+our $friendly_from = '';
+
+# use TLS for the SMTP connection?
+# while in general this would be a good idea, TLS with Mail::Sender 0.8.22 is buggy - https://rt.cpan.org/Public/Bug/Display.html?id=85438
+our $smtp_tls_allowed = 0;
+
+# Set to 1 to enable logging to syslog.
+our $syslog = 0;
+
+# path to logfile, when empty logging is suppressed
+# change to e.g. /dev/null if you want nothing logged.
+# if we can't write to this, and $log_to_file is 1 (below) the script will abort.
+our $logfile='/var/log/vacation.log';
+# 2 = debug + info, 1 = info only, 0 = error only
+our $log_level = 2;
+# Whether to log to file or not, 0 = do not write to a log file
+our $log_to_file = 0;
+
+# notification interval, in seconds
+# set to 0 to notify only once
+# e.g. 1 day ...
+#our $interval = 60*60*24;
+# disabled by default
+our $interval = 0;
+
+# Send vacation mails to do-not-reply email addresses.
+# By default vacation email addresses will be sent.
+# For now emails from bounce|do-not-reply|facebook|linkedin|list-|myspace|twitter won't
+# be answered when $custom_noreply_pattern is set to 1.
+# default = 0
+our $custom_noreply_pattern = 0;
+our $noreply_pattern = 'bounce|do-not-reply|facebook|linkedin|list-|myspace|twitter'; 
+
+
+# instead of changing this script, you can put your settings to /etc/mail/postfixadmin/vacation.conf
+# or /etc/postfixadmin/vacation.conf just use Perl syntax there to fill the variables listed above
+# (without the "our" keyword). Example:
+# $db_username = 'mail';
+if (-f '/etc/mail/postfixadmin/vacation.conf') {
+    require '/etc/mail/postfixadmin/vacation.conf';
+} elsif (-f '/etc/postfixadmin/vacation.conf') {
+    require '/etc/postfixadmin/vacation.conf';
+}
+
+# =========== end configuration ===========
+
+if($log_to_file == 1) {
+    if (( ! -w $logfile ) && (! -w dirname($logfile))) {
+        # Cannot log; no where to write to.
+        die("Cannot create logfile : $logfile");
+    }
+}
+
+my ($from, $to, $cc, $replyto , $subject, $messageid, $lastheader, $smtp_sender, $smtp_recipient, %opts, $test_mode, $logger);
+
+$subject='';
+$messageid='unknown';
+
+# Setup a logger...
+#
+getopts('f:t:', \%opts) or die "Usage: $0 [-t yes] -f sender -- recipient\n\t-t for testing only\n";
+$opts{f} and $smtp_sender = $opts{f} or die '-f sender not present on command line';
+$test_mode = 0;
+$opts{t} and $test_mode = 1;
+$smtp_recipient = shift or die 'recipient not given on command line';
+
+my $log_layout = Log::Log4perl::Layout::PatternLayout->new('%d %p> %F:%L %M - %m%n');
+
+if($test_mode == 1) {
+    $logger = get_logger();
+    # log to stdout
+    my $appender = Log::Log4perl::Appender->new('Log::Dispatch::Screen');
+    $appender->layout($log_layout);
+    $logger->add_appender($appender);
+    $logger->debug('Test mode enabled');
+} else {
+    $logger = get_logger();
+    if($log_to_file == 1) {
+        # log to file
+        my $appender = Log::Log4perl::Appender->new(
+            'Log::Dispatch::File',
+            filename => $logfile,
+            mode => 'append');
+
+        $appender->layout($log_layout);
+        $logger->add_appender($appender);
+    }
+
+    if($syslog == 1) {
+        my $syslog_appender = Log::Log4perl::Appender->new(
+            'Log::Dispatch::Syslog',
+            facility => 'mail',
+        );
+        $logger->add_appender($syslog_appender);
+    }
+}
+
+# change to $DEBUG, $INFO or $ERROR depending on how much logging you want.
+$logger->level($ERROR);
+if($log_level == 1) {
+    $logger->level($INFO);
+}
+if($log_level == 2) {
+    $logger->level($DEBUG);
+}
+
+binmode (STDIN,':encoding(UTF-8)');
+
+my $dbh;
+if ($db_host) {
+    $dbh = DBI->connect("DBI:$db_type:dbname=$db_name;host=$db_host","$db_username", "$db_password", { RaiseError => 1 });
+} else {
+    $dbh = DBI->connect("DBI:$db_type:dbname=$db_name","$db_username", "$db_password", { RaiseError => 1 });
+}
+
+if (!$dbh) {
+    $logger->error('Could not connect to database'); # eval { } etc better here?
+    exit(0);
+}
+
+my $db_true; # MySQL and PgSQL use different values for TRUE, and unicode support...
+if ($db_type eq 'mysql') {
+    $dbh->do('SET CHARACTER SET utf8;');
+    $db_true = '1';
+} else { # Pg
+    $dbh->do("SET CLIENT_ENCODING TO 'UTF8'");
+    $db_true = 'True';
+}
+
+# used to detect infinite address lookup loops
+my $loopcount=0;
+
+#
+# Get interval_time for email user from the vacation table 
+#
+sub get_interval {
+    my ($to) = @_;
+    my $query = qq{SELECT interval_time  FROM vacation  WHERE  email=? };
+    my $stm = $dbh->prepare($query) or panic_prepare($query);
+    $stm->execute($to) or panic_execute($query," 'email='$to'");
+    my $rv = $stm->rows;
+    if ($rv == 1) {
+        my @row = $stm->fetchrow_array;
+        my $interval = $row[0] ;
+        return $interval ;
+    } else {
+        return 0 ;
+    }
+}
+
+
+sub already_notified {
+    my ($to, $from) = @_;
+    my $logger = get_logger();
+    my $query;
+
+    # delete old notifications
+    if ($db_type eq 'Pg') {
+        $query = qq{DELETE FROM vacation_notification USING vacation WHERE vacation.email = vacation_notification.on_vacation AND on_vacation = ? AND notified = ? AND notified_at < vacation.activefrom;};
+    } else { # mysql
+        $query = qq{DELETE vacation_notification.* FROM vacation_notification LEFT JOIN vacation ON vacation.email = vacation_notification.on_vacation WHERE on_vacation = ? AND notified = ? AND notified_at < vacation.activefrom};
+    }
+    my $stm = $dbh->prepare($query);
+    if (!$stm) {
+        $logger->error("Could not prepare query (trying to delete old vacation notifications) :'$query' to: $to, from:$from");
+        return 1;
+    }
+    $stm->execute($to,$from);
+
+    $query = qq{INSERT into vacation_notification (on_vacation,notified) values (?,?)};
+    $stm = $dbh->prepare($query);
+    if (!$stm) {
+        $logger->error("Could not prepare query '$query' to: $to, from:$from");
+        return 1;
+    }
+    $stm->{'PrintError'} = 0;
+    $stm->{'RaiseError'} = 0;
+    if (!$stm->execute($to,$from)) {
+        my $e=$dbh->errstr;
+
+# Violation of a primary key constraint may happen here, and that's
+# fine. All other error conditions are not fine, however.
+        if ($e !~ /(?:_pkey|^Duplicate entry)/) {
+            $logger->error("Failed to insert into vacation_notification table (to:$to from:$from error:'$e' query:'$query')");
+            # Let's play safe and notify anyway
+            return 1;
+        }
+
+        $interval = get_interval($to);
+
+        if ($interval) {
+            if ($db_type eq 'Pg') {
+                $query = qq{SELECT extract( epoch from (NOW()-notified_at))::int FROM vacation_notification WHERE on_vacation=? AND notified=?};
+            } else { # mysql
+                $query = qq{SELECT NOW()-notified_at FROM vacation_notification WHERE on_vacation=? AND notified=?};
+            }
+            $stm = $dbh->prepare($query) or panic_prepare($query);
+            $stm->execute($to,$from) or panic_execute($query,"on_vacation='$to', notified='$from'");
+            my @row = $stm->fetchrow_array;
+            my $int = $row[0];
+            if ($int > $interval) {
+                $logger->info("[Interval elapsed, sending the message]: From: $from To:$to");
+                $query = qq{UPDATE vacation_notification SET notified_at=NOW() WHERE on_vacation=? AND notified=?};
+                $stm = $dbh->prepare($query);
+                if (!$stm) {
+                    $logger->error("Could not prepare query '$query' (to: '$to', from: '$from')");
+                    return 0;
+                }
+                if (!$stm->execute($to,$from)) {
+                    $e=$dbh->errstr;
+                    $logger->error("Error from running query '$query' (to: '$to', from: '$from', error: '$e')");
+                }
+                return 0;
+            } else {
+                $logger->debug("Notification interval not elapsed; not sending vacation reply (to: '$to', from: '$from')");
+                return 1;
+            }
+        } else {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+#
+# Check to see if there is a vacation record against a specific email address. 
+#
+sub check_for_vacation {
+    my ($email_to_check) =@_;
+    my $query = qq{SELECT email FROM vacation WHERE email=? and active=$db_true and activefrom <= NOW() and activeuntil >= NOW()};
+    my $stm = $dbh->prepare($query) or panic_prepare($query);
+    $stm->execute($email_to_check) or panic_execute($query,"email='$email_to_check'");
+    my $rv = $stm->rows;
+    return $rv;
+}
+
+
+# try and determine if email address has vacation turned on; we
+# have to do alias searching, and domain aliasing resolution for this.
+# If found, return ($num_matches, $real_email);
+sub find_real_address {
+    my ($email) = @_;
+    my $logger = get_logger();
+    if (++$loopcount > 20) {
+        $logger->error("find_real_address loop! (more than 20 attempts!) currently: $email");
+        exit(1);
+    }
+    my $realemail = '';
+    my $rv = check_for_vacation($email);
+
+# Recipient has vacation
+    if ($rv == 1) {
+        $realemail = $email;
+        $logger->debug("Found '$email' has vacation active");
+    } else {
+        my $vemail = $email;
+        $vemail =~ s/\@/#/g;
+        $vemail = $vemail . "\@" . $vacation_domain;
+        $logger->debug("Looking for alias records that '$email' resolves to with vacation turned on");
+        my $query = qq{SELECT goto FROM alias WHERE address=? AND (goto LIKE ? OR goto LIKE ? OR goto LIKE ? OR goto = ?)};
+        my $stm = $dbh->prepare($query) or panic_prepare($query);
+        $stm->execute($email,"$vemail,%","%,$vemail","%,$vemail,%", "$vemail") or panic_execute($query,"address='$email'");
+        $rv = $stm->rows;
+
+
+# Recipient is an alias, check if mailbox has vacation
+        if ($rv == 1) {
+            my @row = $stm->fetchrow_array;
+            my $alias = $row[0];
+            if ($alias =~ /,/) {
+                for (split(/\s*,\s*/, lc($alias))) {
+                    my $singlealias = $_;
+                    $logger->debug("Found alias \'$singlealias\' for email \'$email\'. Looking if vacation is on for alias.");
+                    $rv = check_for_vacation($singlealias);
+# Alias has vacation
+                    if ($rv == 1) {
+                        $realemail = $singlealias;
+                        last;
+                    }
+                }
+            } else {
+                $rv = check_for_vacation($alias);
+# Alias has vacation
+                if ($rv == 1) {
+                    $realemail = $alias;
+                }
+            }
+
+# We have to look for alias domain (domain1 -> domain2)
+        } else {
+            my ($user, $domain) = split(/@/, $email);
+            $logger->debug("Looking for alias domain for $domain / $email / $user");
+            $query = qq{SELECT target_domain FROM alias_domain WHERE alias_domain=?};
+            $stm = $dbh->prepare($query) or panic_prepare($query);
+            $stm->execute($domain) or panic_execute($query,"alias_domain='$domain'");
+            $rv = $stm->rows;
+
+# The domain has a alias domain level alias
+            if ($rv == 1) {
+                my @row = $stm->fetchrow_array;
+                my $alias_domain_dest = $row[0];
+                ($rv, $realemail) = find_real_address ("$user\@$alias_domain_dest");
+
+# We still have to look for domain level aliases...
+            } else {
+                my ($user, $domain) = split(/@/, $email);
+                $logger->debug("Looking for domain level aliases for $domain / $email / $user");
+                $query = qq{SELECT goto FROM alias WHERE address=?};
+                $stm = $dbh->prepare($query) or panic_prepare($query);
+                $stm->execute("\@$domain") or panic_execute($query,"address='\@$domain'");
+                $rv = $stm->rows;
+
+# The recipient has a domain level alias
+                if ($rv == 1) {
+                    my @row = $stm->fetchrow_array;
+                    my $wildcard_dest = $row[0];
+                    my ($wilduser, $wilddomain) = split(/@/, $wildcard_dest);
+
+# Check domain alias
+                    if ($wilduser) {
+                        ($rv, $realemail) = find_real_address ($wildcard_dest);
+                    } else {
+                        ($rv, $realemail) = find_real_address ("$user\@$wilddomain");
+                    }
+                } else {
+                    $logger->debug("No domain level alias present for $domain / $email / $user");
+                }
+            }
+        }
+    }
+    return ($rv, $realemail);
+}
+
+# sends the vacation mail to the original sender.
+#
+sub send_vacation_email {
+    my ($email, $orig_from, $orig_to, $orig_messageid, $orig_subject, $test_mode) = @_;
+    my $logger = get_logger();
+    $logger->debug("Asked to send vacation reply to $email thanks to $orig_messageid");
+    my $query = qq{SELECT subject,body FROM vacation WHERE email=?};
+    my $stm = $dbh->prepare($query) or panic_prepare($query);
+    $stm->execute($email) or panic_execute($query,"email='$email'");
+    my $rv = $stm->rows;
+    if ($rv == 1) {
+        my @row = $stm->fetchrow_array;
+        if (already_notified($email, $orig_from) == 1) {
+            $logger->debug("Already notified $orig_from, or some error prevented us from doing so");
+            return;
+        }
+
+        $logger->debug("Will send vacation response for $orig_messageid: FROM: $email (orig_to: $orig_to), TO: $orig_from; VACATION SUBJECT: $row[0] ; VACATION BODY: $row[1]");
+
+        my $subject = $row[0];
+        $subject =~ s/\$SUBJECT/$orig_subject/g;
+        if ($subject ne $row[0]) {
+          $logger->debug("Patched Subject of vacation message to: $subject");
+        }
+
+        my $body = $row[1];
+        my $from = $email;
+        my $to = $orig_from;
+        my %smtp_connection;
+        %smtp_connection = (
+            'smtp' => $smtp_server,
+            'port' => $smtp_server_port,
+            'auth' => $smtp_auth,
+            'authid' => $smtp_authid,
+            'authpwd' => $smtp_authpwd,
+            'tls_allowed' => $smtp_tls_allowed,
+            'smtp_client' => $smtp_client,
+            'skip_bad_recipients' => 'true',
+            'encoding' => 'Base64',
+            'ctype' => 'text/plain; charset=UTF-8',
+            'headers' => 'Precedence: junk',
+            'headers' => 'X-Loop: Postfix Admin Virtual Vacation',
+            'on_errors' => 'die', # raise exception on error
+        );
+        my %mail;
+        %mail = (
+            'subject' => encode_mimewords($subject, 'Charset', 'UTF-8'),
+            'from' => $from,
+            'fake_from' => $friendly_from . " <$from>",
+            'to' => $to,
+            'msg' => encode_base64($body)
+        );
+        if($test_mode == 1) {
+            $logger->info("** TEST MODE ** : Vacation response sent to $to from $from subject $subject (not) sent\n");
+            $logger->info(%mail);
+            return 0;
+        }
+        eval {
+            $Mail::Sender::NO_X_MAILER = 1;
+            my $sender = new Mail::Sender({%smtp_connection});
+            $sender->Open({%mail});
+            $sender->SendLineEnc($body);
+            $sender->Close();
+            $logger->debug("Vacation response sent to $to, from $from");
+        };
+        if ($@) {
+            $logger->error("Failed to send vacation response: $@ / " . $Mail::Sender::Error);
+        }
+    }
+}
+
+# Convert a (list of) email address(es) from RFC 822 style addressing to
+# RFC 821 style addressing. e.g. convert:
+#   "John Jones" <JJones@acme.com>, "Jane Doe/Sales/ACME" <JDoe@acme.com>
+# to:
+#   jjones@acme.com, jdoe@acme.com
+sub strip_address {
+    my ($arg) = @_;
+    if(!$arg) {
+        return '';
+    }
+    my @ok;
+    $logger = get_logger();
+    my @list;
+    @list = $arg =~ m/([\w\.\-\+\'\=_\^\|\$\/\{\}~\?\*\\&\!`\%]+\@[\w\.\-]+\w+)/g;
+    foreach(@list) {
+        #$logger->debug("Checking: $_");
+        my $temp = Email::Valid->address( -address => $_, -mxcheck => 0);
+        if($temp) {
+            push(@ok, $temp);
+        } else {
+            $logger->debug("Email not valid : $Email::Valid::Details");
+        }
+    }
+    # remove duplicates
+    my %seen = ();
+    my @uniq;
+    foreach my $item (@ok) {
+        push(@uniq, $item) unless $seen{$item}++
+    }
+
+    my $result = lc(join(', ', @uniq));
+    #$logger->debug("Result: $result");
+    return $result;
+}
+
+sub panic_prepare {
+    my ($arg) = @_;
+    my $logger = get_logger();
+    $logger->error("Could not prepare sql statement: '$arg'");
+    exit(0);
+}
+
+sub panic_execute {
+    my ($arg,$param) = @_;
+    my $logger = get_logger();
+    $logger->error("Could not execute sql statement - '$arg' with parameters '$param'");
+    exit(0);
+}
+
+# Make sure the email wasn't sent by someone who could be a mailing list etc; if it was,
+# then we abort after appropriate logging.
+sub check_and_clean_from_address {
+    my ($address) = @_;
+    my $logger = get_logger();
+
+    if($address =~ /^(noreply|postmaster|mailer\-daemon|listserv|majordomo|owner\-|request\-|bounces\-)/i ||
+        $address =~ /\-(owner|request|bounces)\@/i ||
+        ($custom_noreply_pattern == 1 && $address =~ /^.*($noreply_pattern).*/i) ) {
+            $logger->debug("sender $address contains $1 - will not send vacation message");
+            exit(0);
+        }
+    $address = strip_address($address);
+    if($address eq '') {
+        $logger->error("Address $address is not valid; exiting");
+        exit(0);
+    }
+    #$logger->debug("Address cleaned up to $address");
+    return $address;
+}
+########################### main #################################
+
+# Take headers apart
+$cc = '';
+$replyto = '';
+
+$logger->debug("Script argument SMTP recipient is : '$smtp_recipient' and smtp_sender : '$smtp_sender'");
+while (<STDIN>) {
+    last if (/^$/);
+    if (/^\s+(.*)/ and $lastheader) { $$lastheader .= " $1"; next; }
+    elsif (/^from:\s*(.*)\n$/i) { $from = $1; $lastheader = \$from; }
+    elsif (/^to:\s*(.*)\n$/i) { $to = $1; $lastheader = \$to; }
+    elsif (/^cc:\s*(.*)\n$/i) { $cc = $1; $lastheader = \$cc; }
+    elsif (/^Reply\-to:\s*(.*)\s*\n$/i) { $replyto = $1; $lastheader = \$replyto; }
+    elsif (/^subject:\s*(.*)\n$/i) { $subject = $1; $lastheader = \$subject; }
+    elsif (/^message\-id:\s*(.*)\s*\n$/i) { $messageid = $1; $lastheader = \$messageid; }
+    elsif (/^x\-spam\-(flag|status):\s+yes/i) { $logger->debug("x-spam-$1: yes found; exiting"); exit (0); }
+    elsif (/^x\-facebook\-notify:/i) { $logger->debug('Mail from facebook, ignoring'); exit(0); }
+    elsif (/^precedence:\s+(bulk|list|junk)/i) { $logger->debug("precedence: $1 found; exiting"); exit (0); }
+    elsif (/^x\-loop:\s+postfix\ admin\ virtual\ vacation/i) { $logger->debug('x-loop: postfix admin virtual vacation found; exiting'); exit (0); }
+    elsif (/^Auto\-Submitted:\s*no/i) { next; }
+    elsif (/^Auto\-Submitted:/i) { $logger->debug('Auto-Submitted: something found; exiting'); exit (0); }
+    elsif (/^List\-(Id|Post|Unsubscribe):/i) { $logger->debug("List-$1: found; exiting"); exit (0); }
+    elsif (/^(x\-(barracuda\-)?spam\-status):\s+(yes)/i) { $logger->debug("$1: $3 found; exiting"); exit (0); }
+    elsif (/^(x\-dspam\-result):\s+(spam|bl[ao]cklisted)/i) { $logger->debug("$1: $2 found; exiting"); exit (0); }
+    elsif (/^(x\-(anti|avas\-)?virus\-status):\s+(infected)/i) { $logger->debug("$1: $3 found; exiting"); exit (0); }
+    elsif (/^(x\-(avas\-spam|spamtest|crm114|razor|pyzor)\-status):\s+(spam)/i) { $logger->debug("$1: $3 found; exiting"); exit (0); }
+    elsif (/^(x\-osbf\-lua\-score):\s+[0-9\/\.\-\+]+\s+\[([-S])\]/i) { $logger->debug("$1: $2 found; exiting"); exit (0); }
+    else {$lastheader = '' ; }
+}
+
+if($smtp_recipient =~ /\@$vacation_domain/) {
+    # the regexp used here could probably be improved somewhat, for now hope that people won't use # as a valid mailbox character.
+    my $tmp = $smtp_recipient;
+    $tmp =~ s/\@$vacation_domain//;
+    $tmp =~ s/#/\@/;
+    $logger->debug("Converted autoreply mailbox back to normal style - from $smtp_recipient to $tmp");
+    $smtp_recipient = $tmp;
+    undef $tmp;
+}
+
+# If either From: or To: are not set, exit
+if(!$from || !$to || !$messageid || !$smtp_sender || !$smtp_recipient) {
+    $logger->info("One of from=$from, to=$to, messageid=$messageid, smtp sender=$smtp_sender, smtp recipient=$smtp_recipient empty");
+    exit(0);
+}
+$logger->debug("Email headers have to: '$to' and From: '$from'");
+$to = strip_address($to);
+$cc = strip_address($cc);
+$from = check_and_clean_from_address($from);
+if($replyto ne '') {
+    # if reply-to is invalid, or looks like a mailing list, then we probably don't want to send a reply.
+    $replyto = check_and_clean_from_address($replyto);
+}
+$smtp_sender = check_and_clean_from_address($smtp_sender);
+$smtp_recipient = check_and_clean_from_address($smtp_recipient);
+
+if ($smtp_sender eq $smtp_recipient) {
+    $logger->debug("smtp sender $smtp_sender and recipient $smtp_recipient are the same; aborting");
+    exit(0);
+}
+
+for (split(/,\s*/, lc($to)), split(/,\s*/, lc($cc))) {
+    my $header_recipient = strip_address($_);
+    if ($smtp_sender eq $header_recipient) {
+        $logger->debug("sender header $smtp_sender contains recipient $header_recipient (mailing myself?)");
+        exit(0);
+    }
+}
+
+my ($rv, $email) = find_real_address($smtp_recipient);
+if ($rv == 1) {
+    $logger->debug("Attempting to send vacation response for: $messageid to: $smtp_sender, $smtp_recipient, $email (test_mode = $test_mode)");
+    send_vacation_email($email, $smtp_sender, $smtp_recipient, $messageid, $subject, $test_mode);
+} else {
+    $logger->debug("SMTP recipient $smtp_recipient which resolves to $email does not have an active vacation (rv: $rv, email: $email)");
+}
+
+0;
+
+#/* vim: set expandtab softtabstop=4 tabstop=4 shiftwidth=4: */

+ 140 - 0
backup.php

@@ -0,0 +1,140 @@
+<?php
+/** 
+ * Postfix Admin 
+ * 
+ * LICENSE 
+ * This source file is subject to the GPL license that is bundled with  
+ * this package in the file LICENSE.TXT. 
+ * 
+ * Further details on the project are available at http://postfixadmin.sf.net 
+ * 
+ * @version $Id: backup.php 1582 2013-11-16 00:00:53Z christian_boltz $ 
+ * @license GNU GPL v2 or later. 
+ * 
+ * File: backup.php
+ * Used to save all settings - but only works for MySQL databases.
+ * Template File: -none-
+ *
+ * Template Variables: -none-
+ *
+ * Form POST \ GET Variables: -none-
+ */
+
+require_once('common.php');
+
+authentication_require_role('global-admin');
+
+(($CONF['backup'] == 'NO') ? header("Location: main.php") && exit : '1');
+
+// TODO: make backup supported for postgres
+if (db_pgsql()) {
+	flash_error('Sorry: Backup is currently not supported for your DBMS ('.$CONF['database_type'].').');
+	$smarty->assign ('smarty_template', 'message');
+	$smarty->display ('index.tpl');
+   die;
+}
+
+if (safeget('download') == "") {
+	$smarty->assign ('smarty_template', 'backupwarning');
+	$smarty->display ('index.tpl');
+   die;
+}
+
+# Still here? Then let's create the database dump...
+
+/*
+	SELECT attnum,attname,typname,atttypmod-4,attnotnull,atthasdef,adsrc
+	AS def FROM pg_attribute,pg_class,pg_type,pg_attrdef
+	WHERE pg_class.oid=attrelid AND pg_type.oid=atttypid
+	AND attnum>0 AND pg_class.oid=adrelid AND adnum=attnum AND atthasdef='t' AND lower(relname)='admin'
+	UNION SELECT attnum,attname,typname,atttypmod-4,attnotnull,atthasdef,''
+	AS def FROM pg_attribute,pg_class,pg_type
+	WHERE pg_class.oid=attrelid
+	AND pg_type.oid=atttypid
+	AND attnum>0
+	AND atthasdef='f'
+	AND lower(relname)='admin'
+$db = $_GET['db'];
+$cmd = "pg_dump -c -D -f /tix/miner/miner.sql -F p -N -U postgres $db";
+$res = `$cmd`;
+// Alternate: $res = shell_exec($cmd);
+echo $res; 
+*/
+
+if ($_SERVER['REQUEST_METHOD'] == "GET")
+{
+   umask (077);
+   $path = (ini_get('upload_tmp_dir') != '') ? ini_get('upload_tmp_dir') : '/tmp';
+   date_default_timezone_set(@date_default_timezone_get()); # Suppress date.timezone warnings
+   $filename = "postfixadmin-" . date ("Ymd") . "-" . getmypid() . ".sql";
+   $backup = $path . DIRECTORY_SEPARATOR . $filename;
+
+   $header = "#\n# Postfix Admin $version\n# Date: " . date ("D M j G:i:s T Y") . "\n#\n";
+
+   if (!$fh = fopen ($backup, 'w'))
+   {
+      flash_error("<div class=\"error_msg\">Cannot open file ($backup)</div>");
+		$smarty->assign ('smarty_template', 'message');
+		$smarty->display ('index.tpl');
+   } 
+   else
+   {
+      fwrite ($fh, $header);
+      
+      $tables = array(
+         'admin',
+         'alias',
+         'alias_domain',
+         'config',
+         'domain',
+         'domain_admins',
+         'fetchmail',
+         'log',
+         'mailbox',
+		 'quota',
+		 'quota2',
+         'vacation',
+         'vacation_notification'
+      );
+
+      for ($i = 0 ; $i < sizeof ($tables) ; ++$i)
+      {
+         $result = db_query ("SHOW CREATE TABLE " . table_by_key($tables[$i]));
+         if ($result['rows'] > 0)
+         {
+            while ($row = db_array ($result['result']))
+            {
+               fwrite ($fh, "$row[1];\n\n");
+            }
+         }
+      }   
+
+      for ($i = 0 ; $i < sizeof ($tables) ; ++$i)
+      {
+         $result = db_query ("SELECT * FROM " . table_by_key($tables[$i]));
+         if ($result['rows'] > 0)
+         {
+            while ($row = db_assoc ($result['result']))
+            {
+                $fields = array_keys($row);
+                $values = array_values($row);
+                $values = array_map('escape_string', $values);
+
+               fwrite ($fh, "INSERT INTO ". $tables[$i] . " (". implode (',',$fields) . ") VALUES ('" . implode ('\',\'',$values) . "');\n");
+               $fields = "";
+               $values = "";
+            }
+         }
+      }
+   }
+   header ("Content-Type: text/plain");
+   header ("Content-Disposition: attachment; filename=\"$filename\"");
+   header ("Content-Transfer-Encoding: binary");
+   header ("Content-Length: " . filesize("$backup"));
+   header ("Content-Description: Postfix Admin");
+   $download_backup = fopen ("$backup", "r");
+   unlink ("$backup");
+   fpassthru ($download_backup);
+}
+/* vim: set expandtab softtabstop=3 tabstop=3 shiftwidth=3: */
+?>

+ 102 - 0
broadcast-message.php

@@ -0,0 +1,102 @@
+<?php
+/** 
+ * Postfix Admin 
+ * 
+ * LICENSE 
+ * This source file is subject to the GPL license that is bundled with  
+ * this package in the file LICENSE.TXT. 
+ * 
+ * Further details on the project are available at http://postfixadmin.sf.net 
+ * 
+ * @version $Id: broadcast-message.php 1781 2015-04-06 22:44:51Z christian_boltz $ 
+ * @license GNU GPL v2 or later. 
+ * 
+ * File: broadcast-message.php
+ * Used to send a message to _ALL_ users with mailboxes on this server.
+ *
+ * Template File: broadcast-message.tpl
+ *
+ * Template Variables: -none-
+ *
+ * Form POST \ GET Variables:
+ *
+ * name
+ * subject
+ * message
+ */
+
+require_once('common.php');
+
+authentication_require_role('global-admin');
+
+if ($CONF['sendmail'] != 'YES') {
+   header("Location: main.php");
+   exit;
+}
+
+$smtp_from_email = smtp_get_admin_email();
+
+if ($_SERVER['REQUEST_METHOD'] == "POST")
+{
+   if (empty($_POST['subject']) || empty($_POST['message']) || empty($_POST['name']))
+   {
+      $error = 1;
+      flash_error($PALANG['pBroadcast_error_empty']);
+   }
+   else
+   {
+      $table_mailbox = table_by_key('mailbox');
+	  $table_alias = table_by_key('alias');
+      
+	  $q = "select username from $table_mailbox union select goto from $table_alias " .
+		   "where goto not in (select username from $table_mailbox)";
+
+      $result = db_query ($q);
+      if ($result['rows'] > 0)
+      {
+         mb_internal_encoding("UTF-8");
+         $b_name = mb_encode_mimeheader( $_POST['name'], 'UTF-8', 'Q');
+         $b_subject = mb_encode_mimeheader( $_POST['subject'], 'UTF-8', 'Q');
+         $b_message = base64_encode($_POST['message']);
+
+         $i = 0;
+         while ($row = db_array ($result['result'])) {
+            $fTo = $row[0];
+            $fHeaders  = 'To: ' . $fTo . "\n";
+            $fHeaders .= 'From: ' . $b_name . ' <' . $smtp_from_email . ">\n";
+            $fHeaders .= 'Subject: ' . $b_subject . "\n";
+            $fHeaders .= 'MIME-Version: 1.0' . "\n";
+            $fHeaders .= 'Content-Type: text/plain; charset=UTF-8' . "\n";
+            $fHeaders .= 'Content-Transfer-Encoding: base64' . "\n";
+
+            $fHeaders .= $b_message;
+
+            if (!smtp_mail ($fTo, $smtp_from_email, $fHeaders))
+            {
+               flash_error(Config::lang_f('pSendmail_result_error', $fTo));
+            }
+            else
+            {
+               flash_info(Config::lang_f('pSendmail_result_success', $fTo));
+            }
+         }
+      }
+		flash_info($PALANG['pBroadcast_success']);
+		$smarty->assign ('smarty_template', 'message');
+		$smarty->display ('index.tpl');
+//		echo '<p>'.$PALANG['pBroadcast_success'].'</p>';
+   }
+}
+
+if ($_SERVER['REQUEST_METHOD'] == "GET" || $error == 1)
+{
+	$smarty->assign ('smtp_from_email', $smtp_from_email);
+	$smarty->assign ('error', $error);
+	$smarty->assign ('smarty_template', 'broadcast-message');
+	$smarty->display ('index.tpl');
+
+//   include ("templates/broadcast-message.tpl");
+}
+
+/* vim: set expandtab softtabstop=3 tabstop=3 shiftwidth=3: */
+?>

Some files were not shown because too many files changed in this diff