Project

General

Profile

Download (7.54 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * xmlreader.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2018 Rubicon Communications, LLC (Netgate)
7
 * All rights reserved.
8
 *
9
 * originally part of m0n0wall (http://m0n0.ch/wall)
10
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
11
 * All rights reserved.
12
 *
13
 * Licensed under the Apache License, Version 2.0 (the "License");
14
 * you may not use this file except in compliance with the License.
15
 * You may obtain a copy of the License at
16
 *
17
 * http://www.apache.org/licenses/LICENSE-2.0
18
 *
19
 * Unless required by applicable law or agreed to in writing, software
20
 * distributed under the License is distributed on an "AS IS" BASIS,
21
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22
 * See the License for the specific language governing permissions and
23
 * limitations under the License.
24
 */
25

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

    
57
/* Package XML tags that should be treat as a list not as a traditional array */
58
function listtags_pkg() {
59
	$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');
60

    
61
	return array_flip($ret);
62
}
63

    
64
function add_elements(&$cfgarray, &$parser) {
65
	global $listtags;
66

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

    
91
					if ($parser->isEmptyElement) {
92
						if (is_array($cfgref)) {
93
							$cfgref[] = array();
94
						} else {
95
							$cfgref = "";
96
						}
97
					} else {
98
						if (is_array($cfgref)) {
99
							$cfgref =& $cfgarray[$parser->name][count($cfgarray[$parser->name])];
100
							add_elements($cfgref, $parser);
101
						} else {
102
							add_elements($cfgref, $parser);
103
						}
104
					}
105
				}
106

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

    
126
function parse_xml_config($cffile, $rootobj, $isstring = "false") {
127
	global $listtags;
128

    
129
	$listtags = listtags();
130
	if (isset($GLOBALS['custom_listtags'])) {
131
		foreach ($GLOBALS['custom_listtags'] as $tag) {
132
			$listtags[$tag] = $tag;
133
		}
134
	}
135

    
136
	return parse_xml_config_raw($cffile, $rootobj);
137
}
138

    
139
function parse_xml_config_pkg($cffile, $rootobj, $isstring = "false") {
140
	global $listtags;
141

    
142
	$listtags = listtags_pkg();
143
	if (isset($GLOBALS['custom_listtags_pkg'])) {
144
		foreach ($GLOBALS['custom_listtags_pkg'] as $tag) {
145
			$listtags[$tag] = $tag;
146
		}
147
	}
148
	return parse_xml_config_raw($cffile, $rootobj, $isstring);
149
}
150

    
151
function parse_xml_config_raw($cffile, $rootobj, $isstring = "false") {
152
	global $listtags;
153

    
154
	$parsedcfg = array();
155

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

    
164
	if ($rootobj) {
165
		if (!is_array($rootobj)) {
166
			$rootobj = array($rootobj);
167
		}
168
		foreach ($rootobj as $rootobj_name) {
169
			if ($parsedcfg[$rootobj_name]) {
170
				break;
171
			}
172
		}
173

    
174
		return $parsedcfg[$rootobj_name];
175
	} else {
176
		return $parsedcfg;
177
	}
178
}
179

    
180
function dump_xml_config_sub(& $writer, $arr) {
181
	global $listtags;
182

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

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

    
232
	$listtags = listtags();
233
	if (isset($GLOBALS['custom_listtags'])) {
234
		foreach ($GLOBALS['custom_listtags'] as $tag) {
235
			$listtags[$tag] = $tag;
236
		}
237
	}
238

    
239

    
240
	return dump_xml_config_raw($arr, $rootobj);
241
}
242

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

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

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

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

    
264
	dump_xml_config_sub($writer, $arr);
265

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

    
270
	return $xmlconfig;
271
}
272

    
273
?>
(57-57/58)