iChatServer_verify [plain text]
$DIFF = "/usr/bin/diff";
$RM = "/bin/rm";
$PBUDDY = "/usr/libexec/PlistBuddy";
$TAR = "/usr/bin/tar";
$SQLITE = "/usr/bin/sqlite3";
$ServiceConf = "75-iChatServer.plist";
$SBS_CONF = "/private/etc/server_backup";
$tmpPath = "/private/var/jabberd/tmp";
$servermgrJabberConfigPath = "/Library/Preferences/com.apple.ichatserver.plist";
%dbinfo = {};
%BigList = "";
$CONF_EXT = ".conf";
$STATUS_EXT = ".status";
$ret = 0;
$VERBOSE = 0;
$DEBUG = 0;
$FUNCLOG = 0;
($OUTPUT_NONE, $OUTPUT_DEBUG, $OUTPUT_VERBOSE,
$OUTPUT_FUNCLOG, $OUTPUT_PRINT) = (0..4);
$LOG_PATH = &_get_log_path(@ARGV);
if($ENV{VERBOSE} eq 1) {$VERBOSE = '1';}
if($ENV{DEBUG} eq 1) {$DEBUG = '1';}
if($ENV{FUNCLOG} eq 1) {$FUNCLOG = '1';}
&_log($OUTPUT_VERBOSE, "iChatServer_verify was called.\n");
ParseOptions();
if ($DEBUG)
{ dumpAssociativeArray(@ARGV); }
$ret = validateOptionsAndDispatch(@ARGV);
exit($ret);
sub validateOptionsAndDispatch()
{
$ret = 0;
%BigList = @_;
SWITCH: {
if (uc($BigList{"-cmd"}) eq uc("actions")) { if($DEBUG) {print("actions\n");} Actions(); last SWITCH; }
if (uc($BigList{"-cmd"}) eq uc("help")) { if ($DEBUG) {print("help\n");} Usage(); last SWITCH; }
if ((uc($BigList{"-cmd"}) eq uc("verify")) && (-e ($BigList{"-path"})) ) { if ($DEBUG) {print("verify\n");} $ret = Verify(); last SWITCH; }
if (uc($BigList{"-cmd"}) eq uc("version")) { if($DEBUG) {print("version\n");} Version(); last SWITCH; }
$nothing = 1;
}
if($nothing eq 1)
{print("Legal options were not supplied!\n");Usage();}
return($ret);
}
sub Actions()
{
&_log($OUTPUT_FUNCLOG, "Start Actions-------------------------------------------------------+\n");
&_log($OUTPUT_VERBOSE, (qq(${PBUDDY} -c \"Print :VerifyActions\" $SBS_CONF/$ServiceConf) . "\n"));
$Version = qx(${PBUDDY} -c \"Print :VerifyActions\" $SBS_CONF/$ServiceConf);
&_log($OUTPUT_PRINT, $Version);
&_log($OUTPUT_FUNCLOG, "End Actions-------------------------------------------------------+\n");
}
sub Verify()
{
&_log($OUTPUT_FUNCLOG, "Start Verify-------------------------------------------------------+\n");
my $successCount = 0;
my $failureCount = 0;
my $omittedCount = 0;
my $imagePath = $BigList{"-path"};
my $OPT = $BigList{"-opt"};
my $diffFilePath = "$tmpPath/iChatServer_verify_diff_tmp";
my $storedFileDir = "$tmpPath/iChatServer_restored_for_verify";
my $restoredSqlFile = "iChatServer_data_backup.sql";
my $newSqlFile = "iChatServer_data_current.sql";
my $sqliteDefaultDbPath = "/private/var/jabberd/sqlite/jabberd2.db";
my $sqliteDbPath = "";
my @diffLines;
my $cmd;
my $pbuddyDbPath = qx(${PBUDDY} -c \"Print :jabberdDatabasePath:\" $servermgrJabberConfigPath);
chomp($pbuddyDbPath);
if (-e $pbuddyDbPath) {
$sqliteDbPath = $pbuddyDbPath;
} else {
$sqliteDbPath = $sqliteDefaultDbPath;
}
umask(077);
&_log($OUTPUT_DEBUG, "IMAGE_PATH := $imagePath\n");
if ($OPT ne "configuration" && $OPT ne "data" && $OPT ne "all") {
&_log($OUTPUT_PRINT, "Invalid or missing -opt given.\n");
return 1;
}
if (! -e $imagePath) {
&_log($OUTPUT_PRINT, "The provided image path does not exist. Aborting.\npath was: $imagePath\n");
return 1;
}
if (! opendir(SBSDIR, "$imagePath")) {
&_log($OUTPUT_PRINT, "Couldn't open the directory for reading: $imagePath\n");
return 1;
}
my @imageTarFiles = readdir(SBSDIR);
closedir(SBSDIR);
mkdir($storedFileDir);
FINDCONF: foreach my $imageTarFile (@imageTarFiles) {
if ($imageTarFile =~ /iChatServer.conf.tar.gz$/) {
my $origCWD = $ENV{PWD};
chdir($storedFileDir);
qx($TAR -xzf \"$imagePath/$imageTarFile\");
chdir($origCWD);
last FINDCONF;
}
}
FINDDATA: foreach my $imageTarFile (@imageTarFiles) {
if ($imageTarFile =~ /iChatServer.data.tar.gz$/) {
my $origCWD = $ENV{PWD};
chdir($storedFileDir);
qx($TAR -xzf \"$imagePath/$imageTarFile\");
chdir($origCWD);
last FINDDATA;
}
}
if ($OPT eq "configuration" || $OPT eq "all") {
my @configurationFiles;
my @configurationFilesPbuddy = qx(${PBUDDY} -c \"Print :ConfigurationFilesToTar:\" $SBS_CONF/$ServiceConf);
if ($ for (my $i = 1; $i < $ my $configTmp = $configurationFilesPbuddy[$i];
chomp($configTmp);
$configTmp =~ s/^\s*//;
push(@configurationFiles, $configTmp);
}
}
my $origCWD = $ENV{PWD};
chdir($storedFileDir);
foreach $configFile (@configurationFiles) {
if ($configFile =~ /\*/) {
&_log($OUTPUT_VERBOSE, "Found a wildcard in the plist ($configFile), expanding for later processing...\n");
my @expFiles = `ls -1 $configFile`;
chomp(@expFiles);
foreach my $expFile (@expFiles) {
&_log($OUTPUT_VERBOSE, "Adding wildcard expansion to configurationFiles array: $expFile\n");
push(@configurationFiles, $expFile);
}
next;
}
&_log($OUTPUT_VERBOSE, "Comparing $configFile...\n");
my $relativeFilePath = $configFile;
$relativeFilePath =~ s/^\///;
$cmd = "$DIFF -q \"$configFile\" \"$relativeFilePath\" &> \"$diffFilePath\"";
&_log($OUTPUT_VERBOSE, "Executing: $cmd\n");
qx($cmd);
open(DIFF, "<$diffFilePath");
@diffLines = <DIFF>;
close(DIFF);
chomp(@diffLines);
if ($diffLines[0] eq "") {
$successCount++;
&_log($OUTPUT_VERBOSE, "File match ($configFile)\n");
} else {
if (! -e $configFile && ! -e $relativeFilePath) {
$successCount++;
&_log($OUTPUT_VERBOSE, "Ignoring file ($configFile), counting as a match\n");
} else {
&_log($OUTPUT_VERBOSE, "VERIFICATION FAILURE: config file $configFile does not match original\n");
$failureCount++;
}
}
}
unlink($diffFilePath);
}
if ($OPT eq "data" || $OPT eq "all") {
open(DIR, ".");
my @files = <DIR>;
closedir(DIR);
if (! -e "$storedFileDir/$restoredSqlFile") {
&_log($OUTPUT_VERBOSE, "VERIFICATION FAILURE: Could not find original .sql file for database comparison");
$failureCount++;
} else {
qx(echo ".dump" | $SQLITE $sqliteDbPath > $tmpPath/$newSqlFile);
qx($DIFF -q \"$storedFileDir/$restoredSqlFile\" \"$tmpPath/$newSqlFile\" &> \"$diffFilePath\");
open(DIFF, "<$diffFilePath");
@diffLines = <DIFF>;
close(DIFF);
chomp(@diffLines);
if ($diffLines[0] eq "") {
$successCount++;
} else {
&_log($OUTPUT_VERBOSE, "VERIFICATION FAILURE: Backed up database does not match current database\n");
$failureCount++;
}
}
unlink($diffFilePath);
unlink("$tmpPath/$newSqlFile");
qx($RM -rf \"$storedFileDir\");
chdir($origCWD);
}
&_log($OUTPUT_PRINT, "\nVerify service := iChatServer resulted in:\nSuccessful matches := $successCount\nNumber of failures to match := $failureCount\n");
$ret = 1;
&_log($OUTPUT_FUNCLOG, "End Verify-------------------------------------------------------+\n");
return($ret);
}
sub Version()
{
&_log($OUTPUT_FUNCLOG, "Start Version-------------------------------------------------------+\n");
$Version = qx(${PBUDDY} -c \"Print :Version\" $SBS_CONF/$ServiceConf);
&_log($OUTPUT_PRINT, $Version);
&_log($OUTPUT_FUNCLOG, "End Version-------------------------------------------------------+\n");
}
sub ParseOptions {
local (@optval) = @_;
local ($opt, @opts, %valFollows, @newargs);
while (@optval) {
$opt = shift(@optval);
push(@opts,$opt);
$valFollows{$opt} = shift(@optval);
}
@optArgs = ();
%opt = ();
arg: while (defined($arg = shift(@ARGV))) {
foreach $opt (@opts) {
if ($arg eq $opt) {
push(@optArgs, $arg);
if ($valFollows{$opt}) {
if (@ARGV == 0) {
Usage();
}
$opt{$opt} = shift(@ARGV);
push(@optArgs, $opt{$opt});
} else {
$opt{$opt} = 1;
}
next arg;
}
}
push(@newargs,$arg);
}
@ARGV = @newargs;
}
sub Usage()
{
print "Usage:\n";
print "iChatServer_verify supports the following options:\n";
print " -cmd actions : Prints out the dictionary of VerifyActions from the conf file := $SBS_CONF$ServiceConf\n";
print " -cmd help : Displays this usage.\n";
print " -cmd verify -path path -opt option Verify the service data, it is verifing what's in the image with what is on the boot drive.\n";
print " where path is the path to the image.\n";
print " where option is one of: configuration, data, all\n";
print " -cmd version : Prints out the version value from the property list := $SBS_CONF$ServiceConf\n";
exit(0);
}
sub dumpAssociativeArray()
{
%BigList = @_;
while(($theKey, $theVal) = each (%BigList))
{ print "$theKey is the key for value $theVal\n"; }
if($BigList{"-cmd"} eq "backup")
{ print "cmd := ", $BigList{"-cmd"}, "\n"; }
}
sub timestamp()
{
my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
localtime(time);
$year += 1900;
$mon += 1;
if ( $hour =~ /^\d$/ ) { $hour = "0" . $hour; }
if ( $min =~ /^\d$/ ) { $min = "0" . $min; }
if ( $sec =~ /^\d$/ ) { $sec = "0" . $sec; }
my $ret = $year."-".$mon."-".$mday."-$hour:$min:$sec";
return $ret;
}
sub _log {
my $type = shift;
my $msg = shift;
if ($LOG_PATH ne "") {
open(OUT, ">>$LOG_PATH") || die "ERROR: Cannot open log file at path: $LOG_PATH : $!";
print OUT ×tamp."\t".$msg;
close(OUT);
}
if (($type == $OUTPUT_PRINT) ||
($FUNCLOG && ($type == $OUTPUT_FUNCLOG)) ||
($DEBUG && ($type == $OUTPUT_DEBUG)) ||
($VERBOSE && ($type == $OUTPUT_VERBOSE))) {
print $msg;
}
}
sub _get_log_path {
my ($theKey, $theVal);
my %theArgList = @ARGV;
while(($theKey, $theVal) = each (%theArgList)) {
if ($theKey eq "-log") {
return $theVal;
}
}
return "";
}