Project

General

Profile

Download (6.57 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	xmlparse.inc
5
	functions to parse/dump configuration files in XML format
6
	part of m0n0wall (http://m0n0.ch/wall)
7

    
8
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
9
	All rights reserved.
10

    
11
	Redistribution and use in source and binary forms, with or without
12
	modification, are permitted provided that the following conditions are met:
13

    
14
	1. Redistributions of source code must retain the above copyright notice,
15
	   this list of conditions and the following disclaimer.
16

    
17
	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

    
21
	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
/* Config XML tags that should be treat as a list not as a traditional array */
34
function listtags() {
35
	$ret = explode(" ", "cacert row config package columnitem option item fieldname field rule user key subqueue " .
36
                "dnsserver winsserver encryption-algorithm-option hash-algorithm-option hosts tunnel " .
37
                "onetoone staticmap route alias queue shellcmd earlyshellcmd mobilekey " .
38
                "service servernat proxyarpnet passthrumac allowedip wolentry vlan menu domainoverrides " .
39
		"vip");
40

    
41
	return $ret;
42
}
43

    
44
/* Package XML tags that should be treat as a list not as a traditional array */
45
function listtags_pkg() {
46
	$ret = array("onetoone", "queue", "rule", "servernat", "alias", "additional_files_needed", "tab", "template", "menu", "rowhelperfield", "service", "step", "package", "columnitem", "option", "item", "field", "package");
47

    
48
	return $ret;
49
}
50

    
51
function startElement($parser, $name, $attrs) {
52
	global $parsedcfg, $depth, $curpath, $havedata, $listtags;
53

    
54
	array_push($curpath, strtolower($name));
55

    
56
	$ptr =& $parsedcfg;
57
	foreach ($curpath as $path) {
58
		$ptr =& $ptr[$path];
59
	}
60

    
61
	/* is it an element that belongs to a list? */
62
	if (in_array(strtolower($name), $listtags)) {
63

    
64
		/* is there an array already? */
65
		if (!is_array($ptr)) {
66
			/* make an array */
67
			$ptr = array();
68
		}
69

    
70
		array_push($curpath, count($ptr));
71

    
72
	} else if (isset($ptr)) {
73
		/* multiple entries not allowed for this element, bail out */
74
		die(sprintf("XML error: %s at line %d cannot occur more than once\n",
75
				$name,
76
				xml_get_current_line_number($parser)));
77
	}
78

    
79
	$depth++;
80
	$havedata = $depth;
81
}
82

    
83
function endElement($parser, $name) {
84
	global $depth, $curpath, $parsedcfg, $havedata, $listtags;
85

    
86
	if ($havedata == $depth) {
87
		$ptr =& $parsedcfg;
88
		foreach ($curpath as $path) {
89
			$ptr =& $ptr[$path];
90
		}
91
		$ptr = "";
92
	}
93

    
94
	array_pop($curpath);
95

    
96
	if (in_array(strtolower($name), $listtags))
97
		array_pop($curpath);
98

    
99
	$depth--;
100
}
101

    
102
function cData($parser, $data) {
103
	global $depth, $curpath, $parsedcfg, $havedata;
104

    
105
	$data = trim($data, "\t\n\r");
106

    
107
	if ($data != "") {
108
		$ptr =& $parsedcfg;
109
		foreach ($curpath as $path) {
110
			$ptr =& $ptr[$path];
111
		}
112

    
113
		if (is_string($ptr)) {
114
			$ptr .= $data;
115
		} else {
116
			if (trim($data, " ") != "") {
117
				$ptr = $data;
118
				$havedata++;
119
			}
120
		}
121
	}
122
}
123

    
124
function parse_xml_config($cffile, $rootobj) {
125
	global $listtags;
126
	$listtags = listtags();
127
	return parse_xml_config_raw($cffile, $rootobj);
128
}
129

    
130
function parse_xml_config_pkg($cffile, $rootobj) {
131
	global $listtags;
132
	$listtags = listtags_pkg();
133
	return parse_xml_config_raw($cffile, $rootobj);
134
}
135

    
136
function parse_xml_config_raw($cffile, $rootobj) {
137

    
138
	global $depth, $curpath, $parsedcfg, $havedata, $listtags;
139
	$parsedcfg = array();
140
	$curpath = array();
141
	$depth = 0;
142
	$havedata = 0;
143

    
144
	$xml_parser = xml_parser_create();
145

    
146
	xml_set_element_handler($xml_parser, "startElement", "endElement");
147
	xml_set_character_data_handler($xml_parser, "cdata");
148

    
149
	if (!($fp = fopen($cffile, "r"))) {
150
		die("Error: could not open XML input\n");
151
	}
152

    
153
	while ($data = fread($fp, 4096)) {
154
		if (!xml_parse($xml_parser, $data, feof($fp))) {
155
			die(sprintf("XML error: %s at line %d\n",
156
						xml_error_string(xml_get_error_code($xml_parser)),
157
						xml_get_current_line_number($xml_parser)));
158
		}
159
	}
160
	xml_parser_free($xml_parser);
161

    
162
	if (!$parsedcfg[$rootobj]) {
163
		die("XML error: no $rootobj object found!\n");
164
	}
165

    
166
	return $parsedcfg[$rootobj];
167
}
168

    
169
function dump_xml_config_sub($arr, $indent) {
170

    
171
	global $listtags;
172

    
173
	$xmlconfig = "";
174

    
175
	foreach ($arr as $ent => $val) {
176
		if (is_array($val)) {
177
			/* is it just a list of multiple values? */
178
			if (in_array(strtolower($ent), $listtags)) {
179
				foreach ($val as $cval) {
180
					if (is_array($cval)) {
181
						$xmlconfig .= str_repeat("\t", $indent);
182
						$xmlconfig .= "<$ent>\n";
183
						$xmlconfig .= dump_xml_config_sub($cval, $indent + 1);
184
						$xmlconfig .= str_repeat("\t", $indent);
185
						$xmlconfig .= "</$ent>\n";
186
					} else {
187
						$xmlconfig .= str_repeat("\t", $indent);
188
						if ((is_bool($cval) && ($cval == true)) ||
189
							($cval === ""))
190
							$xmlconfig .= "<$ent/>\n";
191
						else if (!is_bool($cval))
192
							$xmlconfig .= "<$ent>" . htmlspecialchars($cval) . "</$ent>\n";
193
					}
194
				}
195
			} else {
196
				/* it's an array */
197
				$xmlconfig .= str_repeat("\t", $indent);
198
				$xmlconfig .= "<$ent>\n";
199
				$xmlconfig .= dump_xml_config_sub($val, $indent + 1);
200
				$xmlconfig .= str_repeat("\t", $indent);
201
				$xmlconfig .= "</$ent>\n";
202
			}
203
		} else {
204
			if ((is_bool($val) && ($val == true)) || ($val === "")) {
205
				$xmlconfig .= str_repeat("\t", $indent);
206
				$xmlconfig .= "<$ent/>\n";
207
			} else if (!is_bool($val)) {
208
				$xmlconfig .= str_repeat("\t", $indent);
209
				$xmlconfig .= "<$ent>" . htmlspecialchars($val) . "</$ent>\n";
210
			}
211
		}
212
	}
213

    
214
	return $xmlconfig;
215
}
216

    
217
function dump_xml_config($arr, $rootobj) {
218
	global $listtags;
219
	$listtags = listtags();
220
	return dump_xml_config_raw($arr, $rootobj);
221
}
222

    
223
function dump_xml_config_pkg($arr, $rootobj) {
224
	global $listtags;
225
	$listtags = listtags_pkg();
226
	return dump_xml_config_raw($arr, $rootobj);
227
}
228

    
229
function dump_xml_config_raw($arr, $rootobj) {
230

    
231
	$xmlconfig = "<?xml version=\"1.0\"?" . ">\n";
232
	$xmlconfig .= "<$rootobj>\n";
233

    
234
	$xmlconfig .= dump_xml_config_sub($arr, 1);
235

    
236
	$xmlconfig .= "</$rootobj>\n";
237

    
238
	return $xmlconfig;
239
}
240

    
241
?>
(19-19/22)