Project

General

Profile

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

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

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

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

    
16
	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

    
20
	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
/* The following items will be treated as arrays in config.xml */
33
function listtags() {
34
	/*
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
		'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
		'npt', 'ntpserver',
50
		'onetoone', 'openvpn-server', 'openvpn-client', 'openvpn-csc', 'option',
51
		'package', 'passthrumac', 'phase1', 'phase2', 'ppp', 'pppoe', 'priv', 'proxyarpnet', 'pool',
52
		'qinqentry', 'queue',
53
		'pages', 'pipe', 'radnsserver', 'roll', 'route', 'row', 'rrddatafile', 'rule',
54
		'schedule', 'service', 'servernat', 'servers',
55
		'serversdisabled', 'shellcmd', 'staticmap', 'subqueue',
56
		'timerange', 'tunnel', 'user', 'vip', 'virtual_server', 'vlan',
57
		'winsserver', 'wolentry', 'widget'
58
	);
59
	return array_flip($ret);
60
}
61

    
62
/* Package XML tags that should be treat as a list not as a traditional array */
63
function listtags_pkg() {
64
	$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');
65

    
66
	return array_flip($ret);
67
}
68

    
69
function add_elements(&$cfgarray, &$parser) {
70
	global $listtags;
71

    
72
	while ($parser->read()) {
73
		switch ($parser->nodeType) {
74
			case XMLReader::WHITESPACE:
75
			case XMLReader::SIGNIFICANT_WHITESPACE:
76
				break;
77
			case XMLReader::ELEMENT:
78
				if (isset($listtags[strtolower($parser->name)])) {
79
					$cfgref =& $cfgarray[$parser->name][count($cfgarray[$parser->name])];
80
					if (!$parser->isEmptyElement) {
81
						add_elements($cfgref, $parser);
82
					} else {
83
						$cfgref = array();
84
					}
85
				} else {
86
					if (isset($cfgarray[$parser->name]) && (!is_array($cfgarray[$parser->name]) || !isset($cfgarray[$parser->name][0]))) {
87
						$nodebkp = $cfgarray[$parser->name];
88
						$cfgarray[$parser->name] = array();
89
						$cfgarray[$parser->name][] = $nodebkp;
90
						$cfgref =& $cfgarray[$parser->name][0];
91
						unset($nodebkp);
92
					} else {
93
						$cfgref =& $cfgarray[$parser->name];
94
					}
95

    
96
					if ($parser->isEmptyElement) {
97
						if (is_array($cfgref)) {
98
							$cfgref[] = array();
99
						} else {
100
							$cfgref = "";
101
						}
102
					} else {
103
						if (is_array($cfgref)) {
104
							$cfgref =& $cfgarray[$parser->name][count($cfgarray[$parser->name])];
105
							add_elements($cfgref, $parser);
106
						} else {
107
							add_elements($cfgref, $parser);
108
						}
109
					}
110
				}
111

    
112
				$i = 0;
113
				while ($parser->moveToAttributeNo($i)) {
114
					$cfgref[$parser->name] = $parser->value;
115
					$i++;
116
				}
117
				break;
118
			case XMLReader::TEXT:
119
			case XMLReader::CDATA:
120
				$cfgarray = $parser->value;
121
				break;
122
			case XMLReader::END_ELEMENT:
123
				return;
124
				break;
125
			default:
126
				break;
127
		}
128
	}
129
}
130

    
131
function parse_xml_config($cffile, $rootobj, $isstring = "false") {
132
	global $listtags;
133

    
134
	$listtags = listtags();
135
	if (isset($GLOBALS['custom_listtags'])) {
136
		foreach ($GLOBALS['custom_listtags'] as $tag) {
137
			$listtags[$tag] = $tag;
138
		}
139
	}
140

    
141
	return parse_xml_config_raw($cffile, $rootobj);
142
}
143

    
144
function parse_xml_config_pkg($cffile, $rootobj, $isstring = "false") {
145
	global $listtags;
146

    
147
	$listtags = listtags_pkg();
148
	if (isset($GLOBALS['custom_listtags_pkg'])) {
149
		foreach ($GLOBALS['custom_listtags_pkg'] as $tag) {
150
			$listtags[$tag] = $tag;
151
		}
152
	}
153
	return parse_xml_config_raw($cffile, $rootobj, $isstring);
154
}
155

    
156
function parse_xml_config_raw($cffile, $rootobj, $isstring = "false") {
157
	global $listtags;
158

    
159
	$parsedcfg = array();
160

    
161
	$par = new XMLReader();
162
	if ($par->open($cffile, "UTF-8", LIBXML_NOERROR | LIBXML_NOWARNING)) {
163
		add_elements($parsedcfg, $par);
164
		$par->close();
165
	} else {
166
		log_error(sprintf(gettext("Error returned while trying to parse %s"), $cffile));
167
	}
168

    
169
	if ($rootobj) {
170
		if (!is_array($rootobj)) {
171
			$rootobj = array($rootobj);
172
		}
173
		foreach ($rootobj as $rootobj_name) {
174
			if ($parsedcfg[$rootobj_name]) {
175
				break;
176
			}
177
		}
178

    
179
		return $parsedcfg[$rootobj_name];
180
	} else {
181
		return $parsedcfg;
182
	}
183
}
184

    
185
function dump_xml_config_sub(& $writer, $arr) {
186
	global $listtags;
187

    
188
	foreach ($arr as $ent => $val) {
189
		if (is_array($val)) {
190
			/* is it just a list of multiple values? */
191
			if (isset($listtags[strtolower($ent)])) {
192
				foreach ($val as $cval) {
193
					if (is_array($cval)) {
194
						if (empty($cval)) {
195
							$writer->writeElement($ent);
196
						} else {
197
							$writer->startElement($ent);
198
							dump_xml_config_sub($writer, $cval);
199
							$writer->endElement();
200
						}
201
					} else {
202
						if ($cval === false) {
203
							continue;
204
						}
205
						if ((is_bool($val) && ($val == true)) || ($val === "")) {
206
							$writer->writeElement($ent);
207
						} else if (!is_bool($val)) {
208
							$writer->writeElement($ent, $cval);
209
						}
210
					}
211
				}
212
			} else if (empty($val)) {
213
				$writer->writeElement($ent);
214
			} else {
215
				/* it's an array */
216
				$writer->startElement($ent);
217
				dump_xml_config_sub($writer, $val);
218
				$writer->endElement();
219
			}
220
		} else {
221
			if ((is_bool($val) && ($val == true)) || ($val === "")) {
222
				$writer->writeElement($ent);
223
			} else if (!is_bool($val)) {
224
				$writer->writeElement($ent, $val);
225
			}
226
		}
227
	}
228
}
229

    
230
function dump_xml_config($arr, $rootobj) {
231
	global $listtags;
232

    
233
	$listtags = listtags();
234
	if (isset($GLOBALS['custom_listtags'])) {
235
		foreach ($GLOBALS['custom_listtags'] as $tag) {
236
			$listtags[$tag] = $tag;
237
		}
238
	}
239
	return dump_xml_config_raw($arr, $rootobj);
240
}
241

    
242
function dump_xml_config_pkg($arr, $rootobj) {
243
	global $listtags;
244

    
245
	$listtags = listtags_pkg();
246
	if (isset($GLOBALS['custom_listtags_pkg'])) {
247
		foreach ($GLOBALS['custom_listtags_pkg'] as $tag) {
248
			$listtags[$tag] = $tag;
249
		}
250
	}
251
	return dump_xml_config_raw($arr, $rootobj);
252
}
253

    
254
function dump_xml_config_raw($arr, $rootobj) {
255

    
256
	$writer = new XMLWriter();
257
	$writer->openMemory();
258
	$writer->setIndent(true);
259
	$writer->setIndentString("\t");
260
	$writer->startDocument("1.0", "UTF-8");
261
	$writer->startElement($rootobj);
262

    
263
	dump_xml_config_sub($writer, $arr);
264

    
265
	$writer->endElement();
266
	$writer->endDocument();
267
	$xmlconfig = $writer->outputMemory(true);
268

    
269
	return $xmlconfig;
270
}
271

    
272
?>
(62-62/65)