#!/usr/bin/perl
# 
# ***** BEGIN LICENSE BLOCK *****
# 
# Portions created by Zimbra are Copyright (C) 2005, 2006 Zimbra, Inc.
# All Rights Reserved.
# 
# The Original Code is: Zimbra Network
# 
# ***** END LICENSE BLOCK *****
# 

use strict;

use Getopt::Long;

my $id = `whoami`;
chomp $id;
if ($id ne "zimbra") {
	print STDERR "Error: must be run as zimbra user\n";
	exit (1);
}

my %opts = ();

my $target = "/opt/zimbra/backup";

my $backupfile;

&GetOptions(\%opts, "h", "lbs", "lb=s", "t=s", "a", "l") or usage();

sub usage {

	my ($msg) = (@_);

	$msg && print STDERR "\nERROR: $msg\n";
	print STDERR <<USAGE;

Restore accounts from ldap backup

Usage: zmrestoreldap -lb session -t target <options>
	-lb:  Session label (e.g. full200512291821113) to restore from.
	-t:   Backup target (default to /opt/zimbra/backup)
<options> are:	
	-lbs: List all session labels in backup
	-l:   List accounts in file
	-a:   Restore named account(s). 
	      List account names separated by white space.

USAGE
	exit (1);
}

sub listAccounts {

	open BACKUP, $backupfile or die "Can't open $backupfile: $!";
	my @lines = <BACKUP>;
	close BACKUP;

	for (my $i = 0; $i <= $#lines; $i++) {
		if ($lines[$i] =~ /zimbraMailDeliveryAddress:/) {
			my $isAccount = (split ' ', $lines[$i], 2)[1];
			chomp $isAccount;
			print "$isAccount\n";
		}
	}
}

sub restoreAccounts {

	open BACKUP, $backupfile or die "Can't open $backupfile: $!";
	my @lines = <BACKUP>;
	close BACKUP;

	open LDAP, ">/tmp/zmrestoreldap.$$" or 
		die "Can't open /tmp/zmrestoreldap.$$: $!";

	my @curobject = ();
	my $isAccount = 0;
	for (my $i = 0; $i <= $#lines; $i++) {
		if ($lines[$i] =~ /^$/) {
			if ($isAccount) {
				if ($opts{a} && grep (/$isAccount/, @ARGV)) {
					print "Restoring $isAccount\n";
					print LDAP @curobject;
					print LDAP "\n";
				}
			}
			$isAccount = 0;
			@curobject = ();
			next;
		}
		if ($lines[$i] =~ /zimbraMailDeliveryAddress:/) {
			$isAccount = (split ' ', $lines[$i], 2)[1];
			chomp $isAccount;
			# print "Found $isAccount\n";
		}
		push @curobject, $lines[$i];
	}

	close LDAP;
	restoreLdap("/tmp/zmrestoreldap.$$");
	unlink "/tmp/zmrestoreldap.$$";
}

sub fullLdapRestore {
	my $file = shift;
  print "Stopping ldap...";
  my $rc = 0xffff & system("ldap stop");
  if ($rc != 0) {
    print "ERROR: failed to stop ldap.\n";
    exit 1;
  }
  print "done.\n";
  

  system("mv /opt/zimbra/openldap-data/.prev /opt/zimbra/openldap-data/.prev.$$")
    if (-e "/opt/zimbra/openldap-data/.prev");
  $rc = 0xffff & system("mkdir -p /opt/zimbra/openldap-data/.prev");
  if ($rc != 0) {
    print "ERROR: Failed to create /opt/zimbra/openldap-data/.prev\n";
    exit 1;
  }

  $rc = 0xffff & system("mv /opt/zimbra/openldap-data/* /opt/zimbra/openldap-data/.prev 2> /dev/null");
  if ($rc > 1) {
    print "ERROR: Failed to move existing ldap data: $rc\n";
    exit 1;
  }
  restoreLdap($file);

  print "Starting ldap...";
  my $rc = 0xffff & system("ldap start");
  if ($rc != 0) {
    print "ERROR: failed to start ldap.\n";
    exit 1;
  }
  print "done.\n";
}

sub restoreLdap {
	my $file = shift;

	if (! -r $file) {
		die "Can't read $file: $!";
	}


	`cat $file | egrep -v '^zimbraMailHostPool:' | /opt/zimbra/openldap/sbin/slapadd -f /opt/zimbra/conf/slapd.conf -cv `;

}

$opts{h} && usage();

$opts{t} && ( $target = $opts{t} );

if ($opts{lbs}) {
    print `/bin/ls -t "$target/ldap"`;
    exit 0;
} elsif ($opts{lb}) {
    $backupfile = "$target/ldap/$opts{lb}/ldap.bak";
} else {
	print "backup session label not specified in -lb.\n";
	usage();
}

if ($opts{l}) {
	listAccounts();
} elsif ($opts{a}) {
	restoreAccounts();
} else {
	fullLdapRestore($backupfile);
}
