1<?php
2// common code used by the poller, the manual-run from the Cacti UI, and from the command-line manual-run.
3// this is the easiest way to keep it all consistent!
4
5function weathermap_memory_check($note="MEM")
6{
7	if(function_exists("memory_get_usage"))
8	{
9		$mem_used = nice_bandwidth(memory_get_usage());
10		$mem_allowed = ini_get("memory_limit");
11		debug("$note: memory_get_usage() says ".$mem_used."Bytes used. Limit is ".$mem_allowed."\n");
12	}
13}
14
15function weathermap_cron_part($value,$checkstring)
16{
17	// XXX - this should really handle a few more crontab niceties like */5 or 3,5-9 but this will do for now
18	if($checkstring == '*') return(true);
19	if($checkstring == sprintf("%s",$value) ) return(true);
20
21	if( preg_match("/\*\/(\d+)/",$checkstring, $matches))
22	{
23		$mod = $matches[1];
24		if( ($value % $mod ) == 0) return true;
25	}
26
27	return (false);
28}
29
30function weathermap_check_cron($time,$string)
31{
32	if($string == '') return(true);
33	if($string == '*') return(true);
34
35	$lt = localtime($time, true);
36	list($minute,$hour,$wday,$day,$month) = preg_split('/\s+/',$string);
37
38	$matched = true;
39
40	$matched = $matched && weathermap_cron_part($lt['tm_min'],$minute);
41	$matched = $matched && weathermap_cron_part($lt['tm_hour'],$hour);
42	$matched = $matched && weathermap_cron_part($lt['tm_wday'],$wday);
43	$matched = $matched && weathermap_cron_part($lt['tm_mday'],$day);
44	$matched = $matched && weathermap_cron_part($lt['tm_mon']+1,$month);
45
46	return($matched);
47}
48
49function weathermap_run_maps($mydir) {
50	global $config;
51	global $weathermap_debugging, $WEATHERMAP_VERSION;
52	global $weathermap_map;
53	global $weathermap_warncount;
54	global $weathermap_poller_start_time;
55
56	include_once($mydir.DIRECTORY_SEPARATOR."HTML_ImageMap.class.php");
57	include_once($mydir.DIRECTORY_SEPARATOR."Weathermap.class.php");
58
59	$total_warnings = 0;
60
61	$start_time = time();
62	if($weathermap_poller_start_time==0) $weathermap_poller_start_time = $start_time;
63
64	$outdir = $mydir.DIRECTORY_SEPARATOR.'output';
65	$confdir = $mydir.DIRECTORY_SEPARATOR.'configs';
66
67	$mapcount = 0;
68
69	// take our debugging cue from the poller - turn on Poller debugging to get weathermap debugging
70	if (read_config_option("log_verbosity") >= POLLER_VERBOSITY_DEBUG)
71	{
72		$weathermap_debugging = TRUE;
73		$mode_message = "DEBUG mode is on";
74	}
75	else
76	{
77		$mode_message = "Normal logging mode. Turn on DEBUG in Cacti for more information";
78	}
79	$quietlogging = read_config_option("weathermap_quiet_logging");
80	// moved this outside the module_checks, so there should always be something in the logs!
81	if($quietlogging==0) cacti_log("Weathermap $WEATHERMAP_VERSION starting - $mode_message\n",true,"WEATHERMAP");
82
83	if(module_checks())
84	{
85		weathermap_memory_check("MEM Initial");
86		// move to the weathermap folder so all those relatives paths don't *have* to be absolute
87		$orig_cwd = getcwd();
88		chdir($mydir);
89
90		db_execute("replace into settings values('weathermap_last_start_time','".mysql_escape_string(time())."')");
91
92		// first, see if the output directory even exists
93		if(is_dir($outdir))
94		{
95			// next, make sure that we stand a chance of writing files
96			//// $testfile = realpath($outdir."weathermap.permissions.test");
97			$testfile = $outdir.DIRECTORY_SEPARATOR."weathermap.permissions.test";
98			$testfd = fopen($testfile, 'w');
99			if($testfd)
100			{
101				fclose($testfd);
102				unlink($testfile);
103
104				$queryrows = db_fetch_assoc("select m.*, g.name as groupname from weathermap_maps m,weathermap_groups g where m.group_id=g.id and active='on' order by sortorder,id");
105
106				if( is_array($queryrows) )
107				{
108					debug("Iterating all maps.");
109
110					$imageformat = strtolower(read_config_option("weathermap_output_format"));
111					$rrdtool_path =  read_config_option("path_rrdtool");
112
113					foreach ($queryrows as $map) {
114						// reset the warning counter
115						$weathermap_warncount=0;
116						// this is what will prefix log entries for this map
117						$weathermap_map = "[Map ".$map['id']."] ".$map['configfile'];
118
119						debug("FIRST TOUCH\n");
120
121						if(weathermap_check_cron($weathermap_poller_start_time,$map['schedule']))
122						{
123							$mapfile = $confdir.DIRECTORY_SEPARATOR.$map['configfile'];
124							$htmlfile = $outdir.DIRECTORY_SEPARATOR.$map['filehash'].".html";
125							$imagefile = $outdir.DIRECTORY_SEPARATOR.$map['filehash'].".".$imageformat;
126							$thumbimagefile = $outdir.DIRECTORY_SEPARATOR.$map['filehash'].".thumb.".$imageformat;
127
128							if(file_exists($mapfile))
129							{
130								if($quietlogging==0) warn("Map: $mapfile -> $htmlfile & $imagefile\n",TRUE);
131								db_execute("replace into settings values('weathermap_last_started_file','".mysql_escape_string($weathermap_map)."')");
132								$map_start = time();
133								weathermap_memory_check("MEM starting $mapcount");
134								$wmap = new Weathermap;
135								$wmap->context = "cacti";
136
137								// we can grab the rrdtool path from Cacti's config, in this case
138								$wmap->rrdtool  = $rrdtool_path;
139
140								$wmap->ReadConfig($mapfile);
141
142								$wmap->add_hint("mapgroup",$map['groupname']);
143								$wmap->add_hint("mapgroupextra",($map['group_id'] ==1 ? "" : $map['groupname'] ));
144
145								# in the order of precedence - global extras, group extras, and finally map extras
146								$queries = array();
147								$queries[] = "select * from weathermap_settings where mapid=0 and groupid=0";
148								$queries[] = "select * from weathermap_settings where mapid=0 and groupid=".intval($map['group_id']);
149								$queries[] = "select * from weathermap_settings where mapid=".intval($map['id']);
150
151								foreach ($queries as $sql)
152								{
153									$settingrows = db_fetch_assoc($sql);
154									if( is_array($settingrows) && count($settingrows) > 0 )
155									{
156
157									foreach ($settingrows as $setting)
158									{
159										if($setting['mapid']==0 && $setting['groupid']==0)
160										{
161											debug("Setting additional (all maps) option: ".$setting['optname']." to '".$setting['optvalue']."'\n");
162											$wmap->add_hint($setting['optname'],$setting['optvalue']);
163										}
164										elseif($setting['groupid']!=0)
165										{
166											debug("Setting additional (all maps in group) option: ".$setting['optname']." to '".$setting['optvalue']."'\n");
167											$wmap->add_hint($setting['optname'],$setting['optvalue']);
168										}
169										else
170										{	debug("Setting additional map-global option: ".$setting['optname']." to '".$setting['optvalue']."'\n");
171											$wmap->add_hint($setting['optname'],$setting['optvalue']);
172										}
173									}
174									}
175								}
176
177								weathermap_memory_check("MEM postread $mapcount");
178								$wmap->ReadData();
179								weathermap_memory_check("MEM postdata $mapcount");
180
181								// why did I change this before? It's useful...
182								// $wmap->imageuri = $config['url_path'].'/plugins/weathermap/output/weathermap_'.$map['id'].".".$imageformat;
183								$wmap->imageuri = 'weathermap-cacti-plugin.php?action=viewimage&id='.$map['filehash']."&time=".time();
184
185								if($quietlogging==0) warn("About to write image file. If this is the last message in your log, increase memory_limit in php.ini [WMPOLL01]\n",TRUE);
186								weathermap_memory_check("MEM pre-render $mapcount");
187
188								$wmap->DrawMap($imagefile,$thumbimagefile,read_config_option("weathermap_thumbsize"));
189
190								if($quietlogging==0) warn("Wrote map to $imagefile and $thumbimagefile\n",TRUE);
191								$fd = @fopen($htmlfile, 'w');
192								if($fd != FALSE)
193								{
194									fwrite($fd, $wmap->MakeHTML('weathermap_'.$map['filehash'].'_imap'));
195									fclose($fd);
196									debug("Wrote HTML to $htmlfile");
197								}
198								else
199								{
200									if(file_exists($htmlfile))
201									{
202										warn("Failed to overwrite $htmlfile - permissions of existing file are wrong? [WMPOLL02]\n");
203									}
204									else
205									{
206										warn("Failed to create $htmlfile - permissions of output directory are wrong? [WMPOLL03]\n");
207									}
208								}
209
210								$processed_title = $wmap->ProcessString($wmap->title,$wmap);
211
212								db_execute("update weathermap_maps set titlecache='".mysql_real_escape_string($processed_title)."' where id=".intval($map['id']));
213								if(intval($wmap->thumb_width) > 0)
214								{
215									db_execute("update weathermap_maps set thumb_width=".intval($wmap->thumb_width).", thumb_height=".intval($wmap->thumb_height)." where id=".intval($map['id']));
216								}
217
218								unset($wmap);
219								$map_duration = time() - $map_start;
220								debug("TIME: $mapfile took $map_duration seconds.\n");
221								weathermap_memory_check("MEM after $mapcount");
222								$mapcount++;
223								db_execute("replace into settings values('weathermap_last_finished_file','".mysql_escape_string($weathermap_map)."')");
224							}
225							else
226							{
227								warn("Mapfile $mapfile is not readable or doesn't exist [WMPOLL04]\n");
228							}
229							db_execute("update weathermap_maps set warncount=".intval($weathermap_warncount)." where id=".intval($map['id']));
230							$total_warnings += $weathermap_warncount;
231							$weathermap_warncount = 0;
232							$weathermap_map="";
233						}
234						else
235						{
236							debug("Skipping ".$map['id']." (".$map['configfile'].") due to schedule.\n");
237						}
238					}
239					debug("Iterated all $mapcount maps.\n");
240				}
241				else
242				{
243					if($quietlogging==0) warn("No activated maps found. [WMPOLL05]\n");
244				}
245			}
246			else
247			{
248				warn("Output directory ($outdir) isn't writable (tried to create '$testfile'). No maps created. You probably need to make it writable by the poller process (like you did with the RRA directory) [WMPOLL06]\n");
249			}
250		}
251		else
252		{
253			warn("Output directory ($outdir) doesn't exist!. No maps created. You probably need to create that directory, and make it writable by the poller process (like you did with the RRA directory) [WMPOLL07]\n");
254		}
255		weathermap_memory_check("MEM Final");
256		chdir($orig_cwd);
257		$duration = time() - $start_time;
258
259		$stats_string = date(DATE_RFC822) . ": $mapcount maps were run in $duration seconds with $total_warnings warnings.";
260		if($quietlogging==0) warn("STATS: Weathermap $WEATHERMAP_VERSION run complete - $stats_string\n", TRUE);
261		db_execute("replace into settings values('weathermap_last_stats','".mysql_escape_string($stats_string)."')");
262		db_execute("replace into settings values('weathermap_last_finish_time','".mysql_escape_string(time())."')");
263	}
264	else
265	{
266		warn("Required modules for PHP Weathermap $WEATHERMAP_VERSION were not present. Not running. [WMPOLL08]\n");
267	}
268}
269
270// vim:ts=4:sw=4:
271?>
272