From 17649b8c77b765d2d6c8753a09166af9d51ec323 Mon Sep 17 00:00:00 2001
From: Ramon Novoa <rnovoa@artica.es>
Date: Fri, 25 Jun 2010 12:38:32 +0000
Subject: [PATCH] 2010-06-25  Ramon Novoa  <rnovoa@artica.es>

	* pandora_agent: Added the module_cron feature to schedule modules
          using a cron-like syntax.




git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@2928 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
---
 pandora_agents/unix/ChangeLog     |  5 +++
 pandora_agents/unix/pandora_agent | 60 ++++++++++++++++++++++++++++++-
 2 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/pandora_agents/unix/ChangeLog b/pandora_agents/unix/ChangeLog
index e494cf8ac0..29eae9d2cf 100644
--- a/pandora_agents/unix/ChangeLog
+++ b/pandora_agents/unix/ChangeLog
@@ -1,3 +1,8 @@
+2010-06-25  Ramon Novoa  <rnovoa@artica.es>
+
+	* pandora_agent: Added the module_cron feature to schedule modules
+	  using a cron-like syntax.
+
 2010-06-23  Ramon Novoa  <rnovoa@artica.es>
 
 	* pandora_agent: Added the module_save and module_condition features.
diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent
index 1a32f920c0..3b67cb905c 100755
--- a/pandora_agents/unix/pandora_agent
+++ b/pandora_agents/unix/pandora_agent
@@ -235,7 +235,9 @@ sub read_config (;$) {
 				'min' => 0,
 				'postprocess' => 0,
 				'save' => '',
-				'actions' => []
+				'actions' => [],
+				'cron' => '',
+				'cron_utimestamp' => 0
 			};
 		} elsif ($line =~ /^\s*module_name\s+(.+)$/) {
 			$module->{'name'} = $1;
@@ -295,6 +297,8 @@ sub read_config (;$) {
 			} elsif ($action =~ /^\s*=~\s+(\S*)\s+(.*)$/) {
 				push (@{$module->{'conditions'}}, {'operator' => '=~', 'value_1' => $1, 'command' => $2});
 			}
+		} elsif ($line =~ /^\s*module_cron\s+((\*|\d+)\s+(\*|\d+)\s+(\*|\d+)\s+(\*|\d+)\s+(\*|\d+))\s*$/) {
+			$module->{'cron'} = $1;
 		} elsif ($line =~ /^\s*module_end\s*$/) {
 			next unless ($module->{'name'} ne '') and ($module->{'func'} != 0);
 			push (@Modules, $module);
@@ -634,6 +638,9 @@ sub exec_module ($) {
 	# Check module interval
 	return undef unless (++($module->{'counter'}) >= $module->{'interval'});
 
+	# Check module cron
+	return unless (check_module_cron ($module) == 1);
+	
 	# Reset module counter
 	$module->{'counter'} = 0;
 
@@ -927,6 +934,57 @@ sub evaluate_module_conditions ($$) {
 	}
 }
 
+################################################################################
+# Checks the module's cron string. Returns 1 if the module should be run, 0 if
+# not.
+################################################################################
+sub check_module_cron ($) {
+	my $module = shift;
+	
+	# No cron string defined
+	return 0 unless ($module->{'cron'} ne '');
+
+	# Check if the module was already executed
+	return 0 unless (time() > $module->{'cron_utimestamp'});
+
+	# Get cron configuration
+	my @cron_params = split (/\s/, $module->{'cron'});
+
+	# Get current time
+	my $current_time = time();
+	my @time = localtime($current_time);
+
+	# Minutes, hours, day of the month, month and day of the week
+	my @time_params = @time[1, 2, 3, 4, 6];
+
+	# Fix month (localtime retuns 0..11 and we need 1..12)
+	$time_params[3] += 1;
+	
+	# Check cron parameters	
+	for (my $i = 0; $i < 5; $i++) {
+		return 0 if ($time_params[$i] ne $cron_params[$i] && $cron_params[$i] ne '*');
+	}
+
+	# Do not check in the next minute, hour, day or month.
+	my $offset = 0; 
+	if($cron_params[0] ne '*') {
+		# 1 minute
+		$offset = 60;
+	} elsif($cron_params[1] ne '*') {
+		# 1 hour
+		$offset = 3600;
+	} elsif($cron_params[2] ne '*' || $cron_params[4] ne '*') {
+		# 1 day
+		$offset = 86400;
+	} elsif($cron_params[3] ne '*') {
+		# 31 days
+		$offset = 2678400;
+	}
+
+	$module->{'cron_utimestamp'} = $current_time + $offset;
+	return 1;
+}
+
 ################################################################################
 # Main.
 ################################################################################