#!/usr/bin/perl -w

#----------------------------------------------------------------------
# copyright (C) 1999-2003 Mitel Networks Corporation
# 
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
# 
# Technical support for this program is available from Mitel Networks 
# Please visit our web site www.mitel.com/sme/ for details.
#----------------------------------------------------------------------
use strict;

use esmith::AccountsDB;
use User::pwent;
use File::Find;

my $event = $ARGV[0] || 'Unknown';

my $adb = esmith::AccountsDB->open;

die "Couldn't open AccountsDB\n" unless $adb;

my @users = ('admin', map { $_->key } $adb->users);

foreach my $user ( @users ) {
    my $pwent = getpwnam($user) 
        or die "Couldn't get password entry for $user\n";

    chdir $pwent->dir or die "Couldn't chdir $pwent->dir:$!\n";

    %::maildirs = ();
    # Go and find maildirs we wish to relocate
    find({ wanted => \&wanted, no_chdir => 1 }, '.');

    # We do a reverse sort here so that we are doing a depth first
    # move of directories
    foreach my $here (reverse sort keys %::maildirs) {
        my $there = $::maildirs{$here};
        if ( -e "$there" ) {
            $there .= "-" . time if ( -e "$there" );
            if ( -e "$there" ) {
                warn "Conflict for $user: Can't determine new name for $here\n";
                next;
            }
        }

        warn "Moving $here to $there\n";
        rename $here, $there
            or warn("Could not rename $here to $there: $!\n");
    }

    # Now make sure that we have a junkmail mailbox
    my $prefix = "Maildir/;junkmail";
    unless (-d "$prefix" &&
            -d "$prefix/tmp" &&
            -d "$prefix/new" &&
            -d "$prefix/cur")
    {
        # We'd better make them then ...
        my $pid = fork;
        die "Could not fork in $ARGV[0]" unless defined $pid;
        if ($pid) {
            waitpid($pid, 0);
        } else {
            $) = $pwent->gid;
            $> = $pwent->uid;
            umask 077;
            foreach my $suffix ("", qw(/tmp /cur /new)) {
                my $dir = "$prefix$suffix";
                unless (-d "$dir") {
                    mkdir("$dir", 0700) or warn("Error creating $dir: $!\n");
                }
            }
            exit 0;
            # NOTREACHED
        }
    }
    if (-f ".mailboxlist" && ! -f "Maildir/.subscriptions") {
        my $pid = fork;
        die "Could not fork in $ARGV[0]" unless defined $pid;
        if ($pid) {
            waitpid($pid, 0);
        } else {
            $) = $pwent->gid;
            $> = $pwent->uid;
            umask 077;
            open (OSUBS, "<.mailboxlist") or
                die "Could not open mailboxlist file: $!\n";
            open (NSUBS, ">Maildir/.subscriptions") or
                die "Could not open subscriptions file: $!\n";
            while (<OSUBS>) {
                s/^Mail\///;
                s/\//;/g;
                print NSUBS;
            }
            close NSUBS;
            close OSUBS;
            unlink ".mailboxlist";
            exit 0;
            # NOTREACHED
        }
    }
}


sub wanted {
    my $here = $_;
    # Don't follow symlinks or descend into ./Maildir
    if (-l $here || $here eq "./Maildir" || $here eq "./files") {
        #print "Pruning at $here\n";
        $File::Find::prune = 1;
        return;
    }
    # We only care about directories, and they must be maildirs
    if (-d $here && -d "$here/cur" && -d "$here/tmp" && -d "$here/new") {
        my $there = $here;
        $there =~ s/^\.\///;
        $there =~ s/^Mail\///;
        $there =~ s/\//;/g;
        next if $here eq $there;	# We shouldn't get here
        # Save a notion of where we will move this maildir
        $::maildirs{$here} = "./Maildir/;$there";
    }
}
