Project

General

Profile

Download (9.85 KB) Statistics
| Branch: | Tag: | Revision:
1 5b237745 Scott Ullrich
<?php
2
/*
3
	xmlparse.inc
4
	functions to parse/dump configuration files in XML format
5
	part of m0n0wall (http://m0n0.ch/wall)
6 528ae96e Scott Ullrich
7 5b237745 Scott Ullrich
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
8
	All rights reserved.
9 528ae96e Scott Ullrich
10 5b237745 Scott Ullrich
	Redistribution and use in source and binary forms, with or without
11
	modification, are permitted provided that the following conditions are met:
12 528ae96e Scott Ullrich
13 5b237745 Scott Ullrich
	1. Redistributions of source code must retain the above copyright notice,
14
	   this list of conditions and the following disclaimer.
15 528ae96e Scott Ullrich
16 5b237745 Scott Ullrich
	2. Redistributions in binary form must reproduce the above copyright
17
	   notice, this list of conditions and the following disclaimer in the
18
	   documentation and/or other materials provided with the distribution.
19 528ae96e Scott Ullrich
20 5b237745 Scott Ullrich
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
21
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
22
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
24
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
	POSSIBILITY OF SUCH DAMAGE.
30
*/
31
32 2e5ebf5d Scott Ullrich
/* The following items will be treated as arrays in config.xml */
33 eeb6c16e Bill Marquette
function listtags() {
34 72a8c829 Ermal
	/*
35
	 * Please keep this list alpha sorted and no longer than 80 characters
36
	 * I know it's a pain, but it's a pain to find stuff too if it's not
37
	 */
38
	$ret = array(
39 79262830 Phil Davis
		'acls', 'alias', 'aliasurl', 'allowedip', 'allowedhostname', 'authserver',
40
		'bridged', 'build_port_path',
41
		'ca', 'cacert', 'cert', 'crl', 'clone', 'config', 'container', 'columnitem',
42
		'depends_on_package', 'disk', 'dnsserver', 'dnsupdate', 'domainoverrides', 'dyndns',
43
		'earlyshellcmd', 'element', 'encryption-algorithm-option',
44
		'field', 'fieldname',
45
		'gateway_item', 'gateway_group', 'gif', 'gre', 'group',
46
		'hash-algorithm-option', 'hosts', 'member', 'ifgroupentry', 'igmpentry', 'interface_array', 'item', 'key',
47
		'lagg', 'lbaction', 'lbpool', 'l7rules', 'lbprotocol',
48
		'member', 'menu', 'tab', 'mobilekey', 'monitor_type', 'mount',
49 72a8c829 Ermal
		'npt', 'ntpserver',
50 79262830 Phil Davis
		'onetoone', 'openvpn-server', 'openvpn-client', 'openvpn-csc', 'option',
51
		'package', 'passthrumac', 'phase1', 'phase2', 'ppp', 'pppoe', 'priv', 'proxyarpnet', 'pool',
52 72a8c829 Ermal
		'qinqentry', 'queue',
53 79262830 Phil Davis
		'pages', 'pipe', 'radnsserver', 'roll', 'route', 'row', 'rrddatafile', 'rule',
54 72a8c829 Ermal
		'schedule', 'service', 'servernat', 'servers',
55 79262830 Phil Davis
		'serversdisabled', 'shellcmd', 'staticmap', 'subqueue',
56 72a8c829 Ermal
		'timerange', 'tunnel', 'user', 'vip', 'virtual_server', 'vlan',
57
		'winsserver', 'wolentry', 'widget'
58
	);
59 6d84c956 Ermal
	return array_flip($ret);
60 eeb6c16e Bill Marquette
}
61
62 79262830 Phil Davis
/* Package XML tags that should be treated as a list not as a traditional array */
63 eeb6c16e Bill Marquette
function listtags_pkg() {
64 72a8c829 Ermal
	$ret = array('build_port_path', 'depends_on_package', 'onetoone', 'queue', 'rule', 'servernat', 'alias', 'additional_files_needed', 'tab', 'template', 'menu', 'rowhelperfield', 'service', 'step', 'package', 'columnitem', 'option', 'item', 'field', 'package', 'file');
65 eeb6c16e Bill Marquette
66 1c62178a Ermal
	return array_flip($ret);
67 eeb6c16e Bill Marquette
}
68
69 26433cb8 Scott Ullrich
function startElement($parser, $name, $attrs) {
70 1fb064e8 Erik Fonnesbeck
	global $parsedcfg, $depth, $curpath, $havedata, $listtags;
71 528ae96e Scott Ullrich
72 26433cb8 Scott Ullrich
	array_push($curpath, strtolower($name));
73
74
	$ptr =& $parsedcfg;
75
	foreach ($curpath as $path) {
76
		$ptr =& $ptr[$path];
77
	}
78
79
	/* is it an element that belongs to a list? */
80 6d84c956 Ermal
	if (isset($listtags[strtolower($name)])) {
81 26433cb8 Scott Ullrich
82
		/* is there an array already? */
83
		if (!is_array($ptr)) {
84
			/* make an array */
85
			$ptr = array();
86
		}
87
88
		array_push($curpath, count($ptr));
89
90
	} else if (isset($ptr)) {
91
		/* multiple entries not allowed for this element, bail out */
92 addc0439 Renato Botelho
		die(sprintf(gettext('XML error: %1$s at line %2$d cannot occur more than once') . "\n",
93 79262830 Phil Davis
		    $name,
94
		    xml_get_current_line_number($parser)));
95 26433cb8 Scott Ullrich
	}
96
97
	$depth++;
98
	$havedata = $depth;
99
}
100
101
function endElement($parser, $name) {
102
	global $depth, $curpath, $parsedcfg, $havedata, $listtags;
103
104
	if ($havedata == $depth) {
105
		$ptr =& $parsedcfg;
106
		foreach ($curpath as $path) {
107
			$ptr =& $ptr[$path];
108
		}
109
		$ptr = "";
110
	}
111
112
	array_pop($curpath);
113
114 79262830 Phil Davis
	if (isset($listtags[strtolower($name)])) {
115 26433cb8 Scott Ullrich
		array_pop($curpath);
116 79262830 Phil Davis
	}
117 26433cb8 Scott Ullrich
118
	$depth--;
119
}
120
121
function cData($parser, $data) {
122
	global $depth, $curpath, $parsedcfg, $havedata;
123
124
	$data = trim($data, "\t\n\r");
125
126
	if ($data != "") {
127
		$ptr =& $parsedcfg;
128
		foreach ($curpath as $path) {
129
			$ptr =& $ptr[$path];
130
		}
131
132
		if (is_string($ptr)) {
133 2e6a43a1 Ermal
			$ptr .= html_entity_decode($data);
134 26433cb8 Scott Ullrich
		} else {
135
			if (trim($data, " ") != "") {
136 2e6a43a1 Ermal
				$ptr = html_entity_decode($data);
137 26433cb8 Scott Ullrich
				$havedata++;
138
			}
139
		}
140
	}
141 5b237745 Scott Ullrich
}
142
143 48ca2dc9 Colin Smith
function parse_xml_config($cffile, $rootobj, $isstring = "false") {
144 cb980a2f Colin Smith
	global $listtags;
145 eeb6c16e Bill Marquette
	$listtags = listtags();
146 79262830 Phil Davis
	if (isset($GLOBALS['custom_listtags'])) {
147
		foreach ($GLOBALS['custom_listtags'] as $tag) {
148
			$listtags[$tag] = $tag;
149
		}
150
	}
151 26433cb8 Scott Ullrich
	return parse_xml_config_raw($cffile, $rootobj, $isstring);
152 cb980a2f Colin Smith
}
153
154 48ca2dc9 Colin Smith
function parse_xml_config_pkg($cffile, $rootobj, $isstring = "false") {
155 cb980a2f Colin Smith
	global $listtags;
156 eeb6c16e Bill Marquette
	$listtags = listtags_pkg();
157 79262830 Phil Davis
	if (isset($GLOBALS['custom_listtags_pkg'])) {
158
		foreach ($GLOBALS['custom_listtags_pkg'] as $tag) {
159
			$listtags[$tag] = $tag;
160
		}
161
	}
162 bef6cb99 Ermal
	$cfg =parse_xml_config_raw($cffile, $rootobj, $isstring);
163 79262830 Phil Davis
	if ($cfg == -1) {
164 187ce62b Ermal
		return array();
165 79262830 Phil Davis
	}
166
167 bef6cb99 Ermal
	return $cfg;
168 cb980a2f Colin Smith
}
169
170 48ca2dc9 Colin Smith
function parse_xml_config_raw($cffile, $rootobj, $isstring = "false") {
171 5b237745 Scott Ullrich
172 26433cb8 Scott Ullrich
	global $depth, $curpath, $parsedcfg, $havedata, $listtags;
173 08c3872d Colin Smith
	$parsedcfg = array();
174 26433cb8 Scott Ullrich
	$curpath = array();
175
	$depth = 0;
176
	$havedata = 0;
177
178
	$xml_parser = xml_parser_create();
179
180
	xml_set_element_handler($xml_parser, "startElement", "endElement");
181
	xml_set_character_data_handler($xml_parser, "cdata");
182 086cf944 Phil Davis
	xml_parser_set_option($xml_parser, XML_OPTION_SKIP_WHITE, 1);
183 26433cb8 Scott Ullrich
184
	if (!($fp = fopen($cffile, "r"))) {
185 ada992bd Renato Botelho
		log_error(gettext("Error: could not open XML input") . "\n");
186 541989d5 Ermal
		return -1;
187 26433cb8 Scott Ullrich
	}
188 d7b6c842 Ermal Lu?i
189 26433cb8 Scott Ullrich
	while ($data = fread($fp, 4096)) {
190
		if (!xml_parse($xml_parser, $data, feof($fp))) {
191 c92ccac7 Vinicius Coque
			log_error(sprintf(gettext('XML error: %1$s at line %2$d in %3$s') . "\n",
192 79262830 Phil Davis
				xml_error_string(xml_get_error_code($xml_parser)),
193
				xml_get_current_line_number($xml_parser),
194
				$cffile));
195 26433cb8 Scott Ullrich
			return -1;
196
		}
197
	}
198
	xml_parser_free($xml_parser);
199
200 428c289f Darren Embry
	if ($rootobj) {
201 79262830 Phil Davis
		if (!is_array($rootobj)) {
202 428c289f Darren Embry
			$rootobj = array($rootobj);
203 79262830 Phil Davis
		}
204
		foreach ($rootobj as $rootobj_name) {
205
			if ($parsedcfg[$rootobj_name]) {
206 428c289f Darren Embry
				break;
207 79262830 Phil Davis
			}
208
		}
209
210 428c289f Darren Embry
		if (!$parsedcfg[$rootobj_name]) {
211
			log_error(sprintf(gettext("XML error: no %s object found!") . "\n", implode(" or ", $rootobj)));
212
			return -1;
213
		}
214
		return $parsedcfg[$rootobj_name];
215
	} else {
216
		return $parsedcfg;
217 26433cb8 Scott Ullrich
	}
218 5b237745 Scott Ullrich
}
219
220
function dump_xml_config_sub($arr, $indent) {
221
222
	global $listtags;
223 528ae96e Scott Ullrich
224 5b237745 Scott Ullrich
	$xmlconfig = "";
225
226
	foreach ($arr as $ent => $val) {
227
		if (is_array($val)) {
228
			/* is it just a list of multiple values? */
229 6d84c956 Ermal
			if (isset($listtags[strtolower($ent)])) {
230 5b237745 Scott Ullrich
				foreach ($val as $cval) {
231
					if (is_array($cval)) {
232 70d6b5c4 Ermal
						if (empty($cval)) {
233
							$xmlconfig .= str_repeat("\t", $indent);
234
							$xmlconfig .= "<$ent/>\n";
235
						} else {
236
							$xmlconfig .= str_repeat("\t", $indent);
237
							$xmlconfig .= "<$ent>\n";
238
							$xmlconfig .= dump_xml_config_sub($cval, $indent + 1);
239
							$xmlconfig .= str_repeat("\t", $indent);
240
							$xmlconfig .= "</$ent>\n";
241
						}
242 5b237745 Scott Ullrich
					} else {
243 79262830 Phil Davis
						if ($cval === false) {
244
							continue;
245
						}
246 70d6b5c4 Ermal
						$xmlconfig .= str_repeat("\t", $indent);
247 79262830 Phil Davis
						if ((is_bool($cval) && $cval == true) || ($cval === "")) {
248 5b237745 Scott Ullrich
							$xmlconfig .= "<$ent/>\n";
249 79262830 Phil Davis
						} else if ((substr($ent, 0, 5) == "descr") ||
250
						    (substr($ent, 0, 6) == "detail") ||
251
						    (substr($ent, 0, 12) == "login_banner") ||
252
						    (substr($ent, 0, 9) == "ldap_attr") ||
253
						    (substr($ent, 0, 9) == "ldap_bind") ||
254
						    (substr($ent, 0, 11) == "ldap_basedn") ||
255
						    (substr($ent, 0, 18) == "ldap_authcn") ||
256
						    (substr($ent, 0, 19) == "ldap_extended_query")) {
257 02611466 Ermal
							$xmlconfig .= "<$ent><![CDATA[" . htmlentities($cval) . "]]></$ent>\n";
258 0d57f5f3 Scott Ullrich
						} else {
259 2e6a43a1 Ermal
							$xmlconfig .= "<$ent>" . htmlentities($cval) . "</$ent>\n";
260 70d6b5c4 Ermal
						}
261 5b237745 Scott Ullrich
					}
262
				}
263 78dd5020 Ermal Lu?i
			} else if (empty($val)) {
264
				$xmlconfig .= str_repeat("\t", $indent);
265
				$xmlconfig .= "<$ent/>\n";
266 5b237745 Scott Ullrich
			} else {
267
				/* it's an array */
268
				$xmlconfig .= str_repeat("\t", $indent);
269
				$xmlconfig .= "<$ent>\n";
270
				$xmlconfig .= dump_xml_config_sub($val, $indent + 1);
271
				$xmlconfig .= str_repeat("\t", $indent);
272
				$xmlconfig .= "</$ent>\n";
273
			}
274
		} else {
275
			if ((is_bool($val) && ($val == true)) || ($val === "")) {
276
				$xmlconfig .= str_repeat("\t", $indent);
277
				$xmlconfig .= "<$ent/>\n";
278
			} else if (!is_bool($val)) {
279
				$xmlconfig .= str_repeat("\t", $indent);
280 79262830 Phil Davis
				if ((substr($ent, 0, 5) == "descr") ||
281
				    (substr($ent, 0, 6) == "detail") ||
282
				    (substr($ent, 0, 12) == "login_banner") ||
283
				    (substr($ent, 0, 9) == "ldap_attr") ||
284
				    (substr($ent, 0, 9) == "ldap_bind") ||
285
				    (substr($ent, 0, 11) == "ldap_basedn") ||
286
				    (substr($ent, 0, 18) == "ldap_authcn") ||
287 086cf944 Phil Davis
				    (substr($ent, 0, 19) == "ldap_extended_query")) {
288 02611466 Ermal
					$xmlconfig .= "<$ent><![CDATA[" . htmlentities($val) . "]]></$ent>\n";
289 086cf944 Phil Davis
				} else {
290 2e6a43a1 Ermal
					$xmlconfig .= "<$ent>" . htmlentities($val) . "</$ent>\n";
291 79262830 Phil Davis
				}
292 5b237745 Scott Ullrich
			}
293
		}
294
	}
295 528ae96e Scott Ullrich
296 5b237745 Scott Ullrich
	return $xmlconfig;
297
}
298
299
function dump_xml_config($arr, $rootobj) {
300 ba6882bf Colin Smith
	global $listtags;
301 eeb6c16e Bill Marquette
	$listtags = listtags();
302 79262830 Phil Davis
	if (isset($GLOBALS['custom_listtags'])) {
303
		foreach ($GLOBALS['custom_listtags'] as $tag) {
304
			$listtags[$tag] = $tag;
305
		}
306
	}
307 ba6882bf Colin Smith
	return dump_xml_config_raw($arr, $rootobj);
308
}
309
310
function dump_xml_config_pkg($arr, $rootobj) {
311
	global $listtags;
312 eeb6c16e Bill Marquette
	$listtags = listtags_pkg();
313 79262830 Phil Davis
	if (isset($GLOBALS['custom_listtags_pkg'])) {
314
		foreach ($GLOBALS['custom_listtags_pkg'] as $tag) {
315
			$listtags[$tag] = $tag;
316
		}
317
	}
318 ba6882bf Colin Smith
	return dump_xml_config_raw($arr, $rootobj);
319
}
320
321
function dump_xml_config_raw($arr, $rootobj) {
322 5b237745 Scott Ullrich
323
	$xmlconfig = "<?xml version=\"1.0\"?" . ">\n";
324
	$xmlconfig .= "<$rootobj>\n";
325 528ae96e Scott Ullrich
326 5b237745 Scott Ullrich
	$xmlconfig .= dump_xml_config_sub($arr, 1);
327 528ae96e Scott Ullrich
328 5b237745 Scott Ullrich
	$xmlconfig .= "</$rootobj>\n";
329 528ae96e Scott Ullrich
330 5b237745 Scott Ullrich
	return $xmlconfig;
331
}
332
333 187ce62b Ermal
?>