#!/usr/bin/perl
# Copyright (c) 2009 AdCycle.com All rights reserved.
use strict;
use IO::Socket;



# >> DAEMON OPTIONS [UPDATE!]
#  Review the README.txt file for install instructions.
#  If possible, run this script during server startup or run in cron every 15 min or so
#  These first two options must mirror the options found in adcycle.c.

my $daemon_qty="1";    # the number of daemons (1 is adequate for most sites)
my $sock_dir="/full/path/to/sock";     # path to sock directory [no slash at end!]
my $adcycle_dir="/full/path/to/adcycle";    # path to adcycle directory [no slash at end!]
my $daemon_ping="300";    # in seconds, (default recommended)

# << DAEMON OPTIONS




# ** No other mods are required **



# >> file test
unlink("$sock_dir/file_check");
if(-e "$sock_dir/file_check"){
	print "There is a problem with the sock directory: \"$sock_dir\" AdCycle cannot delete files in it. :(\n";
	exit(0);
}
if(!-e "$adcycle_dir/adcycled"){
	print "There is a problem with the adcycle directory: \"$adcycle_dir\"\n";
	exit(0);
}
open(W,">$sock_dir/file_check");
print W "FILE CHECK\n";
close(W);
if(!-e "$sock_dir/file_check"){
	print "There is a problem with the sock directory: $sock_dir. Check it's permissions(770).\n";
	exit(0);
}
# << file test



# >> startup check
my $pid=$$;
my $old_pid=0;
open(W,"$sock_dir/safe_pid");
$old_pid=<W>;
close(W);
open(W,">$sock_dir/safe_pid");
print W $pid;
close(W);
my @safe_list=`/bin/ps xaww | grep safe_adcycled | grep -v "grep"`;
my $safe_daemons=@safe_list;
my $safe_found="no";
for(my $k=0;$k<$safe_daemons;$k++){
	my $pro_pid=substr($safe_list[$k],0,5);
	if($pro_pid+0 == $old_pid+0){
		$safe_found="yes";
	}
}
if($safe_found eq "yes"){
	system("kill -9 $old_pid > $sock_dir/run.log");
}
# << startup check


# >> shutdown
if($ARGV[0] eq "stop" || $ARGV[0] eq "shutdown"){
	my @process_list=`/bin/ps xaww | grep $adcycle_dir/adcycled | grep -v "grep"`;
	my $active_daemons=@process_list;
	for(my $k=0;$k<$active_daemons;$k++){
		my $pro_pid=substr($process_list[$k],0,5);
		$pro_pid+=0;
		system("kill -9 $pro_pid > $sock_dir/run.log");
	}
	print "\nShutdown Complete\n";
exit(0);
}
# << shutdown



# >> probe loop
my $fail_count;
while($fail_count < 100){
	my @process_list=`/bin/ps xaww | grep $adcycle_dir/adcycled | grep -v "grep"`;
	my $active_daemons=@process_list;
	my $restart="no";

	# >> dead dameon
	if($active_daemons != $daemon_qty){
		$restart="yes";
	}
	# << dead dameon

	# >> daemon alive check
	if($restart ne "yes"){
		for(my $k=0;$k<$daemon_qty;$k++){
			my $sockid=$k+1;
			my $buf;
			my $new_sock;
			my $sock_client=new IO::Socket::UNIX(
			  Peer    => "$sock_dir/adsock$sockid",
			  Type    => SOCK_STREAM,
			  Timeout => 10
			) || die "Socket init failure: $!";
			$sock_client->autoflush(1);
			print $sock_client "DAEMON_PING\n";
			print $sock_client "xENDx\n";
			$buf=<$sock_client>;
			close($sock_client);
			if(index($buf,"GOOD")==-1){
				$restart="yes";
			}
		}
	}
	# << daemon alive check

	# >> kill and restart daemons
	if($restart eq "yes"){
		$fail_count++;
		my @pids;
		for(my $k=0;$k<$active_daemons;$k++){
			my $pro_pid=substr($process_list[$k],0,5);
			$pro_pid+=0;
			$pids[$k]=$pro_pid;
			system("kill -9 $pro_pid > $sock_dir/run.log");
		}
		for(my $k=0;$k<$daemon_qty;$k++){
			my $new_id=$k+1;
			system("nohup perl $adcycle_dir/adcycled socket_id=$new_id socket_dir=$sock_dir > $sock_dir/run.log &");
		}
	}else{
		$fail_count=0;
	}
	# << kill and restart daemons

	sleep($daemon_ping);
}
# << probe loop


# Copyright (c) 2009 AdCycle.com All rights reserved.