1 | 1 | simandl | <?php |
2 | 85 | simandl | |
3 | | | /** editor.inc.php |
4 | | | * |
5 | | | * All the functions used by the editor. |
6 | | | */ |
7 | | | |
8 | | | /** @function fix_gpc_string |
9 | | | * |
10 | | | * Take a string (that we got from $_REQUEST) and make it back to how the |
11 | | | * user TYPED it, regardless of whether magic_quotes_gpc is turned on or off. |
12 | | | * |
13 | | | * @param string $input String to fix |
14 | | | * |
15 | | | * @returns string Fixed string |
16 | | | * |
17 | | | */ |
18 | | | function fix_gpc_string($input) |
19 | | | { |
20 | | | if (true == function_exists('get_magic_quotes_gpc') && 1 == get_magic_quotes_gpc()) { |
21 | | | $input = stripslashes($input); |
22 | | | } |
23 | | | return ($input); |
24 | | | } |
25 | | | |
26 | 1 | simandl | function show_editor_startpage() |
27 | | | { |
28 | 85 | simandl | global $mapdir, $WEATHERMAP_VERSION, $config_loaded, $cacti_found, $ignore_cacti,$configerror; |
29 | 1 | simandl | |
30 | 85 | simandl | $fromplug = false; |
31 | | | if (isset($_REQUEST['plug']) && (intval($_REQUEST['plug'])==1) ) { |
32 | | | $fromplug = true; |
33 | | | } |
34 | | | |
35 | 1 | simandl | $matches=0; |
36 | | | |
37 | 85 | simandl | print '<html xmlns="http://www.w3.org/1999/xhtml"><head><link rel="stylesheet" type="text/css" media="screen" href="editor.css" /><script type="text/javascript" src="editor-resources/jquery-latest.min.js"></script><script src="editor.js" type="text/javascript"></script><title>PHP Weathermap Editor ' . $WEATHERMAP_VERSION |
38 | 1 | simandl | . '</title></head><body>'; |
39 | | | |
40 | | | print '<div id="nojs" class="alert"><b>WARNING</b> - '; |
41 | | | print 'Sorry, it\'s partly laziness on my part, but you really need JavaScript enabled and DOM support in your browser to use this editor. It\'s a visual tool, so accessibility is already an issue, if it is, and from a security viewpoint, you\'re already running my '; |
42 | | | print 'code on your <i>server</i> so either you trust it all having read it, or you\'re already screwed.<P>'; |
43 | | | print 'If it\'s a major issue for you, please feel free to complain. It\'s mainly laziness as I said, and there could be a fallback (not so smooth) mode for non-javascript browsers if it was seen to be worthwhile (I would take a bit of convincing, because I don\'t see a benefit, personally).</div>'; |
44 | 13 | simandl | |
45 | | | $errormessage = ""; |
46 | 85 | simandl | |
47 | | | if ($configerror!='') { |
48 | | | $errormessage .= $configerror.'<p>'; |
49 | | | } |
50 | 13 | simandl | |
51 | 85 | simandl | if (! $cacti_found && !$ignore_cacti) { |
52 | 13 | simandl | $errormessage .= '$cacti_base is not set correctly. Cacti integration will be disabled in the editor.'; |
53 | 85 | simandl | if ($config_loaded != 1) { |
54 | | | $errormessage .= " You might need to copy editor-config.php-dist to editor-config.php and edit it."; |
55 | | | } |
56 | 13 | simandl | } |
57 | | | |
58 | 85 | simandl | if ($errormessage != '') { |
59 | 13 | simandl | print '<div class="alert" id="nocacti">'.$errormessage.'</div>'; |
60 | | | } |
61 | 1 | simandl | |
62 | | | print '<div id="withjs">'; |
63 | | | print '<div id="dlgStart" class="dlgProperties" ><div class="dlgTitlebar">Welcome</div><div class="dlgBody">'; |
64 | | | print 'Welcome to the PHP Weathermap '.$WEATHERMAP_VERSION.' editor.<p>'; |
65 | 85 | simandl | print '<div style="border: 3px dashed red; background: #055; padding: 5px; font-size: 90%;"><b>NOTE:</b> This editor is not finished! There are many features of '; |
66 | 1 | simandl | print 'Weathermap that you will be missing out on if you choose to use the editor only.'; |
67 | | | print 'These include: curves, node offsets, font definitions, colour changing, per-node/per-link settings and image uploading. You CAN use the editor without damaging these features if you added them by hand, however.</div><p>'; |
68 | 13 | simandl | |
69 | 1 | simandl | print 'Do you want to:<p>'; |
70 | | | print 'Create A New Map:<br>'; |
71 | | | print '<form method="GET">'; |
72 | | | print 'Named: <input type="text" name="mapname" size="20">'; |
73 | | | |
74 | | | print '<input name="action" type="hidden" value="newmap">'; |
75 | 85 | simandl | print '<input name="plug" type="hidden" value="'.$fromplug.'">'; |
76 | | | |
77 | 1 | simandl | print '<input type="submit" value="Create">'; |
78 | | | print '</form>'; |
79 | | | |
80 | | | $titles = array(); |
81 | | | |
82 | 85 | simandl | $errorstring=""; |
83 | | | |
84 | | | if (is_dir($mapdir)) { |
85 | 1 | simandl | $n=0; |
86 | | | $dh=opendir($mapdir); |
87 | | | |
88 | 85 | simandl | if ($dh) { |
89 | | | while (false !== ($file = readdir($dh))) { |
90 | 1 | simandl | $realfile=$mapdir . DIRECTORY_SEPARATOR . $file; |
91 | 85 | simandl | $note = ""; |
92 | 1 | simandl | |
93 | 85 | simandl | if ( (is_file($realfile)) && (is_readable($realfile)) && (!preg_match("/^\./",$file) ) ) { |
94 | | | if (!is_writable($realfile)) { |
95 | | | $note .= "(read-only)"; |
96 | | | } |
97 | 1 | simandl | $title='(no title)'; |
98 | | | $fd=fopen($realfile, "r"); |
99 | 85 | simandl | if ($fd) { |
100 | | | while (!feof($fd)) { |
101 | 13 | simandl | $buffer=fgets($fd, 4096); |
102 | | | |
103 | 85 | simandl | if (preg_match("/^\s*TITLE\s+(.*)/i", $buffer, $matches)) { |
104 | | | $title=$matches[1]; |
105 | | | } |
106 | 13 | simandl | } |
107 | | | |
108 | | | fclose ($fd); |
109 | | | $titles[$file] = $title; |
110 | 85 | simandl | $notes[$file] = $note; |
111 | 13 | simandl | $n++; |
112 | 1 | simandl | } |
113 | | | } |
114 | | | } |
115 | | | |
116 | | | closedir ($dh); |
117 | 85 | simandl | } else { |
118 | | | $errorstring = "Can't open mapdir to read."; |
119 | | | } |
120 | 1 | simandl | |
121 | | | ksort($titles); |
122 | | | |
123 | 85 | simandl | if ($n == 0) { |
124 | | | $errorstring = "No files in mapdir"; |
125 | | | } |
126 | | | } else { |
127 | | | $errorstring = "NO DIRECTORY named $mapdir"; |
128 | | | } |
129 | | | |
130 | | | |
131 | | | print 'OR<br />Create A New Map as a copy of an existing map:<br>'; |
132 | | | print '<form method="GET">'; |
133 | | | print 'Named: <input type="text" name="mapname" size="20"> based on '; |
134 | | | |
135 | | | print '<input name="action" type="hidden" value="newmapcopy">'; |
136 | | | print '<input name="plug" type="hidden" value="'.$fromplug.'">'; |
137 | | | print '<select name="sourcemap">'; |
138 | | | |
139 | | | if ($errorstring == '') { |
140 | | | foreach ($titles as $file=>$title) { |
141 | | | $nicefile = htmlspecialchars($file); |
142 | | | print "<option value=\"$nicefile\">$nicefile</option>\n"; |
143 | | | } |
144 | | | } else { |
145 | | | print '<option value="">'.$errorstring.'</option>'; |
146 | | | } |
147 | | | |
148 | | | print '</select>'; |
149 | | | print '<input type="submit" value="Create Copy">'; |
150 | | | print '</form>'; |
151 | | | print 'OR<br />'; |
152 | | | print 'Open An Existing Map (looking in ' . $mapdir . '):<ul class="filelist">'; |
153 | | | |
154 | | | if ($errorstring == '') { |
155 | | | foreach ($titles as $file=>$title) { |
156 | 1 | simandl | $title = $titles[$file]; |
157 | 85 | simandl | $note = $notes[$file]; |
158 | | | $nicefile = htmlspecialchars($file); |
159 | | | print "<li>$note<a href=\"?mapname=$nicefile&plug=$fromplug\">$nicefile</a> - <span class=\"comment\">$title</span></li>\n"; |
160 | 1 | simandl | } |
161 | 85 | simandl | } else { |
162 | | | print '<li>'.$errorstring.'</li>'; |
163 | 1 | simandl | } |
164 | | | |
165 | 85 | simandl | print "</ul>"; |
166 | 1 | simandl | |
167 | | | print "</div>"; // dlgbody |
168 | | | print '<div class="dlgHelp" id="start_help">PHP Weathermap ' . $WEATHERMAP_VERSION |
169 | 85 | simandl | . ' Copyright © 2005-2010 Howard Jones - howie@thingy.com<br />The current version should always be <a href="http://www.network-weathermap.com/">available here</a>, along with other related software. PHP Weathermap is licensed under the GNU Public License, version 2. See COPYING for details. This distribution also includes the Overlib library by Erik Bosrup.</div>'; |
170 | 1 | simandl | |
171 | | | print "</div>"; // dlgStart |
172 | | | print "</div>"; // withjs |
173 | | | print "</body></html>"; |
174 | | | } |
175 | | | |
176 | | | function snap($coord, $gridsnap = 0) |
177 | | | { |
178 | 85 | simandl | if ($gridsnap == 0) { |
179 | | | return ($coord); |
180 | | | } else { |
181 | | | return ($coord - ($coord % $gridsnap)); |
182 | | | } |
183 | 1 | simandl | } |
184 | | | |
185 | | | // Following function is based on code taken from here: |
186 | | | // http://uk2.php.net/manual/en/security.globals.php |
187 | | | // |
188 | | | // It extracts a set of named variables into the global namespace, |
189 | 85 | simandl | // validating them as they go. Returns true or false depending on if |
190 | 1 | simandl | // validation fails. If it does fail, then nothing is added to the |
191 | | | // global namespace. |
192 | | | // |
193 | 85 | simandl | function extract_with_validation($array, $paramarray, $prefix = "", $debug = false) |
194 | 1 | simandl | { |
195 | 85 | simandl | $all_present=true; |
196 | | | $candidates=array( ); |
197 | 1 | simandl | |
198 | 85 | simandl | if ($debug) { |
199 | 1 | simandl | print '<pre>'; |
200 | 85 | simandl | print_r ($paramarray); |
201 | 1 | simandl | print_r ($array); |
202 | 85 | simandl | } |
203 | 1 | simandl | |
204 | 85 | simandl | foreach ($paramarray as $var) { |
205 | 1 | simandl | $varname=$var[0]; |
206 | | | $vartype=$var[1]; |
207 | | | $varreqd=$var[2]; |
208 | | | |
209 | 85 | simandl | if ($varreqd == 'req' && !array_key_exists($varname, $array)) { |
210 | | | $all_present=false; |
211 | | | } |
212 | 1 | simandl | |
213 | 85 | simandl | if (array_key_exists($varname, $array)) { |
214 | 1 | simandl | $varvalue=$array[$varname]; |
215 | | | |
216 | 85 | simandl | if ($debug) { |
217 | 1 | simandl | print "Checking $varname..."; |
218 | 85 | simandl | } |
219 | 1 | simandl | |
220 | | | $waspresent=$all_present; |
221 | | | |
222 | | | switch ($vartype) |
223 | | | { |
224 | | | case 'int': |
225 | 85 | simandl | if (!preg_match('/^\-*\d+$/', $varvalue)) { |
226 | | | $all_present=false; |
227 | | | } |
228 | 1 | simandl | |
229 | | | break; |
230 | | | |
231 | | | case 'float': |
232 | 85 | simandl | if (!preg_match('/^\d+\.\d+$/', $varvalue)) { |
233 | | | $all_present=false; |
234 | | | } |
235 | 1 | simandl | |
236 | | | break; |
237 | | | |
238 | | | case 'yesno': |
239 | 85 | simandl | if (!preg_match('/^(y|n|yes|no)$/i', $varvalue)) { |
240 | | | $all_present=false; |
241 | | | } |
242 | 1 | simandl | |
243 | | | break; |
244 | | | |
245 | | | case 'sqldate': |
246 | 85 | simandl | if (!preg_match('/^\d\d\d\d\-\d\d\-\d\d$/i', $varvalue)) { |
247 | | | $all_present=false; |
248 | | | } |
249 | 1 | simandl | |
250 | | | break; |
251 | | | |
252 | | | case 'any': |
253 | | | // we don't care at all |
254 | | | break; |
255 | | | |
256 | | | case 'ip': |
257 | 85 | simandl | if (!preg_match( '/^((\d|[1-9]\d|2[0-4]\d|25[0-5]|1\d\d)(?:\.(\d|[1-9]\d|2[0-4]\d|25[0-5]|1\d\d)){3})$/', $varvalue)) { |
258 | | | $all_present=false; |
259 | | | } |
260 | 1 | simandl | |
261 | | | break; |
262 | | | |
263 | | | case 'alpha': |
264 | 85 | simandl | if (!preg_match('/^[A-Za-z]+$/', $varvalue)) { |
265 | | | $all_present=false; |
266 | | | } |
267 | 1 | simandl | |
268 | | | break; |
269 | | | |
270 | | | case 'alphanum': |
271 | 85 | simandl | if (!preg_match('/^[A-Za-z0-9]+$/', $varvalue)) { |
272 | | | $all_present=false; |
273 | | | } |
274 | 1 | simandl | |
275 | | | break; |
276 | | | |
277 | | | case 'bandwidth': |
278 | 85 | simandl | if (!preg_match('/^\d+\.?\d*[KMGT]*$/i', $varvalue)) { |
279 | | | $all_present=false; |
280 | | | } |
281 | 1 | simandl | |
282 | | | break; |
283 | | | |
284 | | | default: |
285 | | | // an unknown type counts as an error, really |
286 | 85 | simandl | $all_present=false; |
287 | 1 | simandl | |
288 | | | break; |
289 | | | } |
290 | | | |
291 | 85 | simandl | if ($debug && $waspresent != $all_present) { |
292 | | | print "Failed on $varname."; |
293 | | | } |
294 | 1 | simandl | |
295 | 85 | simandl | if ($all_present) { |
296 | 1 | simandl | $candidates["{$prefix}{$varname}"]=$varvalue; |
297 | | | $candidates["{$prefix}{$varname}_slashes"]=addslashes($varvalue); |
298 | | | $candidates["{$prefix}{$varname}_url"]=urlencode($varvalue); |
299 | | | $candidates["{$prefix}{$varname}_html"]=htmlspecialchars($varvalue); |
300 | | | $candidates["{$prefix}{$varname}_url_html"]=htmlspecialchars(urlencode($varvalue)); |
301 | | | } |
302 | 85 | simandl | } else { |
303 | | | if ($debug) { |
304 | 1 | simandl | print "Skipping $varname\n"; |
305 | 85 | simandl | } |
306 | 1 | simandl | } |
307 | | | } |
308 | | | |
309 | 85 | simandl | if ($debug) { |
310 | 1 | simandl | print_r ($candidates); |
311 | 85 | simandl | } |
312 | 1 | simandl | |
313 | 85 | simandl | if ($all_present) { |
314 | | | foreach ($candidates as $key => $value) { |
315 | | | $GLOBALS[$key]=$value; |
316 | | | } |
317 | 1 | simandl | } |
318 | | | |
319 | 85 | simandl | if ($debug) { |
320 | 1 | simandl | print '</pre>'; |
321 | 85 | simandl | } |
322 | 1 | simandl | |
323 | | | return ($all_present); |
324 | | | } |
325 | | | |
326 | | | function get_imagelist($imagedir) |
327 | | | { |
328 | | | $imagelist = array(); |
329 | | | |
330 | 85 | simandl | if (is_dir($imagedir)) { |
331 | 1 | simandl | $n=0; |
332 | | | $dh=opendir($imagedir); |
333 | | | |
334 | 85 | simandl | if ($dh) { |
335 | | | while ($file=readdir($dh)) { |
336 | 1 | simandl | $realfile=$imagedir . DIRECTORY_SEPARATOR . $file; |
337 | | | $uri = $imagedir . "/" . $file; |
338 | | | |
339 | 85 | simandl | if (is_file($realfile) && ( preg_match('/\.(gif|jpg|png)$/i',$file) )) { |
340 | 1 | simandl | $imagelist[] = $uri; |
341 | | | $n++; |
342 | | | } |
343 | | | } |
344 | | | |
345 | | | closedir ($dh); |
346 | | | } |
347 | | | } |
348 | | | return ($imagelist); |
349 | | | } |
350 | 13 | simandl | |
351 | | | function handle_inheritance(&$map, &$inheritables) |
352 | | | { |
353 | 85 | simandl | foreach ($inheritables as $inheritable) { |
354 | 13 | simandl | $fieldname = $inheritable[1]; |
355 | | | $formname = $inheritable[2]; |
356 | | | |
357 | | | $new = $_REQUEST[$formname]; |
358 | | | |
359 | 85 | simandl | $old = ($inheritable[0]=='node' ? $map->nodes['DEFAULT']->$fieldname : $map->links['DEFAULT']->$fieldname); |
360 | 13 | simandl | |
361 | 85 | simandl | if ($old != $new) { |
362 | | | if ($inheritable[0]=='node') { |
363 | | | $map->nodes['DEFAULT']->$fieldname = $new; |
364 | | | foreach ($map->nodes as $node) { |
365 | | | if ($node->name != ":: DEFAULT ::" && $node->$fieldname == $old) { |
366 | 13 | simandl | $map->nodes[$node->name]->$fieldname = $new; |
367 | | | } |
368 | | | } |
369 | | | } |
370 | | | |
371 | 85 | simandl | if ($inheritable[0]=='link') { |
372 | | | $map->links['DEFAULT']->$fieldname = $new; |
373 | | | foreach ($map->links as $link) { |
374 | | | |
375 | | | if ($link->name != ":: DEFAULT ::" && $link->$fieldname == $old) { |
376 | 13 | simandl | $map->links[$link->name]->$fieldname = $new; |
377 | | | } |
378 | | | } |
379 | | | } |
380 | | | } |
381 | | | } |
382 | | | } |
383 | | | |
384 | | | function get_fontlist(&$map,$name,$current) |
385 | | | { |
386 | 85 | simandl | $output = '<select class="fontcombo" name="'.$name.'">'; |
387 | | | |
388 | | | ksort($map->fonts); |
389 | | | |
390 | | | foreach ($map->fonts as $fontnumber => $font) { |
391 | | | $output .= '<option '; |
392 | | | if ($current == $fontnumber) { |
393 | | | $output .= 'SELECTED'; |
394 | | | } |
395 | | | $output .= ' value="'.$fontnumber.'">'.$fontnumber.' ('.$font->type.')</option>'; |
396 | | | } |
397 | | | |
398 | | | $output .= "</select>"; |
399 | | | |
400 | | | return($output); |
401 | 13 | simandl | } |
402 | | | |
403 | 85 | simandl | function editor_log($str) |
404 | | | { |
405 | | | // $f = fopen("editor.log","a"); |
406 | | | // fputs($f, $str); |
407 | | | // fclose($f); |
408 | | | } |
409 | | | |
410 | 1 | simandl | // vim:ts=4:sw=4: |
411 | | | ?> |