Project

General

Profile

Download (7.94 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
/*
33
	pfSense_MODULE:	utils
34
*/
35

    
36
/* The following items will be treated as arrays in config.xml */
37
function listtags() {
38
	/*
39
	 * Please keep this list alpha sorted and no longer than 80 characters
40
	 * I know it's a pain, but it's a pain to find stuff too if it's not
41
	 */
42
	$ret = array(
43
		'acls', 'alias', 'aliasurl', 'allowedip', 'allowedhostname', 'authserver',
44
		'bridged', 'build_port_path',
45
		'ca', 'cacert', 'cert', 'crl', 'clone', 'config', 'container', 'columnitem',
46
		'depends_on_package', 'disk', 'dnsserver', 'dnsupdate', 'domainoverrides', 'dyndns',
47
		'earlyshellcmd', 'element', 'encryption-algorithm-option',
48
		'field', 'fieldname',
49
		'gateway_item', 'gateway_group', 'gif', 'gre', 'group',
50
		'hash-algorithm-option', 'hosts', 'member', 'ifgroupentry', 'igmpentry', 'interface_array', 'item', 'key',
51
		'lagg', 'lbaction', 'lbpool', 'l7rules', 'lbprotocol',
52
		'member', 'menu', 'tab', 'mobilekey', 'monitor_type', 'mount',
53
		'npt', 'ntpserver',
54
		'onetoone', 'openvpn-server', 'openvpn-client', 'openvpn-csc', 'option',
55
		'package', 'passthrumac', 'phase1', 'phase2', 'ppp', 'pppoe', 'priv', 'proxyarpnet', 'pool',
56
		'qinqentry', 'queue',
57
		'pages', 'pipe', 'radnsserver', 'roll', 'route', 'row', 'rrddatafile', 'rule',
58
		'schedule', 'service', 'servernat', 'servers',
59
		'serversdisabled', 'shellcmd', 'staticmap', 'subqueue',
60
		'timerange', 'tunnel', 'user', 'vip', 'virtual_server', 'vlan',
61
		'winsserver', 'wolentry', 'widget'
62
	);
63
	return array_flip($ret);
64
}
65

    
66
/* Package XML tags that should be treat as a list not as a traditional array */
67
function listtags_pkg() {
68
	$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');
69

    
70
	return array_flip($ret);
71
}
72

    
73
function add_elements(&$cfgarray, &$parser) {
74
	global $listtags;
75

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

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

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

    
135
function parse_xml_config($cffile, $rootobj, $isstring = "false") {
136
	global $listtags;
137

    
138
	$listtags = listtags();
139
	if (isset($GLOBALS['custom_listtags'])) {
140
		foreach ($GLOBALS['custom_listtags'] as $tag) {
141
			$listtags[$tag] = $tag;
142
		}
143
	}
144

    
145
	return parse_xml_config_raw($cffile, $rootobj);
146
}
147

    
148
function parse_xml_config_pkg($cffile, $rootobj, $isstring = "false") {
149
	global $listtags;
150

    
151
	$listtags = listtags_pkg();
152
	if (isset($GLOBALS['custom_listtags_pkg'])) {
153
		foreach ($GLOBALS['custom_listtags_pkg'] as $tag) {
154
			$listtags[$tag] = $tag;
155
		}
156
	}
157
	return parse_xml_config_raw($cffile, $rootobj, $isstring);
158
}
159

    
160
function parse_xml_config_raw($cffile, $rootobj, $isstring = "false") {
161
	global $listtags;
162

    
163
	$parsedcfg = array();
164

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

    
173
	if ($rootobj) {
174
		if (!is_array($rootobj)) {
175
			$rootobj = array($rootobj);
176
		}
177
		foreach ($rootobj as $rootobj_name) {
178
			if ($parsedcfg[$rootobj_name]) {
179
				break;
180
			}
181
		}
182

    
183
		return $parsedcfg[$rootobj_name];
184
	} else {
185
		return $parsedcfg;
186
	}
187
}
188

    
189
function dump_xml_config_sub(& $writer, $arr) {
190
	global $listtags;
191

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

    
234
function dump_xml_config($arr, $rootobj) {
235
	global $listtags;
236

    
237
	$listtags = listtags();
238
	if (isset($GLOBALS['custom_listtags'])) {
239
		foreach ($GLOBALS['custom_listtags'] as $tag) {
240
			$listtags[$tag] = $tag;
241
		}
242
	}
243
	return dump_xml_config_raw($arr, $rootobj);
244
}
245

    
246
function dump_xml_config_pkg($arr, $rootobj) {
247
	global $listtags;
248

    
249
	$listtags = listtags_pkg();
250
	if (isset($GLOBALS['custom_listtags_pkg'])) {
251
		foreach ($GLOBALS['custom_listtags_pkg'] as $tag) {
252
			$listtags[$tag] = $tag;
253
		}
254
	}
255
	return dump_xml_config_raw($arr, $rootobj);
256
}
257

    
258
function dump_xml_config_raw($arr, $rootobj) {
259

    
260
	$writer = new XMLWriter();
261
	$writer->openMemory();
262
	$writer->setIndent(true);
263
	$writer->setIndentString("\t");
264
	$writer->startDocument("1.0", "UTF-8");
265
	$writer->startElement($rootobj);
266

    
267
	dump_xml_config_sub($writer, $arr);
268

    
269
	$writer->endElement();
270
	$writer->endDocument();
271
	$xmlconfig = $writer->outputMemory(true);
272

    
273
	return $xmlconfig;
274
}
275

    
276
?>
(64-64/67)