xref: /titanic_41/usr/src/cmd/svr4pkg/libinst/sml.c (revision 5c51f1241dbbdf2656d0e10011981411ed0c9673)
1*5c51f124SMoriah Waterland /*
2*5c51f124SMoriah Waterland  * CDDL HEADER START
3*5c51f124SMoriah Waterland  *
4*5c51f124SMoriah Waterland  * The contents of this file are subject to the terms of the
5*5c51f124SMoriah Waterland  * Common Development and Distribution License (the "License").
6*5c51f124SMoriah Waterland  * You may not use this file except in compliance with the License.
7*5c51f124SMoriah Waterland  *
8*5c51f124SMoriah Waterland  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*5c51f124SMoriah Waterland  * or http://www.opensolaris.org/os/licensing.
10*5c51f124SMoriah Waterland  * See the License for the specific language governing permissions
11*5c51f124SMoriah Waterland  * and limitations under the License.
12*5c51f124SMoriah Waterland  *
13*5c51f124SMoriah Waterland  * When distributing Covered Code, include this CDDL HEADER in each
14*5c51f124SMoriah Waterland  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*5c51f124SMoriah Waterland  * If applicable, add the following below this CDDL HEADER, with the
16*5c51f124SMoriah Waterland  * fields enclosed by brackets "[]" replaced with your own identifying
17*5c51f124SMoriah Waterland  * information: Portions Copyright [yyyy] [name of copyright owner]
18*5c51f124SMoriah Waterland  *
19*5c51f124SMoriah Waterland  * CDDL HEADER END
20*5c51f124SMoriah Waterland  */
21*5c51f124SMoriah Waterland 
22*5c51f124SMoriah Waterland /*
23*5c51f124SMoriah Waterland  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*5c51f124SMoriah Waterland  * Use is subject to license terms.
25*5c51f124SMoriah Waterland  */
26*5c51f124SMoriah Waterland 
27*5c51f124SMoriah Waterland 
28*5c51f124SMoriah Waterland /*
29*5c51f124SMoriah Waterland  * Module:	sml.c
30*5c51f124SMoriah Waterland  * Synopsis:	simplified markup language (SML) support
31*5c51f124SMoriah Waterland  * Taxonomy:	project private
32*5c51f124SMoriah Waterland  * Debug flag:	sml
33*5c51f124SMoriah Waterland  * Description:
34*5c51f124SMoriah Waterland  *
35*5c51f124SMoriah Waterland  *   This module implements methods that support the processing of a
36*5c51f124SMoriah Waterland  *   simplified markup language (SML). Objects that contain SML data
37*5c51f124SMoriah Waterland  *   can be created and manipulated, and SML can be imported into
38*5c51f124SMoriah Waterland  *   internal SML objects or exported from internal SML objects.
39*5c51f124SMoriah Waterland  *
40*5c51f124SMoriah Waterland  * Public Methods:
41*5c51f124SMoriah Waterland  *
42*5c51f124SMoriah Waterland  *   smlAddTag - Add new tag object into existing tag object
43*5c51f124SMoriah Waterland  *   smlConvertStringToTag - Convert string into tag object
44*5c51f124SMoriah Waterland  *   smlConvertTagToString - Convert a tag object into a string
45*5c51f124SMoriah Waterland  *		representation of the XML
46*5c51f124SMoriah Waterland  *   smlDbgPrintTag - Print a representation of an XML tag if debugging
47*5c51f124SMoriah Waterland  *   smlDelParam - Delete a parameter from a tag object
48*5c51f124SMoriah Waterland  *   smlDelTag - Delete element from tag object
49*5c51f124SMoriah Waterland  *   smlDup - Duplicate a tag object
50*5c51f124SMoriah Waterland  *   smlFindAndDelTag - Delete a tag if found in tag object
51*5c51f124SMoriah Waterland  *   smlFreeTag - Free a tag object and all its contents when no
52*5c51f124SMoriah Waterland  *		longer needed
53*5c51f124SMoriah Waterland  *   smlFstatCompareEq - Compare file status information
54*5c51f124SMoriah Waterland  *   smlGetElementName - Return a tag's element name
55*5c51f124SMoriah Waterland  *   smlGetNumParams - Get number of parameters set in tag
56*5c51f124SMoriah Waterland  *   smlGetParam - Get a parameter from a tag
57*5c51f124SMoriah Waterland  *   smlGetParamF - Get a formatted parameter from a tag
58*5c51f124SMoriah Waterland  *   smlGetParamByTag - Get a parameter by tag and index
59*5c51f124SMoriah Waterland  *   smlGetParamByTagParam Get parameter given tag name, index,
60*5c51f124SMoriah Waterland  *		parameter name, and value
61*5c51f124SMoriah Waterland  *   smlGetParamName - Get the name of a tag parameter given its index
62*5c51f124SMoriah Waterland  *   smlGetParam_r - Get a parameter from a tag into fixed buffer
63*5c51f124SMoriah Waterland  *   smlGetTag - Get an element from a tag
64*5c51f124SMoriah Waterland  *   smlGetTagByName - Get an element given a name and an index
65*5c51f124SMoriah Waterland  *   smlGetTagByTagParam - Get element given tag name, index, parameter name,
66*5c51f124SMoriah Waterland  *		and value
67*5c51f124SMoriah Waterland  *   smlGetVerbose - get current verbose mode setting
68*5c51f124SMoriah Waterland  *   smlLoadTagFromFile - Load a file into a tag object
69*5c51f124SMoriah Waterland  *   smlNewTag - Create a new (empty) tag object
70*5c51f124SMoriah Waterland  *   smlParamEq - Determine if parameter is equal to a specified value
71*5c51f124SMoriah Waterland  *   smlParamEqF - Determine if parameter is equal to a specified value
72*5c51f124SMoriah Waterland  *   smlPrintTag - Print a simple XML representation of a tag to stderr
73*5c51f124SMoriah Waterland  *   smlReadOneTag - read one complete tag from a datastream
74*5c51f124SMoriah Waterland  *   smlReadTagFromDs - read tag object from datastream
75*5c51f124SMoriah Waterland  *   smlSetFileStatInfo - encode file status information into tag
76*5c51f124SMoriah Waterland  *   smlSetVerbose - set/clear verbose mode for debugging output
77*5c51f124SMoriah Waterland  *   smlSetParam - Set parameter value in tag object
78*5c51f124SMoriah Waterland  *   smlSetParamF - Set parameter value in tag object
79*5c51f124SMoriah Waterland  *   smlWriteTagToDs - Write an XML representation of a tag to a datastream
80*5c51f124SMoriah Waterland  *   smlWriteTagToFd - Write an XML representation of a tag to an open file
81*5c51f124SMoriah Waterland  *		descriptor
82*5c51f124SMoriah Waterland  *   smlWriteTagToFile - Write an XML representation of a tag to a file
83*5c51f124SMoriah Waterland  */
84*5c51f124SMoriah Waterland 
85*5c51f124SMoriah Waterland /*
86*5c51f124SMoriah Waterland  * Unix includes
87*5c51f124SMoriah Waterland  */
88*5c51f124SMoriah Waterland 
89*5c51f124SMoriah Waterland #include <locale.h>
90*5c51f124SMoriah Waterland #include <signal.h>
91*5c51f124SMoriah Waterland #include <stdio.h>
92*5c51f124SMoriah Waterland #include <stdlib.h>
93*5c51f124SMoriah Waterland #include <libintl.h>
94*5c51f124SMoriah Waterland #include <stdarg.h>
95*5c51f124SMoriah Waterland #include <string.h>
96*5c51f124SMoriah Waterland #include <unistd.h>
97*5c51f124SMoriah Waterland #include <sys/statvfs.h>
98*5c51f124SMoriah Waterland #include <errno.h>
99*5c51f124SMoriah Waterland #include <assert.h>
100*5c51f124SMoriah Waterland #include <sys/types.h>
101*5c51f124SMoriah Waterland #include <sys/stat.h>
102*5c51f124SMoriah Waterland #include <fcntl.h>
103*5c51f124SMoriah Waterland #include <limits.h>
104*5c51f124SMoriah Waterland #include <strings.h>
105*5c51f124SMoriah Waterland 
106*5c51f124SMoriah Waterland /*
107*5c51f124SMoriah Waterland  * liblu Includes
108*5c51f124SMoriah Waterland  */
109*5c51f124SMoriah Waterland 
110*5c51f124SMoriah Waterland #include "libinst.h"
111*5c51f124SMoriah Waterland #include "messages.h"
112*5c51f124SMoriah Waterland 
113*5c51f124SMoriah Waterland /* Should be defined by cc -D */
114*5c51f124SMoriah Waterland #if	!defined(TEXT_DOMAIN)
115*5c51f124SMoriah Waterland #define	TEXT_DOMAIN "SYS_TEST"
116*5c51f124SMoriah Waterland #endif
117*5c51f124SMoriah Waterland 
118*5c51f124SMoriah Waterland /*
119*5c51f124SMoriah Waterland  * Private Method Forward Declarations
120*5c51f124SMoriah Waterland  */
121*5c51f124SMoriah Waterland 
122*5c51f124SMoriah Waterland /*PRINTFLIKE2*/
123*5c51f124SMoriah Waterland static void	_smlLogMsg(LogMsgType a_type, const char *a_format, ...);
124*5c51f124SMoriah Waterland 
125*5c51f124SMoriah Waterland static int	_smlReadTag(SML_TAG **r_tag, char **a_str, char *parent);
126*5c51f124SMoriah Waterland 
127*5c51f124SMoriah Waterland static int	_smlWriteSimpleTag(char **a_str,
128*5c51f124SMoriah Waterland 				SML_TAG *tag);
129*5c51f124SMoriah Waterland 
130*5c51f124SMoriah Waterland static int	_smlWriteParamValue(char **a_str, char *value);
131*5c51f124SMoriah Waterland 
132*5c51f124SMoriah Waterland static void		_smlFreeTag(SML_TAG *tag);
133*5c51f124SMoriah Waterland 
134*5c51f124SMoriah Waterland static char		*_sml_fileStatInfoTag = "File-Stat-Info";
135*5c51f124SMoriah Waterland 
136*5c51f124SMoriah Waterland static boolean_t	verbose = B_FALSE;
137*5c51f124SMoriah Waterland 
138*5c51f124SMoriah Waterland /*
139*5c51f124SMoriah Waterland  *
140*5c51f124SMoriah Waterland  * This definition controls the maximum size of any individual sml
141*5c51f124SMoriah Waterland  * component, such as a tag name, tag *value*, etc. The code should
142*5c51f124SMoriah Waterland  * someday be revised to dynamically allocate whatever memory is needed
143*5c51f124SMoriah Waterland  * to hold such components while parsing, but that exercise is left for
144*5c51f124SMoriah Waterland  * another day. Any component that exceeds this length is silently
145*5c51f124SMoriah Waterland  * truncated...
146*5c51f124SMoriah Waterland  */
147*5c51f124SMoriah Waterland 
148*5c51f124SMoriah Waterland #define	MAX_SML_COMPONENT_LENGTH	16384
149*5c51f124SMoriah Waterland 
150*5c51f124SMoriah Waterland /*
151*5c51f124SMoriah Waterland  * Public Methods
152*5c51f124SMoriah Waterland  */
153*5c51f124SMoriah Waterland 
154*5c51f124SMoriah Waterland /*
155*5c51f124SMoriah Waterland  * Name:	smlAddTag
156*5c51f124SMoriah Waterland  * Description:	Add new tag object into existing tag object
157*5c51f124SMoriah Waterland  * Arguments:	r_tag - [RO, *RW] - (SML_TAG **)
158*5c51f124SMoriah Waterland  *			Pointer to handle to the tag object to update
159*5c51f124SMoriah Waterland  *			The handle may be updated if the tag object is
160*5c51f124SMoriah Waterland  *			moved in memory
161*5c51f124SMoriah Waterland  *		a_index - [RO] - (int)
162*5c51f124SMoriah Waterland  *			Add the tag after the "n"th tag in the tag object
163*5c51f124SMoriah Waterland  *			-1 == add the tag to the end of the tag object
164*5c51f124SMoriah Waterland  *			0 == add the tag to the beginning of the tag object
165*5c51f124SMoriah Waterland  *		a_subTag - [RO, *RW] - (SML_TAG *)
166*5c51f124SMoriah Waterland  *			The tag to add to 'tag'
167*5c51f124SMoriah Waterland  * Returns:	SML_TAG *
168*5c51f124SMoriah Waterland  *			The location within "r_tag" where "a_subTag"
169*5c51f124SMoriah Waterland  *			has been added - this is the handle into the r_tag
170*5c51f124SMoriah Waterland  *			object to the tag that was just added
171*5c51f124SMoriah Waterland  * Errors:	If the tag object cannot be updated, the process exits
172*5c51f124SMoriah Waterland  */
173*5c51f124SMoriah Waterland 
174*5c51f124SMoriah Waterland SML_TAG *
smlAddTag(SML_TAG ** r_tag,int a_index,SML_TAG * a_subTag)175*5c51f124SMoriah Waterland smlAddTag(SML_TAG **r_tag, int a_index, SML_TAG *a_subTag)
176*5c51f124SMoriah Waterland {
177*5c51f124SMoriah Waterland 	SML_TAG	*tag;
178*5c51f124SMoriah Waterland 
179*5c51f124SMoriah Waterland 	/* entry assertions */
180*5c51f124SMoriah Waterland 
181*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(a_subTag));
182*5c51f124SMoriah Waterland 	assert(SML_TAG__R_ISVALID(r_tag));
183*5c51f124SMoriah Waterland 
184*5c51f124SMoriah Waterland 	/* if no tag to update specified, ignore request */
185*5c51f124SMoriah Waterland 
186*5c51f124SMoriah Waterland 	tag = *r_tag;
187*5c51f124SMoriah Waterland 	if (tag == SML_TAG__NULL) {
188*5c51f124SMoriah Waterland 		return (tag);
189*5c51f124SMoriah Waterland 	}
190*5c51f124SMoriah Waterland 
191*5c51f124SMoriah Waterland 	/* entry debugging info */
192*5c51f124SMoriah Waterland 
193*5c51f124SMoriah Waterland 	_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_ADD_TAG,
194*5c51f124SMoriah Waterland 		a_subTag->name, tag->name);
195*5c51f124SMoriah Waterland 
196*5c51f124SMoriah Waterland 	/* if index is out of range or -1, append to tag object */
197*5c51f124SMoriah Waterland 
198*5c51f124SMoriah Waterland 	if ((a_index > tag->tags_num) || (a_index == -1)) {
199*5c51f124SMoriah Waterland 		a_index = tag->tags_num;
200*5c51f124SMoriah Waterland 	}
201*5c51f124SMoriah Waterland 
202*5c51f124SMoriah Waterland 	/* bump number of tags in tag object */
203*5c51f124SMoriah Waterland 
204*5c51f124SMoriah Waterland 	tag->tags_num++;
205*5c51f124SMoriah Waterland 
206*5c51f124SMoriah Waterland 	/* expand tag object to hold new subtag */
207*5c51f124SMoriah Waterland 
208*5c51f124SMoriah Waterland 	tag->tags = (SML_TAG *)realloc(tag->tags,
209*5c51f124SMoriah Waterland 		sizeof (SML_TAG) * tag->tags_num);
210*5c51f124SMoriah Waterland 
211*5c51f124SMoriah Waterland 	/* if not appending, adjust tag object to hold new subtag */
212*5c51f124SMoriah Waterland 
213*5c51f124SMoriah Waterland 	if (a_index < (tag->tags_num - 1)) {
214*5c51f124SMoriah Waterland 		(void) memmove(&(tag->tags[a_index + 1]), &(tag->tags[a_index]),
215*5c51f124SMoriah Waterland 			sizeof (SML_TAG) * (tag->tags_num - a_index - 1));
216*5c51f124SMoriah Waterland 	}
217*5c51f124SMoriah Waterland 
218*5c51f124SMoriah Waterland 	/* copy new subtag into correct location in tag object */
219*5c51f124SMoriah Waterland 
220*5c51f124SMoriah Waterland 	(void) memcpy(&(tag->tags[a_index]), a_subTag,
221*5c51f124SMoriah Waterland 		sizeof (SML_TAG));
222*5c51f124SMoriah Waterland 
223*5c51f124SMoriah Waterland 	return (&(tag->tags[a_index]));
224*5c51f124SMoriah Waterland }
225*5c51f124SMoriah Waterland 
226*5c51f124SMoriah Waterland /*
227*5c51f124SMoriah Waterland  * Name:	smlDelTag
228*5c51f124SMoriah Waterland  * Description:	Delete element from tag object
229*5c51f124SMoriah Waterland  * Arguments:	tag - [RO, *RW] - (SML_TAG *)
230*5c51f124SMoriah Waterland  *			The tag object to update
231*5c51f124SMoriah Waterland  *		sub_tag - [RO, *RW] - (SML_TAG *)
232*5c51f124SMoriah Waterland  *			Element to be removed from the tag object
233*5c51f124SMoriah Waterland  * Returns:	void
234*5c51f124SMoriah Waterland  *			The sub_tag is removed from the tag object
235*5c51f124SMoriah Waterland  * NOTE:	The sub-tag and all elements contained within it are deallocated
236*5c51f124SMoriah Waterland  *		the sub-tag is no longer valid when this method returns
237*5c51f124SMoriah Waterland  */
238*5c51f124SMoriah Waterland 
239*5c51f124SMoriah Waterland void
smlDelTag(SML_TAG * tag,SML_TAG * sub_tag)240*5c51f124SMoriah Waterland smlDelTag(SML_TAG *tag, SML_TAG *sub_tag)
241*5c51f124SMoriah Waterland {
242*5c51f124SMoriah Waterland 	int	index;
243*5c51f124SMoriah Waterland 
244*5c51f124SMoriah Waterland 	/* entry assertions */
245*5c51f124SMoriah Waterland 
246*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(sub_tag));
247*5c51f124SMoriah Waterland 
248*5c51f124SMoriah Waterland 	/* if no tag to update specified, ignore request */
249*5c51f124SMoriah Waterland 
250*5c51f124SMoriah Waterland 	if (tag == SML_TAG__NULL) {
251*5c51f124SMoriah Waterland 		return;
252*5c51f124SMoriah Waterland 	}
253*5c51f124SMoriah Waterland 
254*5c51f124SMoriah Waterland 	/* entry debugging info */
255*5c51f124SMoriah Waterland 
256*5c51f124SMoriah Waterland 	_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_DEL_TAG,
257*5c51f124SMoriah Waterland 		sub_tag->name, tag->name);
258*5c51f124SMoriah Waterland 
259*5c51f124SMoriah Waterland 	/* if tag object is empty, ignore request */
260*5c51f124SMoriah Waterland 
261*5c51f124SMoriah Waterland 	if (tag->tags_num == 0) {
262*5c51f124SMoriah Waterland 		return;
263*5c51f124SMoriah Waterland 	}
264*5c51f124SMoriah Waterland 
265*5c51f124SMoriah Waterland 	/* determine index into tag object of element to remove */
266*5c51f124SMoriah Waterland 	for (index = 0; index < tag->tags_num; index++) {
267*5c51f124SMoriah Waterland 		if (sub_tag == &tag->tags[index]) {
268*5c51f124SMoriah Waterland 			break;
269*5c51f124SMoriah Waterland 		}
270*5c51f124SMoriah Waterland 	}
271*5c51f124SMoriah Waterland 
272*5c51f124SMoriah Waterland 	/* if element not found in tag, ignore request */
273*5c51f124SMoriah Waterland 
274*5c51f124SMoriah Waterland 	if (index >= tag->tags_num) {
275*5c51f124SMoriah Waterland 		return;
276*5c51f124SMoriah Waterland 	}
277*5c51f124SMoriah Waterland 
278*5c51f124SMoriah Waterland 	/* free up the subtag to be deleted */
279*5c51f124SMoriah Waterland 
280*5c51f124SMoriah Waterland 	_smlFreeTag(sub_tag);
281*5c51f124SMoriah Waterland 
282*5c51f124SMoriah Waterland 	/*
283*5c51f124SMoriah Waterland 	 * if not removing last element, collapse tag object removing
284*5c51f124SMoriah Waterland 	 * target element
285*5c51f124SMoriah Waterland 	 */
286*5c51f124SMoriah Waterland 
287*5c51f124SMoriah Waterland 	if (index < (tag->tags_num - 1)) {
288*5c51f124SMoriah Waterland 		(void) memmove(&(tag->tags[index]), &(tag->tags[index + 1]),
289*5c51f124SMoriah Waterland 			sizeof (SML_TAG) *(tag->tags_num - index - 1));
290*5c51f124SMoriah Waterland 	}
291*5c51f124SMoriah Waterland 
292*5c51f124SMoriah Waterland 	/* one less tag object in tag */
293*5c51f124SMoriah Waterland 
294*5c51f124SMoriah Waterland 	tag->tags_num --;
295*5c51f124SMoriah Waterland 
296*5c51f124SMoriah Waterland 	/*
297*5c51f124SMoriah Waterland 	 * If only one tag left, then delete entire tag structure
298*5c51f124SMoriah Waterland 	 * otherwise reallocate removing unneeded entry
299*5c51f124SMoriah Waterland 	 */
300*5c51f124SMoriah Waterland 
301*5c51f124SMoriah Waterland 	if (tag->tags_num > 0) {
302*5c51f124SMoriah Waterland 		/* realloc removing last element in tag object */
303*5c51f124SMoriah Waterland 
304*5c51f124SMoriah Waterland 		tag->tags = (SML_TAG *)realloc(tag->tags,
305*5c51f124SMoriah Waterland 			sizeof (SML_TAG) *tag->tags_num);
306*5c51f124SMoriah Waterland 	} else {
307*5c51f124SMoriah Waterland 		tag->tags = SML_TAG__NULL;
308*5c51f124SMoriah Waterland 	}
309*5c51f124SMoriah Waterland }
310*5c51f124SMoriah Waterland 
311*5c51f124SMoriah Waterland /*
312*5c51f124SMoriah Waterland  * Name:	smlFreeTag
313*5c51f124SMoriah Waterland  * Description:	Free a tag object and all its contents when no longer needed
314*5c51f124SMoriah Waterland  * Arguments:	tag - [RO, *RW] - (SML_TAG *)
315*5c51f124SMoriah Waterland  *			The tag object to be deleted
316*5c51f124SMoriah Waterland  * Returns:	void
317*5c51f124SMoriah Waterland  *			The tag object and all its contents are deallocated
318*5c51f124SMoriah Waterland  */
319*5c51f124SMoriah Waterland 
320*5c51f124SMoriah Waterland void
smlFreeTag(SML_TAG * tag)321*5c51f124SMoriah Waterland smlFreeTag(SML_TAG *tag)
322*5c51f124SMoriah Waterland {
323*5c51f124SMoriah Waterland 	/* entry assertions */
324*5c51f124SMoriah Waterland 
325*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(tag));
326*5c51f124SMoriah Waterland 
327*5c51f124SMoriah Waterland 	/* entry debugging info */
328*5c51f124SMoriah Waterland 
329*5c51f124SMoriah Waterland 	if (tag->name != (char *)NULL) {
330*5c51f124SMoriah Waterland 		_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_FREE_TAG,
331*5c51f124SMoriah Waterland 			(unsigned long)tag, tag->name);
332*5c51f124SMoriah Waterland 	}
333*5c51f124SMoriah Waterland 
334*5c51f124SMoriah Waterland 	/* free the tag object contents */
335*5c51f124SMoriah Waterland 
336*5c51f124SMoriah Waterland 	_smlFreeTag(tag);
337*5c51f124SMoriah Waterland 
338*5c51f124SMoriah Waterland 	/* free the tag object handle */
339*5c51f124SMoriah Waterland 
340*5c51f124SMoriah Waterland 	bzero(tag, sizeof (SML_TAG));
341*5c51f124SMoriah Waterland 	free(tag);
342*5c51f124SMoriah Waterland }
343*5c51f124SMoriah Waterland 
344*5c51f124SMoriah Waterland /*
345*5c51f124SMoriah Waterland  * Name:	smlGetNumParams
346*5c51f124SMoriah Waterland  * Synopsis:	Get number of parameters set in tag
347*5c51f124SMoriah Waterland  * Description:	Return the number of parameters set in a tag
348*5c51f124SMoriah Waterland  * Arguments:	a_tag - [RO, *RO] - (SML_TAG *)
349*5c51f124SMoriah Waterland  *			The tag object to obtain the # params from
350*5c51f124SMoriah Waterland  * Returns:	int
351*5c51f124SMoriah Waterland  *			Number of parameters set in tag
352*5c51f124SMoriah Waterland  *			0 = no parameters are set
353*5c51f124SMoriah Waterland  */
354*5c51f124SMoriah Waterland 
355*5c51f124SMoriah Waterland int
smlGetNumParams(SML_TAG * a_tag)356*5c51f124SMoriah Waterland smlGetNumParams(SML_TAG *a_tag)
357*5c51f124SMoriah Waterland {
358*5c51f124SMoriah Waterland 	return (a_tag ? a_tag->params_num : 0);
359*5c51f124SMoriah Waterland }
360*5c51f124SMoriah Waterland 
361*5c51f124SMoriah Waterland 
362*5c51f124SMoriah Waterland /*
363*5c51f124SMoriah Waterland  * Name:	smlGetParam_r
364*5c51f124SMoriah Waterland  * Description:	Get a parameter from a tag into a buffer of fixed size
365*5c51f124SMoriah Waterland  * Arguments:	tag - [RO, *RO] - (SML_TAG *)
366*5c51f124SMoriah Waterland  *			The tag object to obtain the parameter from
367*5c51f124SMoriah Waterland  *		name - [RO, *RO] - (char *)
368*5c51f124SMoriah Waterland  *			Name of the parameter to retrieve
369*5c51f124SMoriah Waterland  *		buf - [RO, *RW] - (char *)
370*5c51f124SMoriah Waterland  *			Location of buffer to contain results
371*5c51f124SMoriah Waterland  *		bufLen - [RO, *RO] - (int)
372*5c51f124SMoriah Waterland  *			Maximum bytes available in buffer to contain results
373*5c51f124SMoriah Waterland  * Returns:	void
374*5c51f124SMoriah Waterland  */
375*5c51f124SMoriah Waterland 
376*5c51f124SMoriah Waterland void
smlGetParam_r(SML_TAG * tag,char * name,char * buf,int bufLen)377*5c51f124SMoriah Waterland smlGetParam_r(SML_TAG *tag, char *name, char *buf, int bufLen)
378*5c51f124SMoriah Waterland {
379*5c51f124SMoriah Waterland 	int	k;
380*5c51f124SMoriah Waterland 
381*5c51f124SMoriah Waterland 	/* entry assertions */
382*5c51f124SMoriah Waterland 
383*5c51f124SMoriah Waterland 	assert(name != (char *)NULL);
384*5c51f124SMoriah Waterland 	assert(*name != '\0');
385*5c51f124SMoriah Waterland 	assert(buf != (char *)NULL);
386*5c51f124SMoriah Waterland 	assert(bufLen > 0);
387*5c51f124SMoriah Waterland 
388*5c51f124SMoriah Waterland 	/* terminate the buffer */
389*5c51f124SMoriah Waterland 
390*5c51f124SMoriah Waterland 	buf[0] = '\0';
391*5c51f124SMoriah Waterland 	buf[bufLen-1] = '\0';
392*5c51f124SMoriah Waterland 
393*5c51f124SMoriah Waterland 	bzero(buf, bufLen);
394*5c51f124SMoriah Waterland 
395*5c51f124SMoriah Waterland 	/* if no tag specified, return NULL */
396*5c51f124SMoriah Waterland 
397*5c51f124SMoriah Waterland 	if (tag == SML_TAG__NULL) {
398*5c51f124SMoriah Waterland 		return;
399*5c51f124SMoriah Waterland 	}
400*5c51f124SMoriah Waterland 
401*5c51f124SMoriah Waterland 	/* if no parameters in tag, return NULL */
402*5c51f124SMoriah Waterland 
403*5c51f124SMoriah Waterland 	if (tag->params == NULL) {
404*5c51f124SMoriah Waterland 		return;
405*5c51f124SMoriah Waterland 	}
406*5c51f124SMoriah Waterland 
407*5c51f124SMoriah Waterland 	/* entry debugging info */
408*5c51f124SMoriah Waterland 
409*5c51f124SMoriah Waterland 	_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_GET_PARAM,
410*5c51f124SMoriah Waterland 		name, tag->name);
411*5c51f124SMoriah Waterland 
412*5c51f124SMoriah Waterland 	/* scan tag object looking for specified parameter */
413*5c51f124SMoriah Waterland 
414*5c51f124SMoriah Waterland 	for (k = 0; k < tag->params_num; k++) {
415*5c51f124SMoriah Waterland 		assert(tag->params[k].name != (char *)NULL);
416*5c51f124SMoriah Waterland 		assert(tag->params[k].value != (char *)NULL);
417*5c51f124SMoriah Waterland 		if (streq(tag->params[k].name, name)) {
418*5c51f124SMoriah Waterland 			_smlLogMsg(LOG_MSG_DEBUG,
419*5c51f124SMoriah Waterland 				DBG_SML_GOT_PARAM,
420*5c51f124SMoriah Waterland 				tag->name, name, tag->params[k].value);
421*5c51f124SMoriah Waterland 			(void) strncpy(buf, tag->params[k].value, bufLen-1);
422*5c51f124SMoriah Waterland 			return;
423*5c51f124SMoriah Waterland 		}
424*5c51f124SMoriah Waterland 	}
425*5c51f124SMoriah Waterland 
426*5c51f124SMoriah Waterland 	/* parameter not found - return */
427*5c51f124SMoriah Waterland }
428*5c51f124SMoriah Waterland 
429*5c51f124SMoriah Waterland /*
430*5c51f124SMoriah Waterland  * Name:	smlGetParam
431*5c51f124SMoriah Waterland  * Description:	Get a parameter from a tag
432*5c51f124SMoriah Waterland  * Arguments:	tag - [RO, *RO] - (SML_TAG *)
433*5c51f124SMoriah Waterland  *			The tag object to obtain the parameter from
434*5c51f124SMoriah Waterland  *		name - [RO, *RO] - (char *)
435*5c51f124SMoriah Waterland  *			Name of the parameter to retrieve
436*5c51f124SMoriah Waterland  * Returns:	char *
437*5c51f124SMoriah Waterland  *			Value of the specified parameter
438*5c51f124SMoriah Waterland  *			== (char *)NULL if the parameter does not exist
439*5c51f124SMoriah Waterland  * NOTE:    	Any parameter returned is placed in new storage for the
440*5c51f124SMoriah Waterland  *		calling method. The caller must use 'free' to dispose
441*5c51f124SMoriah Waterland  *		of the storage once the parameter is no longer needed.
442*5c51f124SMoriah Waterland  */
443*5c51f124SMoriah Waterland 
444*5c51f124SMoriah Waterland char *
smlGetParam(SML_TAG * tag,char * name)445*5c51f124SMoriah Waterland smlGetParam(SML_TAG *tag, char *name)
446*5c51f124SMoriah Waterland {
447*5c51f124SMoriah Waterland 	int	k;
448*5c51f124SMoriah Waterland 
449*5c51f124SMoriah Waterland 	/* entry assertions */
450*5c51f124SMoriah Waterland 
451*5c51f124SMoriah Waterland 	assert(name != (char *)NULL);
452*5c51f124SMoriah Waterland 	assert(*name != '\0');
453*5c51f124SMoriah Waterland 
454*5c51f124SMoriah Waterland 	/* entry debugging info */
455*5c51f124SMoriah Waterland 
456*5c51f124SMoriah Waterland 	_smlLogMsg(LOG_MSG_DEBUG, "get param param <%s>", name);
457*5c51f124SMoriah Waterland 
458*5c51f124SMoriah Waterland 	/* if no tag specified, return NULL */
459*5c51f124SMoriah Waterland 
460*5c51f124SMoriah Waterland 	if (tag == SML_TAG__NULL) {
461*5c51f124SMoriah Waterland 		return ((char *)NULL);
462*5c51f124SMoriah Waterland 	}
463*5c51f124SMoriah Waterland 
464*5c51f124SMoriah Waterland 	/* if no parameters in tag, return NULL */
465*5c51f124SMoriah Waterland 
466*5c51f124SMoriah Waterland 	if (tag->params == NULL) {
467*5c51f124SMoriah Waterland 		return ((char *)NULL);
468*5c51f124SMoriah Waterland 	}
469*5c51f124SMoriah Waterland 
470*5c51f124SMoriah Waterland 	/* entry debugging info */
471*5c51f124SMoriah Waterland 
472*5c51f124SMoriah Waterland 	_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_GET_PARAM,
473*5c51f124SMoriah Waterland 		name, tag->name);
474*5c51f124SMoriah Waterland 
475*5c51f124SMoriah Waterland 	/* scan tag object looking for specified parameter */
476*5c51f124SMoriah Waterland 
477*5c51f124SMoriah Waterland 	for (k = 0; k < tag->params_num; k++) {
478*5c51f124SMoriah Waterland 		assert(tag->params[k].name != (char *)NULL);
479*5c51f124SMoriah Waterland 		assert(tag->params[k].value != (char *)NULL);
480*5c51f124SMoriah Waterland 		if (streq(tag->params[k].name, name)) {
481*5c51f124SMoriah Waterland 			_smlLogMsg(LOG_MSG_DEBUG,
482*5c51f124SMoriah Waterland 				DBG_SML_GOT_PARAM,
483*5c51f124SMoriah Waterland 				tag->name, name, tag->params[k].value);
484*5c51f124SMoriah Waterland 			return (strdup(tag->params[k].value));
485*5c51f124SMoriah Waterland 		}
486*5c51f124SMoriah Waterland 	}
487*5c51f124SMoriah Waterland 
488*5c51f124SMoriah Waterland 	/* parameter not found - return NULL */
489*5c51f124SMoriah Waterland 
490*5c51f124SMoriah Waterland 	return ((char *)NULL);
491*5c51f124SMoriah Waterland }
492*5c51f124SMoriah Waterland 
493*5c51f124SMoriah Waterland /*
494*5c51f124SMoriah Waterland  * Name:	smlGetParamName
495*5c51f124SMoriah Waterland  * Description:	Get the name of a tag parameter given its index
496*5c51f124SMoriah Waterland  * Arguments:	tag - [RO, *RO] - (SML_TAG *)
497*5c51f124SMoriah Waterland  *			The tag object to obtain the parameter name from
498*5c51f124SMoriah Waterland  *		index - [RO] - (int)
499*5c51f124SMoriah Waterland  *			Index of parameter name to return
500*5c51f124SMoriah Waterland  * Returns:	char *
501*5c51f124SMoriah Waterland  *			Name of 'index'th parameter
502*5c51f124SMoriah Waterland  *			== (char *)NULL if no such parameter exists in tag
503*5c51f124SMoriah Waterland  * NOTE:    	Any parameter name returned is placed in new storage for the
504*5c51f124SMoriah Waterland  *		calling method. The caller must use 'free' to dispose
505*5c51f124SMoriah Waterland  *		of the storage once the parameter name is no longer needed.
506*5c51f124SMoriah Waterland  */
507*5c51f124SMoriah Waterland 
508*5c51f124SMoriah Waterland char *
smlGetParamName(SML_TAG * tag,int index)509*5c51f124SMoriah Waterland smlGetParamName(SML_TAG *tag, int index)
510*5c51f124SMoriah Waterland {
511*5c51f124SMoriah Waterland 	/* if no tag specified, return NULL */
512*5c51f124SMoriah Waterland 
513*5c51f124SMoriah Waterland 	if (tag == NULL) {
514*5c51f124SMoriah Waterland 		return ((char *)NULL);
515*5c51f124SMoriah Waterland 	}
516*5c51f124SMoriah Waterland 
517*5c51f124SMoriah Waterland 	/* entry debugging info */
518*5c51f124SMoriah Waterland 
519*5c51f124SMoriah Waterland 	_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_GET_PARAM_NAME,
520*5c51f124SMoriah Waterland 		tag->name, index);
521*5c51f124SMoriah Waterland 
522*5c51f124SMoriah Waterland 	/* if no parameters in tag, return NULL */
523*5c51f124SMoriah Waterland 
524*5c51f124SMoriah Waterland 	if (tag->params == NULL) {
525*5c51f124SMoriah Waterland 		return ((char *)NULL);
526*5c51f124SMoriah Waterland 	}
527*5c51f124SMoriah Waterland 
528*5c51f124SMoriah Waterland 	/* if index not within range, return NULL */
529*5c51f124SMoriah Waterland 
530*5c51f124SMoriah Waterland 	if (index >= tag->params_num) {
531*5c51f124SMoriah Waterland 		return ((char *)NULL);
532*5c51f124SMoriah Waterland 	}
533*5c51f124SMoriah Waterland 
534*5c51f124SMoriah Waterland 	/* index within range - return parameter name */
535*5c51f124SMoriah Waterland 
536*5c51f124SMoriah Waterland 	assert(tag->params[index].name != (char *)NULL);
537*5c51f124SMoriah Waterland 	assert(tag->params[index].value != (char *)NULL);
538*5c51f124SMoriah Waterland 
539*5c51f124SMoriah Waterland 	_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_GOT_PARAM_NAME,
540*5c51f124SMoriah Waterland 		tag->name, index, tag->params[index].name);
541*5c51f124SMoriah Waterland 
542*5c51f124SMoriah Waterland 	return (strdup(tag->params[index].name));
543*5c51f124SMoriah Waterland }
544*5c51f124SMoriah Waterland 
545*5c51f124SMoriah Waterland /*
546*5c51f124SMoriah Waterland  * Name:	smlGetParamByTag
547*5c51f124SMoriah Waterland  * Synopsis:	Get a parameter value from a tag by name and index
548*5c51f124SMoriah Waterland  * Description:	Call to look for a parameter value from a tag with
549*5c51f124SMoriah Waterland  *		a given name with a parameter of a given name
550*5c51f124SMoriah Waterland  * Arguments:	tag - [RO, *RO] - (SML_TAG *)
551*5c51f124SMoriah Waterland  *			The tag object to obtain the parameter
552*5c51f124SMoriah Waterland  *		index - [RO] - (int)
553*5c51f124SMoriah Waterland  *			Index of nth tag by name to look for
554*5c51f124SMoriah Waterland  *		tagName - [RO, *RO] - (char *)
555*5c51f124SMoriah Waterland  *			Name of tag to look for
556*5c51f124SMoriah Waterland  *		paramName - [RO, *RO] - (char *)
557*5c51f124SMoriah Waterland  *			Name of parameter to return value of
558*5c51f124SMoriah Waterland  * Returns:	char *
559*5c51f124SMoriah Waterland  *			== (char *)NULL - no parameter value set
560*5c51f124SMoriah Waterland  *			!= (char *)NULL - value of parameter set
561*5c51f124SMoriah Waterland  */
562*5c51f124SMoriah Waterland 
563*5c51f124SMoriah Waterland char *
smlGetParamByTag(SML_TAG * tag,int index,char * tagName,char * paramName)564*5c51f124SMoriah Waterland smlGetParamByTag(SML_TAG *tag, int index,
565*5c51f124SMoriah Waterland 	char *tagName, char *paramName)
566*5c51f124SMoriah Waterland {
567*5c51f124SMoriah Waterland 	SML_TAG	*rtag;
568*5c51f124SMoriah Waterland 
569*5c51f124SMoriah Waterland 	/* entry assertions */
570*5c51f124SMoriah Waterland 
571*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(tag));
572*5c51f124SMoriah Waterland 	assert(tagName != (char *)NULL);
573*5c51f124SMoriah Waterland 	assert(*tagName != '\0');
574*5c51f124SMoriah Waterland 	assert(paramName != (char *)NULL);
575*5c51f124SMoriah Waterland 	assert(*paramName != '\0');
576*5c51f124SMoriah Waterland 
577*5c51f124SMoriah Waterland 	/* entry debugging info */
578*5c51f124SMoriah Waterland 
579*5c51f124SMoriah Waterland 	_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_GET_PARAM_BY_TAG,
580*5c51f124SMoriah Waterland 		tagName, index, paramName);
581*5c51f124SMoriah Waterland 
582*5c51f124SMoriah Waterland 	/* find the requested tag by name  and index */
583*5c51f124SMoriah Waterland 
584*5c51f124SMoriah Waterland 	rtag = smlGetTagByName(tag, index, tagName);
585*5c51f124SMoriah Waterland 	if (rtag == SML_TAG__NULL) {
586*5c51f124SMoriah Waterland 		return ((char *)NULL);
587*5c51f124SMoriah Waterland 	}
588*5c51f124SMoriah Waterland 
589*5c51f124SMoriah Waterland 	return (smlGetParam(rtag, paramName));
590*5c51f124SMoriah Waterland }
591*5c51f124SMoriah Waterland 
592*5c51f124SMoriah Waterland /*
593*5c51f124SMoriah Waterland  * Name:	smlGetTagByTagParam
594*5c51f124SMoriah Waterland  * Synopsis:	Get element given tag name, index, parameter name, and value
595*5c51f124SMoriah Waterland  * Description:	Call to look for a tag with a given nae, that has a parameter
596*5c51f124SMoriah Waterland  *		of a given name with a specified value
597*5c51f124SMoriah Waterland  * Arguments:	tag - [RO, *RO] - (SML_TAG *)
598*5c51f124SMoriah Waterland  *			The tag object to obtain the element from
599*5c51f124SMoriah Waterland  *		index - [RO] - (int)
600*5c51f124SMoriah Waterland  *			Index of nth name to return
601*5c51f124SMoriah Waterland  *		tagName - [RO, *RO] - (char *)
602*5c51f124SMoriah Waterland  *			Tag name to look up
603*5c51f124SMoriah Waterland  *		paramName - [RO, *RO] - (char *)
604*5c51f124SMoriah Waterland  *			Parameter name to look up
605*5c51f124SMoriah Waterland  *		paramValue - [RO, *RO] - (char *)
606*5c51f124SMoriah Waterland  *			Parameter value to match
607*5c51f124SMoriah Waterland  * Returns:	SML_TAG *
608*5c51f124SMoriah Waterland  *			The 'index'th occurance of element 'name' with
609*5c51f124SMoriah Waterland  *			a parameter 'name' with value specified
610*5c51f124SMoriah Waterland  *			== SML_TAG__NULL if no such element exists
611*5c51f124SMoriah Waterland  */
612*5c51f124SMoriah Waterland 
613*5c51f124SMoriah Waterland SML_TAG *
smlGetTagByTagParam(SML_TAG * tag,int index,char * tagName,char * paramName,char * paramValue)614*5c51f124SMoriah Waterland smlGetTagByTagParam(SML_TAG *tag, int index,
615*5c51f124SMoriah Waterland 	char *tagName, char *paramName, char *paramValue)
616*5c51f124SMoriah Waterland {
617*5c51f124SMoriah Waterland 	int		ti;		/* tag structure index */
618*5c51f124SMoriah Waterland 
619*5c51f124SMoriah Waterland 	/* entry assertions */
620*5c51f124SMoriah Waterland 
621*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(tag));
622*5c51f124SMoriah Waterland 	assert(tagName != (char *)NULL);
623*5c51f124SMoriah Waterland 	assert(*tagName != '\0');
624*5c51f124SMoriah Waterland 	assert(paramName != (char *)NULL);
625*5c51f124SMoriah Waterland 	assert(*paramName != '\0');
626*5c51f124SMoriah Waterland 	assert(paramValue != (char *)NULL);
627*5c51f124SMoriah Waterland 	assert(*paramValue != '\0');
628*5c51f124SMoriah Waterland 
629*5c51f124SMoriah Waterland 	/* if tag has no elements, return NULL */
630*5c51f124SMoriah Waterland 
631*5c51f124SMoriah Waterland 	if (tag->tags == NULL) {
632*5c51f124SMoriah Waterland 		return (SML_TAG__NULL);
633*5c51f124SMoriah Waterland 	}
634*5c51f124SMoriah Waterland 
635*5c51f124SMoriah Waterland 	/*
636*5c51f124SMoriah Waterland 	 * Search algorithm:
637*5c51f124SMoriah Waterland 	 *  -> search tag structure; for each tag with element == "tagName":
638*5c51f124SMoriah Waterland 	 *  -> search tag parameters; if parameter name == "paramName"
639*5c51f124SMoriah Waterland 	 *  -> if parameter value != "paramValue"; to next tag
640*5c51f124SMoriah Waterland 	 *  -> if parameter value == "paramValue":
641*5c51f124SMoriah Waterland 	 *  -> if not the "index"th paramValue found; to next tag
642*5c51f124SMoriah Waterland 	 *  -> return tag found
643*5c51f124SMoriah Waterland 	 */
644*5c51f124SMoriah Waterland 
645*5c51f124SMoriah Waterland 	for (ti = 0; ti < tag->tags_num; ti++) {
646*5c51f124SMoriah Waterland 		int	pi;	/* parameter structure index */
647*5c51f124SMoriah Waterland 
648*5c51f124SMoriah Waterland 		/* if tag element does not match, go on to next tag */
649*5c51f124SMoriah Waterland 
650*5c51f124SMoriah Waterland 		if (strcmp(tag->tags[ti].name, tagName)) {
651*5c51f124SMoriah Waterland 			continue;
652*5c51f124SMoriah Waterland 		}
653*5c51f124SMoriah Waterland 
654*5c51f124SMoriah Waterland 		/* element matches: search for specified parameter name/value */
655*5c51f124SMoriah Waterland 
656*5c51f124SMoriah Waterland 		for (pi = 0; pi < tag->tags[ti].params_num; pi++) {
657*5c51f124SMoriah Waterland 			assert(tag->tags[ti].params[pi].name != (char *)NULL);
658*5c51f124SMoriah Waterland 			assert(tag->tags[ti].params[pi].value != (char *)NULL);
659*5c51f124SMoriah Waterland 
660*5c51f124SMoriah Waterland 			/* if parameter name doesnt match to next parameter */
661*5c51f124SMoriah Waterland 
662*5c51f124SMoriah Waterland 			if (strcmp(tag->tags[ti].params[pi].name, paramName)) {
663*5c51f124SMoriah Waterland 				continue;
664*5c51f124SMoriah Waterland 			}
665*5c51f124SMoriah Waterland 
666*5c51f124SMoriah Waterland 			/* if parameter value doesnt match to next tag */
667*5c51f124SMoriah Waterland 
668*5c51f124SMoriah Waterland 			if (strcmp(tag->tags[ti].params[pi].value,
669*5c51f124SMoriah Waterland 				paramValue)) {
670*5c51f124SMoriah Waterland 				break;
671*5c51f124SMoriah Waterland 			}
672*5c51f124SMoriah Waterland 
673*5c51f124SMoriah Waterland 			/*
674*5c51f124SMoriah Waterland 			 * found element/paramname/paramvalue:
675*5c51f124SMoriah Waterland 			 * -> if this is not the 'index'th one, go to next tag
676*5c51f124SMoriah Waterland 			 */
677*5c51f124SMoriah Waterland 
678*5c51f124SMoriah Waterland 			if (index-- != 0) {
679*5c51f124SMoriah Waterland 				break;
680*5c51f124SMoriah Waterland 			}
681*5c51f124SMoriah Waterland 
682*5c51f124SMoriah Waterland 			/*
683*5c51f124SMoriah Waterland 			 * found specified element/paramname/paramvalue:
684*5c51f124SMoriah Waterland 			 * -> return the tag found
685*5c51f124SMoriah Waterland 			 */
686*5c51f124SMoriah Waterland 
687*5c51f124SMoriah Waterland 			return (&tag->tags[ti]);
688*5c51f124SMoriah Waterland 		}
689*5c51f124SMoriah Waterland 
690*5c51f124SMoriah Waterland 	}
691*5c51f124SMoriah Waterland 
692*5c51f124SMoriah Waterland 	/* no such element found - return NULL */
693*5c51f124SMoriah Waterland 
694*5c51f124SMoriah Waterland 	return (SML_TAG__NULL);
695*5c51f124SMoriah Waterland }
696*5c51f124SMoriah Waterland 
697*5c51f124SMoriah Waterland /*
698*5c51f124SMoriah Waterland  * Name:	smlGetParamByTagParam
699*5c51f124SMoriah Waterland  * Synopsis:	Get parameter given tag name, index, parameter name, and value
700*5c51f124SMoriah Waterland  * Description:	Call to return the value of a parameter from a tag of a
701*5c51f124SMoriah Waterland  *		given name, with a parameter of a given name with a
702*5c51f124SMoriah Waterland  *		specified value
703*5c51f124SMoriah Waterland  * Arguments:	tag - [RO, *RO] - (SML_TAG *)
704*5c51f124SMoriah Waterland  *			The tag object to obtain the element from
705*5c51f124SMoriah Waterland  *		index - [RO] - (int)
706*5c51f124SMoriah Waterland  *			Index of nth name to return
707*5c51f124SMoriah Waterland  *		tagName - [RO, *RO] - (char *)
708*5c51f124SMoriah Waterland  *			Tag name to look up
709*5c51f124SMoriah Waterland  *		paramName - [RO, *RO] - (char *)
710*5c51f124SMoriah Waterland  *			Parameter name to look up
711*5c51f124SMoriah Waterland  *		paramValue - [RO, *RO] - (char *)
712*5c51f124SMoriah Waterland  *			Parameter value to match
713*5c51f124SMoriah Waterland  *		paramReturn - [RO, *RO] - (char *)
714*5c51f124SMoriah Waterland  *			Parameter name to return the value of
715*5c51f124SMoriah Waterland  * Returns:	char *
716*5c51f124SMoriah Waterland  *			The value of parameter 'paramReturn' from the
717*5c51f124SMoriah Waterland  *			The 'index'th occurance of element 'name' with
718*5c51f124SMoriah Waterland  *			a parameter 'name' with value specified
719*5c51f124SMoriah Waterland  *			== (char *)NULL if no such parameter exists
720*5c51f124SMoriah Waterland  */
721*5c51f124SMoriah Waterland 
722*5c51f124SMoriah Waterland char *
smlGetParamByTagParam(SML_TAG * tag,int index,char * tagName,char * paramName,char * paramValue,char * paramReturn)723*5c51f124SMoriah Waterland smlGetParamByTagParam(SML_TAG *tag, int index,
724*5c51f124SMoriah Waterland 	char *tagName, char *paramName, char *paramValue, char *paramReturn)
725*5c51f124SMoriah Waterland {
726*5c51f124SMoriah Waterland 	int		ti;		/* tag structure index */
727*5c51f124SMoriah Waterland 
728*5c51f124SMoriah Waterland 	/* entry assertions */
729*5c51f124SMoriah Waterland 
730*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(tag));
731*5c51f124SMoriah Waterland 	assert(tagName != (char *)NULL);
732*5c51f124SMoriah Waterland 	assert(*tagName != '\0');
733*5c51f124SMoriah Waterland 	assert(paramName != (char *)NULL);
734*5c51f124SMoriah Waterland 	assert(*paramName != '\0');
735*5c51f124SMoriah Waterland 	assert(paramValue != (char *)NULL);
736*5c51f124SMoriah Waterland 	assert(*paramValue != '\0');
737*5c51f124SMoriah Waterland 	assert(paramReturn != (char *)NULL);
738*5c51f124SMoriah Waterland 	assert(*paramReturn != '\0');
739*5c51f124SMoriah Waterland 
740*5c51f124SMoriah Waterland 	/* if tag has no elements, return NULL */
741*5c51f124SMoriah Waterland 
742*5c51f124SMoriah Waterland 	if (tag->tags == NULL) {
743*5c51f124SMoriah Waterland 		return ((char *)NULL);
744*5c51f124SMoriah Waterland 	}
745*5c51f124SMoriah Waterland 
746*5c51f124SMoriah Waterland 	/*
747*5c51f124SMoriah Waterland 	 * Search algorithm:
748*5c51f124SMoriah Waterland 	 *  -> search tag structure; for each tag with element == "tagName":
749*5c51f124SMoriah Waterland 	 *  -> search tag parameters; if parameter name == "paramName"
750*5c51f124SMoriah Waterland 	 *  -> if parameter value != "paramValue"; to next tag
751*5c51f124SMoriah Waterland 	 *  -> if parameter value == "paramValue":
752*5c51f124SMoriah Waterland 	 *  -> if not the "index"th paramValue found; to next tag
753*5c51f124SMoriah Waterland 	 *  -> return value of "paramReturn"
754*5c51f124SMoriah Waterland 	 */
755*5c51f124SMoriah Waterland 
756*5c51f124SMoriah Waterland 	for (ti = 0; ti < tag->tags_num; ti++) {
757*5c51f124SMoriah Waterland 		int	pi;	/* parameter structure index */
758*5c51f124SMoriah Waterland 
759*5c51f124SMoriah Waterland 		/* if tag element does not match, go on to next tag */
760*5c51f124SMoriah Waterland 
761*5c51f124SMoriah Waterland 		if (strcmp(tag->tags[ti].name, tagName)) {
762*5c51f124SMoriah Waterland 			continue;
763*5c51f124SMoriah Waterland 		}
764*5c51f124SMoriah Waterland 
765*5c51f124SMoriah Waterland 		/* element matches: search for specified parameter name/value */
766*5c51f124SMoriah Waterland 
767*5c51f124SMoriah Waterland 		for (pi = 0; pi < tag->tags[ti].params_num; pi++) {
768*5c51f124SMoriah Waterland 			assert(tag->tags[ti].params[pi].name != (char *)NULL);
769*5c51f124SMoriah Waterland 			assert(tag->tags[ti].params[pi].value != (char *)NULL);
770*5c51f124SMoriah Waterland 
771*5c51f124SMoriah Waterland 			/* if parameter name doesnt match to next parameter */
772*5c51f124SMoriah Waterland 
773*5c51f124SMoriah Waterland 			if (strcmp(tag->tags[ti].params[pi].name, paramName)) {
774*5c51f124SMoriah Waterland 				continue;
775*5c51f124SMoriah Waterland 			}
776*5c51f124SMoriah Waterland 
777*5c51f124SMoriah Waterland 			/* if parameter value doesnt match to next tag */
778*5c51f124SMoriah Waterland 
779*5c51f124SMoriah Waterland 			if (strcmp(tag->tags[ti].params[pi].value,
780*5c51f124SMoriah Waterland 				paramValue)) {
781*5c51f124SMoriah Waterland 				break;
782*5c51f124SMoriah Waterland 			}
783*5c51f124SMoriah Waterland 
784*5c51f124SMoriah Waterland 			/*
785*5c51f124SMoriah Waterland 			 * found element/paramname/paramvalue:
786*5c51f124SMoriah Waterland 			 * -> if this is not the 'index'th one, go to next tag
787*5c51f124SMoriah Waterland 			 */
788*5c51f124SMoriah Waterland 
789*5c51f124SMoriah Waterland 			if (index-- != 0) {
790*5c51f124SMoriah Waterland 				break;
791*5c51f124SMoriah Waterland 			}
792*5c51f124SMoriah Waterland 
793*5c51f124SMoriah Waterland 			/*
794*5c51f124SMoriah Waterland 			 * found specified element/paramname/paramvalue:
795*5c51f124SMoriah Waterland 			 * -> return parameter requested
796*5c51f124SMoriah Waterland 			 */
797*5c51f124SMoriah Waterland 
798*5c51f124SMoriah Waterland 			return (smlGetParam(&tag->tags[ti], paramReturn));
799*5c51f124SMoriah Waterland 		}
800*5c51f124SMoriah Waterland 
801*5c51f124SMoriah Waterland 	}
802*5c51f124SMoriah Waterland 
803*5c51f124SMoriah Waterland 	/* no such element found - return NULL */
804*5c51f124SMoriah Waterland 
805*5c51f124SMoriah Waterland 	return ((char *)NULL);
806*5c51f124SMoriah Waterland }
807*5c51f124SMoriah Waterland 
808*5c51f124SMoriah Waterland /*
809*5c51f124SMoriah Waterland  * Name:	smlGetElementName
810*5c51f124SMoriah Waterland  * Description:	Return the name of a given tag
811*5c51f124SMoriah Waterland  * Arguments:	a_tag - [RO, *RO] - (SML_TAG *)
812*5c51f124SMoriah Waterland  *			The tag object to obtain the element name from
813*5c51f124SMoriah Waterland  * Returns:	char *
814*5c51f124SMoriah Waterland  *			Value of name of specified tag
815*5c51f124SMoriah Waterland  * NOTE:    	Any name string returned is placed in new storage for the
816*5c51f124SMoriah Waterland  *		calling method. The caller must use 'free' to dispose
817*5c51f124SMoriah Waterland  *		of the storage once the name string is no longer needed.
818*5c51f124SMoriah Waterland  */
819*5c51f124SMoriah Waterland 
820*5c51f124SMoriah Waterland char *
smlGetElementName(SML_TAG * a_tag)821*5c51f124SMoriah Waterland smlGetElementName(SML_TAG *a_tag)
822*5c51f124SMoriah Waterland {
823*5c51f124SMoriah Waterland 	/* entry assertions */
824*5c51f124SMoriah Waterland 
825*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(a_tag));
826*5c51f124SMoriah Waterland 	assert(a_tag->name != (char *)NULL);
827*5c51f124SMoriah Waterland 	assert(*a_tag->name != '\0');
828*5c51f124SMoriah Waterland 
829*5c51f124SMoriah Waterland 	/* return the tag name */
830*5c51f124SMoriah Waterland 
831*5c51f124SMoriah Waterland 	return (strdup(a_tag->name));
832*5c51f124SMoriah Waterland }
833*5c51f124SMoriah Waterland 
834*5c51f124SMoriah Waterland /*
835*5c51f124SMoriah Waterland  * Name:	smlGetTag
836*5c51f124SMoriah Waterland  * Description:	Get an element from a tag
837*5c51f124SMoriah Waterland  * Arguments:	tag - [RO, *RO] - (SML_TAG *)
838*5c51f124SMoriah Waterland  *			The tag object to obtain the element from
839*5c51f124SMoriah Waterland  *		index - [RO] - (int)
840*5c51f124SMoriah Waterland  *			Index of element to return
841*5c51f124SMoriah Waterland  * Returns:	SML_TAG *
842*5c51f124SMoriah Waterland  *			The 'index'th element from the specified tag
843*5c51f124SMoriah Waterland  *			== SML_TAG__NULL if no such tag or element
844*5c51f124SMoriah Waterland  */
845*5c51f124SMoriah Waterland 
846*5c51f124SMoriah Waterland SML_TAG *
smlGetTag(SML_TAG * tag,int index)847*5c51f124SMoriah Waterland smlGetTag(SML_TAG *tag, int index)
848*5c51f124SMoriah Waterland {
849*5c51f124SMoriah Waterland 	/* if no tag specified, return NULL */
850*5c51f124SMoriah Waterland 
851*5c51f124SMoriah Waterland 	if (tag == NULL) {
852*5c51f124SMoriah Waterland 		return (SML_TAG__NULL);
853*5c51f124SMoriah Waterland 	}
854*5c51f124SMoriah Waterland 
855*5c51f124SMoriah Waterland 	/* if tag has no elements, return NULL */
856*5c51f124SMoriah Waterland 
857*5c51f124SMoriah Waterland 	if (tag->tags == NULL) {
858*5c51f124SMoriah Waterland 		return (SML_TAG__NULL);
859*5c51f124SMoriah Waterland 	}
860*5c51f124SMoriah Waterland 
861*5c51f124SMoriah Waterland 	/* if index not within range, return NULL */
862*5c51f124SMoriah Waterland 
863*5c51f124SMoriah Waterland 	if (tag->tags_num <= index) {
864*5c51f124SMoriah Waterland 		return (SML_TAG__NULL);
865*5c51f124SMoriah Waterland 	}
866*5c51f124SMoriah Waterland 
867*5c51f124SMoriah Waterland 	/* index within range, return element specified */
868*5c51f124SMoriah Waterland 
869*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(&tag->tags[index]));
870*5c51f124SMoriah Waterland 
871*5c51f124SMoriah Waterland 	return (&tag->tags[index]);
872*5c51f124SMoriah Waterland }
873*5c51f124SMoriah Waterland 
874*5c51f124SMoriah Waterland /*
875*5c51f124SMoriah Waterland  * Name:	smlGetTagByName
876*5c51f124SMoriah Waterland  * Description:	Get an element given a name and an index
877*5c51f124SMoriah Waterland  * Arguments:	tag - [RO, *RO] - (SML_TAG *)
878*5c51f124SMoriah Waterland  *			The tag object to obtain the element from
879*5c51f124SMoriah Waterland  *		index - [RO] - (int)
880*5c51f124SMoriah Waterland  *			Index of nth name to return
881*5c51f124SMoriah Waterland  *		name - [RO, *RO] - (char *)
882*5c51f124SMoriah Waterland  *			Tag name to look up
883*5c51f124SMoriah Waterland  * Returns:	SML_TAG *
884*5c51f124SMoriah Waterland  *			The 'index'th occurance of element 'name'
885*5c51f124SMoriah Waterland  *			== SML_TAG__NULL if no such element exists
886*5c51f124SMoriah Waterland  */
887*5c51f124SMoriah Waterland 
888*5c51f124SMoriah Waterland SML_TAG *
smlGetTagByName(SML_TAG * tag,int index,char * name)889*5c51f124SMoriah Waterland smlGetTagByName(SML_TAG *tag, int index, char *name)
890*5c51f124SMoriah Waterland {
891*5c51f124SMoriah Waterland 	int k;
892*5c51f124SMoriah Waterland 
893*5c51f124SMoriah Waterland 	_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_GET_TAG_BY_NAME, name, index);
894*5c51f124SMoriah Waterland 
895*5c51f124SMoriah Waterland 	/* if no tag specified, return NULL */
896*5c51f124SMoriah Waterland 
897*5c51f124SMoriah Waterland 	if (tag == NULL) {
898*5c51f124SMoriah Waterland 		return (SML_TAG__NULL);
899*5c51f124SMoriah Waterland 	}
900*5c51f124SMoriah Waterland 
901*5c51f124SMoriah Waterland 	/* if this tag is the one mentioned, return it */
902*5c51f124SMoriah Waterland 
903*5c51f124SMoriah Waterland 	if (streq(tag->name, name) && (index == 0)) {
904*5c51f124SMoriah Waterland 		return (tag);
905*5c51f124SMoriah Waterland 	}
906*5c51f124SMoriah Waterland 
907*5c51f124SMoriah Waterland 	/* if tag has no elements, return NULL */
908*5c51f124SMoriah Waterland 
909*5c51f124SMoriah Waterland 	if (tag->tags == NULL) {
910*5c51f124SMoriah Waterland 		return (SML_TAG__NULL);
911*5c51f124SMoriah Waterland 	}
912*5c51f124SMoriah Waterland 
913*5c51f124SMoriah Waterland 	/* if index out of range, return NULL */
914*5c51f124SMoriah Waterland 
915*5c51f124SMoriah Waterland 	if (tag->tags_num <= index) {
916*5c51f124SMoriah Waterland 		return (SML_TAG__NULL);
917*5c51f124SMoriah Waterland 	}
918*5c51f124SMoriah Waterland 
919*5c51f124SMoriah Waterland 	/* index within range - search for specified element */
920*5c51f124SMoriah Waterland 
921*5c51f124SMoriah Waterland 	for (k = 0; k < tag->tags_num; k++) {
922*5c51f124SMoriah Waterland 		if (streq(tag->tags[k].name, name)) {
923*5c51f124SMoriah Waterland 			if (index == 0) {
924*5c51f124SMoriah Waterland 				assert(SML_TAG__ISVALID(&tag->tags[k]));
925*5c51f124SMoriah Waterland 				return (&tag->tags[k]);
926*5c51f124SMoriah Waterland 			} else {
927*5c51f124SMoriah Waterland 				index--;
928*5c51f124SMoriah Waterland 			}
929*5c51f124SMoriah Waterland 		}
930*5c51f124SMoriah Waterland 	}
931*5c51f124SMoriah Waterland 
932*5c51f124SMoriah Waterland 	/* no such element found - return NULL */
933*5c51f124SMoriah Waterland 
934*5c51f124SMoriah Waterland 	return (SML_TAG__NULL);
935*5c51f124SMoriah Waterland }
936*5c51f124SMoriah Waterland 
937*5c51f124SMoriah Waterland /*
938*5c51f124SMoriah Waterland  * Name:	smlConvertStringToTag
939*5c51f124SMoriah Waterland  * Description:	Convert string into tag object
940*5c51f124SMoriah Waterland  * Arguments:	err - [RO, *RW] (LU_ERR)
941*5c51f124SMoriah Waterland  *			Error object - used to contain any errors encountered
942*5c51f124SMoriah Waterland  *			and return those errors to this methods caller
943*5c51f124SMoriah Waterland  *		r_tag - [RW, *RW] - (SML_TAG **)
944*5c51f124SMoriah Waterland  *			Pointer to handle to place new tag object
945*5c51f124SMoriah Waterland  *		str - [RO, *RO] - (char *)
946*5c51f124SMoriah Waterland  *			String object to convert to tag object
947*5c51f124SMoriah Waterland  * Returns:	int
948*5c51f124SMoriah Waterland  *			RESULT_OK - string converted to tag object
949*5c51f124SMoriah Waterland  *			RESULT_ERR - problem converting string to tag object
950*5c51f124SMoriah Waterland  * NOTE:    	Any tag object returned is placed in new storage for the
951*5c51f124SMoriah Waterland  *		calling method. The caller must use 'smlFreeTag' to dispose
952*5c51f124SMoriah Waterland  *		of the storage once the tag object name is no longer needed.
953*5c51f124SMoriah Waterland  */
954*5c51f124SMoriah Waterland 
955*5c51f124SMoriah Waterland int
smlConvertStringToTag(SML_TAG ** r_tag,char * str)956*5c51f124SMoriah Waterland smlConvertStringToTag(SML_TAG **r_tag, char *str)
957*5c51f124SMoriah Waterland {
958*5c51f124SMoriah Waterland 	int	r;
959*5c51f124SMoriah Waterland 	SML_TAG	*tag = SML_TAG__NULL;
960*5c51f124SMoriah Waterland 	SML_TAG	*tmp_tag;
961*5c51f124SMoriah Waterland 
962*5c51f124SMoriah Waterland 	/* entry assertions */
963*5c51f124SMoriah Waterland 
964*5c51f124SMoriah Waterland 	assert(SML_TAG__R_ISVALID(r_tag));
965*5c51f124SMoriah Waterland 	assert(str != (char *)NULL);
966*5c51f124SMoriah Waterland 	assert(*str != '\0');
967*5c51f124SMoriah Waterland 
968*5c51f124SMoriah Waterland 	tag = smlNewTag("tagfile");
969*5c51f124SMoriah Waterland 
970*5c51f124SMoriah Waterland 	for (;;) {
971*5c51f124SMoriah Waterland 		r = _smlReadTag(&tmp_tag, &str, NULL);
972*5c51f124SMoriah Waterland 		if (r != RESULT_OK) {
973*5c51f124SMoriah Waterland 			smlFreeTag(tag);
974*5c51f124SMoriah Waterland 			return (r);
975*5c51f124SMoriah Waterland 		}
976*5c51f124SMoriah Waterland 		if (tmp_tag == SML_TAG__NULL) {
977*5c51f124SMoriah Waterland 			if (*str != '\0') {
978*5c51f124SMoriah Waterland 				continue;
979*5c51f124SMoriah Waterland 			}
980*5c51f124SMoriah Waterland 			_smlLogMsg(LOG_MSG_DEBUG,
981*5c51f124SMoriah Waterland 				DBG_SML_LOADED_TAGS_FROM_STR,
982*5c51f124SMoriah Waterland 				(unsigned long)tag, tag->name);
983*5c51f124SMoriah Waterland 			*r_tag = tag;
984*5c51f124SMoriah Waterland 			return (RESULT_OK);
985*5c51f124SMoriah Waterland 		}
986*5c51f124SMoriah Waterland 		_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_READ_IN_TOP_TAG,
987*5c51f124SMoriah Waterland 			tmp_tag->name);
988*5c51f124SMoriah Waterland 		tag->tags_num++;
989*5c51f124SMoriah Waterland 		tag->tags = (SML_TAG *)realloc(tag->tags,
990*5c51f124SMoriah Waterland 			sizeof (SML_TAG) *tag->tags_num);
991*5c51f124SMoriah Waterland 		(void) memcpy(&(tag->tags[tag->tags_num - 1]), tmp_tag,
992*5c51f124SMoriah Waterland 			sizeof (SML_TAG));
993*5c51f124SMoriah Waterland 	}
994*5c51f124SMoriah Waterland }
995*5c51f124SMoriah Waterland 
996*5c51f124SMoriah Waterland /*
997*5c51f124SMoriah Waterland  * Name:	smlReadOneTag
998*5c51f124SMoriah Waterland  * Description:	read one complete tag from a datastream
999*5c51f124SMoriah Waterland  * Arguments:	err - [RO, *RW] (LU_ERR)
1000*5c51f124SMoriah Waterland  *			Error object - used to contain any errors encountered
1001*5c51f124SMoriah Waterland  *			and return those errors to this methods caller
1002*5c51f124SMoriah Waterland  *		r_tag - [RW, *RW] - (SML_TAG **)
1003*5c51f124SMoriah Waterland  *			Pointer to handle to place new tag object
1004*5c51f124SMoriah Waterland  *			== SML_TAG__NULL if empty tag found (not an error)
1005*5c51f124SMoriah Waterland  *		ds - [RO, *RO] - (LU_DS)
1006*5c51f124SMoriah Waterland  *			Handle to datastream to read tag from
1007*5c51f124SMoriah Waterland  * Returns:	int
1008*5c51f124SMoriah Waterland  *			RESULT_OK - tag successfully read
1009*5c51f124SMoriah Waterland  *			RESULT_ERR - problem reading tag
1010*5c51f124SMoriah Waterland  * NOTE:    	Any tag object returned is placed in new storage for the
1011*5c51f124SMoriah Waterland  *		calling method. The caller must use 'smlFreeTag' to dispose
1012*5c51f124SMoriah Waterland  *		of the storage once the tag object name is no longer needed.
1013*5c51f124SMoriah Waterland  */
1014*5c51f124SMoriah Waterland 
1015*5c51f124SMoriah Waterland int
smlReadOneTag(SML_TAG ** r_tag,char * a_str)1016*5c51f124SMoriah Waterland smlReadOneTag(SML_TAG **r_tag, char *a_str)
1017*5c51f124SMoriah Waterland {
1018*5c51f124SMoriah Waterland 	int	r;
1019*5c51f124SMoriah Waterland 
1020*5c51f124SMoriah Waterland 	/* entry assertions */
1021*5c51f124SMoriah Waterland 
1022*5c51f124SMoriah Waterland 	assert(SML_TAG__R_ISVALID(r_tag));
1023*5c51f124SMoriah Waterland 	assert(a_str != (char *)NULL);
1024*5c51f124SMoriah Waterland 
1025*5c51f124SMoriah Waterland 	/* entry debugging info */
1026*5c51f124SMoriah Waterland 
1027*5c51f124SMoriah Waterland 	_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_READ_ONE_TAG, a_str);
1028*5c51f124SMoriah Waterland 
1029*5c51f124SMoriah Waterland 	/* reset return tag */
1030*5c51f124SMoriah Waterland 
1031*5c51f124SMoriah Waterland 	*r_tag = SML_TAG__NULL;
1032*5c51f124SMoriah Waterland 
1033*5c51f124SMoriah Waterland 	/* read tag from datastream, no parent tag to attach it to */
1034*5c51f124SMoriah Waterland 
1035*5c51f124SMoriah Waterland 	r = _smlReadTag(r_tag, &a_str, NULL);
1036*5c51f124SMoriah Waterland 	if (r != RESULT_OK) {
1037*5c51f124SMoriah Waterland 		_smlLogMsg(LOG_MSG_ERR, ERR_SML_CANNOT_READ_TAG);
1038*5c51f124SMoriah Waterland 		return (r);
1039*5c51f124SMoriah Waterland 	}
1040*5c51f124SMoriah Waterland 
1041*5c51f124SMoriah Waterland 	if (*r_tag != SML_TAG__NULL) {
1042*5c51f124SMoriah Waterland 		_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_ONE_TAG_READ,
1043*5c51f124SMoriah Waterland 			(unsigned long)*r_tag,
1044*5c51f124SMoriah Waterland 			(*r_tag)->name ? (*r_tag)->name : "<no name>");
1045*5c51f124SMoriah Waterland 	} else {
1046*5c51f124SMoriah Waterland 		_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_READ_ONE_TAG_NOTAG);
1047*5c51f124SMoriah Waterland 	}
1048*5c51f124SMoriah Waterland 
1049*5c51f124SMoriah Waterland 	/* exit debugging info */
1050*5c51f124SMoriah Waterland 
1051*5c51f124SMoriah Waterland 	return (RESULT_OK);
1052*5c51f124SMoriah Waterland }
1053*5c51f124SMoriah Waterland 
1054*5c51f124SMoriah Waterland /*
1055*5c51f124SMoriah Waterland  * Name:	smlNewTag
1056*5c51f124SMoriah Waterland  * Description:	Create a new (empty) tag object
1057*5c51f124SMoriah Waterland  * Arguments:	name - [RO, *RO] - (char *)
1058*5c51f124SMoriah Waterland  *			Name of tag; NULL to give the tag no name
1059*5c51f124SMoriah Waterland  * Returns:	SML_TAG *
1060*5c51f124SMoriah Waterland  *			Tag object created
1061*5c51f124SMoriah Waterland  * NOTE:    	Any tag object returned is placed in new storage for the
1062*5c51f124SMoriah Waterland  *		calling method. The caller must use 'smlFreeTag' to dispose
1063*5c51f124SMoriah Waterland  *		of the storage once the tag object name is no longer needed.
1064*5c51f124SMoriah Waterland  * Errors:	If the tag object cannot be created, the process exits
1065*5c51f124SMoriah Waterland  */
1066*5c51f124SMoriah Waterland 
1067*5c51f124SMoriah Waterland SML_TAG *
smlNewTag(char * name)1068*5c51f124SMoriah Waterland smlNewTag(char *name)
1069*5c51f124SMoriah Waterland {
1070*5c51f124SMoriah Waterland 	SML_TAG	*tag;
1071*5c51f124SMoriah Waterland 
1072*5c51f124SMoriah Waterland 	/* entry assertions */
1073*5c51f124SMoriah Waterland 
1074*5c51f124SMoriah Waterland 	assert((name == (char *)NULL) || (*name != '\0'));
1075*5c51f124SMoriah Waterland 
1076*5c51f124SMoriah Waterland 	/* entry debugging info */
1077*5c51f124SMoriah Waterland 
1078*5c51f124SMoriah Waterland 	_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_CREATE_NEW_TAG_OBJECT,
1079*5c51f124SMoriah Waterland 		name ? name : "<no name>");
1080*5c51f124SMoriah Waterland 
1081*5c51f124SMoriah Waterland 	/* allocate zeroed storage for the tag object */
1082*5c51f124SMoriah Waterland 
1083*5c51f124SMoriah Waterland 	tag = (SML_TAG *)calloc(1, sizeof (SML_TAG));
1084*5c51f124SMoriah Waterland 	assert(tag != SML_TAG__NULL);
1085*5c51f124SMoriah Waterland 
1086*5c51f124SMoriah Waterland 	/* if name is provided, duplicate and assign it */
1087*5c51f124SMoriah Waterland 
1088*5c51f124SMoriah Waterland 	if (name != (char *)NULL) {
1089*5c51f124SMoriah Waterland 		tag->name = strdup(name);
1090*5c51f124SMoriah Waterland 	}
1091*5c51f124SMoriah Waterland 
1092*5c51f124SMoriah Waterland 	/* exit assertions */
1093*5c51f124SMoriah Waterland 
1094*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(tag));
1095*5c51f124SMoriah Waterland 
1096*5c51f124SMoriah Waterland 	/* exit debugging info */
1097*5c51f124SMoriah Waterland 
1098*5c51f124SMoriah Waterland 	_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_CREATED_NEW_TAG_OBJECT,
1099*5c51f124SMoriah Waterland 		(unsigned long)tag, name ? name : "<no name>");
1100*5c51f124SMoriah Waterland 
1101*5c51f124SMoriah Waterland 	return (tag);
1102*5c51f124SMoriah Waterland }
1103*5c51f124SMoriah Waterland 
1104*5c51f124SMoriah Waterland /*
1105*5c51f124SMoriah Waterland  * Name:	smlConvertTagToString
1106*5c51f124SMoriah Waterland  * Description:	Convert a tag object into a string representation of the XML
1107*5c51f124SMoriah Waterland  * Arguments:	tag - [RO, *RO] - (SML_TAG *)
1108*5c51f124SMoriah Waterland  *			The tag object to convert to a string
1109*5c51f124SMoriah Waterland  * Returns:	char *
1110*5c51f124SMoriah Waterland  *			String representation (in XML) of tag object
1111*5c51f124SMoriah Waterland  *			== (char *)NULL if conversion is not possible
1112*5c51f124SMoriah Waterland  * NOTE:    	Any string returned is placed in new storage for the
1113*5c51f124SMoriah Waterland  *		calling method. The caller must use 'free' to dispose
1114*5c51f124SMoriah Waterland  *		of the storage once the string is no longer needed.
1115*5c51f124SMoriah Waterland  */
1116*5c51f124SMoriah Waterland 
1117*5c51f124SMoriah Waterland char *
smlConvertTagToString(SML_TAG * tag)1118*5c51f124SMoriah Waterland smlConvertTagToString(SML_TAG *tag)
1119*5c51f124SMoriah Waterland {
1120*5c51f124SMoriah Waterland 	char		*str = (char *)NULL;
1121*5c51f124SMoriah Waterland 
1122*5c51f124SMoriah Waterland 	/* entry assertions */
1123*5c51f124SMoriah Waterland 
1124*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(tag));
1125*5c51f124SMoriah Waterland 
1126*5c51f124SMoriah Waterland 	/* convert the tag object into the datastream */
1127*5c51f124SMoriah Waterland 
1128*5c51f124SMoriah Waterland 	(void) _smlWriteSimpleTag(&str, tag);
1129*5c51f124SMoriah Waterland 
1130*5c51f124SMoriah Waterland 	assert(str != (char *)NULL);
1131*5c51f124SMoriah Waterland 	assert(*str != '\0');
1132*5c51f124SMoriah Waterland 
1133*5c51f124SMoriah Waterland 	/* return the results */
1134*5c51f124SMoriah Waterland 
1135*5c51f124SMoriah Waterland 	return (str);
1136*5c51f124SMoriah Waterland }
1137*5c51f124SMoriah Waterland 
1138*5c51f124SMoriah Waterland /*
1139*5c51f124SMoriah Waterland  * Name:	smlDbgPrintTag
1140*5c51f124SMoriah Waterland  * Synopsis:	Print a representation of an XML tag if debugging
1141*5c51f124SMoriah Waterland  * Arguments:	a_tag - [RO, *RO] - (SML_TAG *)
1142*5c51f124SMoriah Waterland  *			Pointer to tag structure to dump
1143*5c51f124SMoriah Waterland  *		a_format - [RO, RO*] (char *)
1144*5c51f124SMoriah Waterland  *			printf-style format for debugging message to be output
1145*5c51f124SMoriah Waterland  *		VARG_LIST - [RO] (?)
1146*5c51f124SMoriah Waterland  *			arguments as appropriate to 'format' specified
1147*5c51f124SMoriah Waterland  * Returns:	void
1148*5c51f124SMoriah Waterland  *			If one of the debugging flags is set, the hexdump
1149*5c51f124SMoriah Waterland  *			is output.
1150*5c51f124SMoriah Waterland  */
1151*5c51f124SMoriah Waterland 
1152*5c51f124SMoriah Waterland /*PRINTFLIKE2*/
1153*5c51f124SMoriah Waterland void
smlDbgPrintTag(SML_TAG * a_tag,char * a_format,...)1154*5c51f124SMoriah Waterland smlDbgPrintTag(SML_TAG *a_tag, char *a_format, ...)
1155*5c51f124SMoriah Waterland {
1156*5c51f124SMoriah Waterland 	va_list	ap;
1157*5c51f124SMoriah Waterland 	size_t		vres = 0;
1158*5c51f124SMoriah Waterland 	char		bfr[1];
1159*5c51f124SMoriah Waterland 	char		*rstr = (char *)NULL;
1160*5c51f124SMoriah Waterland 
1161*5c51f124SMoriah Waterland 	/* entry assertions */
1162*5c51f124SMoriah Waterland 
1163*5c51f124SMoriah Waterland 	assert(a_format != (char *)NULL);
1164*5c51f124SMoriah Waterland 	assert(*a_format != '\0');
1165*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(a_tag));
1166*5c51f124SMoriah Waterland 
1167*5c51f124SMoriah Waterland 	/*
1168*5c51f124SMoriah Waterland 	 * output the message header
1169*5c51f124SMoriah Waterland 	 */
1170*5c51f124SMoriah Waterland 
1171*5c51f124SMoriah Waterland 	/* determine size of the message in bytes */
1172*5c51f124SMoriah Waterland 
1173*5c51f124SMoriah Waterland 	va_start(ap, a_format);
1174*5c51f124SMoriah Waterland 	vres = vsnprintf(bfr, 1, a_format, ap);
1175*5c51f124SMoriah Waterland 	va_end(ap);
1176*5c51f124SMoriah Waterland 
1177*5c51f124SMoriah Waterland 	assert(vres > 0);
1178*5c51f124SMoriah Waterland 
1179*5c51f124SMoriah Waterland 	/* allocate storage to hold the message */
1180*5c51f124SMoriah Waterland 
1181*5c51f124SMoriah Waterland 	rstr = (char *)calloc(1, vres+2);
1182*5c51f124SMoriah Waterland 	assert(rstr != (char *)NULL);
1183*5c51f124SMoriah Waterland 
1184*5c51f124SMoriah Waterland 	/* generate the results of the printf conversion */
1185*5c51f124SMoriah Waterland 
1186*5c51f124SMoriah Waterland 	va_start(ap, a_format);
1187*5c51f124SMoriah Waterland 	vres = vsnprintf(rstr, vres+1, a_format, ap);
1188*5c51f124SMoriah Waterland 	va_end(ap);
1189*5c51f124SMoriah Waterland 
1190*5c51f124SMoriah Waterland 	assert(vres > 0);
1191*5c51f124SMoriah Waterland 	assert(*rstr != '\0');
1192*5c51f124SMoriah Waterland 
1193*5c51f124SMoriah Waterland 	_smlLogMsg(LOG_MSG_DEBUG, "%s", rstr);
1194*5c51f124SMoriah Waterland 	free(rstr);
1195*5c51f124SMoriah Waterland 
1196*5c51f124SMoriah Waterland 	/* convert the tag into a string to be printed */
1197*5c51f124SMoriah Waterland 
1198*5c51f124SMoriah Waterland 	rstr = smlConvertTagToString(a_tag);
1199*5c51f124SMoriah Waterland 	if (rstr != (char *)NULL) {
1200*5c51f124SMoriah Waterland 		_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_PRINTTAG, a_tag->name,
1201*5c51f124SMoriah Waterland 			strlen(rstr), rstr);
1202*5c51f124SMoriah Waterland 	}
1203*5c51f124SMoriah Waterland 	free(rstr);
1204*5c51f124SMoriah Waterland }
1205*5c51f124SMoriah Waterland 
1206*5c51f124SMoriah Waterland /*
1207*5c51f124SMoriah Waterland  * Name:	smlDelParam
1208*5c51f124SMoriah Waterland  * Description:	Delete a parameter from a tag object
1209*5c51f124SMoriah Waterland  * Arguments:	tag - [RO, *RW] - (SML_TAG *)
1210*5c51f124SMoriah Waterland  *			The tag object to delete the parameter from
1211*5c51f124SMoriah Waterland  *		name - [RO, *RO] - (char *)
1212*5c51f124SMoriah Waterland  *			The parameter to delete from the tag object
1213*5c51f124SMoriah Waterland  * Returns:	void
1214*5c51f124SMoriah Waterland  *			If the parameter exists, it is deleted from the tag
1215*5c51f124SMoriah Waterland  */
1216*5c51f124SMoriah Waterland 
1217*5c51f124SMoriah Waterland void
smlDelParam(SML_TAG * tag,char * name)1218*5c51f124SMoriah Waterland smlDelParam(SML_TAG *tag, char *name)
1219*5c51f124SMoriah Waterland {
1220*5c51f124SMoriah Waterland 	int k;
1221*5c51f124SMoriah Waterland 
1222*5c51f124SMoriah Waterland 	/* entry assertions */
1223*5c51f124SMoriah Waterland 
1224*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(tag));
1225*5c51f124SMoriah Waterland 	assert(tag->name != (char *)NULL);
1226*5c51f124SMoriah Waterland 	assert(name != NULL);
1227*5c51f124SMoriah Waterland 	assert(*name != '\0');
1228*5c51f124SMoriah Waterland 
1229*5c51f124SMoriah Waterland 	/* entry debugging info */
1230*5c51f124SMoriah Waterland 
1231*5c51f124SMoriah Waterland 	_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_DELETE_PARAM,
1232*5c51f124SMoriah Waterland 		tag->name, name);
1233*5c51f124SMoriah Waterland 
1234*5c51f124SMoriah Waterland 	/* if tag has no parameters, nothing to delete */
1235*5c51f124SMoriah Waterland 
1236*5c51f124SMoriah Waterland 	if (tag->params == NULL) {
1237*5c51f124SMoriah Waterland 		_smlLogMsg(LOG_MSG_DEBUG,
1238*5c51f124SMoriah Waterland 			DBG_SML_DELETE_PARAM_NO_PARAMS);
1239*5c51f124SMoriah Waterland 		return;
1240*5c51f124SMoriah Waterland 	}
1241*5c51f124SMoriah Waterland 
1242*5c51f124SMoriah Waterland 	assert(tag->params_num > 0);
1243*5c51f124SMoriah Waterland 
1244*5c51f124SMoriah Waterland 	/* search the tag for the parameter */
1245*5c51f124SMoriah Waterland 
1246*5c51f124SMoriah Waterland 	for (k = 0; k < tag->params_num; k++) {
1247*5c51f124SMoriah Waterland 		if (streq(tag->params[k].name, name)) {
1248*5c51f124SMoriah Waterland 			break;
1249*5c51f124SMoriah Waterland 		}
1250*5c51f124SMoriah Waterland 	}
1251*5c51f124SMoriah Waterland 
1252*5c51f124SMoriah Waterland 	/* if the parameter was not found, nothing to delete */
1253*5c51f124SMoriah Waterland 
1254*5c51f124SMoriah Waterland 	if (k >= tag->params_num) {
1255*5c51f124SMoriah Waterland 		_smlLogMsg(LOG_MSG_DEBUG,
1256*5c51f124SMoriah Waterland 			DBG_SML_DELETE_PARAM_NOT_FOUND,
1257*5c51f124SMoriah Waterland 			name);
1258*5c51f124SMoriah Waterland 		return;
1259*5c51f124SMoriah Waterland 	}
1260*5c51f124SMoriah Waterland 
1261*5c51f124SMoriah Waterland 	/* parameter found - indicate deleted */
1262*5c51f124SMoriah Waterland 
1263*5c51f124SMoriah Waterland 	assert(tag->params[k].name != (char *)NULL);
1264*5c51f124SMoriah Waterland 	assert(tag->params[k].value != (char *)NULL);
1265*5c51f124SMoriah Waterland 
1266*5c51f124SMoriah Waterland 	_smlLogMsg(LOG_MSG_DEBUG,
1267*5c51f124SMoriah Waterland 		DBG_SML_DELETE_PARAM_FOUND,
1268*5c51f124SMoriah Waterland 		name, tag->params[k].value);
1269*5c51f124SMoriah Waterland 
1270*5c51f124SMoriah Waterland 	/* free up storage fro parameter */
1271*5c51f124SMoriah Waterland 
1272*5c51f124SMoriah Waterland 	free(tag->params[k].name);
1273*5c51f124SMoriah Waterland 	free(tag->params[k].value);
1274*5c51f124SMoriah Waterland 
1275*5c51f124SMoriah Waterland 	/* if not at end, compact parameter storage */
1276*5c51f124SMoriah Waterland 
1277*5c51f124SMoriah Waterland 	if (k < (tag->params_num -1)) {
1278*5c51f124SMoriah Waterland 		(void) memmove(&(tag->params[k]), &(tag->params[k + 1]),
1279*5c51f124SMoriah Waterland 			sizeof (SML_PARAM) *(tag->params_num - k - 1));
1280*5c51f124SMoriah Waterland 	}
1281*5c51f124SMoriah Waterland 
1282*5c51f124SMoriah Waterland 	/* one less parameter object in tag */
1283*5c51f124SMoriah Waterland 
1284*5c51f124SMoriah Waterland 	tag->params_num --;
1285*5c51f124SMoriah Waterland 
1286*5c51f124SMoriah Waterland 	/*
1287*5c51f124SMoriah Waterland 	 * If only one parameter left, then delete entire parameter storage,
1288*5c51f124SMoriah Waterland 	 * otherwise reallocate removing unneeded entry
1289*5c51f124SMoriah Waterland 	 */
1290*5c51f124SMoriah Waterland 
1291*5c51f124SMoriah Waterland 	if (tag->params_num > 0) {
1292*5c51f124SMoriah Waterland 		/* realloc removing last element in tag object */
1293*5c51f124SMoriah Waterland 
1294*5c51f124SMoriah Waterland 		tag->params = (SML_PARAM *)
1295*5c51f124SMoriah Waterland 			realloc(tag->params,
1296*5c51f124SMoriah Waterland 			sizeof (SML_PARAM) *tag->params_num);
1297*5c51f124SMoriah Waterland 	} else {
1298*5c51f124SMoriah Waterland 		tag->params = (SML_PARAM *)NULL;
1299*5c51f124SMoriah Waterland 	}
1300*5c51f124SMoriah Waterland }
1301*5c51f124SMoriah Waterland 
1302*5c51f124SMoriah Waterland /*
1303*5c51f124SMoriah Waterland  * Name:	smlSetParamF
1304*5c51f124SMoriah Waterland  * Description:	Set formatted parameter value in tag object
1305*5c51f124SMoriah Waterland  * Arguments:	tag - [RO, *RW] - (SML_TAG *)
1306*5c51f124SMoriah Waterland  *			The tag object to set the parameter in
1307*5c51f124SMoriah Waterland  *		name - [RO, *RO] - (char *)
1308*5c51f124SMoriah Waterland  *			The parameter to add to the tag object
1309*5c51f124SMoriah Waterland  *		format - [RO, RO*] (char *)
1310*5c51f124SMoriah Waterland  *			printf-style format to create parameter value from
1311*5c51f124SMoriah Waterland  *		... - [RO] (?)
1312*5c51f124SMoriah Waterland  *			arguments as appropriate to 'format' specified
1313*5c51f124SMoriah Waterland  * Returns:	void
1314*5c51f124SMoriah Waterland  *			The parameter value is set in the tag object
1315*5c51f124SMoriah Waterland  *			according to the results of the format string
1316*5c51f124SMoriah Waterland  *			and arguments
1317*5c51f124SMoriah Waterland  */
1318*5c51f124SMoriah Waterland 
1319*5c51f124SMoriah Waterland /*PRINTFLIKE3*/
1320*5c51f124SMoriah Waterland void
smlSetParamF(SML_TAG * tag,char * name,char * format,...)1321*5c51f124SMoriah Waterland smlSetParamF(SML_TAG *tag, char *name, char *format, ...)
1322*5c51f124SMoriah Waterland {
1323*5c51f124SMoriah Waterland 	va_list	ap;
1324*5c51f124SMoriah Waterland 	size_t		vres = 0;
1325*5c51f124SMoriah Waterland 	char		*bfr = NULL;
1326*5c51f124SMoriah Waterland 	char		fbfr[1];
1327*5c51f124SMoriah Waterland 
1328*5c51f124SMoriah Waterland 	/* entry assertions */
1329*5c51f124SMoriah Waterland 
1330*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(tag));
1331*5c51f124SMoriah Waterland 	assert(name != (char *)NULL);
1332*5c51f124SMoriah Waterland 	assert(*name != '\0');
1333*5c51f124SMoriah Waterland 	assert(format != NULL);
1334*5c51f124SMoriah Waterland 	assert(*format != '\0');
1335*5c51f124SMoriah Waterland 
1336*5c51f124SMoriah Waterland 	/* determine size of the parameter name in bytes */
1337*5c51f124SMoriah Waterland 
1338*5c51f124SMoriah Waterland 	va_start(ap, format);
1339*5c51f124SMoriah Waterland 	vres = vsnprintf(fbfr, 1, format, ap);
1340*5c51f124SMoriah Waterland 	va_end(ap);
1341*5c51f124SMoriah Waterland 
1342*5c51f124SMoriah Waterland 	assert(vres > 0);
1343*5c51f124SMoriah Waterland 
1344*5c51f124SMoriah Waterland 	/* allocate storage to hold the message */
1345*5c51f124SMoriah Waterland 
1346*5c51f124SMoriah Waterland 	bfr = (char *)calloc(1, vres+2);
1347*5c51f124SMoriah Waterland 	assert(bfr != (char *)NULL);
1348*5c51f124SMoriah Waterland 
1349*5c51f124SMoriah Waterland 	/* generate the parameter name and store it in the allocated storage */
1350*5c51f124SMoriah Waterland 
1351*5c51f124SMoriah Waterland 	va_start(ap, format);
1352*5c51f124SMoriah Waterland 	vres = vsnprintf(bfr, vres+1, format, ap);
1353*5c51f124SMoriah Waterland 	va_end(ap);
1354*5c51f124SMoriah Waterland 
1355*5c51f124SMoriah Waterland 	assert(vres > 0);
1356*5c51f124SMoriah Waterland 	assert(*bfr != '\0');
1357*5c51f124SMoriah Waterland 
1358*5c51f124SMoriah Waterland 	/* add the parameter to the tag */
1359*5c51f124SMoriah Waterland 
1360*5c51f124SMoriah Waterland 	smlSetParam(tag, name, bfr);
1361*5c51f124SMoriah Waterland 
1362*5c51f124SMoriah Waterland 	/* free up temporary storage and return */
1363*5c51f124SMoriah Waterland 
1364*5c51f124SMoriah Waterland 	free(bfr);
1365*5c51f124SMoriah Waterland }
1366*5c51f124SMoriah Waterland 
1367*5c51f124SMoriah Waterland /*
1368*5c51f124SMoriah Waterland  * Name:	smlGetParam
1369*5c51f124SMoriah Waterland  * Description:	Get a format-generated parameter from a tag
1370*5c51f124SMoriah Waterland  * Arguments:	tag - [RO, *RO] - (SML_TAG *)
1371*5c51f124SMoriah Waterland  *			The tag object to obtain the parameter from
1372*5c51f124SMoriah Waterland  *		format - [RO, RO*] (char *)
1373*5c51f124SMoriah Waterland  *			printf-style format for parameter name to be
1374*5c51f124SMoriah Waterland  *			looked up to be formatted
1375*5c51f124SMoriah Waterland  *		... - [RO] (?)
1376*5c51f124SMoriah Waterland  *			arguments as appropriate to 'format' specified
1377*5c51f124SMoriah Waterland  * Returns:	char *
1378*5c51f124SMoriah Waterland  *			Value of the specified parameter
1379*5c51f124SMoriah Waterland  *			== (char *)NULL if the parameter does not exist
1380*5c51f124SMoriah Waterland  * NOTE:    	Any parameter returned is placed in new storage for the
1381*5c51f124SMoriah Waterland  *		calling method. The caller must use 'free' to dispose
1382*5c51f124SMoriah Waterland  *		of the storage once the parameter is no longer needed.
1383*5c51f124SMoriah Waterland  */
1384*5c51f124SMoriah Waterland 
1385*5c51f124SMoriah Waterland /*PRINTFLIKE2*/
1386*5c51f124SMoriah Waterland char *
smlGetParamF(SML_TAG * tag,char * format,...)1387*5c51f124SMoriah Waterland smlGetParamF(SML_TAG *tag, char *format, ...)
1388*5c51f124SMoriah Waterland {
1389*5c51f124SMoriah Waterland 	va_list	ap;
1390*5c51f124SMoriah Waterland 	size_t		vres = 0;
1391*5c51f124SMoriah Waterland 	char		*bfr = NULL;
1392*5c51f124SMoriah Waterland 	char		fbfr[1];
1393*5c51f124SMoriah Waterland 	char		*p;
1394*5c51f124SMoriah Waterland 
1395*5c51f124SMoriah Waterland 	/* entry assertions */
1396*5c51f124SMoriah Waterland 
1397*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(tag));
1398*5c51f124SMoriah Waterland 	assert(format != NULL);
1399*5c51f124SMoriah Waterland 	assert(*format != '\0');
1400*5c51f124SMoriah Waterland 
1401*5c51f124SMoriah Waterland 	/* determine size of the parameter name in bytes */
1402*5c51f124SMoriah Waterland 
1403*5c51f124SMoriah Waterland 	va_start(ap, format);
1404*5c51f124SMoriah Waterland 	vres = vsnprintf(fbfr, 1, format, ap);
1405*5c51f124SMoriah Waterland 	va_end(ap);
1406*5c51f124SMoriah Waterland 
1407*5c51f124SMoriah Waterland 	assert(vres > 0);
1408*5c51f124SMoriah Waterland 
1409*5c51f124SMoriah Waterland 	/* allocate storage to hold the message */
1410*5c51f124SMoriah Waterland 
1411*5c51f124SMoriah Waterland 	bfr = (char *)calloc(1, vres+2);
1412*5c51f124SMoriah Waterland 	assert(bfr != (char *)NULL);
1413*5c51f124SMoriah Waterland 
1414*5c51f124SMoriah Waterland 	/* generate the parameter name and store it in the allocated storage */
1415*5c51f124SMoriah Waterland 
1416*5c51f124SMoriah Waterland 	va_start(ap, format);
1417*5c51f124SMoriah Waterland 	vres = vsnprintf(bfr, vres+1, format, ap);
1418*5c51f124SMoriah Waterland 	va_end(ap);
1419*5c51f124SMoriah Waterland 
1420*5c51f124SMoriah Waterland 	assert(vres > 0);
1421*5c51f124SMoriah Waterland 	assert(*bfr != '\0');
1422*5c51f124SMoriah Waterland 
1423*5c51f124SMoriah Waterland 	/* add the parameter to the tag */
1424*5c51f124SMoriah Waterland 
1425*5c51f124SMoriah Waterland 	p = smlGetParam(tag, bfr);
1426*5c51f124SMoriah Waterland 
1427*5c51f124SMoriah Waterland 	/* free up temporary storage and return */
1428*5c51f124SMoriah Waterland 
1429*5c51f124SMoriah Waterland 	free(bfr);
1430*5c51f124SMoriah Waterland 
1431*5c51f124SMoriah Waterland 	return (p);
1432*5c51f124SMoriah Waterland }
1433*5c51f124SMoriah Waterland 
1434*5c51f124SMoriah Waterland /*
1435*5c51f124SMoriah Waterland  * Name:	smlSetParam
1436*5c51f124SMoriah Waterland  * Description:	Set parameter value in tag object
1437*5c51f124SMoriah Waterland  * Arguments:	tag - [RO, *RW] - (SML_TAG *)
1438*5c51f124SMoriah Waterland  *			The tag object to set the parameter in
1439*5c51f124SMoriah Waterland  *		name - [RO, *RO] - (char *)
1440*5c51f124SMoriah Waterland  *			The parameter to add to the tag object
1441*5c51f124SMoriah Waterland  *		value - [RO, *RO] - (char *)
1442*5c51f124SMoriah Waterland  *			The value of the parameter to set in the tag object
1443*5c51f124SMoriah Waterland  * Returns:	void
1444*5c51f124SMoriah Waterland  *			The parameter value is set in the tag object
1445*5c51f124SMoriah Waterland  */
1446*5c51f124SMoriah Waterland 
1447*5c51f124SMoriah Waterland void
smlSetParam(SML_TAG * tag,char * name,char * value)1448*5c51f124SMoriah Waterland smlSetParam(SML_TAG *tag, char *name, char *value)
1449*5c51f124SMoriah Waterland {
1450*5c51f124SMoriah Waterland 	SML_PARAM *parameter;
1451*5c51f124SMoriah Waterland 
1452*5c51f124SMoriah Waterland 	/* entry assertions */
1453*5c51f124SMoriah Waterland 
1454*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(tag));
1455*5c51f124SMoriah Waterland 	assert(name != (char *)NULL);
1456*5c51f124SMoriah Waterland 	assert(*name != '\0');
1457*5c51f124SMoriah Waterland 	assert(value != (char *)NULL);
1458*5c51f124SMoriah Waterland 
1459*5c51f124SMoriah Waterland 	/* entry debugging info */
1460*5c51f124SMoriah Waterland 
1461*5c51f124SMoriah Waterland 	_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_SET_PARAM,
1462*5c51f124SMoriah Waterland 		tag->name, name, value);
1463*5c51f124SMoriah Waterland 
1464*5c51f124SMoriah Waterland 	/* if parameters exist, see if modifying existing parameter */
1465*5c51f124SMoriah Waterland 
1466*5c51f124SMoriah Waterland 	if (tag->params != NULL) {
1467*5c51f124SMoriah Waterland 		int k;
1468*5c51f124SMoriah Waterland 		for (k = 0; k < tag->params_num; k++) {
1469*5c51f124SMoriah Waterland 			assert(tag->params[k].name != (char *)NULL);
1470*5c51f124SMoriah Waterland 			assert(tag->params[k].value != (char *)NULL);
1471*5c51f124SMoriah Waterland 
1472*5c51f124SMoriah Waterland 			/* if name does not match, skip */
1473*5c51f124SMoriah Waterland 
1474*5c51f124SMoriah Waterland 			if (!streq(tag->params[k].name, name)) {
1475*5c51f124SMoriah Waterland 				continue;
1476*5c51f124SMoriah Waterland 			}
1477*5c51f124SMoriah Waterland 
1478*5c51f124SMoriah Waterland 			/* found parameter - if value is same, leave alone */
1479*5c51f124SMoriah Waterland 
1480*5c51f124SMoriah Waterland 			if (streq(tag->params[k].value, value)) {
1481*5c51f124SMoriah Waterland 				_smlLogMsg(LOG_MSG_DEBUG,
1482*5c51f124SMoriah Waterland 					DBG_SML_SET_PARAM_LEAVE_ALONE,
1483*5c51f124SMoriah Waterland 					tag->params[k].value);
1484*5c51f124SMoriah Waterland 				return;
1485*5c51f124SMoriah Waterland 			}
1486*5c51f124SMoriah Waterland 
1487*5c51f124SMoriah Waterland 			/* exists and has different value - change */
1488*5c51f124SMoriah Waterland 
1489*5c51f124SMoriah Waterland 			_smlLogMsg(LOG_MSG_DEBUG,
1490*5c51f124SMoriah Waterland 				DBG_SML_SET_PARAM_MODIFY,
1491*5c51f124SMoriah Waterland 				tag->params[k].value);
1492*5c51f124SMoriah Waterland 				free(tag->params[k].value);
1493*5c51f124SMoriah Waterland 				tag->params[k].value = strdup(value);
1494*5c51f124SMoriah Waterland 				return;
1495*5c51f124SMoriah Waterland 		}
1496*5c51f124SMoriah Waterland 	}
1497*5c51f124SMoriah Waterland 
1498*5c51f124SMoriah Waterland 	/* not modifying existing - add new parameter */
1499*5c51f124SMoriah Waterland 
1500*5c51f124SMoriah Waterland 	_smlLogMsg(LOG_MSG_DEBUG,
1501*5c51f124SMoriah Waterland 		DBG_SML_SET_PARAM_CREATE_NEW);
1502*5c51f124SMoriah Waterland 
1503*5c51f124SMoriah Waterland 	parameter = (SML_PARAM *)calloc(1, sizeof (SML_PARAM));
1504*5c51f124SMoriah Waterland 	bzero(parameter, sizeof (SML_PARAM));
1505*5c51f124SMoriah Waterland 	parameter->name = strdup(name);
1506*5c51f124SMoriah Waterland 	parameter->value = strdup(value);
1507*5c51f124SMoriah Waterland 
1508*5c51f124SMoriah Waterland 	tag->params_num++;
1509*5c51f124SMoriah Waterland 	tag->params = (SML_PARAM *)realloc(tag->params,
1510*5c51f124SMoriah Waterland 			sizeof (SML_PARAM) *tag->params_num);
1511*5c51f124SMoriah Waterland 	(void) memcpy(&(tag->params[tag->params_num - 1]), parameter,
1512*5c51f124SMoriah Waterland 			sizeof (SML_PARAM));
1513*5c51f124SMoriah Waterland 	free(parameter);
1514*5c51f124SMoriah Waterland }
1515*5c51f124SMoriah Waterland 
1516*5c51f124SMoriah Waterland /*
1517*5c51f124SMoriah Waterland  * Name:	smlParamEqF
1518*5c51f124SMoriah Waterland  * Description:	Determine if parameter is equal to a specified formatted value
1519*5c51f124SMoriah Waterland  * Arguments:	tag - [RO, *RO] - (SML_TAG *)
1520*5c51f124SMoriah Waterland  *			The tag object to look for the parameter to compare
1521*5c51f124SMoriah Waterland  *		findTag - [RO, *RO] - (char *)
1522*5c51f124SMoriah Waterland  *			Tag within tag object to look for the parameter in
1523*5c51f124SMoriah Waterland  *		findParam - [RO, *RO] - (char *)
1524*5c51f124SMoriah Waterland  *			Parameter within tag to look for
1525*5c51f124SMoriah Waterland  *		format - [RO, RO*] (char *)
1526*5c51f124SMoriah Waterland  *			printf-style format for value to be compared against
1527*5c51f124SMoriah Waterland  *			parameter value
1528*5c51f124SMoriah Waterland  *		... - [RO] (?)
1529*5c51f124SMoriah Waterland  *			arguments as appropriate to 'format' specified to
1530*5c51f124SMoriah Waterland  *			generate the value to compare parameter with
1531*5c51f124SMoriah Waterland  * Returns:	boolean_t
1532*5c51f124SMoriah Waterland  *			B_TRUE - the parameter exists and matches given value
1533*5c51f124SMoriah Waterland  *			B_FALSE - parameter does not exist or does not match
1534*5c51f124SMoriah Waterland  */
1535*5c51f124SMoriah Waterland 
1536*5c51f124SMoriah Waterland /*PRINTFLIKE4*/
1537*5c51f124SMoriah Waterland boolean_t
smlParamEqF(SML_TAG * tag,char * findTag,char * findParam,char * format,...)1538*5c51f124SMoriah Waterland smlParamEqF(SML_TAG *tag, char *findTag, char *findParam, char *format, ...)
1539*5c51f124SMoriah Waterland {
1540*5c51f124SMoriah Waterland 	va_list	ap;
1541*5c51f124SMoriah Waterland 	size_t		vres = 0;
1542*5c51f124SMoriah Waterland 	char		*bfr = NULL;
1543*5c51f124SMoriah Waterland 	char		fbfr[1];
1544*5c51f124SMoriah Waterland 	boolean_t	b;
1545*5c51f124SMoriah Waterland 
1546*5c51f124SMoriah Waterland 	/* entry assertions */
1547*5c51f124SMoriah Waterland 
1548*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(tag));
1549*5c51f124SMoriah Waterland 	assert(format != NULL);
1550*5c51f124SMoriah Waterland 	assert(*format != '\0');
1551*5c51f124SMoriah Waterland 
1552*5c51f124SMoriah Waterland 	/* determine size of the parameter value in bytes */
1553*5c51f124SMoriah Waterland 
1554*5c51f124SMoriah Waterland 	va_start(ap, format);
1555*5c51f124SMoriah Waterland 	vres = vsnprintf(fbfr, 1, format, ap);
1556*5c51f124SMoriah Waterland 	va_end(ap);
1557*5c51f124SMoriah Waterland 
1558*5c51f124SMoriah Waterland 	assert(vres > 0);
1559*5c51f124SMoriah Waterland 
1560*5c51f124SMoriah Waterland 	/* allocate storage to hold the message */
1561*5c51f124SMoriah Waterland 
1562*5c51f124SMoriah Waterland 	bfr = (char *)calloc(1, vres+2);
1563*5c51f124SMoriah Waterland 	assert(bfr != (char *)NULL);
1564*5c51f124SMoriah Waterland 
1565*5c51f124SMoriah Waterland 	/* generate the parameter value and store it in the allocated storage */
1566*5c51f124SMoriah Waterland 
1567*5c51f124SMoriah Waterland 	va_start(ap, format);
1568*5c51f124SMoriah Waterland 	vres = vsnprintf(bfr, vres+1, format, ap);
1569*5c51f124SMoriah Waterland 	va_end(ap);
1570*5c51f124SMoriah Waterland 
1571*5c51f124SMoriah Waterland 	assert(vres > 0);
1572*5c51f124SMoriah Waterland 	assert(*bfr != '\0');
1573*5c51f124SMoriah Waterland 
1574*5c51f124SMoriah Waterland 	/* add the parameter to the tag */
1575*5c51f124SMoriah Waterland 
1576*5c51f124SMoriah Waterland 	b = smlParamEq(tag, findTag, findParam, bfr);
1577*5c51f124SMoriah Waterland 
1578*5c51f124SMoriah Waterland 	/* free up temporary storage and return */
1579*5c51f124SMoriah Waterland 
1580*5c51f124SMoriah Waterland 	free(bfr);
1581*5c51f124SMoriah Waterland 
1582*5c51f124SMoriah Waterland 	return (b);
1583*5c51f124SMoriah Waterland }
1584*5c51f124SMoriah Waterland 
1585*5c51f124SMoriah Waterland /*
1586*5c51f124SMoriah Waterland  * Name:	smlParamEq
1587*5c51f124SMoriah Waterland  * Description:	Determine if parameter is equal to a specified value
1588*5c51f124SMoriah Waterland  * Arguments:	tag - [RO, *RO] - (SML_TAG *)
1589*5c51f124SMoriah Waterland  *			The tag object to look for the parameter to compare
1590*5c51f124SMoriah Waterland  *		findTag - [RO, *RO] - (char *)
1591*5c51f124SMoriah Waterland  *			Tag within tag object to look for the parameter in
1592*5c51f124SMoriah Waterland  *		findParam - [RO, *RO] - (char *)
1593*5c51f124SMoriah Waterland  *			Parameter within tag to look for
1594*5c51f124SMoriah Waterland  *		str - [RO, *RO] - (char *)
1595*5c51f124SMoriah Waterland  *			Value to compare parameter with
1596*5c51f124SMoriah Waterland  * Returns:	boolean_t
1597*5c51f124SMoriah Waterland  *			B_TRUE - the parameter exists and matches given value
1598*5c51f124SMoriah Waterland  *			B_FALSE - parameter does not exist or does not match
1599*5c51f124SMoriah Waterland  */
1600*5c51f124SMoriah Waterland 
1601*5c51f124SMoriah Waterland boolean_t
smlParamEq(SML_TAG * tag,char * findTag,char * findParam,char * str)1602*5c51f124SMoriah Waterland smlParamEq(SML_TAG *tag, char *findTag, char *findParam, char *str)
1603*5c51f124SMoriah Waterland {
1604*5c51f124SMoriah Waterland 	SML_TAG	*rtag;
1605*5c51f124SMoriah Waterland 	char		*rparm;
1606*5c51f124SMoriah Waterland 	boolean_t	answer;
1607*5c51f124SMoriah Waterland 
1608*5c51f124SMoriah Waterland 	/* entry assertions */
1609*5c51f124SMoriah Waterland 
1610*5c51f124SMoriah Waterland 	assert(str != (char *)NULL);
1611*5c51f124SMoriah Waterland 	assert(findParam != (char *)NULL);
1612*5c51f124SMoriah Waterland 	assert(findTag != (char *)NULL);
1613*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(tag));
1614*5c51f124SMoriah Waterland 
1615*5c51f124SMoriah Waterland 	/* look for the specified tag - if not found, return false */
1616*5c51f124SMoriah Waterland 
1617*5c51f124SMoriah Waterland 	rtag = smlGetTagByName(tag, 0, findTag);
1618*5c51f124SMoriah Waterland 	if (rtag == SML_TAG__NULL) {
1619*5c51f124SMoriah Waterland 		return (B_FALSE);
1620*5c51f124SMoriah Waterland 	}
1621*5c51f124SMoriah Waterland 
1622*5c51f124SMoriah Waterland 	/* look for the specified parameter - if not found, return false */
1623*5c51f124SMoriah Waterland 
1624*5c51f124SMoriah Waterland 	rparm = smlGetParam(rtag, findParam);
1625*5c51f124SMoriah Waterland 	if (rparm == (char *)NULL) {
1626*5c51f124SMoriah Waterland 		return (B_FALSE);
1627*5c51f124SMoriah Waterland 	}
1628*5c51f124SMoriah Waterland 
1629*5c51f124SMoriah Waterland 	/* parameter found - compare against given value */
1630*5c51f124SMoriah Waterland 
1631*5c51f124SMoriah Waterland 	answer = strcasecmp(str, rparm);
1632*5c51f124SMoriah Waterland 
1633*5c51f124SMoriah Waterland 	/* free up parameter storage */
1634*5c51f124SMoriah Waterland 
1635*5c51f124SMoriah Waterland 	free(rparm);
1636*5c51f124SMoriah Waterland 
1637*5c51f124SMoriah Waterland 	/* return results of comparison */
1638*5c51f124SMoriah Waterland 
1639*5c51f124SMoriah Waterland 	return (answer == 0 ? B_TRUE : B_FALSE);
1640*5c51f124SMoriah Waterland }
1641*5c51f124SMoriah Waterland 
1642*5c51f124SMoriah Waterland /*
1643*5c51f124SMoriah Waterland  * Name:	smlFindAndDelTag
1644*5c51f124SMoriah Waterland  * Description:	Delete a tag if found in tag object
1645*5c51f124SMoriah Waterland  * Arguments:	tag - [RO, *RW] - (SML_TAG *)
1646*5c51f124SMoriah Waterland  *			The tag object to delete the tag from
1647*5c51f124SMoriah Waterland  *		findTag - [RO, *RO] - (char *)
1648*5c51f124SMoriah Waterland  *			Tag within tag object to delete
1649*5c51f124SMoriah Waterland  * Returns:	boolean_t
1650*5c51f124SMoriah Waterland  *			B_TRUE - tag found and deleted
1651*5c51f124SMoriah Waterland  *			B_FALSE - tag not found
1652*5c51f124SMoriah Waterland  */
1653*5c51f124SMoriah Waterland 
1654*5c51f124SMoriah Waterland boolean_t
smlFindAndDelTag(SML_TAG * tag,char * findTag)1655*5c51f124SMoriah Waterland smlFindAndDelTag(SML_TAG *tag, char *findTag)
1656*5c51f124SMoriah Waterland {
1657*5c51f124SMoriah Waterland 	SML_TAG	*rtag = SML_TAG__NULL;
1658*5c51f124SMoriah Waterland 
1659*5c51f124SMoriah Waterland 	/* entry assertions */
1660*5c51f124SMoriah Waterland 
1661*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(tag));
1662*5c51f124SMoriah Waterland 	assert(findTag != (char *)NULL);
1663*5c51f124SMoriah Waterland 	assert(*findTag != '\0');
1664*5c51f124SMoriah Waterland 
1665*5c51f124SMoriah Waterland 	/* find the specified tag - if not found, return false */
1666*5c51f124SMoriah Waterland 
1667*5c51f124SMoriah Waterland 	rtag = smlGetTagByName(tag, 0, findTag);
1668*5c51f124SMoriah Waterland 	if (rtag == SML_TAG__NULL) {
1669*5c51f124SMoriah Waterland 		return (B_FALSE);
1670*5c51f124SMoriah Waterland 	}
1671*5c51f124SMoriah Waterland 
1672*5c51f124SMoriah Waterland 	/* tag found - delete it and return true */
1673*5c51f124SMoriah Waterland 
1674*5c51f124SMoriah Waterland 	smlDelTag(tag, rtag);
1675*5c51f124SMoriah Waterland 
1676*5c51f124SMoriah Waterland 	return (B_TRUE);
1677*5c51f124SMoriah Waterland }
1678*5c51f124SMoriah Waterland 
1679*5c51f124SMoriah Waterland /*
1680*5c51f124SMoriah Waterland  * Name:	smlDup
1681*5c51f124SMoriah Waterland  * Description:	Duplicate a tag object
1682*5c51f124SMoriah Waterland  * Arguments:	tag - [RO, *RO] - (SML_TAG *)
1683*5c51f124SMoriah Waterland  *			The tag object to duplicate
1684*5c51f124SMoriah Waterland  * Returns:	SML_TAG *
1685*5c51f124SMoriah Waterland  *			A handle to a complete duplicate of the tag provided
1686*5c51f124SMoriah Waterland  * NOTE:    	Any tag object returned is placed in new storage for the
1687*5c51f124SMoriah Waterland  *		calling method. The caller must use 'smlFreeTag' to dispose
1688*5c51f124SMoriah Waterland  *		of the storage once the tag object name is no longer needed.
1689*5c51f124SMoriah Waterland  * Errors:	If the tag object cannot be duplicated, the process exits
1690*5c51f124SMoriah Waterland  */
1691*5c51f124SMoriah Waterland 
1692*5c51f124SMoriah Waterland SML_TAG *
smlDup(SML_TAG * tag)1693*5c51f124SMoriah Waterland smlDup(SML_TAG *tag)
1694*5c51f124SMoriah Waterland {
1695*5c51f124SMoriah Waterland 	SML_TAG	*rtag = SML_TAG__NULL;
1696*5c51f124SMoriah Waterland 	int		i;
1697*5c51f124SMoriah Waterland 
1698*5c51f124SMoriah Waterland 	/* entry assertions */
1699*5c51f124SMoriah Waterland 
1700*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(tag));
1701*5c51f124SMoriah Waterland 
1702*5c51f124SMoriah Waterland 	/* allocate zeroed storage for the tag object */
1703*5c51f124SMoriah Waterland 
1704*5c51f124SMoriah Waterland 	rtag = (SML_TAG *)calloc(1, sizeof (SML_TAG));
1705*5c51f124SMoriah Waterland 	assert(rtag != SML_TAG__NULL);
1706*5c51f124SMoriah Waterland 
1707*5c51f124SMoriah Waterland 	/* duplicate all parameters of the tag */
1708*5c51f124SMoriah Waterland 
1709*5c51f124SMoriah Waterland 	rtag->name = (tag->name ? strdup(tag->name) : (char *)NULL);
1710*5c51f124SMoriah Waterland 	rtag->params_num = tag->params_num;
1711*5c51f124SMoriah Waterland 	if (tag->params != (SML_PARAM *)NULL) {
1712*5c51f124SMoriah Waterland 		rtag->params = (SML_PARAM *)
1713*5c51f124SMoriah Waterland 			calloc(1, sizeof (SML_PARAM)*rtag->params_num);
1714*5c51f124SMoriah Waterland 		bzero(rtag->params, sizeof (SML_PARAM)*rtag->params_num);
1715*5c51f124SMoriah Waterland 		for (i = 0; i < rtag->params_num; i++) {
1716*5c51f124SMoriah Waterland 			rtag->params[i].name = tag->params[i].name ?
1717*5c51f124SMoriah Waterland 				strdup(tag->params[i].name) :
1718*5c51f124SMoriah Waterland 					(char *)NULL;
1719*5c51f124SMoriah Waterland 			rtag->params[i].value = tag->params[i].value ?
1720*5c51f124SMoriah Waterland 				strdup(tag->params[i].value) :
1721*5c51f124SMoriah Waterland 					(char *)NULL;
1722*5c51f124SMoriah Waterland 		}
1723*5c51f124SMoriah Waterland 	}
1724*5c51f124SMoriah Waterland 
1725*5c51f124SMoriah Waterland 	/* duplicate all elements of the tag */
1726*5c51f124SMoriah Waterland 
1727*5c51f124SMoriah Waterland 	rtag->tags_num = tag->tags_num;
1728*5c51f124SMoriah Waterland 
1729*5c51f124SMoriah Waterland 	if (tag->tags != SML_TAG__NULL) {
1730*5c51f124SMoriah Waterland 		rtag->tags = (SML_TAG *)
1731*5c51f124SMoriah Waterland 			calloc(1, sizeof (SML_TAG)*rtag->tags_num);
1732*5c51f124SMoriah Waterland 		bzero(rtag->tags, sizeof (SML_TAG)*rtag->tags_num);
1733*5c51f124SMoriah Waterland 		for (i = 0; i < rtag->tags_num; i++) {
1734*5c51f124SMoriah Waterland 			SML_TAG *stag;
1735*5c51f124SMoriah Waterland 			stag = smlDup(&tag->tags[i]);
1736*5c51f124SMoriah Waterland 			(void) memcpy(&rtag->tags[i], stag,
1737*5c51f124SMoriah Waterland 				sizeof (SML_TAG));
1738*5c51f124SMoriah Waterland 			free(stag);
1739*5c51f124SMoriah Waterland 		}
1740*5c51f124SMoriah Waterland 	}
1741*5c51f124SMoriah Waterland 
1742*5c51f124SMoriah Waterland 	/* exit assertions */
1743*5c51f124SMoriah Waterland 
1744*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(rtag));
1745*5c51f124SMoriah Waterland 
1746*5c51f124SMoriah Waterland 	/* return */
1747*5c51f124SMoriah Waterland 
1748*5c51f124SMoriah Waterland 	return (rtag);
1749*5c51f124SMoriah Waterland }
1750*5c51f124SMoriah Waterland 
1751*5c51f124SMoriah Waterland /*
1752*5c51f124SMoriah Waterland  * Name:	smlSetFileStatInfo
1753*5c51f124SMoriah Waterland  * Description;	Given a file status structure and path name, encode the
1754*5c51f124SMoriah Waterland  *		structure and place it and the name into the specified tag
1755*5c51f124SMoriah Waterland  *		in a "_sml_fileStatInfoTag" (private) element
1756*5c51f124SMoriah Waterland  * Arguments:	tag - [RO, *RO] - (SML_TAG *)
1757*5c51f124SMoriah Waterland  *			The tag object to deposit the information into
1758*5c51f124SMoriah Waterland  *		statbuf - [RO, *RO] - (struct stat *)
1759*5c51f124SMoriah Waterland  *			Pointer to file status structure to encode
1760*5c51f124SMoriah Waterland  *		path - [RO, *RO] - (char *)
1761*5c51f124SMoriah Waterland  *			Pointer to path name of file to encode
1762*5c51f124SMoriah Waterland  * Returns:	void
1763*5c51f124SMoriah Waterland  *			The information is placed into the specified tag object
1764*5c51f124SMoriah Waterland  */
1765*5c51f124SMoriah Waterland 
1766*5c51f124SMoriah Waterland void
smlSetFileStatInfo(SML_TAG ** tag,struct stat * statbuf,char * path)1767*5c51f124SMoriah Waterland smlSetFileStatInfo(SML_TAG **tag, struct stat *statbuf, char *path)
1768*5c51f124SMoriah Waterland {
1769*5c51f124SMoriah Waterland 	SML_TAG	*rtag;
1770*5c51f124SMoriah Waterland 
1771*5c51f124SMoriah Waterland 	/* entry assertions */
1772*5c51f124SMoriah Waterland 
1773*5c51f124SMoriah Waterland 	assert(SML_TAG__R_ISVALID(tag));
1774*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(*tag));
1775*5c51f124SMoriah Waterland 	assert(statbuf != (struct stat *)NULL);
1776*5c51f124SMoriah Waterland 
1777*5c51f124SMoriah Waterland 	/* if stat info exists, delete it */
1778*5c51f124SMoriah Waterland 
1779*5c51f124SMoriah Waterland 	(void) smlFindAndDelTag(*tag, _sml_fileStatInfoTag);
1780*5c51f124SMoriah Waterland 
1781*5c51f124SMoriah Waterland 	/* create the file stat info inside of the top level tag */
1782*5c51f124SMoriah Waterland 
1783*5c51f124SMoriah Waterland 	assert(smlGetTagByName(*tag, 0, _sml_fileStatInfoTag)
1784*5c51f124SMoriah Waterland 							== SML_TAG__NULL);
1785*5c51f124SMoriah Waterland 	rtag = smlNewTag(_sml_fileStatInfoTag);
1786*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(rtag));
1787*5c51f124SMoriah Waterland 	(void) smlAddTag(tag, 0, rtag);
1788*5c51f124SMoriah Waterland 	free(rtag);
1789*5c51f124SMoriah Waterland 
1790*5c51f124SMoriah Waterland 	/* obtain handle on newly created file stat info tag */
1791*5c51f124SMoriah Waterland 
1792*5c51f124SMoriah Waterland 	rtag = smlGetTagByName(*tag, 0, _sml_fileStatInfoTag);
1793*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(rtag));
1794*5c51f124SMoriah Waterland 
1795*5c51f124SMoriah Waterland 	/* add file info as parameters to the tag */
1796*5c51f124SMoriah Waterland 
1797*5c51f124SMoriah Waterland 	if (path != (char *)NULL) {
1798*5c51f124SMoriah Waterland 		smlSetParam(rtag, "st_path", path);
1799*5c51f124SMoriah Waterland 	}
1800*5c51f124SMoriah Waterland 
1801*5c51f124SMoriah Waterland 	smlSetParamF(rtag, "st_ino", "0x%llx",
1802*5c51f124SMoriah Waterland 		(unsigned long long)statbuf->st_ino);
1803*5c51f124SMoriah Waterland 	smlSetParamF(rtag, "st_mode", "0x%llx",
1804*5c51f124SMoriah Waterland 		(unsigned long long)statbuf->st_mode);
1805*5c51f124SMoriah Waterland 	smlSetParamF(rtag, "st_mtime", "0x%llx",
1806*5c51f124SMoriah Waterland 		(unsigned long long)statbuf->st_mtime);
1807*5c51f124SMoriah Waterland 	smlSetParamF(rtag, "st_ctime", "0x%llx",
1808*5c51f124SMoriah Waterland 		(unsigned long long)statbuf->st_ctime);
1809*5c51f124SMoriah Waterland 	smlSetParamF(rtag, "st_size", "0x%llx",
1810*5c51f124SMoriah Waterland 		(unsigned long long)statbuf->st_size);
1811*5c51f124SMoriah Waterland }
1812*5c51f124SMoriah Waterland 
1813*5c51f124SMoriah Waterland /*
1814*5c51f124SMoriah Waterland  * Name:	smlFstatCompareEQ
1815*5c51f124SMoriah Waterland  * Description:	Given a file status structure and path name, look for the
1816*5c51f124SMoriah Waterland  *		information placed into a tag object via smlSetFileStatInfo
1817*5c51f124SMoriah Waterland  *		and if present compare the encoded information with the
1818*5c51f124SMoriah Waterland  *		arguments provided
1819*5c51f124SMoriah Waterland  * Arguments:	statbuf - [RO, *RO] - (struct stat *)
1820*5c51f124SMoriah Waterland  *			Pointer to file status structure to compare
1821*5c51f124SMoriah Waterland  *		tag - [RO, *RO] - (SML_TAG *)
1822*5c51f124SMoriah Waterland  *			The tag object to compare against
1823*5c51f124SMoriah Waterland  *		path - [RO, *RO] - (char *)
1824*5c51f124SMoriah Waterland  *			Pointer to path name of file to compare
1825*5c51f124SMoriah Waterland  * Returns:	boolean_t
1826*5c51f124SMoriah Waterland  *			B_TRUE - both status structures are identical
1827*5c51f124SMoriah Waterland  *			B_FALSE - the status structures are not equal
1828*5c51f124SMoriah Waterland  */
1829*5c51f124SMoriah Waterland 
1830*5c51f124SMoriah Waterland boolean_t
smlFstatCompareEq(struct stat * statbuf,SML_TAG * tag,char * path)1831*5c51f124SMoriah Waterland smlFstatCompareEq(struct stat *statbuf, SML_TAG *tag, char *path)
1832*5c51f124SMoriah Waterland {
1833*5c51f124SMoriah Waterland 	if (tag == SML_TAG__NULL) {
1834*5c51f124SMoriah Waterland 		return (B_FALSE);
1835*5c51f124SMoriah Waterland 	}
1836*5c51f124SMoriah Waterland 
1837*5c51f124SMoriah Waterland 	assert(SML_TAG__ISVALID(tag));
1838*5c51f124SMoriah Waterland 
1839*5c51f124SMoriah Waterland 	if (statbuf == (struct stat *)NULL) {
1840*5c51f124SMoriah Waterland 		return (B_FALSE);
1841*5c51f124SMoriah Waterland 	}
1842*5c51f124SMoriah Waterland 
1843*5c51f124SMoriah Waterland 	if (path != (char *)NULL) {
1844*5c51f124SMoriah Waterland 		if (smlParamEq(tag,
1845*5c51f124SMoriah Waterland 			_sml_fileStatInfoTag, "st_path", path) != B_TRUE) {
1846*5c51f124SMoriah Waterland 			return (B_FALSE);
1847*5c51f124SMoriah Waterland 		}
1848*5c51f124SMoriah Waterland 	}
1849*5c51f124SMoriah Waterland 
1850*5c51f124SMoriah Waterland 	if (smlParamEqF(tag, _sml_fileStatInfoTag, "st_ino",
1851*5c51f124SMoriah Waterland 		"0x%llx", (unsigned long long)statbuf->st_ino) != B_TRUE) {
1852*5c51f124SMoriah Waterland 		return (B_FALSE);
1853*5c51f124SMoriah Waterland 	}
1854*5c51f124SMoriah Waterland 
1855*5c51f124SMoriah Waterland 	if (smlParamEqF(tag, _sml_fileStatInfoTag, "st_mode",
1856*5c51f124SMoriah Waterland 		"0x%llx", (unsigned long long)statbuf->st_mode) != B_TRUE) {
1857*5c51f124SMoriah Waterland 		return (B_FALSE);
1858*5c51f124SMoriah Waterland 	}
1859*5c51f124SMoriah Waterland 
1860*5c51f124SMoriah Waterland 	if (smlParamEqF(tag, _sml_fileStatInfoTag, "st_mtime",
1861*5c51f124SMoriah Waterland 		"0x%llx", (unsigned long long)statbuf->st_mtime) != B_TRUE) {
1862*5c51f124SMoriah Waterland 		return (B_FALSE);
1863*5c51f124SMoriah Waterland 	}
1864*5c51f124SMoriah Waterland 
1865*5c51f124SMoriah Waterland 	if (smlParamEqF(tag, _sml_fileStatInfoTag, "st_ctime",
1866*5c51f124SMoriah Waterland 		"0x%llx", (unsigned long long)statbuf->st_ctime) != B_TRUE) {
1867*5c51f124SMoriah Waterland 		return (B_FALSE);
1868*5c51f124SMoriah Waterland 	}
1869*5c51f124SMoriah Waterland 
1870*5c51f124SMoriah Waterland 	if (smlParamEqF(tag, _sml_fileStatInfoTag, "st_size",
1871*5c51f124SMoriah Waterland 		"0x%llx", (unsigned long long)statbuf->st_size) != B_TRUE) {
1872*5c51f124SMoriah Waterland 		return (B_FALSE);
1873*5c51f124SMoriah Waterland 	}
1874*5c51f124SMoriah Waterland 
1875*5c51f124SMoriah Waterland 	return (B_TRUE);
1876*5c51f124SMoriah Waterland }
1877*5c51f124SMoriah Waterland 
1878*5c51f124SMoriah Waterland /*
1879*5c51f124SMoriah Waterland  * Name:	set_verbose
1880*5c51f124SMoriah Waterland  * Description:	Turns on verbose output
1881*5c51f124SMoriah Waterland  * Scope:	public
1882*5c51f124SMoriah Waterland  * Arguments:	verbose = B_TRUE indicates verbose mode
1883*5c51f124SMoriah Waterland  * Returns:	none
1884*5c51f124SMoriah Waterland  */
1885*5c51f124SMoriah Waterland void
smlSetVerbose(boolean_t setting)1886*5c51f124SMoriah Waterland smlSetVerbose(boolean_t setting)
1887*5c51f124SMoriah Waterland {
1888*5c51f124SMoriah Waterland 	verbose = setting;
1889*5c51f124SMoriah Waterland }
1890*5c51f124SMoriah Waterland 
1891*5c51f124SMoriah Waterland /*
1892*5c51f124SMoriah Waterland  * Name:	get_verbose
1893*5c51f124SMoriah Waterland  * Description:	Returns whether or not to output verbose messages
1894*5c51f124SMoriah Waterland  * Scope:	public
1895*5c51f124SMoriah Waterland  * Arguments:	none
1896*5c51f124SMoriah Waterland  * Returns:	B_TRUE - verbose messages should be output
1897*5c51f124SMoriah Waterland  */
1898*5c51f124SMoriah Waterland boolean_t
smlGetVerbose()1899*5c51f124SMoriah Waterland smlGetVerbose()
1900*5c51f124SMoriah Waterland {
1901*5c51f124SMoriah Waterland 	return (verbose);
1902*5c51f124SMoriah Waterland }
1903*5c51f124SMoriah Waterland 
1904*5c51f124SMoriah Waterland /*
1905*5c51f124SMoriah Waterland  * Name:	sml_strPrintf
1906*5c51f124SMoriah Waterland  * Synopsis:	Create string from printf style format and arguments
1907*5c51f124SMoriah Waterland  * Description:	Call to convert a printf style format and arguments into a
1908*5c51f124SMoriah Waterland  *		string of characters placed in allocated storage
1909*5c51f124SMoriah Waterland  * Arguments:	format - [RO, RO*] (char *)
1910*5c51f124SMoriah Waterland  *			printf-style format for string to be formatted
1911*5c51f124SMoriah Waterland  *		... - [RO] (?)
1912*5c51f124SMoriah Waterland  *			arguments as appropriate to 'format' specified
1913*5c51f124SMoriah Waterland  * Returns:	char *
1914*5c51f124SMoriah Waterland  *			A string representing the printf conversion results
1915*5c51f124SMoriah Waterland  * NOTE:    	Any string returned is placed in new storage for the
1916*5c51f124SMoriah Waterland  *		calling method. The caller must use 'free' to dispose
1917*5c51f124SMoriah Waterland  *		of the storage once the string is no longer needed.
1918*5c51f124SMoriah Waterland  * Errors:	If the string cannot be created, the process exits
1919*5c51f124SMoriah Waterland  */
1920*5c51f124SMoriah Waterland 
1921*5c51f124SMoriah Waterland /*PRINTFLIKE1*/
1922*5c51f124SMoriah Waterland char *
sml_strPrintf(char * a_format,...)1923*5c51f124SMoriah Waterland sml_strPrintf(char *a_format, ...)
1924*5c51f124SMoriah Waterland {
1925*5c51f124SMoriah Waterland 	va_list	ap;
1926*5c51f124SMoriah Waterland 	size_t		vres = 0;
1927*5c51f124SMoriah Waterland 	char		bfr[1];
1928*5c51f124SMoriah Waterland 	char		*rstr = (char *)NULL;
1929*5c51f124SMoriah Waterland 
1930*5c51f124SMoriah Waterland 	/* entry assertions */
1931*5c51f124SMoriah Waterland 
1932*5c51f124SMoriah Waterland 	assert(a_format != (char *)NULL);
1933*5c51f124SMoriah Waterland 	assert(*a_format != '\0');
1934*5c51f124SMoriah Waterland 
1935*5c51f124SMoriah Waterland 	/* determine size of the message in bytes */
1936*5c51f124SMoriah Waterland 
1937*5c51f124SMoriah Waterland 	va_start(ap, a_format);
1938*5c51f124SMoriah Waterland 	vres = vsnprintf(bfr, 1, a_format, ap);
1939*5c51f124SMoriah Waterland 	va_end(ap);
1940*5c51f124SMoriah Waterland 
1941*5c51f124SMoriah Waterland 	assert(vres > 0);
1942*5c51f124SMoriah Waterland 
1943*5c51f124SMoriah Waterland 	/* allocate storage to hold the message */
1944*5c51f124SMoriah Waterland 
1945*5c51f124SMoriah Waterland 	rstr = (char *)calloc(1, vres+2);
1946*5c51f124SMoriah Waterland 	assert(rstr != (char *)NULL);
1947*5c51f124SMoriah Waterland 
1948*5c51f124SMoriah Waterland 	/* generate the results of the printf conversion */
1949*5c51f124SMoriah Waterland 
1950*5c51f124SMoriah Waterland 	va_start(ap, a_format);
1951*5c51f124SMoriah Waterland 	vres = vsnprintf(rstr, vres+1, a_format, ap);
1952*5c51f124SMoriah Waterland 	va_end(ap);
1953*5c51f124SMoriah Waterland 
1954*5c51f124SMoriah Waterland 	assert(vres > 0);
1955*5c51f124SMoriah Waterland 	assert(*rstr != '\0');
1956*5c51f124SMoriah Waterland 
1957*5c51f124SMoriah Waterland 	/* return the results */
1958*5c51f124SMoriah Waterland 
1959*5c51f124SMoriah Waterland 	return (rstr);
1960*5c51f124SMoriah Waterland }
1961*5c51f124SMoriah Waterland 
1962*5c51f124SMoriah Waterland /*
1963*5c51f124SMoriah Waterland  * Name:	sml_strPrintf_r
1964*5c51f124SMoriah Waterland  * Synopsis:	Create string from printf style format and arguments
1965*5c51f124SMoriah Waterland  * Description:	Call to convert a printf style format and arguments into a
1966*5c51f124SMoriah Waterland  *		string of characters placed in allocated storage
1967*5c51f124SMoriah Waterland  * Arguments:	a_buf - [RO, *RW] - (char *)
1968*5c51f124SMoriah Waterland  *			- Pointer to buffer used as storage space for the
1969*5c51f124SMoriah Waterland  *			  returned string created
1970*5c51f124SMoriah Waterland  *		a_bufLen - [RO, *RO] - (int)
1971*5c51f124SMoriah Waterland  *			- Size of 'a_buf' in bytes - a maximum of 'a_bufLen-1'
1972*5c51f124SMoriah Waterland  *			  bytes will be placed in 'a_buf' - the returned
1973*5c51f124SMoriah Waterland  *			  string is always null terminated
1974*5c51f124SMoriah Waterland  *		a_format - [RO, RO*] (char *)
1975*5c51f124SMoriah Waterland  *			printf-style format for string to be formatted
1976*5c51f124SMoriah Waterland  *		VARG_LIST - [RO] (?)
1977*5c51f124SMoriah Waterland  *			arguments as appropriate to 'format' specified
1978*5c51f124SMoriah Waterland  * Returns:	void
1979*5c51f124SMoriah Waterland  */
1980*5c51f124SMoriah Waterland 
1981*5c51f124SMoriah Waterland /*PRINTFLIKE3*/
1982*5c51f124SMoriah Waterland void
sml_strPrintf_r(char * a_buf,int a_bufLen,char * a_format,...)1983*5c51f124SMoriah Waterland sml_strPrintf_r(char *a_buf, int a_bufLen, char *a_format, ...)
1984*5c51f124SMoriah Waterland {
1985*5c51f124SMoriah Waterland 	va_list	ap;
1986*5c51f124SMoriah Waterland 	size_t		vres = 0;
1987*5c51f124SMoriah Waterland 
1988*5c51f124SMoriah Waterland 	/* entry assertions */
1989*5c51f124SMoriah Waterland 
1990*5c51f124SMoriah Waterland 	assert(a_format != (char *)NULL);
1991*5c51f124SMoriah Waterland 	assert(*a_format != '\0');
1992*5c51f124SMoriah Waterland 	assert(a_buf != (char *)NULL);
1993*5c51f124SMoriah Waterland 	assert(a_bufLen > 1);
1994*5c51f124SMoriah Waterland 
1995*5c51f124SMoriah Waterland 	/* generate the results of the printf conversion */
1996*5c51f124SMoriah Waterland 
1997*5c51f124SMoriah Waterland 	va_start(ap, a_format);
1998*5c51f124SMoriah Waterland 	vres = vsnprintf(a_buf, a_bufLen-1, a_format, ap);
1999*5c51f124SMoriah Waterland 	va_end(ap);
2000*5c51f124SMoriah Waterland 
2001*5c51f124SMoriah Waterland 	assert(vres > 0);
2002*5c51f124SMoriah Waterland 	assert(vres < a_bufLen);
2003*5c51f124SMoriah Waterland 
2004*5c51f124SMoriah Waterland 	a_buf[a_bufLen-1] = '\0';
2005*5c51f124SMoriah Waterland }
2006*5c51f124SMoriah Waterland 
2007*5c51f124SMoriah Waterland /*
2008*5c51f124SMoriah Waterland  * Name:	sml_XmlEncodeString
2009*5c51f124SMoriah Waterland  * Description:	Given a plain text string, convert that string into one that
2010*5c51f124SMoriah Waterland  *		encoded using the XML character reference encoding format.
2011*5c51f124SMoriah Waterland  * Arguments:	a_plain_text_string	- [RO, *RO] (char *)
2012*5c51f124SMoriah Waterland  *			The plain text string to convert (encode)
2013*5c51f124SMoriah Waterland  * Returns:	char *
2014*5c51f124SMoriah Waterland  *			The encoded form of the plain text string provided
2015*5c51f124SMoriah Waterland  * NOTE:    	Any string returned is placed in new storage for the
2016*5c51f124SMoriah Waterland  *		calling method. The caller must use 'lu_memFree' to dispose
2017*5c51f124SMoriah Waterland  *		of the storage once the string is no longer needed.
2018*5c51f124SMoriah Waterland  */
2019*5c51f124SMoriah Waterland 
2020*5c51f124SMoriah Waterland char *
sml_XmlEncodeString(char * a_plainTextString)2021*5c51f124SMoriah Waterland sml_XmlEncodeString(char *a_plainTextString)
2022*5c51f124SMoriah Waterland {
2023*5c51f124SMoriah Waterland 	char *stringHead;	/* -> start of string containing encoded data */
2024*5c51f124SMoriah Waterland 	long stringTail;	/* byte pos of first free byte in stringHead */
2025*5c51f124SMoriah Waterland 	long stringLength;	/* total bytes allocd starting at stringHead */
2026*5c51f124SMoriah Waterland 	char *p;		/* temp -> to retrieve bytes from src string */
2027*5c51f124SMoriah Waterland 	long textLength = 0;	/* length of the string to convert */
2028*5c51f124SMoriah Waterland 
2029*5c51f124SMoriah Waterland 	/* entry assertions */
2030*5c51f124SMoriah Waterland 
2031*5c51f124SMoriah Waterland 	assert(a_plainTextString != (char *)NULL);
2032*5c51f124SMoriah Waterland 
2033*5c51f124SMoriah Waterland 	textLength = strlen(a_plainTextString);
2034*5c51f124SMoriah Waterland 
2035*5c51f124SMoriah Waterland 	/* Allocate initial string buffer to hold results */
2036*5c51f124SMoriah Waterland 
2037*5c51f124SMoriah Waterland 	stringLength = textLength*2;
2038*5c51f124SMoriah Waterland 	stringTail = 0;
2039*5c51f124SMoriah Waterland 	stringHead = (char *)calloc(1, (size_t)stringLength+2);
2040*5c51f124SMoriah Waterland 	assert(stringHead != (char *)NULL);
2041*5c51f124SMoriah Waterland 
2042*5c51f124SMoriah Waterland 	/* Add in the encoded message text */
2043*5c51f124SMoriah Waterland 
2044*5c51f124SMoriah Waterland 	for (p = a_plainTextString; textLength > 0; p++, textLength--) {
2045*5c51f124SMoriah Waterland 		/*
2046*5c51f124SMoriah Waterland 		 * Must have at least 12 bytes: this must be at least the
2047*5c51f124SMoriah Waterland 		 * maximum number of bytes that can be added for a single
2048*5c51f124SMoriah Waterland 		 * byte as the last byte of the stream. Assuming the byte
2049*5c51f124SMoriah Waterland 		 * needs to be encoded, it could be:
2050*5c51f124SMoriah Waterland 		 * &#xxxxxxxx;\0
2051*5c51f124SMoriah Waterland 		 * If not that many bytes left, grow the buffer.
2052*5c51f124SMoriah Waterland 		 */
2053*5c51f124SMoriah Waterland 
2054*5c51f124SMoriah Waterland 		if ((stringLength-stringTail) < 12) {
2055*5c51f124SMoriah Waterland 			stringLength += (textLength*2)+12;
2056*5c51f124SMoriah Waterland 			stringHead =
2057*5c51f124SMoriah Waterland 				realloc(stringHead,
2058*5c51f124SMoriah Waterland 					(size_t)stringLength+2);
2059*5c51f124SMoriah Waterland 			assert(stringHead != (char *)NULL);
2060*5c51f124SMoriah Waterland 		}
2061*5c51f124SMoriah Waterland 
2062*5c51f124SMoriah Waterland 		/*
2063*5c51f124SMoriah Waterland 		 * See if this byte is a 'printable 7-bit ascii value'.
2064*5c51f124SMoriah Waterland 		 * If so just add it to the new string; otherwise, must
2065*5c51f124SMoriah Waterland 		 * output an XML character value encoding for the byte.
2066*5c51f124SMoriah Waterland 		 */
2067*5c51f124SMoriah Waterland 
2068*5c51f124SMoriah Waterland 		switch (*p) {
2069*5c51f124SMoriah Waterland 		case '!':
2070*5c51f124SMoriah Waterland 		case '#':
2071*5c51f124SMoriah Waterland 		case '%':
2072*5c51f124SMoriah Waterland 		case '\'':
2073*5c51f124SMoriah Waterland 		case '(':
2074*5c51f124SMoriah Waterland 		case ')':
2075*5c51f124SMoriah Waterland 		case '*':
2076*5c51f124SMoriah Waterland 		case '+':
2077*5c51f124SMoriah Waterland 		case ',':
2078*5c51f124SMoriah Waterland 		case '-':
2079*5c51f124SMoriah Waterland 		case '.':
2080*5c51f124SMoriah Waterland 		case '/':
2081*5c51f124SMoriah Waterland 		case '0':
2082*5c51f124SMoriah Waterland 		case '1':
2083*5c51f124SMoriah Waterland 		case '2':
2084*5c51f124SMoriah Waterland 		case '3':
2085*5c51f124SMoriah Waterland 		case '4':
2086*5c51f124SMoriah Waterland 		case '5':
2087*5c51f124SMoriah Waterland 		case '6':
2088*5c51f124SMoriah Waterland 		case '7':
2089*5c51f124SMoriah Waterland 		case '8':
2090*5c51f124SMoriah Waterland 		case '9':
2091*5c51f124SMoriah Waterland 		case ':':
2092*5c51f124SMoriah Waterland 		case ';':
2093*5c51f124SMoriah Waterland 		case '<':
2094*5c51f124SMoriah Waterland 		case '=':
2095*5c51f124SMoriah Waterland 		case '>':
2096*5c51f124SMoriah Waterland 		case '?':
2097*5c51f124SMoriah Waterland 		case '@':
2098*5c51f124SMoriah Waterland 		case 'A':
2099*5c51f124SMoriah Waterland 		case 'B':
2100*5c51f124SMoriah Waterland 		case 'C':
2101*5c51f124SMoriah Waterland 		case 'D':
2102*5c51f124SMoriah Waterland 		case 'E':
2103*5c51f124SMoriah Waterland 		case 'F':
2104*5c51f124SMoriah Waterland 		case 'G':
2105*5c51f124SMoriah Waterland 		case 'H':
2106*5c51f124SMoriah Waterland 		case 'I':
2107*5c51f124SMoriah Waterland 		case 'J':
2108*5c51f124SMoriah Waterland 		case 'K':
2109*5c51f124SMoriah Waterland 		case 'L':
2110*5c51f124SMoriah Waterland 		case 'M':
2111*5c51f124SMoriah Waterland 		case 'N':
2112*5c51f124SMoriah Waterland 		case 'O':
2113*5c51f124SMoriah Waterland 		case 'P':
2114*5c51f124SMoriah Waterland 		case 'Q':
2115*5c51f124SMoriah Waterland 		case 'R':
2116*5c51f124SMoriah Waterland 		case 'S':
2117*5c51f124SMoriah Waterland 		case 'T':
2118*5c51f124SMoriah Waterland 		case 'U':
2119*5c51f124SMoriah Waterland 		case 'V':
2120*5c51f124SMoriah Waterland 		case 'W':
2121*5c51f124SMoriah Waterland 		case 'X':
2122*5c51f124SMoriah Waterland 		case 'Y':
2123*5c51f124SMoriah Waterland 		case 'Z':
2124*5c51f124SMoriah Waterland 		case '[':
2125*5c51f124SMoriah Waterland 		case ']':
2126*5c51f124SMoriah Waterland 		case '^':
2127*5c51f124SMoriah Waterland 		case '_':
2128*5c51f124SMoriah Waterland 		case 'a':
2129*5c51f124SMoriah Waterland 		case 'b':
2130*5c51f124SMoriah Waterland 		case 'c':
2131*5c51f124SMoriah Waterland 		case 'd':
2132*5c51f124SMoriah Waterland 		case 'e':
2133*5c51f124SMoriah Waterland 		case 'f':
2134*5c51f124SMoriah Waterland 		case 'g':
2135*5c51f124SMoriah Waterland 		case 'h':
2136*5c51f124SMoriah Waterland 		case 'i':
2137*5c51f124SMoriah Waterland 		case 'j':
2138*5c51f124SMoriah Waterland 		case 'k':
2139*5c51f124SMoriah Waterland 		case 'l':
2140*5c51f124SMoriah Waterland 		case 'm':
2141*5c51f124SMoriah Waterland 		case 'n':
2142*5c51f124SMoriah Waterland 		case 'o':
2143*5c51f124SMoriah Waterland 		case 'p':
2144*5c51f124SMoriah Waterland 		case 'q':
2145*5c51f124SMoriah Waterland 		case 'r':
2146*5c51f124SMoriah Waterland 		case 's':
2147*5c51f124SMoriah Waterland 		case 't':
2148*5c51f124SMoriah Waterland 		case 'u':
2149*5c51f124SMoriah Waterland 		case 'v':
2150*5c51f124SMoriah Waterland 		case 'w':
2151*5c51f124SMoriah Waterland 		case 'x':
2152*5c51f124SMoriah Waterland 		case 'y':
2153*5c51f124SMoriah Waterland 		case 'z':
2154*5c51f124SMoriah Waterland 		case '{':
2155*5c51f124SMoriah Waterland 		case '|':
2156*5c51f124SMoriah Waterland 		case '}':
2157*5c51f124SMoriah Waterland 		case '~':
2158*5c51f124SMoriah Waterland 		case ' ':
2159*5c51f124SMoriah Waterland 			/*
2160*5c51f124SMoriah Waterland 			 * It is a printable 7-bit ascii character:
2161*5c51f124SMoriah Waterland 			 * just add it to the end of the new string.
2162*5c51f124SMoriah Waterland 			 */
2163*5c51f124SMoriah Waterland 
2164*5c51f124SMoriah Waterland 			stringHead[stringTail++] = *p;
2165*5c51f124SMoriah Waterland 			break;
2166*5c51f124SMoriah Waterland 		default:
2167*5c51f124SMoriah Waterland 			/*
2168*5c51f124SMoriah Waterland 			 * It is not a printable 7-bit ascii character:
2169*5c51f124SMoriah Waterland 			 * add it as an xml character value encoding.
2170*5c51f124SMoriah Waterland 			 */
2171*5c51f124SMoriah Waterland 
2172*5c51f124SMoriah Waterland 			stringTail += sprintf(&stringHead[stringTail], "&#%x;",
2173*5c51f124SMoriah Waterland 					(*p)&0xFF);
2174*5c51f124SMoriah Waterland 			break;
2175*5c51f124SMoriah Waterland 		}
2176*5c51f124SMoriah Waterland 	}
2177*5c51f124SMoriah Waterland 
2178*5c51f124SMoriah Waterland 	/* Terminate the new string */
2179*5c51f124SMoriah Waterland 
2180*5c51f124SMoriah Waterland 	stringHead[stringTail] = '\0';
2181*5c51f124SMoriah Waterland 
2182*5c51f124SMoriah Waterland 	/* realloc the string so it is only as big as it needs to be */
2183*5c51f124SMoriah Waterland 
2184*5c51f124SMoriah Waterland 	stringHead = realloc(stringHead, stringTail+1);
2185*5c51f124SMoriah Waterland 	assert(stringHead != (char *)NULL);
2186*5c51f124SMoriah Waterland 
2187*5c51f124SMoriah Waterland 	return (stringHead);
2188*5c51f124SMoriah Waterland }
2189*5c51f124SMoriah Waterland 
2190*5c51f124SMoriah Waterland /*
2191*5c51f124SMoriah Waterland  * Name:	sml_XmlDecodeString
2192*5c51f124SMoriah Waterland  * Description:	Given a string encoded using the XML character reference format,
2193*5c51f124SMoriah Waterland  *		convert that string into a plain text (unencoded) string.
2194*5c51f124SMoriah Waterland  * Arguments:	a_xml_encoded_string	- [RO, *RO] (char *)
2195*5c51f124SMoriah Waterland  *			The XML encoded string to convert to plain text
2196*5c51f124SMoriah Waterland  * Returns:	char *
2197*5c51f124SMoriah Waterland  *			The unencoded (plain text) form of the encoded string
2198*5c51f124SMoriah Waterland  * NOTE:    	Any string returned is placed in new storage for the
2199*5c51f124SMoriah Waterland  *		calling method. The caller must use 'lu_memFree' to dispose
2200*5c51f124SMoriah Waterland  *		of the storage once the string is no longer needed.
2201*5c51f124SMoriah Waterland  */
2202*5c51f124SMoriah Waterland 
2203*5c51f124SMoriah Waterland char *
sml_XmlDecodeString(char * a_xmlEncodedString)2204*5c51f124SMoriah Waterland sml_XmlDecodeString(char *a_xmlEncodedString)
2205*5c51f124SMoriah Waterland {
2206*5c51f124SMoriah Waterland 	char *s = NULL;		/* -> index into encoded bytes string */
2207*5c51f124SMoriah Waterland 	char *d = NULL;		/* -> index into decoded bytes string */
2208*5c51f124SMoriah Waterland 	char *rs = NULL;	/* -> string holding ref bytes allocated */
2209*5c51f124SMoriah Waterland 	char *ri = NULL;	/* -> index into string holding reference */
2210*5c51f124SMoriah Waterland 	long textLength = 0;	/* length of encoded string to decode */
2211*5c51f124SMoriah Waterland 	unsigned long rv = 0;	/* temp to hold scanf results of byte conv */
2212*5c51f124SMoriah Waterland 	char *i = NULL;		/* temp to hold strchr results */
2213*5c51f124SMoriah Waterland 	char *stringHead = NULL;	/* -> plain test buffer */
2214*5c51f124SMoriah Waterland 	ptrdiff_t tmpdiff;
2215*5c51f124SMoriah Waterland 
2216*5c51f124SMoriah Waterland 	/*
2217*5c51f124SMoriah Waterland 	 * A finite state machine is used to convert the xml encoded string
2218*5c51f124SMoriah Waterland 	 * into plain text. The states of the machine are defined below.
2219*5c51f124SMoriah Waterland 	 */
2220*5c51f124SMoriah Waterland 
2221*5c51f124SMoriah Waterland 	int fsmsState = -1;	/* Finite state machine state */
2222*5c51f124SMoriah Waterland #define	fsms_text	0	/* Decoding plain text */
2223*5c51f124SMoriah Waterland #define	fsms_seenAmp	1	/* Found & */
2224*5c51f124SMoriah Waterland #define	fsms_seenPound	2	/* Found # following & */
2225*5c51f124SMoriah Waterland #define	fsms_collect	3	/* Collecting character reference bytes */
2226*5c51f124SMoriah Waterland 
2227*5c51f124SMoriah Waterland 	/* entry assertions */
2228*5c51f124SMoriah Waterland 
2229*5c51f124SMoriah Waterland 	assert(a_xmlEncodedString != (char *)NULL);
2230*5c51f124SMoriah Waterland 
2231*5c51f124SMoriah Waterland 	textLength = strlen(a_xmlEncodedString);
2232*5c51f124SMoriah Waterland 
2233*5c51f124SMoriah Waterland 	/*
2234*5c51f124SMoriah Waterland 	 * Allocate string that can contain the decoded string.
2235*5c51f124SMoriah Waterland 	 * Since decoding always results in a shorter string (bytes encoded
2236*5c51f124SMoriah Waterland 	 * using the XML character reference are larger in the encoded form)
2237*5c51f124SMoriah Waterland 	 * we can allocate a string the same size as the encoded string.
2238*5c51f124SMoriah Waterland 	 */
2239*5c51f124SMoriah Waterland 
2240*5c51f124SMoriah Waterland 	stringHead = (char *)calloc(1, textLength+1);
2241*5c51f124SMoriah Waterland 	assert(stringHead != (char *)NULL);
2242*5c51f124SMoriah Waterland 
2243*5c51f124SMoriah Waterland 	/*
2244*5c51f124SMoriah Waterland 	 * Convert all bytes.
2245*5c51f124SMoriah Waterland 	 */
2246*5c51f124SMoriah Waterland 
2247*5c51f124SMoriah Waterland 	/* Decoding plain text */
2248*5c51f124SMoriah Waterland 	fsmsState = fsms_text;
2249*5c51f124SMoriah Waterland 
2250*5c51f124SMoriah Waterland 	for (s = a_xmlEncodedString, d = stringHead; textLength > 0;
2251*5c51f124SMoriah Waterland 		s++, textLength--) {
2252*5c51f124SMoriah Waterland 		switch (fsmsState) {
2253*5c51f124SMoriah Waterland 		case fsms_text:	/* Decoding plain text */
2254*5c51f124SMoriah Waterland 			if (rs != NULL) {
2255*5c51f124SMoriah Waterland 				free(rs);
2256*5c51f124SMoriah Waterland 				rs = NULL;
2257*5c51f124SMoriah Waterland 				ri = NULL;
2258*5c51f124SMoriah Waterland 			}
2259*5c51f124SMoriah Waterland 			if (*s == '&') {
2260*5c51f124SMoriah Waterland 				/* Found & */
2261*5c51f124SMoriah Waterland 				fsmsState = fsms_seenAmp;
2262*5c51f124SMoriah Waterland 				continue;
2263*5c51f124SMoriah Waterland 			}
2264*5c51f124SMoriah Waterland 			*d++ = *s;
2265*5c51f124SMoriah Waterland 			continue;
2266*5c51f124SMoriah Waterland 
2267*5c51f124SMoriah Waterland 		case fsms_seenAmp:	/* Found & */
2268*5c51f124SMoriah Waterland 			if (*s == '#') {
2269*5c51f124SMoriah Waterland 				/* Found # following & */
2270*5c51f124SMoriah Waterland 				fsmsState = fsms_seenPound;
2271*5c51f124SMoriah Waterland 				continue;
2272*5c51f124SMoriah Waterland 			}
2273*5c51f124SMoriah Waterland 			fsmsState = fsms_text;	/* Decoding plain text */
2274*5c51f124SMoriah Waterland 			*d++ = '&';
2275*5c51f124SMoriah Waterland 			*d++ = *s;
2276*5c51f124SMoriah Waterland 			continue;
2277*5c51f124SMoriah Waterland 
2278*5c51f124SMoriah Waterland 		case fsms_seenPound:		/* Found # following & */
2279*5c51f124SMoriah Waterland 			i = strchr(s, ';');
2280*5c51f124SMoriah Waterland 			if (i == NULL) {
2281*5c51f124SMoriah Waterland 				/* Decoding plain text */
2282*5c51f124SMoriah Waterland 				fsmsState = fsms_text;
2283*5c51f124SMoriah Waterland 				*d++ = '&';
2284*5c51f124SMoriah Waterland 				*d++ = '#';
2285*5c51f124SMoriah Waterland 				*d++ = *s;
2286*5c51f124SMoriah Waterland 				continue;
2287*5c51f124SMoriah Waterland 			}
2288*5c51f124SMoriah Waterland 			tmpdiff = (ptrdiff_t)i - (ptrdiff_t)s;
2289*5c51f124SMoriah Waterland 			rs = (char *)calloc(1, tmpdiff + 1);
2290*5c51f124SMoriah Waterland 			assert(rs != (char *)NULL);
2291*5c51f124SMoriah Waterland 			ri = rs;
2292*5c51f124SMoriah Waterland 			/* Collecting character reference bytes */
2293*5c51f124SMoriah Waterland 			fsmsState = fsms_collect;
2294*5c51f124SMoriah Waterland 
2295*5c51f124SMoriah Waterland 			/*FALLTHRU*/
2296*5c51f124SMoriah Waterland 
2297*5c51f124SMoriah Waterland 		/* Collecting character reference bytes */
2298*5c51f124SMoriah Waterland 		case fsms_collect:
2299*5c51f124SMoriah Waterland 			if (*s != ';') {
2300*5c51f124SMoriah Waterland 				switch (*s) {
2301*5c51f124SMoriah Waterland 				case '0':
2302*5c51f124SMoriah Waterland 				case '1':
2303*5c51f124SMoriah Waterland 				case '2':
2304*5c51f124SMoriah Waterland 				case '3':
2305*5c51f124SMoriah Waterland 				case '4':
2306*5c51f124SMoriah Waterland 				case '5':
2307*5c51f124SMoriah Waterland 				case '6':
2308*5c51f124SMoriah Waterland 				case '7':
2309*5c51f124SMoriah Waterland 				case '8':
2310*5c51f124SMoriah Waterland 				case '9':
2311*5c51f124SMoriah Waterland 				case 'a':
2312*5c51f124SMoriah Waterland 				case 'b':
2313*5c51f124SMoriah Waterland 				case 'c':
2314*5c51f124SMoriah Waterland 				case 'd':
2315*5c51f124SMoriah Waterland 				case 'e':
2316*5c51f124SMoriah Waterland 				case 'f':
2317*5c51f124SMoriah Waterland 				case 'A':
2318*5c51f124SMoriah Waterland 				case 'B':
2319*5c51f124SMoriah Waterland 				case 'C':
2320*5c51f124SMoriah Waterland 				case 'D':
2321*5c51f124SMoriah Waterland 				case 'E':
2322*5c51f124SMoriah Waterland 				case 'F':
2323*5c51f124SMoriah Waterland 					*ri++ = *s;
2324*5c51f124SMoriah Waterland 					break;
2325*5c51f124SMoriah Waterland 				default:
2326*5c51f124SMoriah Waterland 					*ri = '\0';
2327*5c51f124SMoriah Waterland 					*d++ = '&';
2328*5c51f124SMoriah Waterland 					*d++ = '#';
2329*5c51f124SMoriah Waterland 					tmpdiff = (ptrdiff_t)ri - (ptrdiff_t)rs;
2330*5c51f124SMoriah Waterland 					(void) strncpy(d, rs, tmpdiff-1);
2331*5c51f124SMoriah Waterland 					*d++ = *s;
2332*5c51f124SMoriah Waterland 					/* Decoding plain text */
2333*5c51f124SMoriah Waterland 					fsmsState = fsms_text;
2334*5c51f124SMoriah Waterland 					break;
2335*5c51f124SMoriah Waterland 				}
2336*5c51f124SMoriah Waterland 				continue;
2337*5c51f124SMoriah Waterland 			}
2338*5c51f124SMoriah Waterland 			*ri = '\0';
2339*5c51f124SMoriah Waterland 			if (sscanf(rs, "%lx", &rv) != 1) {
2340*5c51f124SMoriah Waterland 				*d++ = '?';
2341*5c51f124SMoriah Waterland 			} else {
2342*5c51f124SMoriah Waterland 				*d++ = (rv & 0xFF);
2343*5c51f124SMoriah Waterland 			}
2344*5c51f124SMoriah Waterland 			/* Decoding plain text */
2345*5c51f124SMoriah Waterland 			fsmsState = fsms_text;
2346*5c51f124SMoriah Waterland 		}
2347*5c51f124SMoriah Waterland 	}
2348*5c51f124SMoriah Waterland 
2349*5c51f124SMoriah Waterland 	/* Done converting bytes - deallocate reference byte storage */
2350*5c51f124SMoriah Waterland 
2351*5c51f124SMoriah Waterland 	free(rs);
2352*5c51f124SMoriah Waterland 
2353*5c51f124SMoriah Waterland 	/* terminate the converted (plain text) string */
2354*5c51f124SMoriah Waterland 
2355*5c51f124SMoriah Waterland 	*d = '\0';
2356*5c51f124SMoriah Waterland 
2357*5c51f124SMoriah Waterland 	/* exit assertions */
2358*5c51f124SMoriah Waterland 
2359*5c51f124SMoriah Waterland 	assert(stringHead != (char *)NULL);
2360*5c51f124SMoriah Waterland 
2361*5c51f124SMoriah Waterland 	return (stringHead);
2362*5c51f124SMoriah Waterland }
2363*5c51f124SMoriah Waterland 
2364*5c51f124SMoriah Waterland /*
2365*5c51f124SMoriah Waterland  * Private Methods
2366*5c51f124SMoriah Waterland  */
2367*5c51f124SMoriah Waterland 
2368*5c51f124SMoriah Waterland /*
2369*5c51f124SMoriah Waterland  * Name:	_smlReadTag
2370*5c51f124SMoriah Waterland  * Description:	read complete tag from a datastream
2371*5c51f124SMoriah Waterland  * Arguments:	err - [RO, *RW] (LU_ERR)
2372*5c51f124SMoriah Waterland  *			Error object - used to contain any errors encountered
2373*5c51f124SMoriah Waterland  *			and return those errors to this methods caller
2374*5c51f124SMoriah Waterland  *		r_tag - [RW, *RW] - (SML_TAG **)
2375*5c51f124SMoriah Waterland  *			Pointer to handle to place new tag object
2376*5c51f124SMoriah Waterland  *			== SML_TAG__NULL if empty tag found (not an error)
2377*5c51f124SMoriah Waterland  *		ds - [RO, *RO] - (LU_DS)
2378*5c51f124SMoriah Waterland  *			Handle to datastream to read tag from
2379*5c51f124SMoriah Waterland  *		parent - [RO, *RO] - (char *)
2380*5c51f124SMoriah Waterland  *			Name for parent of tag (NONE if top of tag)
2381*5c51f124SMoriah Waterland  * Returns:	int
2382*5c51f124SMoriah Waterland  *			RESULT_OK - tag successfully read
2383*5c51f124SMoriah Waterland  *			RESULT_ERR - problem reading tag
2384*5c51f124SMoriah Waterland  * NOTE:    	Any tag object returned is placed in new storage for the
2385*5c51f124SMoriah Waterland  *		calling method. The caller must use 'smlFreeTag' to dispose
2386*5c51f124SMoriah Waterland  *		of the storage once the tag object name is no longer needed.
2387*5c51f124SMoriah Waterland  * Errors:	If the tag object cannot be duplicated, the process exits
2388*5c51f124SMoriah Waterland  */
2389*5c51f124SMoriah Waterland 
2390*5c51f124SMoriah Waterland static int
_smlReadTag(SML_TAG ** r_tag,char ** a_str,char * parent)2391*5c51f124SMoriah Waterland _smlReadTag(SML_TAG **r_tag, char **a_str, char *parent)
2392*5c51f124SMoriah Waterland {
2393*5c51f124SMoriah Waterland 	int	r;
2394*5c51f124SMoriah Waterland 	SML_TAG	*tag;
2395*5c51f124SMoriah Waterland 	SML_TAG	*tmp_tag;
2396*5c51f124SMoriah Waterland 	char	name[MAX_SML_COMPONENT_LENGTH];
2397*5c51f124SMoriah Waterland 	int	pos = 0;
2398*5c51f124SMoriah Waterland 	int	c;
2399*5c51f124SMoriah Waterland 	char	*p = *a_str;
2400*5c51f124SMoriah Waterland 
2401*5c51f124SMoriah Waterland 	/* entry assertions */
2402*5c51f124SMoriah Waterland 
2403*5c51f124SMoriah Waterland 	assert(SML_TAG__R_ISVALID(r_tag));
2404*5c51f124SMoriah Waterland 	assert(a_str != (char **)NULL);
2405*5c51f124SMoriah Waterland 
2406*5c51f124SMoriah Waterland 	/* entry debugging info */
2407*5c51f124SMoriah Waterland 
2408*5c51f124SMoriah Waterland 	_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_READ_TAG,
2409*5c51f124SMoriah Waterland 		parent ? parent : "<<TOP TAG>>");
2410*5c51f124SMoriah Waterland 
2411*5c51f124SMoriah Waterland 	/* reset return tag */
2412*5c51f124SMoriah Waterland 
2413*5c51f124SMoriah Waterland 	*r_tag = SML_TAG__NULL;
2414*5c51f124SMoriah Waterland 
2415*5c51f124SMoriah Waterland 	/* allocate zeroed storage for the tag object */
2416*5c51f124SMoriah Waterland 
2417*5c51f124SMoriah Waterland 	tag = (SML_TAG *)calloc(1, sizeof (SML_TAG));
2418*5c51f124SMoriah Waterland 	assert(tag != SML_TAG__NULL);
2419*5c51f124SMoriah Waterland 
2420*5c51f124SMoriah Waterland 	/* reset name accumulator storage */
2421*5c51f124SMoriah Waterland 
2422*5c51f124SMoriah Waterland 	bzero(name, sizeof (name));
2423*5c51f124SMoriah Waterland 
2424*5c51f124SMoriah Waterland 	/* ignore delimters before tag */
2425*5c51f124SMoriah Waterland 
2426*5c51f124SMoriah Waterland 	for (;;) {
2427*5c51f124SMoriah Waterland 		/* read tag character - handle failure/EOF */
2428*5c51f124SMoriah Waterland 
2429*5c51f124SMoriah Waterland 		if ((*p == '\0') || ((c = (*p++)) == '\0')) {
2430*5c51f124SMoriah Waterland 			if (parent == NULL) {
2431*5c51f124SMoriah Waterland 				_smlLogMsg(LOG_MSG_DEBUG,
2432*5c51f124SMoriah Waterland 					DBG_SML_READTAG_EXPECTED_EOF,
2433*5c51f124SMoriah Waterland 					p ? p : "?");
2434*5c51f124SMoriah Waterland 				smlFreeTag(tag);
2435*5c51f124SMoriah Waterland 				*a_str = p;
2436*5c51f124SMoriah Waterland 				return (RESULT_OK);
2437*5c51f124SMoriah Waterland 			}
2438*5c51f124SMoriah Waterland 
2439*5c51f124SMoriah Waterland 			/* EOF in middle of processing tag */
2440*5c51f124SMoriah Waterland 
2441*5c51f124SMoriah Waterland 			_smlLogMsg(LOG_MSG_ERR,
2442*5c51f124SMoriah Waterland 				DBG_SML_READTAG_UNEXPECTED_EOF,
2443*5c51f124SMoriah Waterland 				p ? p : "?");
2444*5c51f124SMoriah Waterland 			smlFreeTag(tag);
2445*5c51f124SMoriah Waterland 			*a_str = p;
2446*5c51f124SMoriah Waterland 			return (RESULT_ERR);
2447*5c51f124SMoriah Waterland 		}
2448*5c51f124SMoriah Waterland 
2449*5c51f124SMoriah Waterland 		/* if beginning of tag, break out */
2450*5c51f124SMoriah Waterland 
2451*5c51f124SMoriah Waterland 		if (c == '<') {
2452*5c51f124SMoriah Waterland 			break;
2453*5c51f124SMoriah Waterland 		}
2454*5c51f124SMoriah Waterland 
2455*5c51f124SMoriah Waterland 		/* not tag beginning: ignore delimiters if not inside tag yet */
2456*5c51f124SMoriah Waterland 
2457*5c51f124SMoriah Waterland 		if (parent == (char *)NULL) {
2458*5c51f124SMoriah Waterland 			/* ignore delimters */
2459*5c51f124SMoriah Waterland 
2460*5c51f124SMoriah Waterland 			if (strchr(" \t", c) != (char *)NULL) {
2461*5c51f124SMoriah Waterland 				continue;
2462*5c51f124SMoriah Waterland 			}
2463*5c51f124SMoriah Waterland 
2464*5c51f124SMoriah Waterland 			/* on blank lines, return no tag object */
2465*5c51f124SMoriah Waterland 
2466*5c51f124SMoriah Waterland 			if (c == '\n') {
2467*5c51f124SMoriah Waterland 				_smlLogMsg(LOG_MSG_DEBUG,
2468*5c51f124SMoriah Waterland 					DBG_SML_READTAG_BLANKLINE,
2469*5c51f124SMoriah Waterland 					p ? p : "?");
2470*5c51f124SMoriah Waterland 				smlFreeTag(tag);
2471*5c51f124SMoriah Waterland 				*a_str = p;
2472*5c51f124SMoriah Waterland 				return (RESULT_OK);
2473*5c51f124SMoriah Waterland 			}
2474*5c51f124SMoriah Waterland 
2475*5c51f124SMoriah Waterland 			/* invalid character before tag start */
2476*5c51f124SMoriah Waterland 
2477*5c51f124SMoriah Waterland 			_smlLogMsg(LOG_MSG_ERR, ERR_SML_READTAG_BAD_START_CHAR,
2478*5c51f124SMoriah Waterland 				c, (unsigned int)c);
2479*5c51f124SMoriah Waterland 			*a_str = p;
2480*5c51f124SMoriah Waterland 			return (RESULT_ERR);
2481*5c51f124SMoriah Waterland 		}
2482*5c51f124SMoriah Waterland 	}
2483*5c51f124SMoriah Waterland 
2484*5c51f124SMoriah Waterland 	/*
2485*5c51f124SMoriah Waterland 	 * all delimiters have been ignored and opening tag character seen;
2486*5c51f124SMoriah Waterland 	 * process tag
2487*5c51f124SMoriah Waterland 	 */
2488*5c51f124SMoriah Waterland 
2489*5c51f124SMoriah Waterland 	assert(c == '<');
2490*5c51f124SMoriah Waterland 
2491*5c51f124SMoriah Waterland 	c = *p;
2492*5c51f124SMoriah Waterland 	if (*p != '\0') {
2493*5c51f124SMoriah Waterland 		p++;
2494*5c51f124SMoriah Waterland 	}
2495*5c51f124SMoriah Waterland 
2496*5c51f124SMoriah Waterland 	/* handle EOF after tag opening character found */
2497*5c51f124SMoriah Waterland 
2498*5c51f124SMoriah Waterland 	if (c == '\0') {
2499*5c51f124SMoriah Waterland 		_smlLogMsg(LOG_MSG_ERR,
2500*5c51f124SMoriah Waterland 			ERR_SML_EOF_BEFORE_TAG_NAME,
2501*5c51f124SMoriah Waterland 			parent ? parent : "<<NONE>>");
2502*5c51f124SMoriah Waterland 		smlFreeTag(tag);
2503*5c51f124SMoriah Waterland 		*a_str = p;
2504*5c51f124SMoriah Waterland 		return (RESULT_ERR);
2505*5c51f124SMoriah Waterland 	}
2506*5c51f124SMoriah Waterland 
2507*5c51f124SMoriah Waterland 	/* is this a tag closure? */
2508*5c51f124SMoriah Waterland 
2509*5c51f124SMoriah Waterland 	if (c == '/') {
2510*5c51f124SMoriah Waterland 		_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_START_CLOSE_TAG,
2511*5c51f124SMoriah Waterland 			parent ? parent : "<<NONE>>");
2512*5c51f124SMoriah Waterland 
2513*5c51f124SMoriah Waterland 		for (;;) {
2514*5c51f124SMoriah Waterland 			/* get next character of tag name */
2515*5c51f124SMoriah Waterland 
2516*5c51f124SMoriah Waterland 			c = *p;
2517*5c51f124SMoriah Waterland 			if (*p != '\0') {
2518*5c51f124SMoriah Waterland 				p++;
2519*5c51f124SMoriah Waterland 			}
2520*5c51f124SMoriah Waterland 
2521*5c51f124SMoriah Waterland 			/* EOF inside tag name? */
2522*5c51f124SMoriah Waterland 
2523*5c51f124SMoriah Waterland 			if (c == '\0') {
2524*5c51f124SMoriah Waterland 				_smlLogMsg(LOG_MSG_ERR,
2525*5c51f124SMoriah Waterland 					ERR_SML_READTAG_CLOSE_TAG_EOF,
2526*5c51f124SMoriah Waterland 					parent ? parent : "<<NONE>>");
2527*5c51f124SMoriah Waterland 				smlFreeTag(tag);
2528*5c51f124SMoriah Waterland 				*a_str = p;
2529*5c51f124SMoriah Waterland 				return (RESULT_ERR);
2530*5c51f124SMoriah Waterland 			}
2531*5c51f124SMoriah Waterland 
2532*5c51f124SMoriah Waterland 			/* tag close: break out of collection loop */
2533*5c51f124SMoriah Waterland 
2534*5c51f124SMoriah Waterland 			if (c == '>') {
2535*5c51f124SMoriah Waterland 				break;
2536*5c51f124SMoriah Waterland 			}
2537*5c51f124SMoriah Waterland 
2538*5c51f124SMoriah Waterland 			/* see if illegal character in tag name */
2539*5c51f124SMoriah Waterland 
2540*5c51f124SMoriah Waterland 			/* CSTYLED */
2541*5c51f124SMoriah Waterland 			if (strchr("/ \t\n\":<?$'\\`!@#%^&*()+=|[]{};,", c)
2542*5c51f124SMoriah Waterland 				!= NULL) {
2543*5c51f124SMoriah Waterland 				_smlLogMsg(LOG_MSG_ERR,
2544*5c51f124SMoriah Waterland 					ERR_SML_READTAG_CLOSE_TAG_ILLCHAR,
2545*5c51f124SMoriah Waterland 					c, (unsigned int)c, name);
2546*5c51f124SMoriah Waterland 				smlFreeTag(tag);
2547*5c51f124SMoriah Waterland 				*a_str = p;
2548*5c51f124SMoriah Waterland 				return (RESULT_ERR);
2549*5c51f124SMoriah Waterland 			}
2550*5c51f124SMoriah Waterland 
2551*5c51f124SMoriah Waterland 			/* valid character - add to name if room left */
2552*5c51f124SMoriah Waterland 
2553*5c51f124SMoriah Waterland 			if (pos < sizeof (name)-1) {
2554*5c51f124SMoriah Waterland 				name[pos] = (c&0xFF);
2555*5c51f124SMoriah Waterland 				pos++;
2556*5c51f124SMoriah Waterland 			}
2557*5c51f124SMoriah Waterland 
2558*5c51f124SMoriah Waterland 			assert(pos < sizeof (name));
2559*5c51f124SMoriah Waterland 		}
2560*5c51f124SMoriah Waterland 
2561*5c51f124SMoriah Waterland 		/* close of tag found */
2562*5c51f124SMoriah Waterland 
2563*5c51f124SMoriah Waterland 		assert(c == '>');
2564*5c51f124SMoriah Waterland 
2565*5c51f124SMoriah Waterland 		/* is the tag empty? If so that's an error */
2566*5c51f124SMoriah Waterland 
2567*5c51f124SMoriah Waterland 		if (*name == '\0') {
2568*5c51f124SMoriah Waterland 			_smlLogMsg(LOG_MSG_ERR,
2569*5c51f124SMoriah Waterland 				ERR_SML_READTAG_CLOSE_EMPTY_TAG);
2570*5c51f124SMoriah Waterland 			smlFreeTag(tag);
2571*5c51f124SMoriah Waterland 			*a_str = p;
2572*5c51f124SMoriah Waterland 			return (RESULT_ERR);
2573*5c51f124SMoriah Waterland 		}
2574*5c51f124SMoriah Waterland 
2575*5c51f124SMoriah Waterland 		/* if no parent, a close tag outside of any open tag */
2576*5c51f124SMoriah Waterland 
2577*5c51f124SMoriah Waterland 		if (parent == (char *)NULL) {
2578*5c51f124SMoriah Waterland 			_smlLogMsg(LOG_MSG_ERR,
2579*5c51f124SMoriah Waterland 				ERR_SML_READTAG_CLOSE_NO_PARENT,
2580*5c51f124SMoriah Waterland 				name);
2581*5c51f124SMoriah Waterland 			smlFreeTag(tag);
2582*5c51f124SMoriah Waterland 			*a_str = p;
2583*5c51f124SMoriah Waterland 			return (RESULT_ERR);
2584*5c51f124SMoriah Waterland 		}
2585*5c51f124SMoriah Waterland 
2586*5c51f124SMoriah Waterland 		/* if not close to current parent, error */
2587*5c51f124SMoriah Waterland 
2588*5c51f124SMoriah Waterland 		if (!streq(parent, name)) {
2589*5c51f124SMoriah Waterland 			_smlLogMsg(LOG_MSG_ERR,
2590*5c51f124SMoriah Waterland 				ERR_SML_READTAG_CLOSE_WRONG_TAG,
2591*5c51f124SMoriah Waterland 				name, parent);
2592*5c51f124SMoriah Waterland 			smlFreeTag(tag);
2593*5c51f124SMoriah Waterland 			*a_str = p;
2594*5c51f124SMoriah Waterland 			return (RESULT_ERR);
2595*5c51f124SMoriah Waterland 		}
2596*5c51f124SMoriah Waterland 
2597*5c51f124SMoriah Waterland 		/* close of current tag found - success */
2598*5c51f124SMoriah Waterland 
2599*5c51f124SMoriah Waterland 		_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_READTAG_CLOSE_TAG,
2600*5c51f124SMoriah Waterland 			name);
2601*5c51f124SMoriah Waterland 		smlFreeTag(tag);
2602*5c51f124SMoriah Waterland 		*a_str = p;
2603*5c51f124SMoriah Waterland 		return (RESULT_OK);
2604*5c51f124SMoriah Waterland 	}
2605*5c51f124SMoriah Waterland 
2606*5c51f124SMoriah Waterland 	/* not starting a close tag */
2607*5c51f124SMoriah Waterland 
2608*5c51f124SMoriah Waterland 	assert(c != '/');
2609*5c51f124SMoriah Waterland 	assert(c != '<');
2610*5c51f124SMoriah Waterland 
2611*5c51f124SMoriah Waterland 	/* at start of tag - input tag name */
2612*5c51f124SMoriah Waterland 
2613*5c51f124SMoriah Waterland 	bzero(name, sizeof (name));
2614*5c51f124SMoriah Waterland 	pos = 0;
2615*5c51f124SMoriah Waterland 
2616*5c51f124SMoriah Waterland 	for (;;) {
2617*5c51f124SMoriah Waterland 
2618*5c51f124SMoriah Waterland 		/* EOF inside of tag name? */
2619*5c51f124SMoriah Waterland 
2620*5c51f124SMoriah Waterland 		if (c == '\0') {
2621*5c51f124SMoriah Waterland 			_smlLogMsg(LOG_MSG_ERR,
2622*5c51f124SMoriah Waterland 				ERR_SML_READTAG_TAG_EOF,
2623*5c51f124SMoriah Waterland 				name, parent ? parent : "<<NONE>>");
2624*5c51f124SMoriah Waterland 			smlFreeTag(tag);
2625*5c51f124SMoriah Waterland 			*a_str = p;
2626*5c51f124SMoriah Waterland 			return (RESULT_ERR);
2627*5c51f124SMoriah Waterland 		}
2628*5c51f124SMoriah Waterland 
2629*5c51f124SMoriah Waterland 		/* if separator or end of line then tag name collected */
2630*5c51f124SMoriah Waterland 
2631*5c51f124SMoriah Waterland 		if (strchr(" >\t\n", c) != NULL) {
2632*5c51f124SMoriah Waterland 			break;
2633*5c51f124SMoriah Waterland 		}
2634*5c51f124SMoriah Waterland 
2635*5c51f124SMoriah Waterland 		/* see if illegal character in tag name */
2636*5c51f124SMoriah Waterland 
2637*5c51f124SMoriah Waterland 		/*CSTYLED*/
2638*5c51f124SMoriah Waterland 		if (strchr("\":<>?$'\\`!@#%^&*()+=|[]{};,", c) != NULL) {
2639*5c51f124SMoriah Waterland 			_smlLogMsg(LOG_MSG_ERR,
2640*5c51f124SMoriah Waterland 				ERR_SML_READTAG_TAG_ILLCHAR,
2641*5c51f124SMoriah Waterland 				c, (unsigned int)c, name);
2642*5c51f124SMoriah Waterland 			smlFreeTag(tag);
2643*5c51f124SMoriah Waterland 			*a_str = p;
2644*5c51f124SMoriah Waterland 			return (RESULT_ERR);
2645*5c51f124SMoriah Waterland 		}
2646*5c51f124SMoriah Waterland 
2647*5c51f124SMoriah Waterland 		/* close current tag? */
2648*5c51f124SMoriah Waterland 
2649*5c51f124SMoriah Waterland 		if (c == '/') {
2650*5c51f124SMoriah Waterland 			/* get next character of tag name */
2651*5c51f124SMoriah Waterland 
2652*5c51f124SMoriah Waterland 			c = *p;
2653*5c51f124SMoriah Waterland 			if (*p != '\0') {
2654*5c51f124SMoriah Waterland 				p++;
2655*5c51f124SMoriah Waterland 			}
2656*5c51f124SMoriah Waterland 
2657*5c51f124SMoriah Waterland 			/* tag close not found? */
2658*5c51f124SMoriah Waterland 
2659*5c51f124SMoriah Waterland 			if (c != '>') {
2660*5c51f124SMoriah Waterland 				_smlLogMsg(LOG_MSG_ERR,
2661*5c51f124SMoriah Waterland 					ERR_SML_READTAG_BADTAG_CLOSE,
2662*5c51f124SMoriah Waterland 					name, parent ? parent : "<<NONE>>");
2663*5c51f124SMoriah Waterland 				smlFreeTag(tag);
2664*5c51f124SMoriah Waterland 				*a_str = p;
2665*5c51f124SMoriah Waterland 				return (RESULT_ERR);
2666*5c51f124SMoriah Waterland 			}
2667*5c51f124SMoriah Waterland 
2668*5c51f124SMoriah Waterland 			/* is the tag empty? If so that's an error */
2669*5c51f124SMoriah Waterland 
2670*5c51f124SMoriah Waterland 			if (*name == '\0') {
2671*5c51f124SMoriah Waterland 				_smlLogMsg(LOG_MSG_ERR,
2672*5c51f124SMoriah Waterland 					ERR_SML_READTAG_EMPTY_TAG,
2673*5c51f124SMoriah Waterland 					parent ? parent : "<<NONE>>");
2674*5c51f124SMoriah Waterland 				smlFreeTag(tag);
2675*5c51f124SMoriah Waterland 				*a_str = p;
2676*5c51f124SMoriah Waterland 				return (RESULT_ERR);
2677*5c51f124SMoriah Waterland 			}
2678*5c51f124SMoriah Waterland 
2679*5c51f124SMoriah Waterland 			/* tag closed */
2680*5c51f124SMoriah Waterland 
2681*5c51f124SMoriah Waterland 			_smlLogMsg(LOG_MSG_DEBUG,
2682*5c51f124SMoriah Waterland 				DBG_SML_READTAG_CLOSED_TAG,
2683*5c51f124SMoriah Waterland 				name, parent ? parent : "<<NONE>>");
2684*5c51f124SMoriah Waterland 
2685*5c51f124SMoriah Waterland 			tag->name = strdup(name);
2686*5c51f124SMoriah Waterland 			*r_tag = tag;
2687*5c51f124SMoriah Waterland 			*a_str = p;
2688*5c51f124SMoriah Waterland 			return (RESULT_OK);
2689*5c51f124SMoriah Waterland 		}
2690*5c51f124SMoriah Waterland 
2691*5c51f124SMoriah Waterland 		/* valid character - add to name if room left */
2692*5c51f124SMoriah Waterland 
2693*5c51f124SMoriah Waterland 		if (pos < sizeof (name)-1) {
2694*5c51f124SMoriah Waterland 			name[pos] = (c&0xFF);
2695*5c51f124SMoriah Waterland 			pos++;
2696*5c51f124SMoriah Waterland 		}
2697*5c51f124SMoriah Waterland 
2698*5c51f124SMoriah Waterland 		assert(pos < sizeof (name));
2699*5c51f124SMoriah Waterland 
2700*5c51f124SMoriah Waterland 		/* get next character to parse */
2701*5c51f124SMoriah Waterland 
2702*5c51f124SMoriah Waterland 		c = *p;
2703*5c51f124SMoriah Waterland 		if (*p != '\0') {
2704*5c51f124SMoriah Waterland 			p++;
2705*5c51f124SMoriah Waterland 		}
2706*5c51f124SMoriah Waterland 	}
2707*5c51f124SMoriah Waterland 
2708*5c51f124SMoriah Waterland 	/* have a valid tag name: <tagname */
2709*5c51f124SMoriah Waterland 
2710*5c51f124SMoriah Waterland 	_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_HAVE_TAG_NAME,
2711*5c51f124SMoriah Waterland 		name, parent ? parent : "<<NONE>>");
2712*5c51f124SMoriah Waterland 
2713*5c51f124SMoriah Waterland 	assert(*name != '\0');
2714*5c51f124SMoriah Waterland 
2715*5c51f124SMoriah Waterland 	/* place tag name inside of tag object */
2716*5c51f124SMoriah Waterland 
2717*5c51f124SMoriah Waterland 	tag->name = strdup(name);
2718*5c51f124SMoriah Waterland 
2719*5c51f124SMoriah Waterland 	/* clear out name accumulator to get parameters */
2720*5c51f124SMoriah Waterland 
2721*5c51f124SMoriah Waterland 	bzero(name, sizeof (name));
2722*5c51f124SMoriah Waterland 	pos = 0;
2723*5c51f124SMoriah Waterland 
2724*5c51f124SMoriah Waterland 	/* input parameters */
2725*5c51f124SMoriah Waterland 
2726*5c51f124SMoriah Waterland 	if (c != '>')
2727*5c51f124SMoriah Waterland 		for (;;) {
2728*5c51f124SMoriah Waterland 
2729*5c51f124SMoriah Waterland 		char *pname;
2730*5c51f124SMoriah Waterland 		char *pvalue;
2731*5c51f124SMoriah Waterland 		SML_PARAM *parameter;
2732*5c51f124SMoriah Waterland 
2733*5c51f124SMoriah Waterland 		/* pass spaces before parameter name */
2734*5c51f124SMoriah Waterland 
2735*5c51f124SMoriah Waterland 		for (;;) {
2736*5c51f124SMoriah Waterland 
2737*5c51f124SMoriah Waterland 			/* get next character of parameter name */
2738*5c51f124SMoriah Waterland 
2739*5c51f124SMoriah Waterland 			c = *p;
2740*5c51f124SMoriah Waterland 			if (*p != '\0') {
2741*5c51f124SMoriah Waterland 				p++;
2742*5c51f124SMoriah Waterland 			}
2743*5c51f124SMoriah Waterland 
2744*5c51f124SMoriah Waterland 			/* EOF inside parameter name? */
2745*5c51f124SMoriah Waterland 
2746*5c51f124SMoriah Waterland 			if (c == '\0') {
2747*5c51f124SMoriah Waterland 				_smlLogMsg(LOG_MSG_ERR,
2748*5c51f124SMoriah Waterland 					ERR_SML_READTAG_PARM_EOF,
2749*5c51f124SMoriah Waterland 					tag->name,
2750*5c51f124SMoriah Waterland 					parent ? parent : "<<NONE>>");
2751*5c51f124SMoriah Waterland 				smlFreeTag(tag);
2752*5c51f124SMoriah Waterland 				*a_str = p;
2753*5c51f124SMoriah Waterland 				return (RESULT_ERR);
2754*5c51f124SMoriah Waterland 			}
2755*5c51f124SMoriah Waterland 
2756*5c51f124SMoriah Waterland 			/* if separator/end of line tag parameter collected */
2757*5c51f124SMoriah Waterland 
2758*5c51f124SMoriah Waterland 			if (strchr(" \t\n", c) != NULL) {
2759*5c51f124SMoriah Waterland 				continue;
2760*5c51f124SMoriah Waterland 			}
2761*5c51f124SMoriah Waterland 
2762*5c51f124SMoriah Waterland 			/* see if illegal character in parameter name */
2763*5c51f124SMoriah Waterland 
2764*5c51f124SMoriah Waterland 			/*CSTYLED*/
2765*5c51f124SMoriah Waterland 			if (strchr("\":<?$'\\`!@#%^&*()+=|[]{};,.", c) !=
2766*5c51f124SMoriah Waterland 				(char *)NULL) {
2767*5c51f124SMoriah Waterland 				_smlLogMsg(LOG_MSG_ERR,
2768*5c51f124SMoriah Waterland 					ERR_SML_READTAG_PARMNAME_ILLCHAR,
2769*5c51f124SMoriah Waterland 					c, (unsigned int)c, name, tag->name,
2770*5c51f124SMoriah Waterland 					parent ? parent : "<<NONE>>");
2771*5c51f124SMoriah Waterland 				smlFreeTag(tag);
2772*5c51f124SMoriah Waterland 				*a_str = p;
2773*5c51f124SMoriah Waterland 				return (RESULT_ERR);
2774*5c51f124SMoriah Waterland 			}
2775*5c51f124SMoriah Waterland 
2776*5c51f124SMoriah Waterland 			/* tag close found? */
2777*5c51f124SMoriah Waterland 
2778*5c51f124SMoriah Waterland 			if (c == '>') {
2779*5c51f124SMoriah Waterland 				break;
2780*5c51f124SMoriah Waterland 			}
2781*5c51f124SMoriah Waterland 
2782*5c51f124SMoriah Waterland 			/* close tag found ? */
2783*5c51f124SMoriah Waterland 
2784*5c51f124SMoriah Waterland 			if (c == '/') {
2785*5c51f124SMoriah Waterland 				c = *p;
2786*5c51f124SMoriah Waterland 				if (*p != '\0') {
2787*5c51f124SMoriah Waterland 					p++;
2788*5c51f124SMoriah Waterland 				}
2789*5c51f124SMoriah Waterland 				if (c == '>') {
2790*5c51f124SMoriah Waterland 					_smlLogMsg(LOG_MSG_DEBUG,
2791*5c51f124SMoriah Waterland 						DBG_SML_TAG_ONLY,
2792*5c51f124SMoriah Waterland 						tag->name);
2793*5c51f124SMoriah Waterland 					*r_tag = tag;
2794*5c51f124SMoriah Waterland 					*a_str = p;
2795*5c51f124SMoriah Waterland 					return (RESULT_OK);
2796*5c51f124SMoriah Waterland 				}
2797*5c51f124SMoriah Waterland 
2798*5c51f124SMoriah Waterland 				/* / not followed by > */
2799*5c51f124SMoriah Waterland 				_smlLogMsg(LOG_MSG_ERR,
2800*5c51f124SMoriah Waterland 					ERR_SML_READTAG_BADPARMNAME_CLOSE,
2801*5c51f124SMoriah Waterland 					name, tag->name,
2802*5c51f124SMoriah Waterland 					parent ? parent : "<<NONE>>");
2803*5c51f124SMoriah Waterland 				smlFreeTag(tag);
2804*5c51f124SMoriah Waterland 				*a_str = p;
2805*5c51f124SMoriah Waterland 				return (RESULT_ERR);
2806*5c51f124SMoriah Waterland 			}
2807*5c51f124SMoriah Waterland 
2808*5c51f124SMoriah Waterland 			/* valid character - add to name if room left */
2809*5c51f124SMoriah Waterland 
2810*5c51f124SMoriah Waterland 			if (pos < sizeof (name)-1) {
2811*5c51f124SMoriah Waterland 				name[pos] = (c&0xFF);
2812*5c51f124SMoriah Waterland 				pos++;
2813*5c51f124SMoriah Waterland 			}
2814*5c51f124SMoriah Waterland 
2815*5c51f124SMoriah Waterland 			assert(pos < sizeof (name));
2816*5c51f124SMoriah Waterland 			break;
2817*5c51f124SMoriah Waterland 		}
2818*5c51f124SMoriah Waterland 
2819*5c51f124SMoriah Waterland 		if (c == '>') {
2820*5c51f124SMoriah Waterland 			break;
2821*5c51f124SMoriah Waterland 		}
2822*5c51f124SMoriah Waterland 
2823*5c51f124SMoriah Waterland 		/* input parameter name */
2824*5c51f124SMoriah Waterland 
2825*5c51f124SMoriah Waterland 		for (;;) {
2826*5c51f124SMoriah Waterland 			c = *p;
2827*5c51f124SMoriah Waterland 			if (*p != '\0') {
2828*5c51f124SMoriah Waterland 				p++;
2829*5c51f124SMoriah Waterland 			}
2830*5c51f124SMoriah Waterland 
2831*5c51f124SMoriah Waterland 			/* EOF inside of parameter name? */
2832*5c51f124SMoriah Waterland 
2833*5c51f124SMoriah Waterland 			if (c == '\0') {
2834*5c51f124SMoriah Waterland 				_smlLogMsg(LOG_MSG_ERR,
2835*5c51f124SMoriah Waterland 					ERR_SML_READTAG_PARM_EOF,
2836*5c51f124SMoriah Waterland 					tag->name,
2837*5c51f124SMoriah Waterland 					parent ? parent : "<<NONE>>");
2838*5c51f124SMoriah Waterland 				smlFreeTag(tag);
2839*5c51f124SMoriah Waterland 				*a_str = p;
2840*5c51f124SMoriah Waterland 				return (RESULT_ERR);
2841*5c51f124SMoriah Waterland 			}
2842*5c51f124SMoriah Waterland 
2843*5c51f124SMoriah Waterland 			/*CSTYLED*/
2844*5c51f124SMoriah Waterland 			if (strchr("\t \n\":<>?$'\\`!@%^*()+|[]{},./", c) != NULL) {
2845*5c51f124SMoriah Waterland 				_smlLogMsg(LOG_MSG_ERR,
2846*5c51f124SMoriah Waterland 					ERR_SML_READTAG_PARMNAME_ILLCHAR,
2847*5c51f124SMoriah Waterland 					c, (unsigned int)c, name, tag->name,
2848*5c51f124SMoriah Waterland 					parent ? parent : "<<NONE>>");
2849*5c51f124SMoriah Waterland 				smlFreeTag(tag);
2850*5c51f124SMoriah Waterland 				*a_str = p;
2851*5c51f124SMoriah Waterland 				return (RESULT_ERR);
2852*5c51f124SMoriah Waterland 			}
2853*5c51f124SMoriah Waterland 
2854*5c51f124SMoriah Waterland 			/* name - value separator found ? */
2855*5c51f124SMoriah Waterland 
2856*5c51f124SMoriah Waterland 			if (c == '=') {
2857*5c51f124SMoriah Waterland 				break;
2858*5c51f124SMoriah Waterland 			}
2859*5c51f124SMoriah Waterland 
2860*5c51f124SMoriah Waterland 			/* valid character - add to name if room left */
2861*5c51f124SMoriah Waterland 
2862*5c51f124SMoriah Waterland 			if (pos < sizeof (name)-1) {
2863*5c51f124SMoriah Waterland 				name[pos] = (c&0xFF);
2864*5c51f124SMoriah Waterland 				pos++;
2865*5c51f124SMoriah Waterland 			}
2866*5c51f124SMoriah Waterland 
2867*5c51f124SMoriah Waterland 			assert(pos < sizeof (name));
2868*5c51f124SMoriah Waterland 		}
2869*5c51f124SMoriah Waterland 
2870*5c51f124SMoriah Waterland 		/* is the parameter name empty? If so that's an error */
2871*5c51f124SMoriah Waterland 
2872*5c51f124SMoriah Waterland 		if (*name == '\0') {
2873*5c51f124SMoriah Waterland 			_smlLogMsg(LOG_MSG_ERR,
2874*5c51f124SMoriah Waterland 				ERR_SML_READTAG_EMPTY_PARMNAME,
2875*5c51f124SMoriah Waterland 				tag->name, parent ? parent : "<<NONE>>");
2876*5c51f124SMoriah Waterland 			smlFreeTag(tag);
2877*5c51f124SMoriah Waterland 			*a_str = p;
2878*5c51f124SMoriah Waterland 			return (RESULT_ERR);
2879*5c51f124SMoriah Waterland 		}
2880*5c51f124SMoriah Waterland 
2881*5c51f124SMoriah Waterland 		/* have a parameter name */
2882*5c51f124SMoriah Waterland 
2883*5c51f124SMoriah Waterland 		_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_HAVE_PARM_NAME,
2884*5c51f124SMoriah Waterland 			name, tag->name);
2885*5c51f124SMoriah Waterland 
2886*5c51f124SMoriah Waterland 		/* duplicate (save) parameter name */
2887*5c51f124SMoriah Waterland 
2888*5c51f124SMoriah Waterland 		pname = strdup(name);
2889*5c51f124SMoriah Waterland 
2890*5c51f124SMoriah Waterland 		/* clear out name accumulator to get parameters */
2891*5c51f124SMoriah Waterland 
2892*5c51f124SMoriah Waterland 		bzero(name, sizeof (name));
2893*5c51f124SMoriah Waterland 		pos = 0;
2894*5c51f124SMoriah Waterland 
2895*5c51f124SMoriah Waterland 		c = *p;
2896*5c51f124SMoriah Waterland 		if (*p != '\0') {
2897*5c51f124SMoriah Waterland 			p++;
2898*5c51f124SMoriah Waterland 		}
2899*5c51f124SMoriah Waterland 
2900*5c51f124SMoriah Waterland 		if (c != '"') {
2901*5c51f124SMoriah Waterland 			_smlLogMsg(LOG_MSG_ERR,
2902*5c51f124SMoriah Waterland 				ERR_SML_PARM_SEP_BAD,
2903*5c51f124SMoriah Waterland 				c, (unsigned int)c);
2904*5c51f124SMoriah Waterland 			free(pname);
2905*5c51f124SMoriah Waterland 			smlFreeTag(tag);
2906*5c51f124SMoriah Waterland 			*a_str = p;
2907*5c51f124SMoriah Waterland 			return (RESULT_ERR);
2908*5c51f124SMoriah Waterland 		}
2909*5c51f124SMoriah Waterland 
2910*5c51f124SMoriah Waterland 		/* input parameter value */
2911*5c51f124SMoriah Waterland 
2912*5c51f124SMoriah Waterland 		for (;;) {
2913*5c51f124SMoriah Waterland 			c = *p;
2914*5c51f124SMoriah Waterland 			if (*p != '\0') {
2915*5c51f124SMoriah Waterland 				p++;
2916*5c51f124SMoriah Waterland 			}
2917*5c51f124SMoriah Waterland 
2918*5c51f124SMoriah Waterland 			/* EOF inside of parameter value? */
2919*5c51f124SMoriah Waterland 
2920*5c51f124SMoriah Waterland 			if (c == '\0') {
2921*5c51f124SMoriah Waterland 				_smlLogMsg(LOG_MSG_ERR,
2922*5c51f124SMoriah Waterland 					ERR_SML_READTAG_PARMVAL_EOF,
2923*5c51f124SMoriah Waterland 					pname, tag->name,
2924*5c51f124SMoriah Waterland 					parent ? parent : "<<NONE>>");
2925*5c51f124SMoriah Waterland 				smlFreeTag(tag);
2926*5c51f124SMoriah Waterland 				free(pname);
2927*5c51f124SMoriah Waterland 				*a_str = p;
2928*5c51f124SMoriah Waterland 				return (RESULT_ERR);
2929*5c51f124SMoriah Waterland 			}
2930*5c51f124SMoriah Waterland 
2931*5c51f124SMoriah Waterland 			/* close of parameter value? */
2932*5c51f124SMoriah Waterland 
2933*5c51f124SMoriah Waterland 			if (c == '"') {
2934*5c51f124SMoriah Waterland 				break;
2935*5c51f124SMoriah Waterland 			}
2936*5c51f124SMoriah Waterland 
2937*5c51f124SMoriah Waterland 			if (strchr("\n", c) != NULL) {
2938*5c51f124SMoriah Waterland 				_smlLogMsg(LOG_MSG_ERR,
2939*5c51f124SMoriah Waterland 					ERR_SML_READTAG_PARMVAL_NL,
2940*5c51f124SMoriah Waterland 					pname, tag->name,
2941*5c51f124SMoriah Waterland 					parent ? parent : "<<NONE>>");
2942*5c51f124SMoriah Waterland 				free(pname);
2943*5c51f124SMoriah Waterland 				smlFreeTag(tag);
2944*5c51f124SMoriah Waterland 				*a_str = p;
2945*5c51f124SMoriah Waterland 				return (RESULT_ERR);
2946*5c51f124SMoriah Waterland 			}
2947*5c51f124SMoriah Waterland 
2948*5c51f124SMoriah Waterland 			/* valid character - add to value if room left */
2949*5c51f124SMoriah Waterland 
2950*5c51f124SMoriah Waterland 			if (pos < sizeof (name)-1) {
2951*5c51f124SMoriah Waterland 				name[pos] = (c&0xFF);
2952*5c51f124SMoriah Waterland 				pos++;
2953*5c51f124SMoriah Waterland 			}
2954*5c51f124SMoriah Waterland 
2955*5c51f124SMoriah Waterland 			assert(pos < sizeof (name));
2956*5c51f124SMoriah Waterland 		}
2957*5c51f124SMoriah Waterland 
2958*5c51f124SMoriah Waterland 		/* got the value */
2959*5c51f124SMoriah Waterland 
2960*5c51f124SMoriah Waterland 		_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_HAVE_PARM_VALUE,
2961*5c51f124SMoriah Waterland 			pname, name, tag->name);
2962*5c51f124SMoriah Waterland 
2963*5c51f124SMoriah Waterland 		pvalue = sml_XmlDecodeString(name);
2964*5c51f124SMoriah Waterland 		bzero(name, sizeof (name));
2965*5c51f124SMoriah Waterland 		pos = 0;
2966*5c51f124SMoriah Waterland 
2967*5c51f124SMoriah Waterland 		parameter = (SML_PARAM *)calloc(1, sizeof (SML_PARAM));
2968*5c51f124SMoriah Waterland 		bzero(parameter, sizeof (SML_PARAM));
2969*5c51f124SMoriah Waterland 		parameter->name = pname;
2970*5c51f124SMoriah Waterland 		parameter->value = pvalue;
2971*5c51f124SMoriah Waterland 		tag->params_num++;
2972*5c51f124SMoriah Waterland 		tag->params = (SML_PARAM *)
2973*5c51f124SMoriah Waterland 			realloc(tag->params,
2974*5c51f124SMoriah Waterland 				sizeof (SML_PARAM) *tag->params_num);
2975*5c51f124SMoriah Waterland 		(void) memcpy(&(tag->params[tag->params_num - 1]), parameter,
2976*5c51f124SMoriah Waterland 			sizeof (SML_PARAM));
2977*5c51f124SMoriah Waterland 
2978*5c51f124SMoriah Waterland 		free(parameter);
2979*5c51f124SMoriah Waterland 		if (c == '>') {
2980*5c51f124SMoriah Waterland 			break;
2981*5c51f124SMoriah Waterland 		}
2982*5c51f124SMoriah Waterland 	}
2983*5c51f124SMoriah Waterland 
2984*5c51f124SMoriah Waterland 	/* finished processing this tag element entry */
2985*5c51f124SMoriah Waterland 
2986*5c51f124SMoriah Waterland 	_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_TAG_HEAD_DONE,
2987*5c51f124SMoriah Waterland 		tag->name, parent ? parent : "<<NULL>>");
2988*5c51f124SMoriah Waterland 
2989*5c51f124SMoriah Waterland 	tag->tags = NULL;
2990*5c51f124SMoriah Waterland 
2991*5c51f124SMoriah Waterland 	while (((r = _smlReadTag(&tmp_tag, &p, tag->name))
2992*5c51f124SMoriah Waterland 		== RESULT_OK) && (tmp_tag != NULL)) {
2993*5c51f124SMoriah Waterland 		tag->tags_num++;
2994*5c51f124SMoriah Waterland 		tag->tags = (SML_TAG *)realloc(tag->tags,
2995*5c51f124SMoriah Waterland 			sizeof (SML_TAG) *tag->tags_num);
2996*5c51f124SMoriah Waterland 		(void) memcpy(&(tag->tags[tag->tags_num - 1]), tmp_tag,
2997*5c51f124SMoriah Waterland 			sizeof (SML_TAG));
2998*5c51f124SMoriah Waterland 		free(tmp_tag);
2999*5c51f124SMoriah Waterland 	}
3000*5c51f124SMoriah Waterland 
3001*5c51f124SMoriah Waterland 	c = *p;
3002*5c51f124SMoriah Waterland 	if (*p != '\0') {
3003*5c51f124SMoriah Waterland 		p++;
3004*5c51f124SMoriah Waterland 	}
3005*5c51f124SMoriah Waterland 
3006*5c51f124SMoriah Waterland 	*r_tag = tag;
3007*5c51f124SMoriah Waterland 	*a_str = p;
3008*5c51f124SMoriah Waterland 	return (r);
3009*5c51f124SMoriah Waterland }
3010*5c51f124SMoriah Waterland 
3011*5c51f124SMoriah Waterland /*
3012*5c51f124SMoriah Waterland  * Name:	_smlWriteParamValue
3013*5c51f124SMoriah Waterland  * Description:	XML Encode a plain text parameter value and write to datastream
3014*5c51f124SMoriah Waterland  * Arguments:	ds - [RO, *RO] - (LU_DS)
3015*5c51f124SMoriah Waterland  *			Handle to datastream to write parameter value to
3016*5c51f124SMoriah Waterland  *		value - [RO, *RO] - (char *)
3017*5c51f124SMoriah Waterland  *			Parameter value to be encoded and written
3018*5c51f124SMoriah Waterland  * Returns:	int
3019*5c51f124SMoriah Waterland  *			RESULT_OK - tag successfully read
3020*5c51f124SMoriah Waterland  *			RESULT_ERR - problem reading tag
3021*5c51f124SMoriah Waterland  */
3022*5c51f124SMoriah Waterland 
3023*5c51f124SMoriah Waterland static int
_smlWriteParamValue(char ** a_str,char * value)3024*5c51f124SMoriah Waterland _smlWriteParamValue(char **a_str, char *value)
3025*5c51f124SMoriah Waterland {
3026*5c51f124SMoriah Waterland 	char		*ns;
3027*5c51f124SMoriah Waterland 	char		*p;
3028*5c51f124SMoriah Waterland 
3029*5c51f124SMoriah Waterland 	/* entry assertions */
3030*5c51f124SMoriah Waterland 
3031*5c51f124SMoriah Waterland 	assert(a_str != (char **)NULL);
3032*5c51f124SMoriah Waterland 	assert(value != (char *)NULL);
3033*5c51f124SMoriah Waterland 
3034*5c51f124SMoriah Waterland 	/* xml encode the plain text string */
3035*5c51f124SMoriah Waterland 
3036*5c51f124SMoriah Waterland 	p = sml_XmlEncodeString(value);
3037*5c51f124SMoriah Waterland 	assert(p != (char *)NULL);
3038*5c51f124SMoriah Waterland 
3039*5c51f124SMoriah Waterland 	/* write the xml encoded parameter value to the datastream */
3040*5c51f124SMoriah Waterland 
3041*5c51f124SMoriah Waterland 	ns = sml_strPrintf("%s\"%s\"", *a_str ? *a_str : "", p);
3042*5c51f124SMoriah Waterland 
3043*5c51f124SMoriah Waterland 	/* free up xml encoded value storage */
3044*5c51f124SMoriah Waterland 
3045*5c51f124SMoriah Waterland 	free(p);
3046*5c51f124SMoriah Waterland 
3047*5c51f124SMoriah Waterland 	if (ns == NULL) {
3048*5c51f124SMoriah Waterland 		return (RESULT_ERR);
3049*5c51f124SMoriah Waterland 	}
3050*5c51f124SMoriah Waterland 
3051*5c51f124SMoriah Waterland 	if (*a_str != NULL) {
3052*5c51f124SMoriah Waterland 		free(*a_str);
3053*5c51f124SMoriah Waterland 	}
3054*5c51f124SMoriah Waterland 	*a_str = ns;
3055*5c51f124SMoriah Waterland 
3056*5c51f124SMoriah Waterland 	/* return results */
3057*5c51f124SMoriah Waterland 
3058*5c51f124SMoriah Waterland 	return (RESULT_OK);
3059*5c51f124SMoriah Waterland }
3060*5c51f124SMoriah Waterland 
3061*5c51f124SMoriah Waterland static int
_smlWriteSimpleTag(char ** a_str,SML_TAG * tag)3062*5c51f124SMoriah Waterland _smlWriteSimpleTag(char **a_str, SML_TAG *tag)
3063*5c51f124SMoriah Waterland {
3064*5c51f124SMoriah Waterland 	int	r;
3065*5c51f124SMoriah Waterland 	int 	k;
3066*5c51f124SMoriah Waterland 	char	*ns;
3067*5c51f124SMoriah Waterland 	char	*np0;
3068*5c51f124SMoriah Waterland 	char	*np1;
3069*5c51f124SMoriah Waterland 
3070*5c51f124SMoriah Waterland 	if (tag == NULL) {
3071*5c51f124SMoriah Waterland 		return (RESULT_OK);
3072*5c51f124SMoriah Waterland 	}
3073*5c51f124SMoriah Waterland 
3074*5c51f124SMoriah Waterland 	if (*a_str == NULL) {
3075*5c51f124SMoriah Waterland 		*a_str = strdup("");
3076*5c51f124SMoriah Waterland 	}
3077*5c51f124SMoriah Waterland 
3078*5c51f124SMoriah Waterland 	if (tag->params_num == 0) {
3079*5c51f124SMoriah Waterland 		if (tag->tags_num == 0) {
3080*5c51f124SMoriah Waterland 			ns = sml_strPrintf("%s<%s/>\n", *a_str, tag->name);
3081*5c51f124SMoriah Waterland 			free(*a_str);
3082*5c51f124SMoriah Waterland 			*a_str = ns;
3083*5c51f124SMoriah Waterland 			return (RESULT_OK);
3084*5c51f124SMoriah Waterland 		} else {
3085*5c51f124SMoriah Waterland 			ns = sml_strPrintf("%s<%s>\n", *a_str, tag->name);
3086*5c51f124SMoriah Waterland 			if (ns == NULL) {
3087*5c51f124SMoriah Waterland 				return (RESULT_ERR);
3088*5c51f124SMoriah Waterland 			}
3089*5c51f124SMoriah Waterland 			free(*a_str);
3090*5c51f124SMoriah Waterland 			*a_str = ns;
3091*5c51f124SMoriah Waterland 		}
3092*5c51f124SMoriah Waterland 	} else {
3093*5c51f124SMoriah Waterland 		ns = sml_strPrintf("%s<%s %s=", *a_str ? *a_str : "", tag->name,
3094*5c51f124SMoriah Waterland 				tag->params[0].name);
3095*5c51f124SMoriah Waterland 		if (ns == NULL) {
3096*5c51f124SMoriah Waterland 			return (RESULT_ERR);
3097*5c51f124SMoriah Waterland 		}
3098*5c51f124SMoriah Waterland 		free(*a_str);
3099*5c51f124SMoriah Waterland 		*a_str = ns;
3100*5c51f124SMoriah Waterland 
3101*5c51f124SMoriah Waterland 		np0 = NULL;
3102*5c51f124SMoriah Waterland 		r = _smlWriteParamValue(&np0, tag->params[0].value);
3103*5c51f124SMoriah Waterland 		if ((np0 == NULL) || (r != RESULT_OK)) {
3104*5c51f124SMoriah Waterland 			return (RESULT_ERR);
3105*5c51f124SMoriah Waterland 		}
3106*5c51f124SMoriah Waterland 
3107*5c51f124SMoriah Waterland 		ns = sml_strPrintf("%s%s", *a_str, np0);
3108*5c51f124SMoriah Waterland 		if (ns == NULL) {
3109*5c51f124SMoriah Waterland 			return (RESULT_ERR);
3110*5c51f124SMoriah Waterland 		}
3111*5c51f124SMoriah Waterland 
3112*5c51f124SMoriah Waterland 		free(np0);
3113*5c51f124SMoriah Waterland 		free(*a_str);
3114*5c51f124SMoriah Waterland 		*a_str = ns;
3115*5c51f124SMoriah Waterland 
3116*5c51f124SMoriah Waterland 		for (k = 1; k < tag->params_num; k++) {
3117*5c51f124SMoriah Waterland 			np0 = sml_strPrintf(" %s=", tag->params[k].name);
3118*5c51f124SMoriah Waterland 			if (np0 == NULL) {
3119*5c51f124SMoriah Waterland 				return (RESULT_ERR);
3120*5c51f124SMoriah Waterland 			}
3121*5c51f124SMoriah Waterland 			np1 = NULL;
3122*5c51f124SMoriah Waterland 			r = _smlWriteParamValue(&np1, tag->params[k].value);
3123*5c51f124SMoriah Waterland 			if ((np1 == NULL) || (r != RESULT_OK)) {
3124*5c51f124SMoriah Waterland 				return (RESULT_ERR);
3125*5c51f124SMoriah Waterland 			}
3126*5c51f124SMoriah Waterland 
3127*5c51f124SMoriah Waterland 			ns = sml_strPrintf("%s%s%s", *a_str, np0, np1);
3128*5c51f124SMoriah Waterland 			if (ns == NULL) {
3129*5c51f124SMoriah Waterland 				return (RESULT_ERR);
3130*5c51f124SMoriah Waterland 			}
3131*5c51f124SMoriah Waterland 
3132*5c51f124SMoriah Waterland 			free(np0);
3133*5c51f124SMoriah Waterland 			free(np1);
3134*5c51f124SMoriah Waterland 			free(*a_str);
3135*5c51f124SMoriah Waterland 			*a_str = ns;
3136*5c51f124SMoriah Waterland 		}
3137*5c51f124SMoriah Waterland 
3138*5c51f124SMoriah Waterland 		if (tag->tags_num == 0) {
3139*5c51f124SMoriah Waterland 			np0 = sml_strPrintf("/>\n");
3140*5c51f124SMoriah Waterland 			if (np0 == NULL) {
3141*5c51f124SMoriah Waterland 				return (RESULT_ERR);
3142*5c51f124SMoriah Waterland 			}
3143*5c51f124SMoriah Waterland 			ns = sml_strPrintf("%s%s", *a_str, np0);
3144*5c51f124SMoriah Waterland 			if (ns == NULL) {
3145*5c51f124SMoriah Waterland 				return (RESULT_ERR);
3146*5c51f124SMoriah Waterland 			}
3147*5c51f124SMoriah Waterland 			free(np0);
3148*5c51f124SMoriah Waterland 			free(*a_str);
3149*5c51f124SMoriah Waterland 			*a_str = ns;
3150*5c51f124SMoriah Waterland 		} else {
3151*5c51f124SMoriah Waterland 			np0 = sml_strPrintf(">\n");
3152*5c51f124SMoriah Waterland 			if (np0 == NULL) {
3153*5c51f124SMoriah Waterland 				return (RESULT_ERR);
3154*5c51f124SMoriah Waterland 			}
3155*5c51f124SMoriah Waterland 			ns = sml_strPrintf("%s%s", *a_str, np0);
3156*5c51f124SMoriah Waterland 			if (ns == NULL) {
3157*5c51f124SMoriah Waterland 				return (RESULT_ERR);
3158*5c51f124SMoriah Waterland 			}
3159*5c51f124SMoriah Waterland 			free(np0);
3160*5c51f124SMoriah Waterland 			free(*a_str);
3161*5c51f124SMoriah Waterland 			*a_str = ns;
3162*5c51f124SMoriah Waterland 		}
3163*5c51f124SMoriah Waterland 	}
3164*5c51f124SMoriah Waterland 
3165*5c51f124SMoriah Waterland 	for (k = 0; k < tag->tags_num; k++) {
3166*5c51f124SMoriah Waterland 		r = _smlWriteSimpleTag(a_str, &(tag->tags[k]));
3167*5c51f124SMoriah Waterland 		if (r != RESULT_OK) {
3168*5c51f124SMoriah Waterland 			return (r);
3169*5c51f124SMoriah Waterland 		}
3170*5c51f124SMoriah Waterland 	}
3171*5c51f124SMoriah Waterland 
3172*5c51f124SMoriah Waterland 	if (tag->tags_num > 0) {
3173*5c51f124SMoriah Waterland 		np0 = sml_strPrintf("</%s>\n", tag->name);
3174*5c51f124SMoriah Waterland 		if (np0 == NULL) {
3175*5c51f124SMoriah Waterland 			return (RESULT_ERR);
3176*5c51f124SMoriah Waterland 		}
3177*5c51f124SMoriah Waterland 		ns = sml_strPrintf("%s%s", *a_str ? *a_str : "", np0);
3178*5c51f124SMoriah Waterland 		if (ns == NULL) {
3179*5c51f124SMoriah Waterland 			return (RESULT_ERR);
3180*5c51f124SMoriah Waterland 		}
3181*5c51f124SMoriah Waterland 		free(np0);
3182*5c51f124SMoriah Waterland 		free(*a_str);
3183*5c51f124SMoriah Waterland 		*a_str = ns;
3184*5c51f124SMoriah Waterland 	}
3185*5c51f124SMoriah Waterland 
3186*5c51f124SMoriah Waterland 	return (RESULT_OK);
3187*5c51f124SMoriah Waterland }
3188*5c51f124SMoriah Waterland 
3189*5c51f124SMoriah Waterland static void
_smlFreeTag(SML_TAG * tag)3190*5c51f124SMoriah Waterland _smlFreeTag(SML_TAG *tag)
3191*5c51f124SMoriah Waterland {
3192*5c51f124SMoriah Waterland 	int k;
3193*5c51f124SMoriah Waterland 
3194*5c51f124SMoriah Waterland 	/* entry assertions */
3195*5c51f124SMoriah Waterland 
3196*5c51f124SMoriah Waterland 	assert(tag != SML_TAG__NULL);
3197*5c51f124SMoriah Waterland 
3198*5c51f124SMoriah Waterland 	/* entry debugging info */
3199*5c51f124SMoriah Waterland 
3200*5c51f124SMoriah Waterland 	_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_INT_FREE_TAG,
3201*5c51f124SMoriah Waterland 		(unsigned long)tag,
3202*5c51f124SMoriah Waterland 		tag->name ? tag->name : "<<NONE>>",
3203*5c51f124SMoriah Waterland 		tag->params_num, tag->tags_num);
3204*5c51f124SMoriah Waterland 
3205*5c51f124SMoriah Waterland 	for (k = 0; k < tag->params_num; k++) {
3206*5c51f124SMoriah Waterland 		_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_INT_FREE_PARAM_NAME,
3207*5c51f124SMoriah Waterland 			(unsigned long)(&tag->params[k]),
3208*5c51f124SMoriah Waterland 			(unsigned long)(tag->params[k].name),
3209*5c51f124SMoriah Waterland 			tag->params[k].name);
3210*5c51f124SMoriah Waterland 		free(tag->params[k].name);
3211*5c51f124SMoriah Waterland 		tag->params[k].name = (char *)NULL;
3212*5c51f124SMoriah Waterland 		_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_INT_FREE_PARAM_VALUE,
3213*5c51f124SMoriah Waterland 			(unsigned long)(&tag->params[k]),
3214*5c51f124SMoriah Waterland 			(unsigned long)(tag->params[k].value),
3215*5c51f124SMoriah Waterland 			tag->params[k].value);
3216*5c51f124SMoriah Waterland 		free(tag->params[k].value);
3217*5c51f124SMoriah Waterland 		tag->params[k].value = (char *)NULL;
3218*5c51f124SMoriah Waterland 	}
3219*5c51f124SMoriah Waterland 
3220*5c51f124SMoriah Waterland 	for (k = 0; k < tag->tags_num; k++) {
3221*5c51f124SMoriah Waterland 		_smlFreeTag(&tag->tags[k]);
3222*5c51f124SMoriah Waterland 	}
3223*5c51f124SMoriah Waterland 
3224*5c51f124SMoriah Waterland 	if (tag->name != NULL) {
3225*5c51f124SMoriah Waterland 		_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_INT_FREE_TAG_NAME,
3226*5c51f124SMoriah Waterland 			(unsigned long)tag->name, tag->name);
3227*5c51f124SMoriah Waterland 		free(tag->name);
3228*5c51f124SMoriah Waterland 		tag->name = NULL;
3229*5c51f124SMoriah Waterland 	}
3230*5c51f124SMoriah Waterland 
3231*5c51f124SMoriah Waterland 
3232*5c51f124SMoriah Waterland 	if (tag->params != NULL) {
3233*5c51f124SMoriah Waterland 		assert(tag->params_num > 0);
3234*5c51f124SMoriah Waterland 		bzero(tag->params, sizeof (SML_PARAM)*tag->params_num);
3235*5c51f124SMoriah Waterland 		_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_INT_FREE_PARAMS,
3236*5c51f124SMoriah Waterland 					(unsigned long)tag->params);
3237*5c51f124SMoriah Waterland 		free(tag->params);
3238*5c51f124SMoriah Waterland 		tag->params = NULL;
3239*5c51f124SMoriah Waterland 		tag->params_num = 0;
3240*5c51f124SMoriah Waterland 	}
3241*5c51f124SMoriah Waterland 
3242*5c51f124SMoriah Waterland 	if (tag->tags != NULL) {
3243*5c51f124SMoriah Waterland 		assert(tag->tags_num > 0);
3244*5c51f124SMoriah Waterland 		bzero(tag->tags, sizeof (SML_TAG)*tag->tags_num);
3245*5c51f124SMoriah Waterland 		_smlLogMsg(LOG_MSG_DEBUG, DBG_SML_INT_FREE_TAGS,
3246*5c51f124SMoriah Waterland 			(unsigned long)tag->tags);
3247*5c51f124SMoriah Waterland 		free(tag->tags);
3248*5c51f124SMoriah Waterland 		tag->tags = NULL;
3249*5c51f124SMoriah Waterland 		tag->tags_num = 0;
3250*5c51f124SMoriah Waterland 	}
3251*5c51f124SMoriah Waterland }
3252*5c51f124SMoriah Waterland 
3253*5c51f124SMoriah Waterland /*
3254*5c51f124SMoriah Waterland  * Name:	log_msg
3255*5c51f124SMoriah Waterland  * Description:	Outputs messages to logging facility.
3256*5c51f124SMoriah Waterland  * Scope:	public
3257*5c51f124SMoriah Waterland  * Arguments:	type - the severity of the message
3258*5c51f124SMoriah Waterland  *		out - where to output the message.
3259*5c51f124SMoriah Waterland  *		fmt - the printf format, plus its arguments
3260*5c51f124SMoriah Waterland  * Returns:	none
3261*5c51f124SMoriah Waterland  */
3262*5c51f124SMoriah Waterland 
3263*5c51f124SMoriah Waterland /*PRINTFLIKE2*/
3264*5c51f124SMoriah Waterland static void
_smlLogMsg(LogMsgType a_type,const char * a_format,...)3265*5c51f124SMoriah Waterland _smlLogMsg(LogMsgType a_type, const char *a_format, ...)
3266*5c51f124SMoriah Waterland {
3267*5c51f124SMoriah Waterland 	va_list	ap;
3268*5c51f124SMoriah Waterland 	size_t		vres = 0;
3269*5c51f124SMoriah Waterland 	char		bfr[1];
3270*5c51f124SMoriah Waterland 	char		*rstr = (char *)NULL;
3271*5c51f124SMoriah Waterland 	FILE	*out;
3272*5c51f124SMoriah Waterland 	char	*prefix;
3273*5c51f124SMoriah Waterland 
3274*5c51f124SMoriah Waterland 	switch (a_type) {
3275*5c51f124SMoriah Waterland 	case LOG_MSG_ERR:
3276*5c51f124SMoriah Waterland 	default:
3277*5c51f124SMoriah Waterland 		out = stderr;
3278*5c51f124SMoriah Waterland 		prefix = MSG_LOG_ERROR;
3279*5c51f124SMoriah Waterland 		break;
3280*5c51f124SMoriah Waterland 	case LOG_MSG_WRN:
3281*5c51f124SMoriah Waterland 		out = stderr;
3282*5c51f124SMoriah Waterland 		prefix = MSG_LOG_WARNING;
3283*5c51f124SMoriah Waterland 		break;
3284*5c51f124SMoriah Waterland 	case LOG_MSG_INFO:
3285*5c51f124SMoriah Waterland 		out = stdout;
3286*5c51f124SMoriah Waterland 		prefix = NULL;
3287*5c51f124SMoriah Waterland 		break;
3288*5c51f124SMoriah Waterland 	case LOG_MSG_DEBUG:
3289*5c51f124SMoriah Waterland 		if (!smlGetVerbose()) {
3290*5c51f124SMoriah Waterland 			/* no debug messages if not verbose mode */
3291*5c51f124SMoriah Waterland 			return;
3292*5c51f124SMoriah Waterland 		}
3293*5c51f124SMoriah Waterland 		out = stderr;
3294*5c51f124SMoriah Waterland 		prefix = MSG_LOG_DEBUG;
3295*5c51f124SMoriah Waterland 		break;
3296*5c51f124SMoriah Waterland 	}
3297*5c51f124SMoriah Waterland 
3298*5c51f124SMoriah Waterland 	if (prefix != NULL) {
3299*5c51f124SMoriah Waterland 		(void) fprintf(out, "%s: ", prefix);
3300*5c51f124SMoriah Waterland 	}
3301*5c51f124SMoriah Waterland 
3302*5c51f124SMoriah Waterland 	/* determine size of the message in bytes */
3303*5c51f124SMoriah Waterland 
3304*5c51f124SMoriah Waterland 	va_start(ap, a_format);
3305*5c51f124SMoriah Waterland 	vres = vsnprintf(bfr, 1, a_format, ap);
3306*5c51f124SMoriah Waterland 	va_end(ap);
3307*5c51f124SMoriah Waterland 
3308*5c51f124SMoriah Waterland 	/* allocate storage to hold the message */
3309*5c51f124SMoriah Waterland 
3310*5c51f124SMoriah Waterland 	rstr = (char *)malloc(vres+2);
3311*5c51f124SMoriah Waterland 
3312*5c51f124SMoriah Waterland 	/* generate the results of the printf conversion */
3313*5c51f124SMoriah Waterland 
3314*5c51f124SMoriah Waterland 	va_start(ap, a_format);
3315*5c51f124SMoriah Waterland 	vres = vsnprintf(rstr, vres+1, a_format, ap);
3316*5c51f124SMoriah Waterland 	va_end(ap);
3317*5c51f124SMoriah Waterland 
3318*5c51f124SMoriah Waterland 	if (fprintf(out, "%s\n", rstr) < 0) {
3319*5c51f124SMoriah Waterland 		/*
3320*5c51f124SMoriah Waterland 		 * nothing output, try stderr as a
3321*5c51f124SMoriah Waterland 		 * last resort
3322*5c51f124SMoriah Waterland 		 */
3323*5c51f124SMoriah Waterland 		(void) fprintf(stderr, ERR_LOG_FAIL, a_format);
3324*5c51f124SMoriah Waterland 	}
3325*5c51f124SMoriah Waterland 
3326*5c51f124SMoriah Waterland 	free(rstr);
3327*5c51f124SMoriah Waterland }
3328