2 commits - bin/create_mailbox.pl bin/delete_mailbox.pl bin/reconstruct.pl bin/rename_mailbox.pl bin/setquota.pl bin/transfer_mailbox_folder.pl bin/transfer_mailbox.pl bin/undelete_mailbox.pl lib/Kolab lib/Kolab.pm

Jeroen van Meeuwen vanmeeuwen at kolabsys.com
Tue Jun 14 16:48:56 CEST 2011


 bin/create_mailbox.pl          |   23 ++++
 bin/delete_mailbox.pl          |   16 ++
 bin/rename_mailbox.pl          |   20 +++
 bin/setquota.pl                |   17 +++
 bin/transfer_mailbox.pl        |   18 +++
 bin/transfer_mailbox_folder.pl |   16 ++
 lib/Kolab.pm                   |  219 ++++++++++++++++++++++++++++++++++++-----
 lib/Kolab/Cyrus.pm             |   36 +++++-
 8 files changed, 338 insertions(+), 27 deletions(-)

New commits:
commit 381f418a1f6cd0ac1aae4da79f1ca4e33dad0a04
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Tue Jun 14 09:45:46 2011 -0500

    Provide new API calls to set quota, find a mailbox, etc.

diff --git a/lib/Kolab.pm b/lib/Kolab.pm
index f33ba28..91ae68c 100644
--- a/lib/Kolab.pm
+++ b/lib/Kolab.pm
@@ -331,7 +331,6 @@ This function reloads the configuration for the Kolab perl library.
 
     if (!($tempval = URI->new($config{'user_ldap_uri'}))) {
         &log('C', "Unable to parse user_ldap_uri `" . $config{'user_ldap_uri'} . "'", KOLAB_ERROR);
-#        exit(1);
         $error = 1;
     } else {
         $config{'user_ldap_ip'} = $tempval->host;
@@ -464,6 +463,7 @@ sub log
     } else {
         $text = $prefix . ': ' . $text;
     }
+
     syslog('info', "$text") if $config{'log_level'} >= $priority;
     print STDERR "$text\n" if $config{'debug'};
 }
@@ -510,12 +510,12 @@ Example usage:
 
 =cut
 
-    my $location = '';
-
     my $mailboxName = shift;
     my $mailHost = shift || 0;
     my $mailboxType = shift || 'user';
 
+    my $folder = '';
+
     my $connectAddress = (
             $mailHost ? $mailHost :
             ( $Kolab::config{'connect_addr'} ?
@@ -529,39 +529,150 @@ Example usage:
     # folder a boolean.
     my $sharedFolder = ( $mailboxType eq 'user' ? 0 : 1 );
 
-    Kolab::Cyrus::createMailbox( $cyrus, $mailboxName, $sharedFolder);
+    my $rc = Kolab::Cyrus::createMailbox( $cyrus, $mailboxName, $sharedFolder);
+
+    if (!$rc) {
+        Kolab::log("Could not create mailbox", KOLAB_ERROR);
+        exit $rc;
+    }
 
     my $mailboxPath = Kolab::Cyrus::createUid($mailboxName, $sharedFolder);
 
-    use Mail::IMAPClient;
+    my $location = Kolab::cyrusMurderFindMailbox( $cyrus, $mailboxPath);
 
-    my $imap = Mail::IMAPClient->new(
-            Server => $connectAddress,
-            User => $Kolab::config{'cyrus_admin'},
-            Password => $Kolab::config{'cyrus_admin_pw'},
-        );
+    my @mbox = split(/@/, $mailboxPath);
+
+    my $mailbox = $mbox[0];
+    my $domain = $mbox[1];
 
-    if (! $imap) {
-        die("Cannot connect to mail server '$connectAddress' to locate mailbox - $!");
+    $folder = $mailbox . '/Calendar@' . $domain;
+
+    $cyrus->createmailbox($folder);
+    $cyrus->mboxconfig($folder, '/vendor/kolab/folder-test', 'true') or
+        die("Could not set annotations");
+    $cyrus->mboxconfig($folder, '/vendor/kolab/folder-type', 'event.default') or
+        die("Could not set annotations");
+
+    $folder = $mailbox . '/Contacts@' . $domain;
+
+    $cyrus->createmailbox($folder);
+    $cyrus->mboxconfig($folder, '/vendor/kolab/folder-test', 'true') or
+        die("Could not set annotations");
+    $cyrus->mboxconfig($folder, '/vendor/kolab/folder-type', 'contact.default') or
+        die("Could not set annotations");
+
+    $folder = $mailbox . '/_Restore@' . $domain;
+    $cyrus->createmailbox($folder);
+    $cyrus->deleteacl($folder, $mailboxName);
+
+    $folder = $mailbox . '/_Archive@' . $domain;
+    $cyrus->createmailbox($folder);
+    $cyrus->deleteacl($folder, $mailboxName);
+
+    if ( !exists $config{'default_quota'} ) {
+        Kolab::cyrusMurderSetQuota($mailboxName, 0);
+    } else {
+        Kolab::cyrusMurderSetQuota($mailboxName, $config{'default_quota'});
     }
 
-    my @results = $imap->tag_and_run(qq/GETANNOTATION $mailboxPath "*" "value.shared"/);
+    return $location;
+}
 
-    $imap->logout;
+sub cyrusMurderSetQuota {
+    my $mailbox = shift;
+    my $quota = shift || 0;
+    my $mailboxType = shift || 'user';
 
-    foreach my $r (@results) {
-        $r =~ s/\r//g;
-        $r =~ s/\n//g;
-        if ($r =~ /\/vendor\/cmu\/cyrus-imapd\/server" \("value.shared" "(.*)"\)$/) {
-            $location = $1;
-        }
+    my $connectAddress = (
+            $Kolab::config{'connect_addr'} ?
+                $Kolab::config{'connect_addr'} : 'localhost'
+        );
+
+    my $cyrus = Kolab::Cyrus::create($connectAddress);
+
+    # Make whether the mailbox we're about to create is a shared or a user
+    # folder a boolean.
+    my $sharedFolder = ( $mailboxType eq 'user' ? 0 : 1 );
+
+    my $mailboxPath = Kolab::Cyrus::createUid($mailbox, $sharedFolder);
+
+    my $location = Kolab::cyrusMurderFindMailbox( $cyrus, $mailboxPath);
+
+    my $cyrus2 = Kolab::Cyrus::create($location);
+
+    if (!$cyrus2) {
+        die("Cannot connect to Cyrus at `$location'");
     }
 
-    if ($location eq '') {
-        die("Cannot locate mailbox '$mailboxPath'.\n");
+    $cyrus2->setquota($mailboxPath, ('STORAGE' => $quota) );
+
+    return 0;
+}
+
+sub cyrusMurderFindMailbox {
+    my ($cyrus, $mailbox) = @_;
+
+    my %info = $cyrus->info($mailbox, ('/vendor/cmu/cyrus-imapd/server'));
+
+    my $key = '/mailbox/{' . $mailbox . '}/vendor/cmu/cyrus-imapd/server';
+
+    if (exists($info{$key})) {
+        return $info{$key};
     }
 
-    return $location;
+    return 0;
+}
+
+################################################################################
+sub cyrusMurderDeleteMailbox {
+################################################################################
+=pod
+
+=head3 Delete a Mailbox in a Cyrus Murder
+
+=head4 cyrusMurderDeleteMailbox
+
+This function deletes a mailbox in a Cyrus IMAP Murder. It expects to be passed
+a mailbox name, such as 'jdoe', 'jdoe at example.org' or 'info at company.com', and
+a type ('user' or 'shared').
+
+The function connects to the configured 'connect_addr', which should be set to
+a (functional) Cyrus IMAP frontend server using /etc/kolab/kolab.conf.
+
+It creates the administrative connection using the 'cyrus_admin' and
+'cyrus_admin_pw' settings from /etc/kolab/kolab.conf, and issues the delete
+command.
+
+Example usage:
+
+  Kolab::cyrusMurderDeleteMailbox('jdoe at example.org')
+
+  Kolab::cyrusMurderDeleteMailbox('info at example.org', 'shared')
+
+=cut
+
+    my $location = '';
+
+    my $mailboxName = shift;
+    my $mailboxType = shift || 'user';
+
+    my $connectAddress = ( $Kolab::config{'connect_addr'} ?
+            $Kolab::config{'connect_addr'} : 'localhost'
+        );
+
+    my $cyrus = Kolab::Cyrus::create($connectAddress);
+
+    # Make whether the mailbox we're about to create is a shared or a user
+    # folder a boolean.
+    my $sharedFolder = ( $mailboxType eq 'user' ? 0 : 1 );
+
+    my $rc = Kolab::Cyrus::deleteMailbox(
+            $cyrus,
+            $mailboxName,
+            $sharedFolder
+        );
+
+    return $rc;
 }
 
 ################################################################################
@@ -624,6 +735,68 @@ Example usage:
         );
 }
 
+################################################################################
+sub cyrusMurderTransferMailbox {
+################################################################################
+=pod
+
+=head3 Transfer a Mailbox in a Cyrus Murder
+
+=head4 cyrusMurderTrasnferMailbox
+
+This function transfers a mailbox in a Cyrus IMAP Murder. It expects to be
+passed a mailbox name, such as 'jdoe', 'jdoe at example.org' or 'info at company.com',
+and a target server fully qualified domain name, such as 'mail01.example.org'.
+
+A third argument may be specified to indicate the folder type, 'user' or
+'shared'. If the folder type is not specified, 'user' is used.
+
+Example usage:
+
+  Kolab::cyrusMurderTransferMailbox('jdoe at example.org', 'cyrus01.example.org')
+
+  Kolab::cyrusMurderTransferMailbox('info at example.org', 'cyrus04.example.org',
+        'shared'
+    )
+
+=cut
+
+    my $mailboxName = shift;
+    my $mailHost = shift || 0;
+    my $mailboxType = shift || 'user';
+
+    my $connectAddress = (
+            $Kolab::config{'connect_addr'} ?
+                    $Kolab::config{'connect_addr'} : 'localhost'
+        );
+
+    my $cyrus = Kolab::Cyrus::create($connectAddress);
+
+    # Make whether the mailbox we're about to create is a shared or a user
+    # folder a boolean.
+    my $sharedFolder = ( $mailboxType eq 'user' ? 0 : 1 );
+
+    my $mailboxPath = Kolab::Cyrus::createUid($mailboxName, $sharedFolder);
+
+    print $mailboxPath . "\n";
+
+    my $location = Kolab::cyrusMurderFindMailbox($cyrus, $mailboxPath);
+
+    if ($location eq '') {
+        die("Cannot locate mailbox '$mailboxPath'.\n");
+    }
+
+    my $cyrus2 = Kolab::Cyrus::create($location);
+
+    if (!$cyrus2) {
+        die("Cannot connect to Cyrus at `$location'");
+    }
+
+    my $rc = Kolab::Cyrus::transferMailbox($cyrus2, $mailboxPath, $mailHost);
+
+    return $rc;
+}
+
 1;
 __END__
 =head1 NAME
diff --git a/lib/Kolab/Cyrus.pm b/lib/Kolab/Cyrus.pm
index 17b1adf..1cabab1 100644
--- a/lib/Kolab/Cyrus.pm
+++ b/lib/Kolab/Cyrus.pm
@@ -42,6 +42,7 @@ our %EXPORT_TAGS = (
         &createMailbox
         &createCalendar
         &deleteMailbox
+        &transferMailbox
         &renameMailbox
         &setQuota
         &setACL
@@ -106,14 +107,25 @@ sub createMailbox
     my $cyruid = &createUid($uid, $sf);
     my $mailbox = ($cyrus->list($cyruid))[0];
 
-    if ($uid && ($uid ne $Kolab::config{'cyrus_admin'}) && ($uid ne "freebusy") && ($uid ne "nobody") && !defined($mailbox)) {
-        Kolab::log('Y', "Creating mailbox `$cyruid' on ".($partition?"partition `$partition'":"default partition"));
-        if (!$cyrus->create($cyruid, $partition)) {
-            Kolab::log('Y', "Unable to create mailbox `$cyruid', Error = `" . $cyrus->error . "'", KOLAB_WARN);
+    if ($uid && ($uid ne $Kolab::config{'cyrus_admin'}) && ($uid ne "freebusy") && ($uid ne "nobody")) {
+        if ( !defined($mailbox) ) {
+            Kolab::log('Y', "Creating mailbox `$cyruid' on ".($partition?"partition `$partition'":"default partition"));
+            if (!$cyrus->create($cyruid, $partition)) {
+                Kolab::log('Y', "Unable to create mailbox `$cyruid', Error = `" . $cyrus->error . "'", KOLAB_WARN);
+                return 0;
+            } else {
+                return 1;
+            }
+        } else {
+            Kolab::log('Y', "Unable to create mailbox `$cyruid', mailbox already exists", KOLAB_WARN);
+            return 10036;
         }
     } else {
         Kolab::log('Y', "Skipping mailbox creation for $uid (cyruid='$cyruid', mailbox='".join(',',@{$mailbox})."'", KOLAB_DEBUG);
+        return 0;
     }
+
+    return 1;
 }
 
 sub createCalendar
@@ -210,6 +222,22 @@ sub renameMailbox
     }
 }
 
+sub transferMailbox
+{
+    my $cyrus = shift;
+    my $mailboxPath = shift;
+    my $mailHost = shift;
+
+    Kolab::log('Y', "Transferring mailbox `$mailboxPath' to `$mailHost`");
+
+    if (!$cyrus->xfermailbox($mailboxPath, $mailHost)) {
+        Kolab::log('Y', "Unable to transfer mailbox `$mailboxPath' to `$mailHost', Error = `" . $cyrus->error . "'", KOLAB_WARN);
+        return 0;
+    }
+
+    return 1;
+}
+
 sub setACL
 {
     my $cyrus = shift;


commit 99a792d34a770723f28e6c0fe057adc34de3cad9
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Tue Jun 14 09:44:27 2011 -0500

    Add sample scripts for the new API calls

diff --git a/bin/create_mailbox.pl b/bin/create_mailbox.pl
new file mode 100755
index 0000000..efe28a0
--- /dev/null
+++ b/bin/create_mailbox.pl
@@ -0,0 +1,23 @@
+#!/usr/bin/perl
+
+# Create a new mailbox without a preference as to which server the mailbox is
+# created on. To give the preferred mailbox server, set $mailboxPreferredServer
+# to the server's Fully Qualified Domain Name.
+use Kolab;
+use Kolab::Cyrus;
+
+my ($mailboxName, $mailboxPreferredServer, $mailboxType) = @ARGV;
+
+Kolab::reloadConfig('/etc/kolab/kolab-shc.conf');
+
+if ( !$mailboxType ) {
+    $mailboxType = 'user';
+}
+
+if ( !$mailboxPreferredServer ) {
+    $mailboxPreferredServer = 0;
+}
+
+my $mailboxServer = Kolab::cyrusMurderCreateMailbox($mailboxName, $mailboxPreferredServer, $mailboxType);
+
+print $mailboxServer . "\n";
diff --git a/bin/delete_mailbox.pl b/bin/delete_mailbox.pl
new file mode 100755
index 0000000..c0992f6
--- /dev/null
+++ b/bin/delete_mailbox.pl
@@ -0,0 +1,16 @@
+#!/usr/bin/perl
+
+# Delete an existing mailbox.
+use Kolab;
+use Kolab::Cyrus;
+
+# John Doe's contract is terminated
+my ($mailboxName, $mailboxType) = @ARGV;
+
+if ( !$mailboxType ) {
+    $mailboxType = 'user';
+}
+
+Kolab::reloadConfig('/etc/kolab/kolab-shc.conf');
+
+Kolab::cyrusMurderDeleteMailbox($mailboxName, $mailboxType);
diff --git a/bin/reconstruct.pl b/bin/reconstruct.pl
new file mode 100644
index 0000000..e69de29
diff --git a/bin/rename_mailbox.pl b/bin/rename_mailbox.pl
new file mode 100755
index 0000000..796a726
--- /dev/null
+++ b/bin/rename_mailbox.pl
@@ -0,0 +1,20 @@
+#!/usr/bin/perl
+
+# Rename a mailbox.
+use Kolab;
+use Kolab::Cyrus;
+
+# Jane Gi marries John Doe
+my ($mailboxName, $newMailboxName, $mailboxType) = @ARGV;
+
+if ( ! $mailboxType ) {
+    $mailboxType = 'user';
+}
+
+if ( ! $newMailboxName ) {
+    die("Require the new mailbox name in a rename.");
+}
+
+Kolab::reloadConfig('/etc/kolab/kolab.conf');
+
+Kolab::cyrusMurderRenameMailbox($mailboxName, $newMailboxName, $mailboxType);
diff --git a/bin/setquota.pl b/bin/setquota.pl
new file mode 100755
index 0000000..c5b9bee
--- /dev/null
+++ b/bin/setquota.pl
@@ -0,0 +1,17 @@
+#!/usr/bin/perl
+
+# Create a new mailbox without a preference as to which server the mailbox is
+# created on. To give the preferred mailbox server, set $mailboxPreferredServer
+# to the server's Fully Qualified Domain Name.
+use Kolab;
+use Kolab::Cyrus;
+
+my ($mailboxName, $mailboxType) = @ARGV;
+
+Kolab::reloadConfig('/etc/kolab/kolab-shc.conf');
+
+if ( !$mailboxType ) {
+    $mailboxType = 'user';
+}
+
+Kolab::cyrusMurderSetQuota($mailboxName, $mailboxType);
diff --git a/bin/transfer_mailbox.pl b/bin/transfer_mailbox.pl
new file mode 100755
index 0000000..0c3aedb
--- /dev/null
+++ b/bin/transfer_mailbox.pl
@@ -0,0 +1,18 @@
+#!/usr/bin/perl
+
+# Transfer a mailbox from one server to another.
+use Kolab;
+use Kolab::Cyrus;
+
+my $mailboxName = $ARGV[0];
+my $mailboxPreferredServer = $ARGV[1];
+
+if ( !$mailboxPreferredServer ) {
+    die("No target server specified");
+}
+
+Kolab::reloadConfig('/etc/kolab/kolab-shc.conf');
+
+my $rc = Kolab::cyrusMurderTransferMailbox($mailboxName, $mailboxPreferredServer);
+
+exit !$rc;
diff --git a/bin/transfer_mailbox_folder.pl b/bin/transfer_mailbox_folder.pl
new file mode 100755
index 0000000..7871da7
--- /dev/null
+++ b/bin/transfer_mailbox_folder.pl
@@ -0,0 +1,16 @@
+#!/usr/bin/perl
+
+# John Doe's Archive folder is so large, it needs to be on a different server
+# with slower, cheaper storage. Or something like that.
+use Kolab;
+use Kolab::Cyrus;
+
+my ($mailboxName, $mailboxFolder, $mailboxPreferredServer) = @ARGV;
+
+if ( !$mailboxPreferredServer ) {
+    die("No target server specified");
+}
+
+Kolab::reloadConfig('/etc/kolab/kolab-shc.conf');
+
+Kolab::cyrusMurderTransferMailboxFolder($mailboxName, $mailboxFolder, $mailboxPrefferedServer);
diff --git a/bin/undelete_mailbox.pl b/bin/undelete_mailbox.pl
new file mode 100644
index 0000000..e69de29





More information about the commits mailing list