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