1 // Copyright (c) 1999-2018 David Muse
2 // See the file COPYING for more information
3 
4 #include <config.h>
5 #include <sqlrelay/sqlrutil.h>
6 #include <rudiments/xmldom.h>
7 #include <rudiments/stringbuffer.h>
8 #include <rudiments/environment.h>
9 #include <rudiments/directory.h>
10 #include <rudiments/sys.h>
11 #include <rudiments/filedescriptor.h>
12 #include <rudiments/file.h>
13 #include <rudiments/url.h>
14 #include <rudiments/filesystem.h>
15 #include <rudiments/character.h>
16 #include <rudiments/stdio.h>
17 #include <rudiments/process.h>
18 //#define DEBUG_MESSAGES
19 #include <rudiments/debugprint.h>
20 
21 #include <defines.h>
22 #include <defaults.h>
23 
24 class SQLRUTIL_DLLSPEC sqlrconfig_xmldom : public sqlrconfig, public xmldom {
25 	public:
26 			sqlrconfig_xmldom();
27 			~sqlrconfig_xmldom();
28 
29 		void	getEnabledIds(const char *urlname,
30 					linkedlist< char * > *idlist);
31 		bool	load(const char *urlname, const char *id);
32 		bool	accessible();
33 
34 		const char	*getDefaultAddresses();
35 		uint16_t	getDefaultPort();
36 		const char	*getDefaultSocket();
37 
38 		bool		getDefaultKrb();
39 		const char	*getDefaultKrbService();
40 		const char	*getDefaultKrbKeytab();
41 		const char	*getDefaultKrbMech();
42 		const char	*getDefaultKrbFlags();
43 
44 		bool		getDefaultTls();
45 		const char	*getDefaultTlsCiphers();
46 
47 		const char	*getDefaultUser();
48 		const char	*getDefaultPassword();
49 
50 		bool		getListenOnInet();
51 		bool		getListenOnUnix();
52 		const char	*getDbase();
53 		uint32_t	getConnections();
54 		uint32_t	getMaxConnections();
55 		uint32_t	getMaxQueueLength();
56 		uint32_t	getGrowBy();
57 		int32_t		getTtl();
58 		int32_t		getSoftTtl();
59 		uint16_t	getMaxSessionCount();
60 		bool		getDynamicScaling();
61 		const char	*getEndOfSession();
62 		bool		getEndOfSessionCommit();
63 		uint32_t	getSessionTimeout();
64 		const char	*getRunAsUser();
65 		const char	*getRunAsGroup();
66 		uint16_t	getCursors();
67 		uint16_t	getMaxCursors();
68 		uint16_t	getCursorsGrowBy();
69 		const char	*getAuthTier();
70 		bool		getAuthOnConnection();
71 		bool		getAuthOnDatabase();
72 		const char	*getSessionHandler();
73 		const char	*getHandoff();
74 		const char	*getAllowedIps();
75 		const char	*getDeniedIps();
76 		const char	*getDebug();
77 		bool		getDebugSql();
78 		bool		getDebugBulkLoad();
79 		bool		getDebugParser();
80 		bool		getDebugDirectives();
81 		bool		getDebugTranslations();
82 		bool		getDebugFilters();
83 		bool		getDebugTriggers();
84 		bool		getDebugBindTranslations();
85 		bool		getDebugBindVariableTranslations();
86 		bool		getDebugResultSetTranslations();
87 		bool		getDebugResultSetRowTranslations();
88 		bool		getDebugResultSetRowBlockTranslations();
89 		bool		getDebugResultSetHeaderTranslations();
90 		bool		getDebugProtocols();
91 		bool		getDebugAuths();
92 		bool		getDebugPasswordEncryptions();
93 		bool		getDebugLoggers();
94 		bool		getDebugNotifications();
95 		bool		getDebugSchedules();
96 		bool		getDebugRouters();
97 		bool		getDebugQueries();
98 		bool		getDebugModuleDatas();
99 		uint64_t	getMaxClientInfoLength();
100 		uint32_t	getMaxQuerySize();
101 		uint16_t	getMaxBindCount();
102 		uint16_t	getMaxBindNameLength();
103 		uint32_t	getMaxStringBindValueLength();
104 		uint32_t	getMaxLobBindValueLength();
105 		uint32_t	getMaxErrorLength();
106 		int32_t		getIdleClientTimeout();
107 		int64_t		getMaxListeners();
108 		uint32_t	getListenerTimeout();
109 		bool		getReLoginAtStart();
110 		bool		getFakeInputBindVariables();
111 		const char	*getFakeInputBindVariablesDateFormat();
112 		bool		getFakeInputBindVariablesUnicodeStrings();
113 		bool		getBindVariableDelimiterQuestionMarkSupported();
114 		bool		getBindVariableDelimiterColonSupported();
115 		bool		getBindVariableDelimiterAtSignSupported();
116 		bool		getBindVariableDelimiterDollarSignSupported();
117 		bool		getTranslateBindVariables();
118 		const char	*getIsolationLevel();
119 		bool		getIgnoreSelectDatabase();
120 		bool		getWaitForDownDatabase();
121 
122 		linkedlist< char *>	*getSessionStartQueries();
123 		linkedlist< char *>	*getSessionEndQueries();
124 
125 		domnode	*getListeners();
126 		domnode	*getParser();
127 		domnode	*getDirectives();
128 		domnode	*getTranslations();
129 		domnode	*getFilters();
130 		domnode	*getBindVariableTranslations();
131 		domnode	*getResultSetTranslations();
132 		domnode	*getResultSetRowTranslations();
133 		domnode	*getResultSetRowBlockTranslations();
134 		domnode	*getResultSetHeaderTranslations();
135 		domnode	*getTriggers();
136 		domnode	*getLoggers();
137 		domnode	*getNotifications();
138 		domnode	*getSchedules();
139 		domnode	*getRouters();
140 		domnode	*getQueries();
141 		domnode	*getPasswordEncryptions();
142 		domnode	*getAuths();
143 		domnode	*getModuleDatas();
144 
145 		linkedlist< connectstringcontainer * >	*getConnectStringList();
146 		connectstringcontainer	*getConnectString(
147 						const char *connectionid);
148 		uint32_t		getConnectionCount();
149 		uint32_t		getMetricTotal();
150 
151 		linkedlist< routecontainer * >	*getRouteList();
152 	private:
153 		bool			getenabledids;
154 		char			*currentid;
155 		bool			enabled;
156 		linkedlist< char * >	*idlist;
157 
158 		const char	*id;
159 		bool		foundspecifiedinstance;
160 		bool		done;
161 
162 		void	init();
163 		void	clear();
164 
165 		void	parseUrl(const char *urlname);
166 		void	normalizeTree();
167 		void	getTreeValues();
168 		routecontainer	*routeAlreadyExists(routecontainer *cur);
169 		void		moveRegexList(routecontainer *cur,
170 						routecontainer *existing);
171 		uint32_t	atouint32_t(const char *value,
172 						const char *defaultvalue,
173 						uint32_t minvalue);
174 		int32_t		atoint32_t(const char *value,
175 						const char *defaultvalue,
176 						int32_t minvalue);
177 		void	parseDir(const char *dir);
178 		void	parseLinkFile(const char *urlname);
179 
180 		bool	tagStart(const char *ns, const char *name);
181 		bool	tagEnd(const char *ns, const char *name);
182 		bool	attributeName(const char *name);
183 		bool	attributeValue(const char *value);
184 		bool	text(const char *value);
185 		bool	comment(const char *value);
186 
187 		bool	hasDebug(const char *value, const char *debug);
188 
189 		bool		listenoninet;
190 		bool		listenonunix;
191 		const char	*dbase;
192 		uint32_t	connections;
193 		uint32_t	maxconnections;
194 		uint32_t	maxqueuelength;
195 		uint32_t	growby;
196 		int32_t		ttl;
197 		int32_t		softttl;
198 		uint16_t	maxsessioncount;
199 		const char	*endofsession;
200 		bool		endofsessioncommit;
201 		uint32_t	sessiontimeout;
202 		const char	*runasuser;
203 		const char	*runasgroup;
204 		uint16_t	cursors;
205 		uint16_t	maxcursors;
206 		uint16_t	cursorsgrowby;
207 		const char	*authtier;
208 		const char	*sessionhandler;
209 		const char	*handoff;
210 		bool		authonconnection;
211 		bool		authondatabase;
212 		const char	*allowedips;
213 		const char	*deniedips;
214 		const char	*debug;
215 		bool		debugsql;
216 		bool		debugbulkload;
217 		bool		debugparser;
218 		bool		debugdirectives;
219 		bool		debugtranslations;
220 		bool		debugfilters;
221 		bool		debugtriggers;
222 		bool		debugbindtranslations;
223 		bool		debugbindvariabletranslations;
224 		bool		debugresultsettranslations;
225 		bool		debugresultsetrowtranslations;
226 		bool		debugresultsetrowblocktranslations;
227 		bool		debugresultsetheadertranslations;
228 		bool		debugprotocols;
229 		bool		debugauths;
230 		bool		debugpwdencs;
231 		bool		debugloggers;
232 		bool		debugnotifications;
233 		bool		debugschedules;
234 		bool		debugrouters;
235 		bool		debugqueries;
236 		bool		debugmoduledatas;
237 		uint64_t	maxclientinfolength;
238 		uint32_t	maxquerysize;
239 		uint16_t	maxbindcount;
240 		uint16_t	maxbindnamelength;
241 		uint32_t	maxstringbindvaluelength;
242 		uint32_t	maxlobbindvaluelength;
243 		uint32_t	maxerrorlength;
244 		int32_t		idleclienttimeout;
245 		int64_t		maxlisteners;
246 		uint32_t	listenertimeout;
247 		bool		reloginatstart;
248 		bool		fakeinputbindvariables;
249 		const char	*fakeinputbindvariablesdateformat;
250 		bool		fakeinputbindvariablesunicodestrings;
251 		const char	*bindvariabledelimiters;
252 		bool		questionmarksupported;
253 		bool		colonsupported;
254 		bool		atsignsupported;
255 		bool		dollarsignsupported;
256 		bool		translatebindvariables;
257 		const char	*isolationlevel;
258 		bool		ignoreselectdb;
259 		bool		waitfordowndb;
260 
261 		linkedlist< char *>	sessionstartqueries;
262 		linkedlist< char *>	sessionendqueries;
263 
264 		domnode	*listenersxml;
265 		domnode	*parserxml;
266 		domnode	*directivesxml;
267 		domnode	*translationsxml;
268 		domnode	*filtersxml;
269 		domnode	*bindvariabletranslationsxml;
270 		domnode	*resultsettranslationsxml;
271 		domnode	*resultsetrowtranslationsxml;
272 		domnode	*resultsetrowblocktranslationsxml;
273 		domnode	*resultsetheadertranslationsxml;
274 		domnode	*triggersxml;
275 		domnode	*loggersxml;
276 		domnode	*notificationsxml;
277 		domnode	*schedulesxml;
278 		domnode	*routersxml;
279 		domnode	*queriesxml;
280 		domnode	*pwdencsxml;
281 		domnode	*authsxml;
282 		domnode	*moduledatasxml;
283 
284 		uint32_t	metrictotal;
285 
286 		linkedlist< routecontainer *>		routelist;
287 		linkedlist< connectstringcontainer * >	connectstringlist;
288 
289 		domnode	*defaultlistener;
290 		const char	*defaultaddresses;
291 		uint16_t	defaultport;
292 		const char	*defaultsocket;
293 		bool		defaultkrb;
294 		const char	*defaultkrbkeytab;
295 		const char	*defaultkrbservice;
296 		const char	*defaultkrbmech;
297 		const char	*defaultkrbflags;
298 		bool		defaulttls;
299 		const char	*defaulttlsciphers;
300 		const char	*defaultuser;
301 		const char	*defaultpassword;
302 
303 		bool		ininstancetag;
304 		bool		inidattribute;
305 		bool		inenabledattribute;
306 		bool		getattributes;
307 };
308 
sqlrconfig_xmldom()309 sqlrconfig_xmldom::sqlrconfig_xmldom() : sqlrconfig(), xmldom(false) {
310 	debugFunction();
311 
312 	init();
313 }
314 
~sqlrconfig_xmldom()315 sqlrconfig_xmldom::~sqlrconfig_xmldom() {
316 	debugFunction();
317 
318 	clear();
319 }
320 
init()321 void sqlrconfig_xmldom::init() {
322 	debugFunction();
323 
324 	getenabledids=false;
325 	currentid=NULL;
326 	enabled=false;
327 	idlist=NULL;
328 	id=NULL;
329 
330 	foundspecifiedinstance=false;
331 	ininstancetag=false;
332 	inidattribute=false;
333 	inenabledattribute=false;
334 	getattributes=true;
335 	done=false;
336 
337 	listenoninet=false;
338 	listenonunix=false;
339 	dbase=DEFAULT_DBASE;
340 	connections=charstring::toInteger(DEFAULT_CONNECTIONS);
341 	maxconnections=0;
342 	maxqueuelength=charstring::toInteger(DEFAULT_MAXQUEUELENGTH);
343 	growby=charstring::toInteger(DEFAULT_GROWBY);
344 	ttl=charstring::toInteger(DEFAULT_TTL);
345 	softttl=charstring::toInteger(DEFAULT_SOFTTTL);
346 	maxsessioncount=charstring::toInteger(DEFAULT_MAXSESSIONCOUNT);
347 	endofsession=DEFAULT_ENDOFSESSION;
348 	endofsessioncommit=!charstring::compare(endofsession,"commit");
349 	sessiontimeout=charstring::toUnsignedInteger(DEFAULT_SESSIONTIMEOUT);
350 	runasuser=DEFAULT_RUNASUSER;
351 	runasgroup=DEFAULT_RUNASGROUP;
352 	cursors=charstring::toInteger(DEFAULT_CURSORS);
353 	maxcursors=charstring::toInteger(DEFAULT_MAXCURSORS);
354 	cursorsgrowby=charstring::toInteger(DEFAULT_CURSORS_GROWBY);
355 	authtier=DEFAULT_AUTHTIER;
356 	authonconnection=true;
357 	authondatabase=false;
358 	sessionhandler=DEFAULT_SESSION_HANDLER;
359 	handoff=DEFAULT_HANDOFF;
360 	allowedips=DEFAULT_DENIEDIPS;
361 	deniedips=DEFAULT_DENIEDIPS;
362 	debug=DEFAULT_DEBUG;
363 	debugsql=hasDebug(debug,"sql");
364 	debugbulkload=hasDebug(debug,"bulkload");
365 	debugparser=hasDebug(debug,"parser");
366 	debugdirectives=hasDebug(debug,"directives");
367 	debugtranslations=hasDebug(debug,"translations");
368 	debugfilters=hasDebug(debug,"filters");
369 	debugtriggers=hasDebug(debug,"triggers");
370 	debugbindtranslations=
371 		hasDebug(debug,"bindtranslations");
372 	debugbindvariabletranslations=
373 		hasDebug(debug,"bindvariabletranslations");
374 	debugresultsettranslations=
375 		hasDebug(debug,"resultsettranslations");
376 	debugresultsetrowtranslations=
377 		hasDebug(debug,"resultsetrowtranslations");
378 	debugresultsetrowblocktranslations=
379 		hasDebug(debug,"resultsetrowblocktranslations");
380 	debugresultsetheadertranslations=
381 		hasDebug(debug,"resultsetheadertranslations");
382 	debugprotocols=hasDebug(debug,"protocols");
383 	debugauths=hasDebug(debug,"auths");
384 	debugpwdencs=hasDebug(debug,"passwordencrypytions");
385 	debugloggers=hasDebug(debug,"loggers");
386 	debugnotifications=hasDebug(debug,"notifications");
387 	debugschedules=hasDebug(debug,"schedules");
388 	debugrouters=hasDebug(debug,"routers");
389 	debugqueries=hasDebug(debug,"queries");
390 	debugmoduledatas=hasDebug(debug,"moduledatas");
391 	maxclientinfolength=charstring::toInteger(DEFAULT_MAXCLIENTINFOLENGTH);
392 	maxquerysize=charstring::toInteger(DEFAULT_MAXQUERYSIZE);
393 	maxbindcount=charstring::toInteger(DEFAULT_MAXBINDCOUNT);
394 	maxbindnamelength=charstring::toInteger(DEFAULT_MAXBINDNAMELENGTH);
395 	maxstringbindvaluelength=charstring::toInteger(
396 					DEFAULT_MAXSTRINGBINDVALUELENGTH);
397 	maxlobbindvaluelength=charstring::toInteger(
398 					DEFAULT_MAXLOBBINDVALUELENGTH);
399 	maxerrorlength=charstring::toInteger(DEFAULT_MAXERRORLENGTH);
400 	idleclienttimeout=charstring::toInteger(DEFAULT_IDLECLIENTTIMEOUT);
401 	metrictotal=0;
402 	maxlisteners=charstring::toInteger(DEFAULT_MAXLISTENERS);
403 	listenertimeout=charstring::toUnsignedInteger(DEFAULT_LISTENERTIMEOUT);
404 	reloginatstart=charstring::isYes(DEFAULT_RELOGINATSTART);
405 	fakeinputbindvariables=charstring::isYes(
406 					DEFAULT_FAKEINPUTBINDVARIABLES);
407 	fakeinputbindvariablesdateformat=NULL;
408 	fakeinputbindvariablesunicodestrings=charstring::isYes(
409 				DEFAULT_FAKEINPUTBINDVARIABLESUNICODESTRINGS);
410 	bindvariabledelimiters=DEFAULT_BINDVARIABLEDELIMITERS;
411 	questionmarksupported=charstring::contains(bindvariabledelimiters,'?');
412 	colonsupported=charstring::contains(bindvariabledelimiters,':');
413 	atsignsupported=charstring::contains(bindvariabledelimiters,'@');
414 	dollarsignsupported=charstring::contains(bindvariabledelimiters,'$');
415 	translatebindvariables=charstring::isYes(
416 					DEFAULT_TRANSLATEBINDVARIABLES);
417 	isolationlevel=NULL;
418 	ignoreselectdb=false;
419 	waitfordowndb=true;
420 
421 	defaultlistener=NULL;
422 	defaultaddresses=NULL;
423 	defaultport=0;
424 	defaultsocket=NULL;
425 	defaultkrb=false;
426 	defaultkrbkeytab=NULL;
427 	defaultkrbservice=NULL;
428 	defaultkrbmech=NULL;
429 	defaultkrbflags=NULL;
430 	defaulttls=false;
431 	defaulttlsciphers=NULL;
432 	defaultuser=NULL;
433 	defaultpassword=NULL;
434 }
435 
clear()436 void sqlrconfig_xmldom::clear() {
437 	debugFunction();
438 
439 	connectstringlist.clearAndDelete();
440 	routelist.clearAndDelete();
441 	sessionstartqueries.clearAndArrayDelete();
442 	sessionendqueries.clearAndArrayDelete();
443 }
444 
getDefaultAddresses()445 const char *sqlrconfig_xmldom::getDefaultAddresses() {
446 	return defaultaddresses;
447 }
448 
getDefaultPort()449 uint16_t sqlrconfig_xmldom::getDefaultPort() {
450 	return defaultport;
451 }
452 
getDefaultSocket()453 const char *sqlrconfig_xmldom::getDefaultSocket() {
454 	return defaultsocket;
455 }
456 
getDefaultKrb()457 bool sqlrconfig_xmldom::getDefaultKrb() {
458 	return defaultkrb;
459 }
460 
getDefaultKrbService()461 const char *sqlrconfig_xmldom::getDefaultKrbService() {
462 	return defaultkrbservice;
463 }
464 
getDefaultKrbKeytab()465 const char *sqlrconfig_xmldom::getDefaultKrbKeytab() {
466 	return defaultkrbkeytab;
467 }
468 
getDefaultKrbMech()469 const char *sqlrconfig_xmldom::getDefaultKrbMech() {
470 	return defaultkrbmech;
471 }
472 
getDefaultKrbFlags()473 const char *sqlrconfig_xmldom::getDefaultKrbFlags() {
474 	return defaultkrbflags;
475 }
476 
getDefaultTls()477 bool sqlrconfig_xmldom::getDefaultTls() {
478 	return defaulttls;
479 }
480 
getDefaultTlsCiphers()481 const char *sqlrconfig_xmldom::getDefaultTlsCiphers() {
482 	return defaulttlsciphers;
483 }
484 
getDefaultUser()485 const char *sqlrconfig_xmldom::getDefaultUser() {
486 	return defaultuser;
487 }
488 
getDefaultPassword()489 const char *sqlrconfig_xmldom::getDefaultPassword() {
490 	return defaultpassword;
491 }
492 
getListenOnInet()493 bool sqlrconfig_xmldom::getListenOnInet() {
494 	return listenoninet;
495 }
496 
getListenOnUnix()497 bool sqlrconfig_xmldom::getListenOnUnix() {
498 	return listenonunix;
499 }
500 
getDbase()501 const char *sqlrconfig_xmldom::getDbase() {
502 	return dbase;
503 }
504 
getConnections()505 uint32_t sqlrconfig_xmldom::getConnections() {
506 	return connections;
507 }
508 
getMaxConnections()509 uint32_t sqlrconfig_xmldom::getMaxConnections() {
510 	return maxconnections;
511 }
512 
getMaxQueueLength()513 uint32_t sqlrconfig_xmldom::getMaxQueueLength() {
514 	return maxqueuelength;
515 }
516 
getGrowBy()517 uint32_t sqlrconfig_xmldom::getGrowBy() {
518 	return growby;
519 }
520 
getTtl()521 int32_t sqlrconfig_xmldom::getTtl() {
522 	return ttl;
523 }
524 
getSoftTtl()525 int32_t sqlrconfig_xmldom::getSoftTtl() {
526 	return softttl;
527 }
528 
getMaxSessionCount()529 uint16_t sqlrconfig_xmldom::getMaxSessionCount() {
530 	return maxsessioncount;
531 }
532 
getDynamicScaling()533 bool sqlrconfig_xmldom::getDynamicScaling() {
534 	return (maxconnections>connections && growby>0 && ttl>-1 &&
535 		(maxlisteners==-1 || maxqueuelength<=maxlisteners));
536 }
537 
getEndOfSession()538 const char *sqlrconfig_xmldom::getEndOfSession() {
539 	return endofsession;
540 }
541 
getEndOfSessionCommit()542 bool sqlrconfig_xmldom::getEndOfSessionCommit() {
543 	return endofsessioncommit;
544 }
545 
getSessionTimeout()546 uint32_t sqlrconfig_xmldom::getSessionTimeout() {
547 	return sessiontimeout;
548 }
549 
getRunAsUser()550 const char *sqlrconfig_xmldom::getRunAsUser() {
551 	return runasuser;
552 }
553 
getRunAsGroup()554 const char *sqlrconfig_xmldom::getRunAsGroup() {
555 	return runasgroup;
556 }
557 
getCursors()558 uint16_t sqlrconfig_xmldom::getCursors() {
559 	return cursors;
560 }
561 
getMaxCursors()562 uint16_t sqlrconfig_xmldom::getMaxCursors() {
563 	return maxcursors;
564 }
565 
getCursorsGrowBy()566 uint16_t sqlrconfig_xmldom::getCursorsGrowBy() {
567 	return cursorsgrowby;
568 }
569 
getAuthTier()570 const char *sqlrconfig_xmldom::getAuthTier() {
571 	return authtier;
572 }
573 
getSessionHandler()574 const char *sqlrconfig_xmldom::getSessionHandler() {
575 	return sessionhandler;
576 }
577 
getHandoff()578 const char *sqlrconfig_xmldom::getHandoff() {
579 	return handoff;
580 }
581 
getAuthOnConnection()582 bool sqlrconfig_xmldom::getAuthOnConnection() {
583 	return authonconnection;
584 }
585 
getAuthOnDatabase()586 bool sqlrconfig_xmldom::getAuthOnDatabase() {
587 	return authondatabase;
588 }
589 
getAllowedIps()590 const char *sqlrconfig_xmldom::getAllowedIps() {
591 	return allowedips;
592 }
593 
getDeniedIps()594 const char *sqlrconfig_xmldom::getDeniedIps() {
595 	return deniedips;
596 }
597 
getDebug()598 const char *sqlrconfig_xmldom::getDebug() {
599 	return debug;
600 }
601 
getDebugSql()602 bool sqlrconfig_xmldom::getDebugSql() {
603 	return debugsql;
604 }
605 
getDebugBulkLoad()606 bool sqlrconfig_xmldom::getDebugBulkLoad() {
607 	return debugbulkload;
608 }
609 
getDebugParser()610 bool sqlrconfig_xmldom::getDebugParser() {
611 	return debugparser;
612 }
613 
getDebugDirectives()614 bool sqlrconfig_xmldom::getDebugDirectives() {
615 	return debugdirectives;
616 }
617 
getDebugTranslations()618 bool sqlrconfig_xmldom::getDebugTranslations() {
619 	return debugtranslations;
620 }
621 
getDebugFilters()622 bool sqlrconfig_xmldom::getDebugFilters() {
623 	return debugfilters;
624 }
625 
getDebugTriggers()626 bool sqlrconfig_xmldom::getDebugTriggers() {
627 	return debugtriggers;
628 }
629 
getDebugBindTranslations()630 bool sqlrconfig_xmldom::getDebugBindTranslations() {
631 	return debugbindtranslations;
632 }
633 
getDebugBindVariableTranslations()634 bool sqlrconfig_xmldom::getDebugBindVariableTranslations() {
635 	return debugbindvariabletranslations;
636 }
637 
getDebugResultSetTranslations()638 bool sqlrconfig_xmldom::getDebugResultSetTranslations() {
639 	return debugresultsettranslations;
640 }
641 
getDebugResultSetRowTranslations()642 bool sqlrconfig_xmldom::getDebugResultSetRowTranslations() {
643 	return debugresultsetrowtranslations;
644 }
645 
getDebugResultSetRowBlockTranslations()646 bool sqlrconfig_xmldom::getDebugResultSetRowBlockTranslations() {
647 	return debugresultsetrowblocktranslations;
648 }
649 
getDebugResultSetHeaderTranslations()650 bool sqlrconfig_xmldom::getDebugResultSetHeaderTranslations() {
651 	return debugresultsetheadertranslations;
652 }
653 
getDebugProtocols()654 bool sqlrconfig_xmldom::getDebugProtocols() {
655 	return debugprotocols;
656 }
657 
getDebugAuths()658 bool sqlrconfig_xmldom::getDebugAuths() {
659 	return debugauths;
660 }
661 
getDebugPasswordEncryptions()662 bool sqlrconfig_xmldom::getDebugPasswordEncryptions() {
663 	return debugpwdencs;
664 }
665 
getDebugLoggers()666 bool sqlrconfig_xmldom::getDebugLoggers() {
667 	return debugloggers;
668 }
669 
getDebugNotifications()670 bool sqlrconfig_xmldom::getDebugNotifications() {
671 	return debugnotifications;
672 }
673 
getDebugSchedules()674 bool sqlrconfig_xmldom::getDebugSchedules() {
675 	return debugschedules;
676 }
677 
getDebugRouters()678 bool sqlrconfig_xmldom::getDebugRouters() {
679 	return debugrouters;
680 }
681 
getDebugQueries()682 bool sqlrconfig_xmldom::getDebugQueries() {
683 	return debugqueries;
684 }
685 
getDebugModuleDatas()686 bool sqlrconfig_xmldom::getDebugModuleDatas() {
687 	return debugmoduledatas;
688 }
689 
getMaxClientInfoLength()690 uint64_t sqlrconfig_xmldom::getMaxClientInfoLength() {
691 	return maxclientinfolength;
692 }
693 
getMaxQuerySize()694 uint32_t sqlrconfig_xmldom::getMaxQuerySize() {
695 	return maxquerysize;
696 }
697 
getMaxBindCount()698 uint16_t sqlrconfig_xmldom::getMaxBindCount() {
699 	return maxbindcount;
700 }
701 
getMaxBindNameLength()702 uint16_t sqlrconfig_xmldom::getMaxBindNameLength() {
703 	return maxbindnamelength;
704 }
705 
getMaxStringBindValueLength()706 uint32_t sqlrconfig_xmldom::getMaxStringBindValueLength() {
707 	return maxstringbindvaluelength;
708 }
709 
getMaxLobBindValueLength()710 uint32_t sqlrconfig_xmldom::getMaxLobBindValueLength() {
711 	return maxlobbindvaluelength;
712 }
713 
getMaxErrorLength()714 uint32_t sqlrconfig_xmldom::getMaxErrorLength() {
715 	return maxerrorlength;
716 }
717 
getIdleClientTimeout()718 int32_t sqlrconfig_xmldom::getIdleClientTimeout() {
719 	return idleclienttimeout;
720 }
721 
getMaxListeners()722 int64_t sqlrconfig_xmldom::getMaxListeners() {
723 	return maxlisteners;
724 }
725 
getListenerTimeout()726 uint32_t sqlrconfig_xmldom::getListenerTimeout() {
727 	return listenertimeout;
728 }
729 
getReLoginAtStart()730 bool sqlrconfig_xmldom::getReLoginAtStart() {
731 	return reloginatstart;
732 }
733 
getFakeInputBindVariables()734 bool sqlrconfig_xmldom::getFakeInputBindVariables() {
735 	return fakeinputbindvariables;
736 }
737 
getFakeInputBindVariablesDateFormat()738 const char *sqlrconfig_xmldom::getFakeInputBindVariablesDateFormat() {
739 	return fakeinputbindvariablesdateformat;
740 }
741 
getFakeInputBindVariablesUnicodeStrings()742 bool sqlrconfig_xmldom::getFakeInputBindVariablesUnicodeStrings() {
743 	return fakeinputbindvariablesunicodestrings;
744 }
745 
getBindVariableDelimiterQuestionMarkSupported()746 bool sqlrconfig_xmldom::getBindVariableDelimiterQuestionMarkSupported() {
747 	return questionmarksupported;
748 }
749 
getBindVariableDelimiterColonSupported()750 bool sqlrconfig_xmldom::getBindVariableDelimiterColonSupported() {
751 	return colonsupported;
752 }
753 
getBindVariableDelimiterAtSignSupported()754 bool sqlrconfig_xmldom::getBindVariableDelimiterAtSignSupported() {
755 	return atsignsupported;
756 }
757 
getBindVariableDelimiterDollarSignSupported()758 bool sqlrconfig_xmldom::getBindVariableDelimiterDollarSignSupported() {
759 	return dollarsignsupported;
760 }
761 
getTranslateBindVariables()762 bool sqlrconfig_xmldom::getTranslateBindVariables() {
763 	return translatebindvariables;
764 }
765 
getIsolationLevel()766 const char *sqlrconfig_xmldom::getIsolationLevel() {
767 	return isolationlevel;
768 }
769 
getIgnoreSelectDatabase()770 bool sqlrconfig_xmldom::getIgnoreSelectDatabase() {
771 	return ignoreselectdb;
772 }
773 
getWaitForDownDatabase()774 bool sqlrconfig_xmldom::getWaitForDownDatabase() {
775 	return waitfordowndb;
776 }
777 
getSessionStartQueries()778 linkedlist< char * > *sqlrconfig_xmldom::getSessionStartQueries() {
779 	return &sessionstartqueries;
780 }
781 
getSessionEndQueries()782 linkedlist< char * > *sqlrconfig_xmldom::getSessionEndQueries() {
783 	return &sessionendqueries;
784 }
785 
getListeners()786 domnode *sqlrconfig_xmldom::getListeners() {
787 	return listenersxml;
788 }
789 
getParser()790 domnode *sqlrconfig_xmldom::getParser() {
791 	return parserxml;
792 }
793 
getDirectives()794 domnode *sqlrconfig_xmldom::getDirectives() {
795 	return directivesxml;
796 }
797 
getTranslations()798 domnode *sqlrconfig_xmldom::getTranslations() {
799 	return translationsxml;
800 }
801 
getFilters()802 domnode *sqlrconfig_xmldom::getFilters() {
803 	return filtersxml;
804 }
805 
getBindVariableTranslations()806 domnode *sqlrconfig_xmldom::getBindVariableTranslations() {
807 	return bindvariabletranslationsxml;
808 }
809 
getResultSetTranslations()810 domnode *sqlrconfig_xmldom::getResultSetTranslations() {
811 	return resultsettranslationsxml;
812 }
813 
getResultSetRowTranslations()814 domnode *sqlrconfig_xmldom::getResultSetRowTranslations() {
815 	return resultsetrowtranslationsxml;
816 }
817 
getResultSetRowBlockTranslations()818 domnode *sqlrconfig_xmldom::getResultSetRowBlockTranslations() {
819 	return resultsetrowblocktranslationsxml;
820 }
821 
getResultSetHeaderTranslations()822 domnode *sqlrconfig_xmldom::getResultSetHeaderTranslations() {
823 	return resultsetheadertranslationsxml;
824 }
825 
getTriggers()826 domnode *sqlrconfig_xmldom::getTriggers() {
827 	return triggersxml;
828 }
829 
getLoggers()830 domnode *sqlrconfig_xmldom::getLoggers() {
831 	return loggersxml;
832 }
833 
getNotifications()834 domnode *sqlrconfig_xmldom::getNotifications() {
835 	return notificationsxml;
836 }
837 
getSchedules()838 domnode *sqlrconfig_xmldom::getSchedules() {
839 	return schedulesxml;
840 }
841 
getRouters()842 domnode *sqlrconfig_xmldom::getRouters() {
843 	return routersxml;
844 }
845 
getQueries()846 domnode *sqlrconfig_xmldom::getQueries() {
847 	return queriesxml;
848 }
849 
getPasswordEncryptions()850 domnode *sqlrconfig_xmldom::getPasswordEncryptions() {
851 	return pwdencsxml;
852 }
853 
getAuths()854 domnode *sqlrconfig_xmldom::getAuths() {
855 	return authsxml;
856 }
857 
getModuleDatas()858 domnode *sqlrconfig_xmldom::getModuleDatas() {
859 	return moduledatasxml;
860 }
861 
862 linkedlist< connectstringcontainer * > *sqlrconfig_xmldom::
getConnectStringList()863 						getConnectStringList() {
864 	return &connectstringlist;
865 }
866 
getConnectString(const char * connectionid)867 connectstringcontainer *sqlrconfig_xmldom::getConnectString(
868 						const char *connectionid) {
869 	for (connectstringnode *csn=connectstringlist.getFirst();
870 						csn; csn=csn->getNext()) {
871 		if (!charstring::compare(connectionid,
872 					csn->getValue()->getConnectionId())) {
873 			return csn->getValue();
874 		}
875 	}
876 	return NULL;
877 }
878 
getConnectionCount()879 uint32_t sqlrconfig_xmldom::getConnectionCount() {
880 	return connectstringlist.getLength();
881 }
882 
getMetricTotal()883 uint32_t sqlrconfig_xmldom::getMetricTotal() {
884 	// This is tallied here instead of whenever the parser runs into a
885 	// metric attribute because people often forget to include metric
886 	// attributes.  In that case, though each connection has a metric,
887 	// metrictotal=0, causing no connections to start.
888 	if (!metrictotal) {
889 		for (connectstringnode *csn=connectstringlist.getFirst();
890 						csn; csn=csn->getNext()) {
891 			metrictotal=metrictotal+csn->getValue()->getMetric();
892 		}
893 	}
894 	return metrictotal;
895 }
896 
getRouteList()897 linkedlist< routecontainer * >	*sqlrconfig_xmldom::getRouteList() {
898 	return &routelist;
899 }
900 
tagStart(const char * ns,const char * name)901 bool sqlrconfig_xmldom::tagStart(const char *ns, const char *name) {
902 	debugFunction();
903 
904 	debugPrintf("<%s>\n",name);
905 
906 	// bail if we're already done
907 	if (done) {
908 		debugPrintf("  already done\n");
909 		return true;
910 	}
911 
912 	// is this an instance tag?
913 	ininstancetag=!charstring::compare(name,"instance");
914 
915 	if (ininstancetag) {
916 
917 		debugPrintf("  in instance tag\n");
918 
919 		// re-init enabled flag
920 		enabled=false;
921 
922 		// re-init get attributes flag
923 		getattributes=true;
924 
925 	} else {
926 
927 		debugPrintf("  not in instance tag\n");
928 
929 		// bail if we haven't found the specified instance yet
930 		if (!foundspecifiedinstance) {
931 			debugPrintf("  haven't found specified instance yet\n");
932 			return true;
933 		}
934 	}
935 
936 	return (getenabledids)?true:xmldom::tagStart(ns,name);
937 }
938 
tagEnd(const char * ns,const char * name)939 bool sqlrconfig_xmldom::tagEnd(const char *ns, const char *name) {
940 	debugFunction();
941 
942 	debugPrintf("</%s>\n",name);
943 
944 	// bail if we're already done
945 	if (done) {
946 		debugPrintf("  already done\n");
947 		return true;
948 	}
949 
950 	// bail if we haven't found the specified instance yet
951 	// unless we're closing an instance tag
952 	if (!foundspecifiedinstance && charstring::compare(name,"instance")) {
953 		debugPrintf("  haven't found specified instance yet\n");
954 		return true;
955 	}
956 
957 	// if we've found the specified instance at this point then we're done
958 	if (!getenabledids && foundspecifiedinstance &&
959 				!charstring::compare(name,"instance")) {
960 		debugPrintf("  found specified instance\n");
961 		done=true;
962 	}
963 
964 	return (getenabledids)?true:xmldom::tagEnd(ns,name);
965 }
966 
attributeName(const char * name)967 bool sqlrconfig_xmldom::attributeName(const char *name) {
968 	debugFunction();
969 
970 	debugPrintf("attribute name=%s\n",name);
971 
972 	// bail if we're not supposed to get attributes
973 	if (!getattributes) {
974 		debugPrintf("  not getting attributes\n");
975 		return true;
976 	}
977 
978 	// bail if we're already done
979 	if (done) {
980 		debugPrintf("  already done\n");
981 		return true;
982 	}
983 
984 	// bail if we're not in an instance tag and
985 	// we haven't found the specified instance yet
986 	if (!ininstancetag && !foundspecifiedinstance) {
987 		debugPrintf("  not in instance tag, "
988 				"haven't found specified instance yet\n");
989 		return true;
990 	}
991 
992 	// check for id and enabled attributes of the instance tag
993 	inidattribute=(ininstancetag &&
994 				!charstring::compare(name,"id"));
995 	inenabledattribute=(ininstancetag &&
996 				!charstring::compare(name,"enabled"));
997 	debugPrintf("  inidattribute=%d  inenabledattribute=%d\n",
998 					inidattribute,inenabledattribute);
999 
1000 	return (getenabledids)?true:xmldom::attributeName(name);
1001 }
1002 
attributeValue(const char * value)1003 bool sqlrconfig_xmldom::attributeValue(const char *value) {
1004 	debugFunction();
1005 
1006 	debugPrintf("attribute value=\"%s\"\n",value);
1007 
1008 	// bail if we're not supposed to get attributes
1009 	if (!getattributes) {
1010 		debugPrintf("  not getting attributes\n");
1011 		return true;
1012 	}
1013 
1014 	// bail if we're already done
1015 	if (done) {
1016 		debugPrintf("  already done\n");
1017 		return true;
1018 	}
1019 
1020 	// bail if we're not in an instance tag and
1021 	// we haven't found the specified instance yet
1022 	if (!ininstancetag && !foundspecifiedinstance) {
1023 		debugPrintf("  not in instance tag, "
1024 				"haven't found specified instance yet\n");
1025 		return true;
1026 	}
1027 
1028 	if (getenabledids) {
1029 
1030 		// set the current id
1031 		if (inidattribute) {
1032 			delete[] currentid;
1033 			currentid=charstring::duplicate(value);
1034 			debugPrintf("  setting current id to \"%s\"\n",
1035 								currentid);
1036 		}
1037 
1038 		// if this instance is enabled, then add its id to the id list
1039 		if (inenabledattribute && charstring::isYes(value)) {
1040 			idlist->append(charstring::duplicate(currentid));
1041 		}
1042 
1043 	} else {
1044 
1045 		// check for the specified instance, if we haven't found it yet
1046 		if (!foundspecifiedinstance) {
1047 			foundspecifiedinstance=
1048 				(inidattribute && value &&
1049 					!charstring::compare(value,id));
1050 		}
1051 
1052 		// bail if we haven't found the specified instance,
1053 		// unless we're in an instance tag
1054 		if (!foundspecifiedinstance && !ininstancetag) {
1055 			return true;
1056 		}
1057 
1058 		// if this is an id attribute but it wasn't the one we were
1059 		// looking for, then disable getting the rest of the
1060 		// attributes for this tag
1061 		if (!foundspecifiedinstance && inidattribute) {
1062 			getattributes=false;
1063 		}
1064 	}
1065 
1066 	return (getenabledids)?true:xmldom::attributeValue(value);
1067 }
1068 
text(const char * value)1069 bool sqlrconfig_xmldom::text(const char *value) {
1070 	debugFunction();
1071 
1072 	debugPrintf("  text: %s\n",value);
1073 
1074 	// bail if we're already done
1075 	if (done) {
1076 		debugPrintf("  already done\n");
1077 		return true;
1078 	}
1079 
1080 	// bail if we haven't found the specified instance yet
1081 	if (!foundspecifiedinstance) {
1082 		debugPrintf("  haven't found specified instance yet\n");
1083 		return true;
1084 	}
1085 
1086 	// bail if the text is entirely whitespace
1087 	for (const char *c=value; *c; c++) {
1088 		if (!character::isWhitespace(*c)) {
1089 			return xmldom::text(value);
1090 		}
1091 	}
1092 	debugPrintf("  entirely whitespce, removing\n");
1093 	return true;
1094 }
1095 
comment(const char * value)1096 bool sqlrconfig_xmldom::comment(const char *value) {
1097 	debugFunction();
1098 	debugPrintf("  comment: %s\n",value);
1099 	return true;
1100 }
1101 
hasDebug(const char * str,const char * debugstr)1102 bool sqlrconfig_xmldom::hasDebug(const char *str, const char *debugstr) {
1103 
1104 	const char	*end=str+charstring::length(str);
1105 	size_t		debugstrlen=charstring::length(debugstr);
1106 
1107 	while(str<end) {
1108 
1109 		// see if the debug string is in the string at all
1110 		const char	*ptr=charstring::findFirst(str,debugstr);
1111 		if (!ptr) {
1112 			return false;
1113 		}
1114 
1115 		// if we found something, then verify that
1116 		// * it is at the beginning of the string
1117 		//   or
1118 		// * it is preceeded by a space
1119 		// and
1120 		// * it ends at the end of the string
1121 		//   or
1122 		// * it is followed by a space
1123 		if ((ptr==str || *(ptr-1)==' ') &&
1124 			(ptr+debugstrlen==end || *(ptr+debugstrlen)==' ')) {
1125 			return true;
1126 		}
1127 
1128 		// if not, move on and look for it again
1129 		str+=debugstrlen;
1130 	}
1131 	return false;
1132 }
1133 
load(const char * urlname,const char * id)1134 bool sqlrconfig_xmldom::load(const char *urlname, const char *id) {
1135 	debugFunction();
1136 
1137 	debugPrintf("urlname=\"%s\"  id=\"%s\"\n",urlname,id);
1138 
1139 	// sanity check
1140 	if (charstring::isNullOrEmpty(urlname) ||
1141 			charstring::isNullOrEmpty(id)) {
1142 		return false;
1143 	}
1144 
1145 	// re-init
1146 	clear();
1147 	init();
1148 
1149 	// set some stateful variables
1150 	getenabledids=false;
1151 	this->id=id;
1152 	foundspecifiedinstance=false;
1153 	done=false;
1154 
1155 	// parse the url
1156 	parseUrl(urlname);
1157 
1158 	// bail if we didn't find the instance we were looking for
1159 	if (!foundspecifiedinstance) {
1160 		return false;
1161 	}
1162 
1163 	#ifdef DEBUG_MESSAGES
1164 		debugPrintf("\noriginal tree:\n");
1165 		getRootNode()->write(&stdoutput);
1166 		debugPrintf("\n");
1167 	#endif
1168 
1169 	// normalize the tree
1170 	normalizeTree();
1171 
1172 	#ifdef DEBUG_MESSAGES
1173 		debugPrintf("normalized tree:\n");
1174 		getRootNode()->write(&stdoutput);
1175 		debugPrintf("\n");
1176 	#endif
1177 /*stdoutput.printf("normalized tree:\n");
1178 getRootNode()->write(&stdoutput);
1179 stdoutput.printf("\n");*/
1180 
1181 	// get values from the tree
1182 	getTreeValues();
1183 
1184 	return true;
1185 }
1186 
normalizeTree()1187 void sqlrconfig_xmldom::normalizeTree() {
1188 
1189 	// prune instances for non-specified id's
1190 	domnode *instance=getRootNode()->getFirstTagChild("instance");
1191 	while (!instance->isNullNode()) {
1192 		domnode	*next=instance->getNextTagSibling("instance");
1193 		if (charstring::compare(instance->getAttributeValue("id"),id)) {
1194 			instance->getParent()->deleteChild(instance);
1195 		}
1196 		instance=next;
1197 	}
1198 
1199 	// get the instance
1200 	instance=getRootNode()->getFirstTagChild("instance");
1201 
1202 	// addresses="" -> addresses="0.0.0.0"
1203 	domnode	*attr=instance->getAttribute("addresses");
1204 	if (!attr->isNullNode()) {
1205 		if (charstring::isNullOrEmpty(attr->getValue())) {
1206 			attr->setValue("0.0.0.0");
1207 		}
1208 	}
1209 
1210 	// unixport -> socket
1211 	attr=instance->getAttribute("unixport");
1212 	if (!attr->isNullNode()) {
1213 		attr->setName("socket");
1214 	}
1215 
1216 	// authentication -> authtier
1217 	attr=instance->getAttribute("authentication");
1218 	if (!attr->isNullNode()) {
1219 		attr->setName("authtier");
1220 	}
1221 
1222 	// oracle8 -> oracle, sybase -> sap, mariadb -> mysql
1223 	attr=instance->getAttribute("dbase");
1224 	if (!attr->isNullNode()) {
1225 		if (!charstring::compare(attr->getValue(),"oracle8")) {
1226 			attr->setValue("oracle");
1227 		} else if (!charstring::compare(attr->getValue(),"sybase")) {
1228 			attr->setValue("sap");
1229 		} else if (!charstring::compare(attr->getValue(),"mariadb")) {
1230 			attr->setValue("mysql");
1231 		}
1232 	}
1233 
1234 	// add missing listeners tag
1235 	domnode	*listeners=instance->getFirstTagChild("listeners");
1236 	if (listeners->isNullNode()) {
1237 		listeners=instance->insertTag("listeners",0);
1238 	}
1239 
1240 	// addresses/port/socket/etc. in instance -> listener
1241 	domnode	*addresses=instance->getAttribute("addresses");
1242 	domnode	*port=instance->getAttribute("port");
1243 	domnode	*socket=instance->getAttribute("socket");
1244 	domnode	*krb=instance->getAttribute("krb");
1245 	domnode	*krbservice=instance->getAttribute("krbservice");
1246 	domnode	*krbkeytab=instance->getAttribute("krbkeytab");
1247 	domnode	*krbmech=instance->getAttribute("krbmech");
1248 	domnode	*krbflags=instance->getAttribute("krbflags");
1249 	domnode	*tls=instance->getAttribute("tls");
1250 	domnode	*tlsversion=instance->getAttribute("tlsversion");
1251 	domnode	*tlscert=instance->getAttribute("tlscert");
1252 	domnode	*tlskey=instance->getAttribute("tlskey");
1253 	domnode	*tlspassword=instance->getAttribute("tlspassword");
1254 	domnode	*tlsvalidate=instance->getAttribute("tlsvalidate");
1255 	domnode	*tlsca=instance->getAttribute("tlsca");
1256 	domnode	*tlsciphers=instance->getAttribute("tlsciphers");
1257 	domnode	*tlsdepth=instance->getAttribute("tlsdepth");
1258 	if (!addresses->isNullNode() ||
1259 			!port->isNullNode() ||
1260 			!socket->isNullNode() ||
1261 			!krb->isNullNode() ||
1262 			!krbservice->isNullNode() ||
1263 			!krbkeytab->isNullNode() ||
1264 			!krbmech->isNullNode() ||
1265 			!krbflags->isNullNode() ||
1266 			!tls->isNullNode() ||
1267 			!tlsversion->isNullNode() ||
1268 			!tlscert->isNullNode() ||
1269 			!tlskey->isNullNode() ||
1270 			!tlspassword->isNullNode() ||
1271 			!tlsvalidate->isNullNode() ||
1272 			!tlsca->isNullNode() ||
1273 			!tlsciphers->isNullNode() ||
1274 			!tlsdepth->isNullNode()) {
1275 
1276 		domnode	*listener=listeners->insertTag("listener",0);
1277 		listener->setAttributeValue("protocol",DEFAULT_PROTOCOL);
1278 
1279 		if (!addresses->isNullNode()) {
1280 			listener->setAttributeValue("addresses",
1281 							addresses->getValue());
1282 			instance->deleteAttribute(addresses);
1283 		}
1284 		if (!port->isNullNode()) {
1285 			listener->setAttributeValue("port",
1286 							port->getValue());
1287 			instance->deleteAttribute(port);
1288 		}
1289 		if (!socket->isNullNode()) {
1290 			listener->setAttributeValue("socket",
1291 							socket->getValue());
1292 			instance->deleteAttribute(socket);
1293 		}
1294 		if (!krb->isNullNode()) {
1295 			listener->setAttributeValue("krb",
1296 							krb->getValue());
1297 			instance->deleteAttribute(krb);
1298 		}
1299 		if (!krbservice->isNullNode()) {
1300 			listener->setAttributeValue("krbservice",
1301 							krbservice->getValue());
1302 			instance->deleteAttribute(krbservice);
1303 		}
1304 		if (!krbkeytab->isNullNode()) {
1305 			listener->setAttributeValue("krbkeytab",
1306 							krbkeytab->getValue());
1307 			instance->deleteAttribute(krbkeytab);
1308 		}
1309 		if (!krbmech->isNullNode()) {
1310 			listener->setAttributeValue("krbmech",
1311 							krbmech->getValue());
1312 			instance->deleteAttribute(krbmech);
1313 		}
1314 		if (!krbflags->isNullNode()) {
1315 			listener->setAttributeValue("krbflags",
1316 							krbflags->getValue());
1317 			instance->deleteAttribute(krbflags);
1318 		}
1319 		if (!tls->isNullNode()) {
1320 			listener->setAttributeValue("tls",
1321 							tls->getValue());
1322 			instance->deleteAttribute(tls);
1323 		}
1324 		if (!tlsversion->isNullNode()) {
1325 			listener->setAttributeValue("tlsversion",
1326 							tlsversion->getValue());
1327 			instance->deleteAttribute(tlsversion);
1328 		}
1329 		if (!tlscert->isNullNode()) {
1330 			listener->setAttributeValue("tlscert",
1331 							tlscert->getValue());
1332 			instance->deleteAttribute(tlscert);
1333 		}
1334 		if (!tlskey->isNullNode()) {
1335 			listener->setAttributeValue("tlskey",
1336 							tlskey->getValue());
1337 			instance->deleteAttribute(tlskey);
1338 		}
1339 		if (!tlspassword->isNullNode()) {
1340 			listener->setAttributeValue("tlspassword",
1341 						tlspassword->getValue());
1342 			instance->deleteAttribute(tlspassword);
1343 		}
1344 		if (!tlsvalidate->isNullNode()) {
1345 			listener->setAttributeValue("tlsvalidate",
1346 						tlsvalidate->getValue());
1347 			instance->deleteAttribute(tlsvalidate);
1348 		}
1349 		if (!tlsca->isNullNode()) {
1350 			listener->setAttributeValue("tlsca",
1351 						tlsca->getValue());
1352 			instance->deleteAttribute(tlsca);
1353 		}
1354 		if (!tlsciphers->isNullNode()) {
1355 			listener->setAttributeValue("tlsciphers",
1356 						tlsciphers->getValue());
1357 			instance->deleteAttribute(tlsciphers);
1358 		}
1359 		if (!tlsdepth->isNullNode()) {
1360 			listener->setAttributeValue("tlsdepth",
1361 						tlsdepth->getValue());
1362 			instance->deleteAttribute(tlsdepth);
1363 		}
1364 	}
1365 
1366 	// empty listeners tag
1367 	if (listeners->getFirstTagChild("listener")->isNullNode()) {
1368 		domnode	*listener=listeners->appendTag("listener");
1369 		listener->setAttributeValue("protocol",DEFAULT_PROTOCOL);
1370 	}
1371 
1372 	// normalize listeners
1373 	for (domnode *listener=listeners->getFirstTagChild("listener");
1374 			!listener->isNullNode();
1375 			listener=listener->getNextTagSibling("listener")) {
1376 
1377 		bool	hasprotocol=!listener->
1378 				getAttribute("protocol")->isNullNode();
1379 		bool	hasaddresses=!listener->
1380 				getAttribute("addresses")->isNullNode();
1381 		bool	hasport=!listener->
1382 				getAttribute("port")->isNullNode();
1383 		bool	hassocket=!listener->
1384 				getAttribute("socket")->isNullNode();
1385 
1386 		// no protocol -> default protocol
1387 		if (!hasprotocol) {
1388 			listener->setAttributeValue(
1389 					"protocol",DEFAULT_PROTOCOL);
1390 		}
1391 
1392 		// nothing specified -> default address, default port, no socket
1393 		if (!hasaddresses && !hasport && !hassocket) {
1394 			listener->setAttributeValue(
1395 					"addresses",DEFAULT_ADDRESS);
1396 			listener->setAttributeValue(
1397 					"port",DEFAULT_PORT);
1398 		} else
1399 
1400 		// port but no address -> default address
1401 		if (!hasaddresses && hasport) {
1402 			listener->setAttributeValue(
1403 					"addresses",DEFAULT_ADDRESS);
1404 		} else
1405 
1406 		// address but no port -> default port
1407 		if (!hasaddresses && hasport) {
1408 			listener->setAttributeValue(
1409 					"port",DEFAULT_PORT);
1410 		}
1411 
1412 		// krb but no service -> default service
1413 		domnode	*krbservice=
1414 				instance->getAttribute("krbservice");
1415 		if (krbservice->isNullNode() &&
1416 			charstring::isYes(listener->getAttributeValue("krb"))) {
1417 			listener->setAttributeValue("krbservice",
1418 						DEFAULT_KRBSERVICE);
1419 		}
1420 	}
1421 
1422 	// authentications -> auths
1423 	domnode	*auths=instance->getFirstTagChild("authentications");
1424 	if (!auths->isNullNode()) {
1425 		auths->setName("auths");
1426 	}
1427 
1428 	// add missing auths tag
1429 	auths=instance->getFirstTagChild("auths");
1430 	if (auths->isNullNode()) {
1431 		auths=instance->insertTag("auths",1);
1432 	}
1433 
1434 	// authentication -> auth
1435 	for (domnode *auth=auths->getFirstTagChild("authentication");
1436 			!auth->isNullNode();
1437 			auth=auth->getNextTagSibling("authentication")) {
1438 		auth->setName("auth");
1439 	}
1440 
1441 	// users -> auth_userlist
1442 	bool		addeduserlist=false;
1443 	domnode	*users=instance->getFirstTagChild("users");
1444 	if (!users->isNullNode()) {
1445 
1446 		domnode	*auth=auths->insertTag("auth",0);
1447 		auth->setAttributeValue("module","userlist");
1448 
1449 		for (domnode *user=users->getFirstTagChild("user");
1450 				!user->isNullNode();
1451 				user=user->getNextTagSibling("user")) {
1452 
1453 			domnode	*authuser=auth->appendTag("user");
1454 
1455 			domnode	*userattr=
1456 					user->getAttribute("user");
1457 			if (!userattr->isNullNode()) {
1458 				authuser->setAttributeValue(
1459 						"user",
1460 						userattr->getValue());
1461 			}
1462 
1463 			domnode	*passwordattr=
1464 					user->getAttribute("password");
1465 			if (!passwordattr->isNullNode()) {
1466 				authuser->setAttributeValue(
1467 						"password",
1468 						passwordattr->getValue());
1469 			}
1470 
1471 			// passwordencryption -> passwordencryptionid
1472 			domnode	*pwdencidattr=
1473 					user->getAttribute(
1474 						"passwordencryptionid");
1475 			if (pwdencidattr->isNullNode()) {
1476 				pwdencidattr=
1477 					user->getAttribute(
1478 						"passwordencryption");
1479 			}
1480 			if (!pwdencidattr->isNullNode()) {
1481 				authuser->setAttributeValue(
1482 						"passwordencryptionid",
1483 						pwdencidattr->getValue());
1484 			}
1485 		}
1486 
1487 		users->getParent()->deleteChild(users);
1488 
1489 		addeduserlist=true;
1490 	}
1491 
1492 	// authtier="database" -> auth_database
1493 	// authtier="proxied" -> auth_proxied
1494 	attr=instance->getAttribute("authtier");
1495 	if (!attr->isNullNode()) {
1496 		if (!charstring::compare(attr->getValue(),"database") ||
1497 			!charstring::compare(attr->getValue(),"proxied")) {
1498 
1499 			domnode	*auth=(addeduserlist)?
1500 					auths->insertTag("auth",1):
1501 					auths->insertTag("auth",0);
1502 
1503 			auth->setAttributeValue("module",attr->getValue());
1504 
1505 			instance->deleteAttribute(attr);
1506 		}
1507 	}
1508 
1509 	// krb_userlist/tls_userlist -> userlist
1510 	for (domnode *auth=instance->getFirstTagChild("auths")->
1511 						getFirstTagChild("auth");
1512 				!auth->isNullNode();
1513 				auth=auth->getNextTagSibling("auth")) {
1514 		if (!charstring::compare(
1515 				auth->getAttributeValue("module"),
1516 				"krb_userlist") ||
1517 			!charstring::compare(
1518 				auth->getAttributeValue("module"),
1519 				"tls_userlist")) {
1520 			auth->setAttributeValue("module","userlist");
1521 		}
1522 	}
1523 
1524 	// normalize connections
1525 	uint32_t	connectioncount=0;
1526 	domnode	*conns=instance->getFirstTagChild("connections");
1527 	for (domnode *conn=conns->getFirstTagChild("connection");
1528 			!conn->isNullNode();
1529 			conn=conn->getNextTagSibling("connection")) {
1530 
1531 		// add missing connection id
1532 		const char	*connid=conn->getAttributeValue("connectionid");
1533 		if (charstring::isNullOrEmpty(connid)) {
1534 			stringbuffer	connectionid;
1535 			connectionid.append(id)->append('-');
1536 			connectionid.append(connectioncount);
1537 			conn->setAttributeValue("connectionid",
1538 						connectionid.getString());
1539 			connectioncount++;
1540 		}
1541 
1542 		// passwordencryption -> passwordencryptionid
1543 		domnode	*pwdencattr=
1544 				conn->getAttribute("passwordencryption");
1545 		if (!pwdencattr->isNullNode()) {
1546 			pwdencattr->setName("passwordencryptionid");
1547 		}
1548 	}
1549 
1550 	// datetimeformat -> resultsettranslation_reformatdatetime
1551 	domnode	*dtformat=instance->getAttribute("datetimeformat");
1552 	domnode	*dateformat=instance->getAttribute("dateformat");
1553 	domnode	*timeformat=instance->getAttribute("timeformat");
1554 	domnode	*dateddmm=instance->getAttribute("dateddmm");
1555 	domnode	*dateyyyyddmm=instance->getAttribute("dateyyyyddmm");
1556 	domnode	*datedelims=instance->getAttribute("datedelimiters");
1557 	if (!dtformat->isNullNode() ||
1558 		!dateformat->isNullNode() ||
1559 		!timeformat->isNullNode() ||
1560 		!dateddmm->isNullNode() ||
1561 		!dateyyyyddmm->isNullNode() ||
1562 		!datedelims->isNullNode()) {
1563 
1564 		// get/add resultsettranslations tag
1565 		domnode	*rstrans=
1566 			instance->getFirstTagChild("resultsettranslations");
1567 		if (rstrans->isNullNode()) {
1568 			rstrans=instance->appendTag("resultsettranslations");
1569 		}
1570 
1571 		// add resultsettranslation tag
1572 		domnode	*rst=
1573 			rstrans->insertTag("resultsettranslation",0);
1574 		rst->setAttributeValue("module","reformatdatetime");
1575 
1576 		if (!dtformat->isNullNode()) {
1577 			rst->setAttributeValue("datetimeformat",
1578 						dtformat->getValue());
1579 			instance->deleteAttribute(dtformat);
1580 		}
1581 		if (!dateformat->isNullNode()) {
1582 			rst->setAttributeValue("dateformat",
1583 						dateformat->getValue());
1584 			instance->deleteAttribute(dateformat);
1585 		}
1586 		if (!timeformat->isNullNode()) {
1587 			rst->setAttributeValue("timeformat",
1588 						timeformat->getValue());
1589 			instance->deleteAttribute(timeformat);
1590 		}
1591 		if (!dateddmm->isNullNode()) {
1592 			rst->setAttributeValue("dateddmm",
1593 						dateddmm->getValue());
1594 			instance->deleteAttribute(dateddmm);
1595 		}
1596 		if (!dateyyyyddmm->isNullNode()) {
1597 			rst->setAttributeValue("dateyyyyddmm",
1598 						dateyyyyddmm->getValue());
1599 			instance->deleteAttribute(dateyyyyddmm);
1600 		}
1601 		if (!datedelims->isNullNode()) {
1602 			rst->setAttributeValue("datedelims",
1603 						datedelims->getValue());
1604 			instance->deleteAttribute(datedelims);
1605 		}
1606 	}
1607 
1608 	// old router format to new router format
1609 	domnode	*router=instance->getFirstTagChild("router");
1610 	if (!router->isNullNode()) {
1611 
1612 		// add a routers node if none exists
1613 		domnode	*rtrs=instance->getFirstTagChild("routers");
1614 		if (rtrs->isNullNode()) {
1615 			rtrs=instance->appendTag("routers");
1616 		}
1617 
1618 		// add a connections node if none exists
1619 		domnode	*cons=instance->getFirstTagChild("connections");
1620 		if (cons->isNullNode()) {
1621 			cons=instance->appendTag("connections");
1622 		}
1623 
1624 		// for each router.route node...
1625 		uint16_t	index=0;
1626 		stringbuffer	conid;
1627 		stringbuffer	str;
1628 		for (domnode *route=router->getFirstTagChild("route");
1629 				!route->isNullNode();
1630 				route=route->getNextTagSibling("route")) {
1631 
1632 			// generate a connection id
1633 			conid.append("autogenerated-route-")->append(index);
1634 			index++;
1635 
1636 			// build the connect string
1637 			const char	*host=
1638 					route->getAttributeValue("host");
1639 			if (!charstring::isNullOrEmpty(host)) {
1640 				str.append("host=");
1641 				str.append(host)->append(';');
1642 			}
1643 			const char	*port=
1644 					route->getAttributeValue("port");
1645 			if (!charstring::isNullOrEmpty(port)) {
1646 				str.append("port=");
1647 				str.append(port)->append(';');
1648 			}
1649 			const char	*socket=
1650 					route->getAttributeValue("socket");
1651 			if (!charstring::isNullOrEmpty(socket)) {
1652 				str.append("socket=");
1653 				str.append(socket)->append(';');
1654 			}
1655 			const char	*user=
1656 					route->getAttributeValue("user");
1657 			if (!charstring::isNullOrEmpty(user)) {
1658 				str.append("user=");
1659 				str.append(user)->append(';');
1660 			}
1661 			const char	*password=
1662 					route->getAttributeValue("password");
1663 			if (!charstring::isNullOrEmpty(password)) {
1664 				str.append("password=");
1665 				str.append(password)->append(';');
1666 			}
1667 
1668 			// add a connections.connection node
1669 			domnode	*con=cons->appendTag("connection");
1670 			con->setAttributeValue("connectionid",
1671 						conid.getString());
1672 			con->setAttributeValue("string",
1673 						str.getString());
1674 
1675 			// add a routers.router node
1676 			domnode	*rtr=rtrs->appendTag("router");
1677 			rtr->setAttributeValue("module","regex");
1678 			rtr->setAttributeValue("connectionid",
1679 						conid.getString());
1680 
1681 			// for each query...
1682 			for (domnode *query=route->getFirstTagChild("query");
1683 				!query->isNullNode();
1684 				query=query->getNextTagSibling("query")) {
1685 
1686 				// create a routers.router.pattern tag
1687 				rtr->appendTag("pattern")->
1688 					setAttributeValue("pattern",
1689 						query->getAttributeValue(
1690 								"pattern"));
1691 			}
1692 
1693 			// clear buffers
1694 			conid.clear();
1695 			str.clear();
1696 		}
1697 
1698 		// delete the old router tag
1699 		router->getParent()->deleteChild(router);
1700 	}
1701 }
1702 
getTreeValues()1703 void sqlrconfig_xmldom::getTreeValues() {
1704 
1705 	// instance tag...
1706 	domnode	*instance=getRootNode()->getFirstTagChild("instance");
1707 	domnode	*attr=instance->getAttribute("dbase");
1708 	if (!attr->isNullNode()) {
1709 		dbase=attr->getValue();
1710 	}
1711 	attr=instance->getAttribute("connections");
1712 	if (!attr->isNullNode()) {
1713 		connections=atouint32_t(attr->getValue(),
1714 						DEFAULT_CONNECTIONS,0);
1715 		if (connections>MAXCONNECTIONS) {
1716 			connections=MAXCONNECTIONS;
1717 		}
1718 		if (maxconnections<connections) {
1719 			maxconnections=connections;
1720 		}
1721 	}
1722 	attr=instance->getAttribute("maxconnections");
1723 	if (!attr->isNullNode()) {
1724 		maxconnections=atouint32_t(attr->getValue(),
1725 						DEFAULT_CONNECTIONS,1);
1726 		if (maxconnections>MAXCONNECTIONS) {
1727 			maxconnections=MAXCONNECTIONS;
1728 		}
1729 		if (maxconnections<connections) {
1730 			maxconnections=connections;
1731 		}
1732 	}
1733 	attr=instance->getAttribute("maxqueuelength");
1734 	if (!attr->isNullNode()) {
1735 		maxqueuelength=atouint32_t(attr->getValue(),
1736 						DEFAULT_MAXQUEUELENGTH,0);
1737 	}
1738 	attr=instance->getAttribute("growby");
1739 	if (!attr->isNullNode()) {
1740 		growby=atouint32_t(attr->getValue(),DEFAULT_GROWBY,1);
1741 	}
1742 	attr=instance->getAttribute("ttl");
1743 	if (!attr->isNullNode()) {
1744 		ttl=atoint32_t(attr->getValue(),DEFAULT_TTL,0);
1745 	}
1746 	attr=instance->getAttribute("softttl");
1747 	if (!attr->isNullNode()) {
1748 		softttl=atoint32_t(attr->getValue(),DEFAULT_SOFTTTL,0);
1749 	}
1750 	attr=instance->getAttribute("maxsessioncount");
1751 	if (!attr->isNullNode()) {
1752 		maxsessioncount=atouint32_t(attr->getValue(),
1753 						DEFAULT_MAXSESSIONCOUNT,0);
1754 	}
1755 	attr=instance->getAttribute("endofsession");
1756 	if (!attr->isNullNode()) {
1757 		endofsession=attr->getValue();
1758 		endofsessioncommit=!charstring::compare(endofsession,"commit");
1759 	}
1760 	attr=instance->getAttribute("sessiontimeout");
1761 	if (!attr->isNullNode()) {
1762 		sessiontimeout=atouint32_t(attr->getValue(),
1763 						DEFAULT_SESSIONTIMEOUT,1);
1764 	}
1765 	attr=instance->getAttribute("runasuser");
1766 	if (!attr->isNullNode()) {
1767 		runasuser=attr->getValue();
1768 	}
1769 	attr=instance->getAttribute("runasgroup");
1770 	if (!attr->isNullNode()) {
1771 		runasgroup=attr->getValue();
1772 	}
1773 	attr=instance->getAttribute("cursors");
1774 	if (!attr->isNullNode()) {
1775 		cursors=atouint32_t(attr->getValue(),DEFAULT_CURSORS,0);
1776 		if (maxcursors<cursors) {
1777 			maxcursors=cursors;
1778 		}
1779 	}
1780 	attr=instance->getAttribute("maxcursors");
1781 	if (!attr->isNullNode()) {
1782 		maxcursors=atouint32_t(attr->getValue(),DEFAULT_CURSORS,0);
1783 		if (maxcursors<cursors) {
1784 			maxcursors=cursors;
1785 		}
1786 	}
1787 	attr=instance->getAttribute("cursors_growby");
1788 	if (!attr->isNullNode()) {
1789 		cursorsgrowby=atouint32_t(attr->getValue(),
1790 						DEFAULT_CURSORS_GROWBY,1);
1791 	}
1792 	attr=instance->getAttribute("authtier");
1793 	if (!attr->isNullNode()) {
1794 		authtier=attr->getValue();
1795 	}
1796 	attr=instance->getAttribute("sessionhandler");
1797 	if (!attr->isNullNode()) {
1798 		sessionhandler=attr->getValue();
1799 	}
1800 	attr=instance->getAttribute("handoff");
1801 	if (!attr->isNullNode()) {
1802 		handoff=attr->getValue();
1803 	}
1804 	attr=instance->getAttribute("allowedips");
1805 	if (!attr->isNullNode()) {
1806 		allowedips=attr->getValue();
1807 	}
1808 	attr=instance->getAttribute("deniedips");
1809 	if (!attr->isNullNode()) {
1810 		deniedips=attr->getValue();
1811 	}
1812 	attr=instance->getAttribute("debug");
1813 	if (!attr->isNullNode()) {
1814 		debug=attr->getValue();
1815 		debugsql=hasDebug(debug,"sql");
1816 		debugbulkload=hasDebug(debug,"bulkload");
1817 		debugparser=hasDebug(debug,"parser");
1818 		debugdirectives=hasDebug(debug,"directives");
1819 		debugtranslations=hasDebug(debug,"translations");
1820 		debugfilters=hasDebug(debug,"filters");
1821 		debugtriggers=hasDebug(debug,"triggers");
1822 		debugbindtranslations=hasDebug(debug,"bindtranslations");
1823 		debugbindvariabletranslations=
1824 			hasDebug(debug,"bindvariabletranslations");
1825 		debugresultsettranslations=
1826 			hasDebug(debug,"resultsettranslations");
1827 		debugresultsetrowtranslations=
1828 			hasDebug(debug,"resultsetrowtranslations");
1829 		debugresultsetrowblocktranslations=
1830 			hasDebug(debug,"resultsetrowblocktranslations");
1831 		debugresultsetheadertranslations=
1832 			hasDebug(debug,"resultsetheadertranslations");
1833 		debugprotocols=hasDebug(debug,"protocols");
1834 		debugauths=hasDebug(debug,"auths");
1835 		debugpwdencs=hasDebug(debug,"passwordencryptions");
1836 		debugloggers=hasDebug(debug,"loggers");
1837 		debugnotifications=hasDebug(debug,"notifications");
1838 		debugschedules=hasDebug(debug,"schedules");
1839 		debugrouters=hasDebug(debug,"routers");
1840 		debugqueries=hasDebug(debug,"queries");
1841 		debugmoduledatas=hasDebug(debug,"moduledatas");
1842 	}
1843 	attr=instance->getAttribute("maxclientinfolength");
1844 	if (!attr->isNullNode()) {
1845 		maxclientinfolength=charstring::toInteger(attr->getValue());
1846 	}
1847 	attr=instance->getAttribute("maxquerysize");
1848 	if (!attr->isNullNode()) {
1849 		maxquerysize=charstring::toInteger(attr->getValue());
1850 	}
1851 	attr=instance->getAttribute("maxbindcount");
1852 	if (!attr->isNullNode()) {
1853 		maxbindcount=charstring::toInteger(attr->getValue());
1854 	}
1855 	attr=instance->getAttribute("maxbindnamelength");
1856 	if (!attr->isNullNode()) {
1857 		maxbindnamelength=charstring::toInteger(attr->getValue());
1858 	}
1859 	attr=instance->getAttribute("maxstringbindvaluelength");
1860 	if (!attr->isNullNode()) {
1861 		maxstringbindvaluelength=
1862 				charstring::toInteger(attr->getValue());
1863 	}
1864 	attr=instance->getAttribute("maxlobbindvaluelength");
1865 	if (!attr->isNullNode()) {
1866 		maxlobbindvaluelength=charstring::toInteger(attr->getValue());
1867 	}
1868 	attr=instance->getAttribute("maxerrorlength");
1869 	if (!attr->isNullNode()) {
1870 		maxerrorlength=charstring::toInteger(attr->getValue());
1871 	}
1872 	attr=instance->getAttribute("idleclienttimeout");
1873 	if (!attr->isNullNode()) {
1874 		idleclienttimeout=charstring::toInteger(attr->getValue());
1875 	}
1876 	attr=instance->getAttribute("maxlisteners");
1877 	if (!attr->isNullNode()) {
1878 		maxlisteners=charstring::toInteger(attr->getValue());
1879 	}
1880 	attr=instance->getAttribute("listenertimeout");
1881 	if (!attr->isNullNode()) {
1882 		listenertimeout=charstring::toUnsignedInteger(attr->getValue());
1883 	}
1884 	attr=instance->getAttribute("reloginatstart");
1885 	if (!attr->isNullNode()) {
1886 		reloginatstart=charstring::isYes(attr->getValue());
1887 	}
1888 	attr=instance->getAttribute("fakeinputbindvariables");
1889 	if (!attr->isNullNode()) {
1890 		fakeinputbindvariables=charstring::isYes(attr->getValue());
1891 	}
1892 	attr=instance->getAttribute("fakeinputbindvariablesdateformat");
1893 	if (!attr->isNullNode()) {
1894 		fakeinputbindvariablesdateformat=attr->getValue();
1895 	}
1896 	attr=instance->getAttribute("fakeinputbindvariablesunicodestrings");
1897 	if (!attr->isNullNode()) {
1898 		fakeinputbindvariablesunicodestrings=
1899 					charstring::isYes(attr->getValue());
1900 	}
1901 	attr=instance->getAttribute("bindvariabledelimiters");
1902 	if (!attr->isNullNode()) {
1903 		bindvariabledelimiters=attr->getValue();
1904 		questionmarksupported=charstring::contains(
1905 						bindvariabledelimiters,'?');
1906 		colonsupported=charstring::contains(
1907 						bindvariabledelimiters,':');
1908 		atsignsupported=charstring::contains(
1909 						bindvariabledelimiters,'@');
1910 		dollarsignsupported=charstring::contains(
1911 						bindvariabledelimiters,'$');
1912 	}
1913 	attr=instance->getAttribute("translatebindvariables");
1914 	if (!attr->isNullNode()) {
1915 		translatebindvariables=charstring::isYes(attr->getValue());
1916 	}
1917 	attr=instance->getAttribute("isolationlevel");
1918 	if (!attr->isNullNode()) {
1919 		isolationlevel=attr->getValue();
1920 	}
1921 	attr=instance->getAttribute("ignoreselectdatabase");
1922 	if (!attr->isNullNode()) {
1923 		ignoreselectdb=charstring::isYes(attr->getValue());
1924 	}
1925 	attr=instance->getAttribute("waitfordowndatabase");
1926 	if (!attr->isNullNode()) {
1927 		waitfordowndb=charstring::isYes(attr->getValue());
1928 	}
1929 
1930 
1931 	// xmls...
1932 	listenersxml=instance->getFirstTagChild("listeners");
1933 	parserxml=instance->getFirstTagChild("parser");
1934 	directivesxml=instance->getFirstTagChild("directives");
1935 	translationsxml=instance->getFirstTagChild("translations");
1936 	filtersxml=instance->getFirstTagChild("filters");
1937 	bindvariabletranslationsxml=instance->getFirstTagChild(
1938 					"bindvariabletranslations");
1939 	resultsettranslationsxml=instance->getFirstTagChild(
1940 					"resultsettranslations");
1941 	resultsetrowtranslationsxml=instance->getFirstTagChild(
1942 					"resultsetrowtranslations");
1943 	resultsetrowblocktranslationsxml=instance->getFirstTagChild(
1944 					"resultsetrowblocktranslations");
1945 	resultsetheadertranslationsxml=instance->getFirstTagChild(
1946 					"resultsetheadertranslations");
1947 	triggersxml=instance->getFirstTagChild("triggers");
1948 	loggersxml=instance->getFirstTagChild("loggers");
1949 	notificationsxml=instance->getFirstTagChild("notifications");
1950 	schedulesxml=instance->getFirstTagChild("schedules");
1951 	routersxml=instance->getFirstTagChild("routers");
1952 	queriesxml=instance->getFirstTagChild("queries");
1953 	pwdencsxml=instance->getFirstTagChild("passwordencryptions");
1954 	authsxml=instance->getFirstTagChild("auths");
1955 	moduledatasxml=instance->getFirstTagChild("moduledatas");
1956 
1957 
1958 	// listeners tag...
1959 	defaultlistener=NULL;
1960 	for (domnode *node=listenersxml->getFirstTagChild("listener");
1961 				!node->isNullNode();
1962 				node=node->getNextTagSibling("listener")) {
1963 
1964 		// get the default listener...
1965 		// use the first listener for the default protocol,
1966 		if (!defaultlistener &&
1967 			!charstring::compare(
1968 					node->getAttributeValue("protocol"),
1969 					DEFAULT_PROTOCOL)) {
1970 			defaultlistener=node;
1971 		}
1972 
1973 		// listen on inet/unix...
1974 		if (!node->getAttribute("port")->isNullNode()) {
1975 			listenoninet=true;
1976 		}
1977 		if (!node->getAttribute("socket")->isNullNode()) {
1978 			listenonunix=true;
1979 		}
1980 	}
1981 
1982 	// just use the first listener if no default listener was found yet
1983 	if (!defaultlistener) {
1984 		defaultlistener=listenersxml->getFirstTagChild("listener");
1985 	}
1986 
1987 	// default listener parameters
1988 	defaultaddresses=defaultlistener->getAttributeValue("addresses");
1989 	defaultport=charstring::toUnsignedInteger(
1990 			defaultlistener->getAttributeValue("port"));
1991 	defaultsocket=defaultlistener->getAttributeValue("socket");
1992 	defaultkrb=charstring::isYes(defaultlistener->getAttributeValue("krb"));
1993 	defaultkrbkeytab=defaultlistener->getAttributeValue("krbkeytab");
1994 	defaultkrbservice=defaultlistener->getAttributeValue("krbservice");
1995 	defaultkrbmech=defaultlistener->getAttributeValue("krbmech");
1996 	defaultkrbflags=defaultlistener->getAttributeValue("krbflags");
1997 	defaulttls=charstring::isYes(defaultlistener->getAttributeValue("tls"));
1998 	defaulttlsciphers=defaultlistener->getAttributeValue("tlsciphers");
1999 
2000 
2001 	// session queries
2002 	domnode	*session=instance->getFirstTagChild("session");
2003 	domnode	*start=session->getFirstTagChild("start");
2004 	for (domnode *runquery=start->getFirstTagChild("runquery");
2005 			!runquery->isNullNode();
2006 			runquery=runquery->getNextTagSibling("runquery")) {
2007 		sessionstartqueries.append(charstring::duplicate(
2008 				runquery->getFirstChild("text")->getValue()));
2009 	}
2010 	domnode	*end=session->getFirstTagChild("end");
2011 	for (domnode *runquery=end->getFirstTagChild("runquery");
2012 			!runquery->isNullNode();
2013 			runquery=runquery->getNextTagSibling("runquery")) {
2014 		sessionendqueries.append(charstring::duplicate(
2015 				runquery->getFirstChild("text")->getValue()));
2016 	}
2017 
2018 
2019 	// connect string list
2020 	for (domnode *connection=instance->
2021 					getFirstTagChild("connections")->
2022 					getFirstTagChild("connection");
2023 			!connection->isNullNode();
2024 			connection=connection->
2025 					getNextTagSibling("connection")) {
2026 
2027 		// add an item to the connect string list
2028 		connectstringcontainer	*c=new connectstringcontainer();
2029 		const char	*connectionid=connection->
2030 				getAttributeValue("connectionid");
2031 		const char	*str=connection->
2032 				getAttributeValue("string");
2033 		const char	*metric=connection->
2034 				getAttributeValue("metric");
2035 		const char	*blb=connection->
2036 				getAttributeValue("behindloadbalancer");
2037 		const char	*pwdencid=connection->
2038 				getAttributeValue("passwordencryptionid");
2039 		c->setConnectionId(connectionid);
2040 		c->setString((str)?str:DEFAULT_CONNECTSTRING);
2041 		c->parseConnectString();
2042 		c->setMetric(atouint32_t(metric,DEFAULT_METRIC,1));
2043 		c->setBehindLoadBalancer(charstring::isYes(blb));
2044 		c->setPasswordEncryption(pwdencid);
2045 		connectstringlist.append(c);
2046 	}
2047 
2048 
2049 	// route list
2050 	uint32_t	routecount=0;
2051 	for (domnode *route=instance->
2052 				getFirstTagChild("router")->
2053 				getFirstTagChild("route");
2054 			!route->isNullNode();
2055 			route=route->getNextTagSibling("route")) {
2056 
2057 		// add an item to the route list
2058 		routecontainer	*r=new routecontainer();
2059 		r->setIsFilter(false);
2060 		r->setHost(route->getAttributeValue("host"));
2061 		r->setPort(atouint32_t(
2062 				route->getAttributeValue("port"),"0",0));
2063 		r->setSocket(route->getAttributeValue("socket"));
2064 		r->setUser(route->getAttributeValue("user"));
2065 		r->setPassword(route->getAttributeValue("password"));
2066 
2067 		for (domnode *query=route->getFirstTagChild("query");
2068 				!query->isNullNode();
2069 				query=query->getNextTagSibling("query")) {
2070 			const char	*pattern=
2071 					query->getAttributeValue("pattern");
2072 			regularexpression	*re=
2073 				new regularexpression(
2074 					(pattern)?pattern:
2075 						DEFAULT_ROUTER_PATTERN);
2076 			re->study();
2077 			r->getRegexList()->append(re);
2078 		}
2079 
2080 		routecontainer	*er=routeAlreadyExists(r);
2081 		if (er) {
2082 			moveRegexList(r,er);
2083 			delete r;
2084 		} else {
2085 			routelist.append(r);
2086 		}
2087 
2088 		// add an item to the connect string list
2089 		connectstringcontainer	*c=new connectstringcontainer();
2090 		stringbuffer	connectionid;
2091 		connectionid.append(id)->append('-');
2092 		connectionid.append(routecount++);
2093 		c->setConnectionId(connectionid.getString());
2094 		connectstringlist.append(c);
2095 	}
2096 
2097 	// default user/password
2098 	domnode	*defaultusertag=instance->getFirstTagChild("auths")->							getFirstTagChild(
2099 						"auth","module","userlist")->
2100 						getFirstTagChild("user");
2101 	defaultuser=defaultusertag->getAttributeValue("user");
2102 	defaultpassword=defaultusertag->getAttributeValue("password");
2103 }
2104 
routeAlreadyExists(routecontainer * cur)2105 routecontainer *sqlrconfig_xmldom::routeAlreadyExists(routecontainer *cur) {
2106 
2107 	for (routenode *rn=routelist.getFirst(); rn; rn=rn->getNext()) {
2108 
2109 		routecontainer	*rc=rn->getValue();
2110 		if (!charstring::compare(rc->getHost(),
2111 					cur->getHost()) &&
2112 			rc->getPort()==cur->getPort() &&
2113 			!charstring::compare(rc->getSocket(),
2114 						cur->getSocket()) &&
2115 			!charstring::compare(rc->getUser(),
2116 						cur->getUser()) &&
2117 			!charstring::compare(rc->getPassword(),
2118 						cur->getPassword())) {
2119 			return rc;
2120 		}
2121 	}
2122 	return NULL;
2123 }
2124 
moveRegexList(routecontainer * cur,routecontainer * existing)2125 void sqlrconfig_xmldom::moveRegexList(routecontainer *cur,
2126 					routecontainer *existing) {
2127 
2128 	for (linkedlistnode< regularexpression * > *re=
2129 				cur->getRegexList()->getFirst();
2130 						re; re=re->getNext()) {
2131 		existing->getRegexList()->append(re->getValue());
2132 	}
2133 	cur->getRegexList()->clear();
2134 }
2135 
atouint32_t(const char * value,const char * defaultvalue,uint32_t minvalue)2136 uint32_t sqlrconfig_xmldom::atouint32_t(const char *value,
2137 				const char *defaultvalue, uint32_t minvalue) {
2138 	uint32_t	retval=charstring::toUnsignedInteger(
2139 						(value)?value:defaultvalue);
2140 	if (retval<minvalue) {
2141 		retval=charstring::toUnsignedInteger(defaultvalue);
2142 	}
2143 	return retval;
2144 }
2145 
atoint32_t(const char * value,const char * defaultvalue,int32_t minvalue)2146 int32_t sqlrconfig_xmldom::atoint32_t(const char *value,
2147 				const char *defaultvalue, int32_t minvalue) {
2148 	int32_t	retval=charstring::toInteger((value)?value:defaultvalue);
2149 	if (retval<minvalue) {
2150 		retval=charstring::toInteger(defaultvalue);
2151 	}
2152 	return retval;
2153 }
2154 
parseUrl(const char * urlname)2155 void sqlrconfig_xmldom::parseUrl(const char *urlname) {
2156 	debugFunction();
2157 
2158 	// skip leading whitespace
2159 	while (*urlname && character::isWhitespace(*urlname)) {
2160 		urlname++;
2161 	}
2162 
2163 	// bump past xmldom protocol identifiers
2164 	if (!charstring::compare(urlname,"xmldom://",9)) {
2165 		urlname+=9;
2166 	} else if (!charstring::compare(urlname,"xmldom:",7)) {
2167 		urlname+=7;
2168 	}
2169 
2170 	debugPrintf("urlname=\"%s\"\n",urlname);
2171 
2172 	// parse the url as a config directory, config file or link file
2173 	if (!charstring::compare(urlname,"dir:",4)) {
2174 		parseDir(urlname);
2175 	} else {
2176 		debugPrintf("parseFile()...\n");
2177 		if (!parseFile(urlname)) {
2178 			debugPrintf("failed...\n");
2179 			parseLinkFile(urlname);
2180 		}
2181 	}
2182 }
2183 
parseDir(const char * urlname)2184 void sqlrconfig_xmldom::parseDir(const char *urlname) {
2185 	debugFunction();
2186 
2187 	debugPrintf("urlname=\"%s\"\n",urlname);
2188 
2189 	// skip the protocol
2190 	const char	*dir=
2191 		(!charstring::compare(urlname,"dir://",6))?
2192 					(urlname+6):(urlname+4);
2193 
2194 	// attempt to parse files in the config dir
2195 	directory	d;
2196 	stringbuffer	fullpath;
2197 	char		*osname=sys::getOperatingSystemName();
2198 	const char	*slash=(!charstring::compareIgnoringCase(
2199 					osname,"Windows"))?"\\":"/";
2200 	delete[] osname;
2201 
2202 	if (!done && d.open(dir)) {
2203 		while (!done) {
2204 			char	*filename=d.read();
2205 			if (!filename) {
2206 				break;
2207 			}
2208 			if (charstring::compare(filename,".") &&
2209 				charstring::compare(filename,"..")) {
2210 
2211 				fullpath.clear();
2212 				fullpath.append(dir);
2213 				fullpath.append(slash);
2214 				fullpath.append(filename);
2215 
2216 				parseFile(fullpath.getString());
2217 			}
2218 			delete[] filename;
2219 		}
2220 	}
2221 	d.close();
2222 }
2223 
parseLinkFile(const char * urlname)2224 void sqlrconfig_xmldom::parseLinkFile(const char *urlname) {
2225 	debugFunction();
2226 
2227 	// process the file "urlname" as a list of urls...
2228 	filedescriptor	*fd=NULL;
2229 	file	fl;
2230 	url	u;
2231 
2232 	// bump past file protocol identifiers
2233 	if (!charstring::compare(urlname,"file://",7)) {
2234 		urlname+=7;
2235 	} else if (!charstring::compare(urlname,"file:",5)) {
2236 		urlname+=5;
2237 	}
2238 
2239 	// bump past xmldom protocol identifiers
2240 	if (!charstring::compare(urlname,"xmldom://",9)) {
2241 		urlname+=9;
2242 	} else if (!charstring::compare(urlname,"xmldom:",7)) {
2243 		urlname+=7;
2244 	}
2245 
2246 	debugPrintf("urlname=\"%s\"\n",urlname);
2247 
2248 	// parse file or url...
2249 	if (charstring::contains(urlname,"://")) {
2250 
2251 		// open the url
2252 		if (!u.open(urlname,O_RDONLY)) {
2253 			return;
2254 		}
2255 
2256 		// set fd
2257 		fd=&u;
2258 
2259 	} else {
2260 
2261 		// open the file
2262 		if (!fl.open(urlname,O_RDONLY)) {
2263 			return;
2264 		}
2265 
2266 		// optimize
2267 		filesystem	fs;
2268 		if (fs.open(urlname)) {
2269 			fl.setReadBufferSize(fs.getOptimumTransferBlockSize());
2270 		}
2271 		fl.sequentialAccess(0,fl.getSize());
2272 		fl.onlyOnce(0,fl.getSize());
2273 
2274 		// set fd
2275 		fd=&fl;
2276 	}
2277 
2278 	// read lines from the file
2279 	char	*line=NULL;
2280 	while (fd->read(&line,"\n")>0) {
2281 
2282 		// trim whitespace
2283 		charstring::bothTrim(line);
2284 
2285 		// parse the line (skipping blank lines and comments)
2286 		if (line[0] && line[0]!='#') {
2287 			parseUrl(line);
2288 		}
2289 
2290 		// clean up
2291 		delete[] line;
2292 
2293 		// break if we found the id we were looking for
2294 		if (foundspecifiedinstance) {
2295 			break;
2296 		}
2297 	}
2298 }
2299 
getEnabledIds(const char * urlname,linkedlist<char * > * idlist)2300 void sqlrconfig_xmldom::getEnabledIds(const char *urlname,
2301 					linkedlist< char * > *idlist) {
2302 	debugFunction();
2303 
2304 	debugPrintf("urlname=\"%s\"\n",urlname);
2305 
2306 	// sanity check
2307 	if (charstring::isNullOrEmpty(urlname)) {
2308 		return;
2309 	}
2310 
2311 	// re-init
2312 	clear();
2313 	init();
2314 
2315 	// set some variables
2316 	getenabledids=true;
2317 	this->idlist=idlist;
2318 	foundspecifiedinstance=false;
2319 	done=false;
2320 
2321 	// parse the url
2322 	parseUrl(urlname);
2323 
2324 	#ifdef DEBUG_MESSAGES
2325 		debugPrintf("enabled ids:\n");
2326 		for (linkedlistnode< char * > *n=idlist->getFirst();
2327 						n; n=n->getNext()) {
2328 			debugPrintf("  %s\n",n->getValue());
2329 		}
2330 	#endif
2331 }
2332 
accessible()2333 bool sqlrconfig_xmldom::accessible() {
2334 	debugFunction();
2335 	// FIXME: implement this
2336 	return true;
2337 }
2338 
2339 
2340 extern "C" {
new_sqlrconfig_xmldom()2341 	SQLRUTIL_DLLSPEC sqlrconfig *new_sqlrconfig_xmldom() {
2342 		return new sqlrconfig_xmldom();
2343 	}
2344 }
2345