Project

General

Profile

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