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