Project

General

Profile

Download (9.29 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 0919224f Bill Marquette
  /* 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 64cc39d3 Matthew Grooms
	$ret = explode(" ",
39 9f428275 Erik Fonnesbeck
		"alias aliasurl allowedip authserver bridged ca cacert cert clone config ".
40
		"container columnitem depends_on_package disk dnsserver dnsupdate ".
41
		"domainoverrides dyndns earlyshellcmd element encryption-algorithm-option ".
42
		"field fieldname hash-algorithm-option gateway_item gateway_group gif gre ".
43 0ec2fdf0 Ermal Lu?i
		"group hosts member ifgroupentry igmpentry interface_array item key lagg " .
44
		"lbaction lbpool l7rules lbprotocol ".
45
		"member menu tab mobilekey monitor_type mount ntpserver onetoone ".
46 b6617403 Matthew Grooms
		"openvpn-server openvpn-client openvpn-csc " .
47 5f1e1d26 Ermal Lu?i
		"option ppp package passthrumac phase1 phase2 priv proxyarpnet qinqentry queue ".
48 336e3c1c Charlie
		"pages pipe roll route row rrddatafile rule schedule service servernat servers ".
49 0919224f Bill Marquette
		"serversdisabled earlyshellcmd shellcmd staticmap subqueue timerange ".
50 5e7d127a Scott Ullrich
		"tunnel user vip virtual_server vlan winsserver wolentry widget  "
51 0919224f Bill Marquette
		);
52 26433cb8 Scott Ullrich
	return $ret;
53 eeb6c16e Bill Marquette
}
54
55 2fe045e5 Bill Marquette
/* Package XML tags that should be treat as a list not as a traditional array */
56 eeb6c16e Bill Marquette
function listtags_pkg() {
57 e1b5fccb Scott Ullrich
	$ret = array("depends_on_package", "onetoone", "queue", "rule", "servernat", "alias", "additional_files_needed", "tab", "template", "menu", "rowhelperfield", "service", "step", "package", "columnitem", "option", "item", "field", "package", "file");
58 eeb6c16e Bill Marquette
59 26433cb8 Scott Ullrich
	return $ret;
60 eeb6c16e Bill Marquette
}
61
62 071d63b9 Erik Fonnesbeck
/* The following items will be treated as arrays in regdomain.xml */
63
function listtags_rd() {
64
	$ret = explode(" ",
65
		"band country flags freqband netband rd  "
66
		);
67
	return $ret;
68
}
69
70 26433cb8 Scott Ullrich
function startElement($parser, $name, $attrs) {
71 071d63b9 Erik Fonnesbeck
	global $parsedcfg, $depth, $curpath, $havedata, $listtags, $parsedattrs, $parsingattrs;
72 528ae96e Scott Ullrich
73 26433cb8 Scott Ullrich
	array_push($curpath, strtolower($name));
74
75
	$ptr =& $parsedcfg;
76 071d63b9 Erik Fonnesbeck
	if (isset($parsingattrs) && !empty($attrs)) {
77
		$attrptr =& $parsedattrs;
78
		$writeattrs = true;
79
	}
80 26433cb8 Scott Ullrich
	foreach ($curpath as $path) {
81
		$ptr =& $ptr[$path];
82 071d63b9 Erik Fonnesbeck
		if (isset($writeattrs))
83
			$attrptr =& $attrptr[$path];
84 26433cb8 Scott Ullrich
	}
85
86
	/* is it an element that belongs to a list? */
87
	if (in_array(strtolower($name), $listtags)) {
88
89
		/* is there an array already? */
90
		if (!is_array($ptr)) {
91
			/* make an array */
92
			$ptr = array();
93
		}
94
95
		array_push($curpath, count($ptr));
96
97 071d63b9 Erik Fonnesbeck
		if (isset($writeattrs)) {
98
			if (!is_array($attrptr))
99
				$attrptr = array();
100
			$attrptr[count($ptr)] = $attrs;
101
		}
102
103 26433cb8 Scott Ullrich
	} else if (isset($ptr)) {
104
		/* multiple entries not allowed for this element, bail out */
105
		die(sprintf("XML error: %s at line %d cannot occur more than once\n",
106
				$name,
107
				xml_get_current_line_number($parser)));
108 071d63b9 Erik Fonnesbeck
	} else if (isset($writeattrs)) {
109
		$attrptr = $attrs;
110 26433cb8 Scott Ullrich
	}
111
112
	$depth++;
113
	$havedata = $depth;
114
}
115
116
function endElement($parser, $name) {
117
	global $depth, $curpath, $parsedcfg, $havedata, $listtags;
118
119
	if ($havedata == $depth) {
120
		$ptr =& $parsedcfg;
121
		foreach ($curpath as $path) {
122
			$ptr =& $ptr[$path];
123
		}
124
		$ptr = "";
125
	}
126
127
	array_pop($curpath);
128
129
	if (in_array(strtolower($name), $listtags))
130
		array_pop($curpath);
131
132
	$depth--;
133
}
134
135
function cData($parser, $data) {
136
	global $depth, $curpath, $parsedcfg, $havedata;
137
138
	$data = trim($data, "\t\n\r");
139
140
	if ($data != "") {
141
		$ptr =& $parsedcfg;
142
		foreach ($curpath as $path) {
143
			$ptr =& $ptr[$path];
144
		}
145
146
		if (is_string($ptr)) {
147
			$ptr .= $data;
148
		} else {
149
			if (trim($data, " ") != "") {
150
				$ptr = $data;
151
				$havedata++;
152
			}
153
		}
154
	}
155 5b237745 Scott Ullrich
}
156
157 48ca2dc9 Colin Smith
function parse_xml_config($cffile, $rootobj, $isstring = "false") {
158 cb980a2f Colin Smith
	global $listtags;
159 eeb6c16e Bill Marquette
	$listtags = listtags();
160 eb72ceda Scott Ullrich
        if (isset($GLOBALS['custom_listtags'])) {
161
          foreach($GLOBALS['custom_listtags'] as $tag) {
162 26433cb8 Scott Ullrich
            $listtags[] = $tag;
163 eb72ceda Scott Ullrich
          }
164
        }
165 26433cb8 Scott Ullrich
	return parse_xml_config_raw($cffile, $rootobj, $isstring);
166 cb980a2f Colin Smith
}
167
168 48ca2dc9 Colin Smith
function parse_xml_config_pkg($cffile, $rootobj, $isstring = "false") {
169 cb980a2f Colin Smith
	global $listtags;
170 eeb6c16e Bill Marquette
	$listtags = listtags_pkg();
171 eb72ceda Scott Ullrich
        if (isset($GLOBALS['custom_listtags_pkg'])) {
172
          foreach($GLOBALS['custom_listtags_pkg'] as $tag) {
173 26433cb8 Scott Ullrich
            $listtags[] = $tag;
174 eb72ceda Scott Ullrich
          }
175
        }
176 bef6cb99 Ermal
	$cfg =parse_xml_config_raw($cffile, $rootobj, $isstring);
177
	if ($cfg == -1)
178 541989d5 Ermal
		die("XML error: not $rootboj object found!\n");
179 bef6cb99 Ermal
	
180
	return $cfg;
181 cb980a2f Colin Smith
}
182
183 071d63b9 Erik Fonnesbeck
function parse_xml_regdomain(&$rdattributes, $rdfile = '/etc/regdomain.xml', $rootobj = 'regulatory-data') {
184
	global $listtags, $parsedattrs, $parsingattrs;
185
	$listtags = listtags_rd();
186
	if (isset($rdattributes)) {
187
		$parsedattrs = array();
188
		$parsingattrs = true;
189
		$ret = parse_xml_config_raw($rdfile, $rootobj);
190
		if ($parsedattrs[$rootobj])
191
			$rdattributes = $parsedattrs[$rootobj];
192
		unset($parsedattrs);
193
		unset($parsingattrs);
194
		return $ret;
195
	} else {
196
		return parse_xml_config_raw($rdfile, $rootobj);
197
	}
198
}
199
200 48ca2dc9 Colin Smith
function parse_xml_config_raw($cffile, $rootobj, $isstring = "false") {
201 5b237745 Scott Ullrich
202 26433cb8 Scott Ullrich
	global $depth, $curpath, $parsedcfg, $havedata, $listtags;
203 08c3872d Colin Smith
	$parsedcfg = array();
204 26433cb8 Scott Ullrich
	$curpath = array();
205
	$depth = 0;
206
	$havedata = 0;
207
208
	$xml_parser = xml_parser_create();
209
210
	xml_set_element_handler($xml_parser, "startElement", "endElement");
211
	xml_set_character_data_handler($xml_parser, "cdata");
212 9f695b0f Ermal Lu?i
	xml_parser_set_option($xml_parser,XML_OPTION_SKIP_WHITE, 1); 
213 26433cb8 Scott Ullrich
214
	if (!($fp = fopen($cffile, "r"))) {
215 541989d5 Ermal
		log_error("Error: could not open XML input\n");
216
		return -1;
217 26433cb8 Scott Ullrich
	}
218 d7b6c842 Ermal Lu?i
219 26433cb8 Scott Ullrich
	while ($data = fread($fp, 4096)) {
220
		if (!xml_parse($xml_parser, $data, feof($fp))) {
221
			log_error(sprintf("XML error: %s at line %d\n",
222
						xml_error_string(xml_get_error_code($xml_parser)),
223
						xml_get_current_line_number($xml_parser)));
224
			return -1;
225
		}
226
	}
227
	xml_parser_free($xml_parser);
228
229
	if (!$parsedcfg[$rootobj]) {
230 541989d5 Ermal
		log_error("XML error: no $rootobj object found!\n");
231
		return -1;
232 26433cb8 Scott Ullrich
	}
233 528ae96e Scott Ullrich
234 08c3872d Colin Smith
	return $parsedcfg[$rootobj];
235 5b237745 Scott Ullrich
}
236
237
function dump_xml_config_sub($arr, $indent) {
238
239
	global $listtags;
240 528ae96e Scott Ullrich
241 5b237745 Scott Ullrich
	$xmlconfig = "";
242
243
	foreach ($arr as $ent => $val) {
244
		if (is_array($val)) {
245
			/* is it just a list of multiple values? */
246 26433cb8 Scott Ullrich
			if (in_array(strtolower($ent), $listtags)) {
247 5b237745 Scott Ullrich
				foreach ($val as $cval) {
248
					if (is_array($cval)) {
249
						$xmlconfig .= str_repeat("\t", $indent);
250
						$xmlconfig .= "<$ent>\n";
251
						$xmlconfig .= dump_xml_config_sub($cval, $indent + 1);
252
						$xmlconfig .= str_repeat("\t", $indent);
253
						$xmlconfig .= "</$ent>\n";
254
					} else {
255
						$xmlconfig .= str_repeat("\t", $indent);
256 0d57f5f3 Scott Ullrich
						if($cval === false) continue;
257
						if(($cval === true) || ($cval === "")) {
258 5b237745 Scott Ullrich
							$xmlconfig .= "<$ent/>\n";
259 0d57f5f3 Scott Ullrich
						} else {
260 5b237745 Scott Ullrich
							$xmlconfig .= "<$ent>" . htmlspecialchars($cval) . "</$ent>\n";
261
					}
262
				}
263 0d57f5f3 Scott Ullrich
				}
264 78dd5020 Ermal Lu?i
			} else if (empty($val)) {
265
				$xmlconfig .= str_repeat("\t", $indent);
266
				$xmlconfig .= "<$ent/>\n";
267
				$xmlconfig .= str_repeat("\t", $indent);
268 5b237745 Scott Ullrich
			} else {
269
				/* it's an array */
270
				$xmlconfig .= str_repeat("\t", $indent);
271
				$xmlconfig .= "<$ent>\n";
272
				$xmlconfig .= dump_xml_config_sub($val, $indent + 1);
273
				$xmlconfig .= str_repeat("\t", $indent);
274
				$xmlconfig .= "</$ent>\n";
275
			}
276
		} else {
277
			if ((is_bool($val) && ($val == true)) || ($val === "")) {
278
				$xmlconfig .= str_repeat("\t", $indent);
279
				$xmlconfig .= "<$ent/>\n";
280
			} else if (!is_bool($val)) {
281
				$xmlconfig .= str_repeat("\t", $indent);
282
				$xmlconfig .= "<$ent>" . htmlspecialchars($val) . "</$ent>\n";
283
			}
284
		}
285
	}
286 528ae96e Scott Ullrich
287 5b237745 Scott Ullrich
	return $xmlconfig;
288
}
289
290
function dump_xml_config($arr, $rootobj) {
291 ba6882bf Colin Smith
	global $listtags;
292 eeb6c16e Bill Marquette
	$listtags = listtags();
293 4928848f Scott Ullrich
        if (isset($GLOBALS['custom_listtags'])) {
294
          foreach($GLOBALS['custom_listtags'] as $tag) {
295 26433cb8 Scott Ullrich
            $listtags[] = $tag;
296 4928848f Scott Ullrich
          }
297
        }
298 ba6882bf Colin Smith
	return dump_xml_config_raw($arr, $rootobj);
299
}
300
301
function dump_xml_config_pkg($arr, $rootobj) {
302
	global $listtags;
303 eeb6c16e Bill Marquette
	$listtags = listtags_pkg();
304 4928848f Scott Ullrich
        if (isset($GLOBALS['custom_listtags_pkg'])) {
305
          foreach($GLOBALS['custom_listtags_pkg'] as $tag) {
306 26433cb8 Scott Ullrich
            $listtags[] = $tag;
307 4928848f Scott Ullrich
          }
308
        }
309 ba6882bf Colin Smith
	return dump_xml_config_raw($arr, $rootobj);
310
}
311
312
function dump_xml_config_raw($arr, $rootobj) {
313 5b237745 Scott Ullrich
314
	$xmlconfig = "<?xml version=\"1.0\"?" . ">\n";
315
	$xmlconfig .= "<$rootobj>\n";
316 528ae96e Scott Ullrich
317 5b237745 Scott Ullrich
	$xmlconfig .= dump_xml_config_sub($arr, 1);
318 528ae96e Scott Ullrich
319 5b237745 Scott Ullrich
	$xmlconfig .= "</$rootobj>\n";
320 528ae96e Scott Ullrich
321 5b237745 Scott Ullrich
	return $xmlconfig;
322
}
323
324 d173230c Seth Mos
?>