4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
30 * Synopsis: simplified markup language (SML) support
31 * Taxonomy: project private
35 * This module implements methods that support the processing of a
36 * simplified markup language (SML). Objects that contain SML data
37 * can be created and manipulated, and SML can be imported into
38 * internal SML objects or exported from internal SML objects.
42 * smlAddTag - Add new tag object into existing tag object
43 * smlConvertStringToTag - Convert string into tag object
44 * smlConvertTagToString - Convert a tag object into a string
45 * representation of the XML
46 * smlDbgPrintTag - Print a representation of an XML tag if debugging
47 * smlDelParam - Delete a parameter from a tag object
48 * smlDelTag - Delete element from tag object
49 * smlDup - Duplicate a tag object
50 * smlFindAndDelTag - Delete a tag if found in tag object
51 * smlFreeTag - Free a tag object and all its contents when no
53 * smlFstatCompareEq - Compare file status information
54 * smlGetElementName - Return a tag's element name
55 * smlGetNumParams - Get number of parameters set in tag
56 * smlGetParam - Get a parameter from a tag
57 * smlGetParamF - Get a formatted parameter from a tag
58 * smlGetParamByTag - Get a parameter by tag and index
59 * smlGetParamByTagParam Get parameter given tag name, index,
60 * parameter name, and value
61 * smlGetParamName - Get the name of a tag parameter given its index
62 * smlGetParam_r - Get a parameter from a tag into fixed buffer
63 * smlGetTag - Get an element from a tag
64 * smlGetTagByName - Get an element given a name and an index
65 * smlGetTagByTagParam - Get element given tag name, index, parameter name,
67 * smlGetVerbose - get current verbose mode setting
68 * smlLoadTagFromFile - Load a file into a tag object
69 * smlNewTag - Create a new (empty) tag object
70 * smlParamEq - Determine if parameter is equal to a specified value
71 * smlParamEqF - Determine if parameter is equal to a specified value
72 * smlPrintTag - Print a simple XML representation of a tag to stderr
73 * smlReadOneTag - read one complete tag from a datastream
74 * smlReadTagFromDs - read tag object from datastream
75 * smlSetFileStatInfo - encode file status information into tag
76 * smlSetVerbose - set/clear verbose mode for debugging output
77 * smlSetParam - Set parameter value in tag object
78 * smlSetParamF - Set parameter value in tag object
79 * smlWriteTagToDs - Write an XML representation of a tag to a datastream
80 * smlWriteTagToFd - Write an XML representation of a tag to an open file
82 * smlWriteTagToFile - Write an XML representation of a tag to a file
97 #include <sys/statvfs.h>
100 #include <sys/types.h>
101 #include <sys/stat.h>
111 #include "messages.h"
113 /* Should be defined by cc -D */
114 #if !defined(TEXT_DOMAIN)
115 #define TEXT_DOMAIN "SYS_TEST"
119 * Private Method Forward Declarations
123 static void _smlLogMsg(LogMsgType a_type
, const char *a_format
, ...);
125 static int _smlReadTag(SML_TAG
**r_tag
, char **a_str
, char *parent
);
127 static int _smlWriteSimpleTag(char **a_str
,
130 static int _smlWriteParamValue(char **a_str
, char *value
);
132 static void _smlFreeTag(SML_TAG
*tag
);
134 static char *_sml_fileStatInfoTag
= "File-Stat-Info";
136 static boolean_t verbose
= B_FALSE
;
140 * This definition controls the maximum size of any individual sml
141 * component, such as a tag name, tag *value*, etc. The code should
142 * someday be revised to dynamically allocate whatever memory is needed
143 * to hold such components while parsing, but that exercise is left for
144 * another day. Any component that exceeds this length is silently
148 #define MAX_SML_COMPONENT_LENGTH 16384
156 * Description: Add new tag object into existing tag object
157 * Arguments: r_tag - [RO, *RW] - (SML_TAG **)
158 * Pointer to handle to the tag object to update
159 * The handle may be updated if the tag object is
161 * a_index - [RO] - (int)
162 * Add the tag after the "n"th tag in the tag object
163 * -1 == add the tag to the end of the tag object
164 * 0 == add the tag to the beginning of the tag object
165 * a_subTag - [RO, *RW] - (SML_TAG *)
166 * The tag to add to 'tag'
168 * The location within "r_tag" where "a_subTag"
169 * has been added - this is the handle into the r_tag
170 * object to the tag that was just added
171 * Errors: If the tag object cannot be updated, the process exits
175 smlAddTag(SML_TAG
**r_tag
, int a_index
, SML_TAG
*a_subTag
)
179 /* entry assertions */
181 assert(SML_TAG__ISVALID(a_subTag
));
182 assert(SML_TAG__R_ISVALID(r_tag
));
184 /* if no tag to update specified, ignore request */
187 if (tag
== SML_TAG__NULL
) {
191 /* entry debugging info */
193 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_ADD_TAG
,
194 a_subTag
->name
, tag
->name
);
196 /* if index is out of range or -1, append to tag object */
198 if ((a_index
> tag
->tags_num
) || (a_index
== -1)) {
199 a_index
= tag
->tags_num
;
202 /* bump number of tags in tag object */
206 /* expand tag object to hold new subtag */
208 tag
->tags
= (SML_TAG
*)realloc(tag
->tags
,
209 sizeof (SML_TAG
) * tag
->tags_num
);
211 /* if not appending, adjust tag object to hold new subtag */
213 if (a_index
< (tag
->tags_num
- 1)) {
214 (void) memmove(&(tag
->tags
[a_index
+ 1]), &(tag
->tags
[a_index
]),
215 sizeof (SML_TAG
) * (tag
->tags_num
- a_index
- 1));
218 /* copy new subtag into correct location in tag object */
220 (void) memcpy(&(tag
->tags
[a_index
]), a_subTag
,
223 return (&(tag
->tags
[a_index
]));
228 * Description: Delete element from tag object
229 * Arguments: tag - [RO, *RW] - (SML_TAG *)
230 * The tag object to update
231 * sub_tag - [RO, *RW] - (SML_TAG *)
232 * Element to be removed from the tag object
234 * The sub_tag is removed from the tag object
235 * NOTE: The sub-tag and all elements contained within it are deallocated
236 * the sub-tag is no longer valid when this method returns
240 smlDelTag(SML_TAG
*tag
, SML_TAG
*sub_tag
)
244 /* entry assertions */
246 assert(SML_TAG__ISVALID(sub_tag
));
248 /* if no tag to update specified, ignore request */
250 if (tag
== SML_TAG__NULL
) {
254 /* entry debugging info */
256 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_DEL_TAG
,
257 sub_tag
->name
, tag
->name
);
259 /* if tag object is empty, ignore request */
261 if (tag
->tags_num
== 0) {
265 /* determine index into tag object of element to remove */
266 for (index
= 0; index
< tag
->tags_num
; index
++) {
267 if (sub_tag
== &tag
->tags
[index
]) {
272 /* if element not found in tag, ignore request */
274 if (index
>= tag
->tags_num
) {
278 /* free up the subtag to be deleted */
280 _smlFreeTag(sub_tag
);
283 * if not removing last element, collapse tag object removing
287 if (index
< (tag
->tags_num
- 1)) {
288 (void) memmove(&(tag
->tags
[index
]), &(tag
->tags
[index
+ 1]),
289 sizeof (SML_TAG
) *(tag
->tags_num
- index
- 1));
292 /* one less tag object in tag */
297 * If only one tag left, then delete entire tag structure
298 * otherwise reallocate removing unneeded entry
301 if (tag
->tags_num
> 0) {
302 /* realloc removing last element in tag object */
304 tag
->tags
= (SML_TAG
*)realloc(tag
->tags
,
305 sizeof (SML_TAG
) *tag
->tags_num
);
307 tag
->tags
= SML_TAG__NULL
;
313 * Description: Free a tag object and all its contents when no longer needed
314 * Arguments: tag - [RO, *RW] - (SML_TAG *)
315 * The tag object to be deleted
317 * The tag object and all its contents are deallocated
321 smlFreeTag(SML_TAG
*tag
)
323 /* entry assertions */
325 assert(SML_TAG__ISVALID(tag
));
327 /* entry debugging info */
329 if (tag
->name
!= (char *)NULL
) {
330 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_FREE_TAG
,
331 (unsigned long)tag
, tag
->name
);
334 /* free the tag object contents */
338 /* free the tag object handle */
340 bzero(tag
, sizeof (SML_TAG
));
345 * Name: smlGetNumParams
346 * Synopsis: Get number of parameters set in tag
347 * Description: Return the number of parameters set in a tag
348 * Arguments: a_tag - [RO, *RO] - (SML_TAG *)
349 * The tag object to obtain the # params from
351 * Number of parameters set in tag
352 * 0 = no parameters are set
356 smlGetNumParams(SML_TAG
*a_tag
)
358 return (a_tag
? a_tag
->params_num
: 0);
363 * Name: smlGetParam_r
364 * Description: Get a parameter from a tag into a buffer of fixed size
365 * Arguments: tag - [RO, *RO] - (SML_TAG *)
366 * The tag object to obtain the parameter from
367 * name - [RO, *RO] - (char *)
368 * Name of the parameter to retrieve
369 * buf - [RO, *RW] - (char *)
370 * Location of buffer to contain results
371 * bufLen - [RO, *RO] - (int)
372 * Maximum bytes available in buffer to contain results
377 smlGetParam_r(SML_TAG
*tag
, char *name
, char *buf
, int bufLen
)
381 /* entry assertions */
383 assert(name
!= (char *)NULL
);
384 assert(*name
!= '\0');
385 assert(buf
!= (char *)NULL
);
388 /* terminate the buffer */
391 buf
[bufLen
-1] = '\0';
395 /* if no tag specified, return NULL */
397 if (tag
== SML_TAG__NULL
) {
401 /* if no parameters in tag, return NULL */
403 if (tag
->params
== NULL
) {
407 /* entry debugging info */
409 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_GET_PARAM
,
412 /* scan tag object looking for specified parameter */
414 for (k
= 0; k
< tag
->params_num
; k
++) {
415 assert(tag
->params
[k
].name
!= (char *)NULL
);
416 assert(tag
->params
[k
].value
!= (char *)NULL
);
417 if (streq(tag
->params
[k
].name
, name
)) {
418 _smlLogMsg(LOG_MSG_DEBUG
,
420 tag
->name
, name
, tag
->params
[k
].value
);
421 (void) strncpy(buf
, tag
->params
[k
].value
, bufLen
-1);
426 /* parameter not found - return */
431 * Description: Get a parameter from a tag
432 * Arguments: tag - [RO, *RO] - (SML_TAG *)
433 * The tag object to obtain the parameter from
434 * name - [RO, *RO] - (char *)
435 * Name of the parameter to retrieve
437 * Value of the specified parameter
438 * == (char *)NULL if the parameter does not exist
439 * NOTE: Any parameter returned is placed in new storage for the
440 * calling method. The caller must use 'free' to dispose
441 * of the storage once the parameter is no longer needed.
445 smlGetParam(SML_TAG
*tag
, char *name
)
449 /* entry assertions */
451 assert(name
!= (char *)NULL
);
452 assert(*name
!= '\0');
454 /* entry debugging info */
456 _smlLogMsg(LOG_MSG_DEBUG
, "get param param <%s>", name
);
458 /* if no tag specified, return NULL */
460 if (tag
== SML_TAG__NULL
) {
461 return ((char *)NULL
);
464 /* if no parameters in tag, return NULL */
466 if (tag
->params
== NULL
) {
467 return ((char *)NULL
);
470 /* entry debugging info */
472 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_GET_PARAM
,
475 /* scan tag object looking for specified parameter */
477 for (k
= 0; k
< tag
->params_num
; k
++) {
478 assert(tag
->params
[k
].name
!= (char *)NULL
);
479 assert(tag
->params
[k
].value
!= (char *)NULL
);
480 if (streq(tag
->params
[k
].name
, name
)) {
481 _smlLogMsg(LOG_MSG_DEBUG
,
483 tag
->name
, name
, tag
->params
[k
].value
);
484 return (strdup(tag
->params
[k
].value
));
488 /* parameter not found - return NULL */
490 return ((char *)NULL
);
494 * Name: smlGetParamName
495 * Description: Get the name of a tag parameter given its index
496 * Arguments: tag - [RO, *RO] - (SML_TAG *)
497 * The tag object to obtain the parameter name from
498 * index - [RO] - (int)
499 * Index of parameter name to return
501 * Name of 'index'th parameter
502 * == (char *)NULL if no such parameter exists in tag
503 * NOTE: Any parameter name returned is placed in new storage for the
504 * calling method. The caller must use 'free' to dispose
505 * of the storage once the parameter name is no longer needed.
509 smlGetParamName(SML_TAG
*tag
, int index
)
511 /* if no tag specified, return NULL */
514 return ((char *)NULL
);
517 /* entry debugging info */
519 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_GET_PARAM_NAME
,
522 /* if no parameters in tag, return NULL */
524 if (tag
->params
== NULL
) {
525 return ((char *)NULL
);
528 /* if index not within range, return NULL */
530 if (index
>= tag
->params_num
) {
531 return ((char *)NULL
);
534 /* index within range - return parameter name */
536 assert(tag
->params
[index
].name
!= (char *)NULL
);
537 assert(tag
->params
[index
].value
!= (char *)NULL
);
539 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_GOT_PARAM_NAME
,
540 tag
->name
, index
, tag
->params
[index
].name
);
542 return (strdup(tag
->params
[index
].name
));
546 * Name: smlGetParamByTag
547 * Synopsis: Get a parameter value from a tag by name and index
548 * Description: Call to look for a parameter value from a tag with
549 * a given name with a parameter of a given name
550 * Arguments: tag - [RO, *RO] - (SML_TAG *)
551 * The tag object to obtain the parameter
552 * index - [RO] - (int)
553 * Index of nth tag by name to look for
554 * tagName - [RO, *RO] - (char *)
555 * Name of tag to look for
556 * paramName - [RO, *RO] - (char *)
557 * Name of parameter to return value of
559 * == (char *)NULL - no parameter value set
560 * != (char *)NULL - value of parameter set
564 smlGetParamByTag(SML_TAG
*tag
, int index
,
565 char *tagName
, char *paramName
)
569 /* entry assertions */
571 assert(SML_TAG__ISVALID(tag
));
572 assert(tagName
!= (char *)NULL
);
573 assert(*tagName
!= '\0');
574 assert(paramName
!= (char *)NULL
);
575 assert(*paramName
!= '\0');
577 /* entry debugging info */
579 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_GET_PARAM_BY_TAG
,
580 tagName
, index
, paramName
);
582 /* find the requested tag by name and index */
584 rtag
= smlGetTagByName(tag
, index
, tagName
);
585 if (rtag
== SML_TAG__NULL
) {
586 return ((char *)NULL
);
589 return (smlGetParam(rtag
, paramName
));
593 * Name: smlGetTagByTagParam
594 * Synopsis: Get element given tag name, index, parameter name, and value
595 * Description: Call to look for a tag with a given nae, that has a parameter
596 * of a given name with a specified value
597 * Arguments: tag - [RO, *RO] - (SML_TAG *)
598 * The tag object to obtain the element from
599 * index - [RO] - (int)
600 * Index of nth name to return
601 * tagName - [RO, *RO] - (char *)
602 * Tag name to look up
603 * paramName - [RO, *RO] - (char *)
604 * Parameter name to look up
605 * paramValue - [RO, *RO] - (char *)
606 * Parameter value to match
608 * The 'index'th occurance of element 'name' with
609 * a parameter 'name' with value specified
610 * == SML_TAG__NULL if no such element exists
614 smlGetTagByTagParam(SML_TAG
*tag
, int index
,
615 char *tagName
, char *paramName
, char *paramValue
)
617 int ti
; /* tag structure index */
619 /* entry assertions */
621 assert(SML_TAG__ISVALID(tag
));
622 assert(tagName
!= (char *)NULL
);
623 assert(*tagName
!= '\0');
624 assert(paramName
!= (char *)NULL
);
625 assert(*paramName
!= '\0');
626 assert(paramValue
!= (char *)NULL
);
627 assert(*paramValue
!= '\0');
629 /* if tag has no elements, return NULL */
631 if (tag
->tags
== NULL
) {
632 return (SML_TAG__NULL
);
637 * -> search tag structure; for each tag with element == "tagName":
638 * -> search tag parameters; if parameter name == "paramName"
639 * -> if parameter value != "paramValue"; to next tag
640 * -> if parameter value == "paramValue":
641 * -> if not the "index"th paramValue found; to next tag
642 * -> return tag found
645 for (ti
= 0; ti
< tag
->tags_num
; ti
++) {
646 int pi
; /* parameter structure index */
648 /* if tag element does not match, go on to next tag */
650 if (strcmp(tag
->tags
[ti
].name
, tagName
)) {
654 /* element matches: search for specified parameter name/value */
656 for (pi
= 0; pi
< tag
->tags
[ti
].params_num
; pi
++) {
657 assert(tag
->tags
[ti
].params
[pi
].name
!= (char *)NULL
);
658 assert(tag
->tags
[ti
].params
[pi
].value
!= (char *)NULL
);
660 /* if parameter name doesnt match to next parameter */
662 if (strcmp(tag
->tags
[ti
].params
[pi
].name
, paramName
)) {
666 /* if parameter value doesnt match to next tag */
668 if (strcmp(tag
->tags
[ti
].params
[pi
].value
,
674 * found element/paramname/paramvalue:
675 * -> if this is not the 'index'th one, go to next tag
683 * found specified element/paramname/paramvalue:
684 * -> return the tag found
687 return (&tag
->tags
[ti
]);
692 /* no such element found - return NULL */
694 return (SML_TAG__NULL
);
698 * Name: smlGetParamByTagParam
699 * Synopsis: Get parameter given tag name, index, parameter name, and value
700 * Description: Call to return the value of a parameter from a tag of a
701 * given name, with a parameter of a given name with a
703 * Arguments: tag - [RO, *RO] - (SML_TAG *)
704 * The tag object to obtain the element from
705 * index - [RO] - (int)
706 * Index of nth name to return
707 * tagName - [RO, *RO] - (char *)
708 * Tag name to look up
709 * paramName - [RO, *RO] - (char *)
710 * Parameter name to look up
711 * paramValue - [RO, *RO] - (char *)
712 * Parameter value to match
713 * paramReturn - [RO, *RO] - (char *)
714 * Parameter name to return the value of
716 * The value of parameter 'paramReturn' from the
717 * The 'index'th occurance of element 'name' with
718 * a parameter 'name' with value specified
719 * == (char *)NULL if no such parameter exists
723 smlGetParamByTagParam(SML_TAG
*tag
, int index
,
724 char *tagName
, char *paramName
, char *paramValue
, char *paramReturn
)
726 int ti
; /* tag structure index */
728 /* entry assertions */
730 assert(SML_TAG__ISVALID(tag
));
731 assert(tagName
!= (char *)NULL
);
732 assert(*tagName
!= '\0');
733 assert(paramName
!= (char *)NULL
);
734 assert(*paramName
!= '\0');
735 assert(paramValue
!= (char *)NULL
);
736 assert(*paramValue
!= '\0');
737 assert(paramReturn
!= (char *)NULL
);
738 assert(*paramReturn
!= '\0');
740 /* if tag has no elements, return NULL */
742 if (tag
->tags
== NULL
) {
743 return ((char *)NULL
);
748 * -> search tag structure; for each tag with element == "tagName":
749 * -> search tag parameters; if parameter name == "paramName"
750 * -> if parameter value != "paramValue"; to next tag
751 * -> if parameter value == "paramValue":
752 * -> if not the "index"th paramValue found; to next tag
753 * -> return value of "paramReturn"
756 for (ti
= 0; ti
< tag
->tags_num
; ti
++) {
757 int pi
; /* parameter structure index */
759 /* if tag element does not match, go on to next tag */
761 if (strcmp(tag
->tags
[ti
].name
, tagName
)) {
765 /* element matches: search for specified parameter name/value */
767 for (pi
= 0; pi
< tag
->tags
[ti
].params_num
; pi
++) {
768 assert(tag
->tags
[ti
].params
[pi
].name
!= (char *)NULL
);
769 assert(tag
->tags
[ti
].params
[pi
].value
!= (char *)NULL
);
771 /* if parameter name doesnt match to next parameter */
773 if (strcmp(tag
->tags
[ti
].params
[pi
].name
, paramName
)) {
777 /* if parameter value doesnt match to next tag */
779 if (strcmp(tag
->tags
[ti
].params
[pi
].value
,
785 * found element/paramname/paramvalue:
786 * -> if this is not the 'index'th one, go to next tag
794 * found specified element/paramname/paramvalue:
795 * -> return parameter requested
798 return (smlGetParam(&tag
->tags
[ti
], paramReturn
));
803 /* no such element found - return NULL */
805 return ((char *)NULL
);
809 * Name: smlGetElementName
810 * Description: Return the name of a given tag
811 * Arguments: a_tag - [RO, *RO] - (SML_TAG *)
812 * The tag object to obtain the element name from
814 * Value of name of specified tag
815 * NOTE: Any name string returned is placed in new storage for the
816 * calling method. The caller must use 'free' to dispose
817 * of the storage once the name string is no longer needed.
821 smlGetElementName(SML_TAG
*a_tag
)
823 /* entry assertions */
825 assert(SML_TAG__ISVALID(a_tag
));
826 assert(a_tag
->name
!= (char *)NULL
);
827 assert(*a_tag
->name
!= '\0');
829 /* return the tag name */
831 return (strdup(a_tag
->name
));
836 * Description: Get an element from a tag
837 * Arguments: tag - [RO, *RO] - (SML_TAG *)
838 * The tag object to obtain the element from
839 * index - [RO] - (int)
840 * Index of element to return
842 * The 'index'th element from the specified tag
843 * == SML_TAG__NULL if no such tag or element
847 smlGetTag(SML_TAG
*tag
, int index
)
849 /* if no tag specified, return NULL */
852 return (SML_TAG__NULL
);
855 /* if tag has no elements, return NULL */
857 if (tag
->tags
== NULL
) {
858 return (SML_TAG__NULL
);
861 /* if index not within range, return NULL */
863 if (tag
->tags_num
<= index
) {
864 return (SML_TAG__NULL
);
867 /* index within range, return element specified */
869 assert(SML_TAG__ISVALID(&tag
->tags
[index
]));
871 return (&tag
->tags
[index
]);
875 * Name: smlGetTagByName
876 * Description: Get an element given a name and an index
877 * Arguments: tag - [RO, *RO] - (SML_TAG *)
878 * The tag object to obtain the element from
879 * index - [RO] - (int)
880 * Index of nth name to return
881 * name - [RO, *RO] - (char *)
882 * Tag name to look up
884 * The 'index'th occurance of element 'name'
885 * == SML_TAG__NULL if no such element exists
889 smlGetTagByName(SML_TAG
*tag
, int index
, char *name
)
893 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_GET_TAG_BY_NAME
, name
, index
);
895 /* if no tag specified, return NULL */
898 return (SML_TAG__NULL
);
901 /* if this tag is the one mentioned, return it */
903 if (streq(tag
->name
, name
) && (index
== 0)) {
907 /* if tag has no elements, return NULL */
909 if (tag
->tags
== NULL
) {
910 return (SML_TAG__NULL
);
913 /* if index out of range, return NULL */
915 if (tag
->tags_num
<= index
) {
916 return (SML_TAG__NULL
);
919 /* index within range - search for specified element */
921 for (k
= 0; k
< tag
->tags_num
; k
++) {
922 if (streq(tag
->tags
[k
].name
, name
)) {
924 assert(SML_TAG__ISVALID(&tag
->tags
[k
]));
925 return (&tag
->tags
[k
]);
932 /* no such element found - return NULL */
934 return (SML_TAG__NULL
);
938 * Name: smlConvertStringToTag
939 * Description: Convert string into tag object
940 * Arguments: err - [RO, *RW] (LU_ERR)
941 * Error object - used to contain any errors encountered
942 * and return those errors to this methods caller
943 * r_tag - [RW, *RW] - (SML_TAG **)
944 * Pointer to handle to place new tag object
945 * str - [RO, *RO] - (char *)
946 * String object to convert to tag object
948 * RESULT_OK - string converted to tag object
949 * RESULT_ERR - problem converting string to tag object
950 * NOTE: Any tag object returned is placed in new storage for the
951 * calling method. The caller must use 'smlFreeTag' to dispose
952 * of the storage once the tag object name is no longer needed.
956 smlConvertStringToTag(SML_TAG
**r_tag
, char *str
)
959 SML_TAG
*tag
= SML_TAG__NULL
;
962 /* entry assertions */
964 assert(SML_TAG__R_ISVALID(r_tag
));
965 assert(str
!= (char *)NULL
);
966 assert(*str
!= '\0');
968 tag
= smlNewTag("tagfile");
971 r
= _smlReadTag(&tmp_tag
, &str
, NULL
);
972 if (r
!= RESULT_OK
) {
976 if (tmp_tag
== SML_TAG__NULL
) {
980 _smlLogMsg(LOG_MSG_DEBUG
,
981 DBG_SML_LOADED_TAGS_FROM_STR
,
982 (unsigned long)tag
, tag
->name
);
986 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_READ_IN_TOP_TAG
,
989 tag
->tags
= (SML_TAG
*)realloc(tag
->tags
,
990 sizeof (SML_TAG
) *tag
->tags_num
);
991 (void) memcpy(&(tag
->tags
[tag
->tags_num
- 1]), tmp_tag
,
997 * Name: smlReadOneTag
998 * Description: read one complete tag from a datastream
999 * Arguments: err - [RO, *RW] (LU_ERR)
1000 * Error object - used to contain any errors encountered
1001 * and return those errors to this methods caller
1002 * r_tag - [RW, *RW] - (SML_TAG **)
1003 * Pointer to handle to place new tag object
1004 * == SML_TAG__NULL if empty tag found (not an error)
1005 * ds - [RO, *RO] - (LU_DS)
1006 * Handle to datastream to read tag from
1008 * RESULT_OK - tag successfully read
1009 * RESULT_ERR - problem reading tag
1010 * NOTE: Any tag object returned is placed in new storage for the
1011 * calling method. The caller must use 'smlFreeTag' to dispose
1012 * of the storage once the tag object name is no longer needed.
1016 smlReadOneTag(SML_TAG
**r_tag
, char *a_str
)
1020 /* entry assertions */
1022 assert(SML_TAG__R_ISVALID(r_tag
));
1023 assert(a_str
!= (char *)NULL
);
1025 /* entry debugging info */
1027 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_READ_ONE_TAG
, a_str
);
1029 /* reset return tag */
1031 *r_tag
= SML_TAG__NULL
;
1033 /* read tag from datastream, no parent tag to attach it to */
1035 r
= _smlReadTag(r_tag
, &a_str
, NULL
);
1036 if (r
!= RESULT_OK
) {
1037 _smlLogMsg(LOG_MSG_ERR
, ERR_SML_CANNOT_READ_TAG
);
1041 if (*r_tag
!= SML_TAG__NULL
) {
1042 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_ONE_TAG_READ
,
1043 (unsigned long)*r_tag
,
1044 (*r_tag
)->name
? (*r_tag
)->name
: "<no name>");
1046 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_READ_ONE_TAG_NOTAG
);
1049 /* exit debugging info */
1056 * Description: Create a new (empty) tag object
1057 * Arguments: name - [RO, *RO] - (char *)
1058 * Name of tag; NULL to give the tag no name
1059 * Returns: SML_TAG *
1060 * Tag object created
1061 * NOTE: Any tag object returned is placed in new storage for the
1062 * calling method. The caller must use 'smlFreeTag' to dispose
1063 * of the storage once the tag object name is no longer needed.
1064 * Errors: If the tag object cannot be created, the process exits
1068 smlNewTag(char *name
)
1072 /* entry assertions */
1074 assert((name
== (char *)NULL
) || (*name
!= '\0'));
1076 /* entry debugging info */
1078 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_CREATE_NEW_TAG_OBJECT
,
1079 name
? name
: "<no name>");
1081 /* allocate zeroed storage for the tag object */
1083 tag
= (SML_TAG
*)calloc(1, sizeof (SML_TAG
));
1084 assert(tag
!= SML_TAG__NULL
);
1086 /* if name is provided, duplicate and assign it */
1088 if (name
!= (char *)NULL
) {
1089 tag
->name
= strdup(name
);
1092 /* exit assertions */
1094 assert(SML_TAG__ISVALID(tag
));
1096 /* exit debugging info */
1098 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_CREATED_NEW_TAG_OBJECT
,
1099 (unsigned long)tag
, name
? name
: "<no name>");
1105 * Name: smlConvertTagToString
1106 * Description: Convert a tag object into a string representation of the XML
1107 * Arguments: tag - [RO, *RO] - (SML_TAG *)
1108 * The tag object to convert to a string
1110 * String representation (in XML) of tag object
1111 * == (char *)NULL if conversion is not possible
1112 * NOTE: Any string returned is placed in new storage for the
1113 * calling method. The caller must use 'free' to dispose
1114 * of the storage once the string is no longer needed.
1118 smlConvertTagToString(SML_TAG
*tag
)
1120 char *str
= (char *)NULL
;
1122 /* entry assertions */
1124 assert(SML_TAG__ISVALID(tag
));
1126 /* convert the tag object into the datastream */
1128 (void) _smlWriteSimpleTag(&str
, tag
);
1130 assert(str
!= (char *)NULL
);
1131 assert(*str
!= '\0');
1133 /* return the results */
1139 * Name: smlDbgPrintTag
1140 * Synopsis: Print a representation of an XML tag if debugging
1141 * Arguments: a_tag - [RO, *RO] - (SML_TAG *)
1142 * Pointer to tag structure to dump
1143 * a_format - [RO, RO*] (char *)
1144 * printf-style format for debugging message to be output
1145 * VARG_LIST - [RO] (?)
1146 * arguments as appropriate to 'format' specified
1148 * If one of the debugging flags is set, the hexdump
1154 smlDbgPrintTag(SML_TAG
*a_tag
, char *a_format
, ...)
1159 char *rstr
= (char *)NULL
;
1161 /* entry assertions */
1163 assert(a_format
!= (char *)NULL
);
1164 assert(*a_format
!= '\0');
1165 assert(SML_TAG__ISVALID(a_tag
));
1168 * output the message header
1171 /* determine size of the message in bytes */
1173 va_start(ap
, a_format
);
1174 vres
= vsnprintf(bfr
, 1, a_format
, ap
);
1179 /* allocate storage to hold the message */
1181 rstr
= (char *)calloc(1, vres
+2);
1182 assert(rstr
!= (char *)NULL
);
1184 /* generate the results of the printf conversion */
1186 va_start(ap
, a_format
);
1187 vres
= vsnprintf(rstr
, vres
+1, a_format
, ap
);
1191 assert(*rstr
!= '\0');
1193 _smlLogMsg(LOG_MSG_DEBUG
, "%s", rstr
);
1196 /* convert the tag into a string to be printed */
1198 rstr
= smlConvertTagToString(a_tag
);
1199 if (rstr
!= (char *)NULL
) {
1200 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_PRINTTAG
, a_tag
->name
,
1201 strlen(rstr
), rstr
);
1208 * Description: Delete a parameter from a tag object
1209 * Arguments: tag - [RO, *RW] - (SML_TAG *)
1210 * The tag object to delete the parameter from
1211 * name - [RO, *RO] - (char *)
1212 * The parameter to delete from the tag object
1214 * If the parameter exists, it is deleted from the tag
1218 smlDelParam(SML_TAG
*tag
, char *name
)
1222 /* entry assertions */
1224 assert(SML_TAG__ISVALID(tag
));
1225 assert(tag
->name
!= (char *)NULL
);
1226 assert(name
!= NULL
);
1227 assert(*name
!= '\0');
1229 /* entry debugging info */
1231 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_DELETE_PARAM
,
1234 /* if tag has no parameters, nothing to delete */
1236 if (tag
->params
== NULL
) {
1237 _smlLogMsg(LOG_MSG_DEBUG
,
1238 DBG_SML_DELETE_PARAM_NO_PARAMS
);
1242 assert(tag
->params_num
> 0);
1244 /* search the tag for the parameter */
1246 for (k
= 0; k
< tag
->params_num
; k
++) {
1247 if (streq(tag
->params
[k
].name
, name
)) {
1252 /* if the parameter was not found, nothing to delete */
1254 if (k
>= tag
->params_num
) {
1255 _smlLogMsg(LOG_MSG_DEBUG
,
1256 DBG_SML_DELETE_PARAM_NOT_FOUND
,
1261 /* parameter found - indicate deleted */
1263 assert(tag
->params
[k
].name
!= (char *)NULL
);
1264 assert(tag
->params
[k
].value
!= (char *)NULL
);
1266 _smlLogMsg(LOG_MSG_DEBUG
,
1267 DBG_SML_DELETE_PARAM_FOUND
,
1268 name
, tag
->params
[k
].value
);
1270 /* free up storage fro parameter */
1272 free(tag
->params
[k
].name
);
1273 free(tag
->params
[k
].value
);
1275 /* if not at end, compact parameter storage */
1277 if (k
< (tag
->params_num
-1)) {
1278 (void) memmove(&(tag
->params
[k
]), &(tag
->params
[k
+ 1]),
1279 sizeof (SML_PARAM
) *(tag
->params_num
- k
- 1));
1282 /* one less parameter object in tag */
1287 * If only one parameter left, then delete entire parameter storage,
1288 * otherwise reallocate removing unneeded entry
1291 if (tag
->params_num
> 0) {
1292 /* realloc removing last element in tag object */
1294 tag
->params
= (SML_PARAM
*)
1295 realloc(tag
->params
,
1296 sizeof (SML_PARAM
) *tag
->params_num
);
1298 tag
->params
= (SML_PARAM
*)NULL
;
1303 * Name: smlSetParamF
1304 * Description: Set formatted parameter value in tag object
1305 * Arguments: tag - [RO, *RW] - (SML_TAG *)
1306 * The tag object to set the parameter in
1307 * name - [RO, *RO] - (char *)
1308 * The parameter to add to the tag object
1309 * format - [RO, RO*] (char *)
1310 * printf-style format to create parameter value from
1312 * arguments as appropriate to 'format' specified
1314 * The parameter value is set in the tag object
1315 * according to the results of the format string
1321 smlSetParamF(SML_TAG
*tag
, char *name
, char *format
, ...)
1328 /* entry assertions */
1330 assert(SML_TAG__ISVALID(tag
));
1331 assert(name
!= (char *)NULL
);
1332 assert(*name
!= '\0');
1333 assert(format
!= NULL
);
1334 assert(*format
!= '\0');
1336 /* determine size of the parameter name in bytes */
1338 va_start(ap
, format
);
1339 vres
= vsnprintf(fbfr
, 1, format
, ap
);
1344 /* allocate storage to hold the message */
1346 bfr
= (char *)calloc(1, vres
+2);
1347 assert(bfr
!= (char *)NULL
);
1349 /* generate the parameter name and store it in the allocated storage */
1351 va_start(ap
, format
);
1352 vres
= vsnprintf(bfr
, vres
+1, format
, ap
);
1356 assert(*bfr
!= '\0');
1358 /* add the parameter to the tag */
1360 smlSetParam(tag
, name
, bfr
);
1362 /* free up temporary storage and return */
1369 * Description: Get a format-generated parameter from a tag
1370 * Arguments: tag - [RO, *RO] - (SML_TAG *)
1371 * The tag object to obtain the parameter from
1372 * format - [RO, RO*] (char *)
1373 * printf-style format for parameter name to be
1374 * looked up to be formatted
1376 * arguments as appropriate to 'format' specified
1378 * Value of the specified parameter
1379 * == (char *)NULL if the parameter does not exist
1380 * NOTE: Any parameter returned is placed in new storage for the
1381 * calling method. The caller must use 'free' to dispose
1382 * of the storage once the parameter is no longer needed.
1387 smlGetParamF(SML_TAG
*tag
, char *format
, ...)
1395 /* entry assertions */
1397 assert(SML_TAG__ISVALID(tag
));
1398 assert(format
!= NULL
);
1399 assert(*format
!= '\0');
1401 /* determine size of the parameter name in bytes */
1403 va_start(ap
, format
);
1404 vres
= vsnprintf(fbfr
, 1, format
, ap
);
1409 /* allocate storage to hold the message */
1411 bfr
= (char *)calloc(1, vres
+2);
1412 assert(bfr
!= (char *)NULL
);
1414 /* generate the parameter name and store it in the allocated storage */
1416 va_start(ap
, format
);
1417 vres
= vsnprintf(bfr
, vres
+1, format
, ap
);
1421 assert(*bfr
!= '\0');
1423 /* add the parameter to the tag */
1425 p
= smlGetParam(tag
, bfr
);
1427 /* free up temporary storage and return */
1436 * Description: Set parameter value in tag object
1437 * Arguments: tag - [RO, *RW] - (SML_TAG *)
1438 * The tag object to set the parameter in
1439 * name - [RO, *RO] - (char *)
1440 * The parameter to add to the tag object
1441 * value - [RO, *RO] - (char *)
1442 * The value of the parameter to set in the tag object
1444 * The parameter value is set in the tag object
1448 smlSetParam(SML_TAG
*tag
, char *name
, char *value
)
1450 SML_PARAM
*parameter
;
1452 /* entry assertions */
1454 assert(SML_TAG__ISVALID(tag
));
1455 assert(name
!= (char *)NULL
);
1456 assert(*name
!= '\0');
1457 assert(value
!= (char *)NULL
);
1459 /* entry debugging info */
1461 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_SET_PARAM
,
1462 tag
->name
, name
, value
);
1464 /* if parameters exist, see if modifying existing parameter */
1466 if (tag
->params
!= NULL
) {
1468 for (k
= 0; k
< tag
->params_num
; k
++) {
1469 assert(tag
->params
[k
].name
!= (char *)NULL
);
1470 assert(tag
->params
[k
].value
!= (char *)NULL
);
1472 /* if name does not match, skip */
1474 if (!streq(tag
->params
[k
].name
, name
)) {
1478 /* found parameter - if value is same, leave alone */
1480 if (streq(tag
->params
[k
].value
, value
)) {
1481 _smlLogMsg(LOG_MSG_DEBUG
,
1482 DBG_SML_SET_PARAM_LEAVE_ALONE
,
1483 tag
->params
[k
].value
);
1487 /* exists and has different value - change */
1489 _smlLogMsg(LOG_MSG_DEBUG
,
1490 DBG_SML_SET_PARAM_MODIFY
,
1491 tag
->params
[k
].value
);
1492 free(tag
->params
[k
].value
);
1493 tag
->params
[k
].value
= strdup(value
);
1498 /* not modifying existing - add new parameter */
1500 _smlLogMsg(LOG_MSG_DEBUG
,
1501 DBG_SML_SET_PARAM_CREATE_NEW
);
1503 parameter
= (SML_PARAM
*)calloc(1, sizeof (SML_PARAM
));
1504 bzero(parameter
, sizeof (SML_PARAM
));
1505 parameter
->name
= strdup(name
);
1506 parameter
->value
= strdup(value
);
1509 tag
->params
= (SML_PARAM
*)realloc(tag
->params
,
1510 sizeof (SML_PARAM
) *tag
->params_num
);
1511 (void) memcpy(&(tag
->params
[tag
->params_num
- 1]), parameter
,
1512 sizeof (SML_PARAM
));
1518 * Description: Determine if parameter is equal to a specified formatted value
1519 * Arguments: tag - [RO, *RO] - (SML_TAG *)
1520 * The tag object to look for the parameter to compare
1521 * findTag - [RO, *RO] - (char *)
1522 * Tag within tag object to look for the parameter in
1523 * findParam - [RO, *RO] - (char *)
1524 * Parameter within tag to look for
1525 * format - [RO, RO*] (char *)
1526 * printf-style format for value to be compared against
1529 * arguments as appropriate to 'format' specified to
1530 * generate the value to compare parameter with
1531 * Returns: boolean_t
1532 * B_TRUE - the parameter exists and matches given value
1533 * B_FALSE - parameter does not exist or does not match
1538 smlParamEqF(SML_TAG
*tag
, char *findTag
, char *findParam
, char *format
, ...)
1546 /* entry assertions */
1548 assert(SML_TAG__ISVALID(tag
));
1549 assert(format
!= NULL
);
1550 assert(*format
!= '\0');
1552 /* determine size of the parameter value in bytes */
1554 va_start(ap
, format
);
1555 vres
= vsnprintf(fbfr
, 1, format
, ap
);
1560 /* allocate storage to hold the message */
1562 bfr
= (char *)calloc(1, vres
+2);
1563 assert(bfr
!= (char *)NULL
);
1565 /* generate the parameter value and store it in the allocated storage */
1567 va_start(ap
, format
);
1568 vres
= vsnprintf(bfr
, vres
+1, format
, ap
);
1572 assert(*bfr
!= '\0');
1574 /* add the parameter to the tag */
1576 b
= smlParamEq(tag
, findTag
, findParam
, bfr
);
1578 /* free up temporary storage and return */
1587 * Description: Determine if parameter is equal to a specified value
1588 * Arguments: tag - [RO, *RO] - (SML_TAG *)
1589 * The tag object to look for the parameter to compare
1590 * findTag - [RO, *RO] - (char *)
1591 * Tag within tag object to look for the parameter in
1592 * findParam - [RO, *RO] - (char *)
1593 * Parameter within tag to look for
1594 * str - [RO, *RO] - (char *)
1595 * Value to compare parameter with
1596 * Returns: boolean_t
1597 * B_TRUE - the parameter exists and matches given value
1598 * B_FALSE - parameter does not exist or does not match
1602 smlParamEq(SML_TAG
*tag
, char *findTag
, char *findParam
, char *str
)
1608 /* entry assertions */
1610 assert(str
!= (char *)NULL
);
1611 assert(findParam
!= (char *)NULL
);
1612 assert(findTag
!= (char *)NULL
);
1613 assert(SML_TAG__ISVALID(tag
));
1615 /* look for the specified tag - if not found, return false */
1617 rtag
= smlGetTagByName(tag
, 0, findTag
);
1618 if (rtag
== SML_TAG__NULL
) {
1622 /* look for the specified parameter - if not found, return false */
1624 rparm
= smlGetParam(rtag
, findParam
);
1625 if (rparm
== (char *)NULL
) {
1629 /* parameter found - compare against given value */
1631 answer
= strcasecmp(str
, rparm
);
1633 /* free up parameter storage */
1637 /* return results of comparison */
1639 return (answer
== 0 ? B_TRUE
: B_FALSE
);
1643 * Name: smlFindAndDelTag
1644 * Description: Delete a tag if found in tag object
1645 * Arguments: tag - [RO, *RW] - (SML_TAG *)
1646 * The tag object to delete the tag from
1647 * findTag - [RO, *RO] - (char *)
1648 * Tag within tag object to delete
1649 * Returns: boolean_t
1650 * B_TRUE - tag found and deleted
1651 * B_FALSE - tag not found
1655 smlFindAndDelTag(SML_TAG
*tag
, char *findTag
)
1657 SML_TAG
*rtag
= SML_TAG__NULL
;
1659 /* entry assertions */
1661 assert(SML_TAG__ISVALID(tag
));
1662 assert(findTag
!= (char *)NULL
);
1663 assert(*findTag
!= '\0');
1665 /* find the specified tag - if not found, return false */
1667 rtag
= smlGetTagByName(tag
, 0, findTag
);
1668 if (rtag
== SML_TAG__NULL
) {
1672 /* tag found - delete it and return true */
1674 smlDelTag(tag
, rtag
);
1681 * Description: Duplicate a tag object
1682 * Arguments: tag - [RO, *RO] - (SML_TAG *)
1683 * The tag object to duplicate
1684 * Returns: SML_TAG *
1685 * A handle to a complete duplicate of the tag provided
1686 * NOTE: Any tag object returned is placed in new storage for the
1687 * calling method. The caller must use 'smlFreeTag' to dispose
1688 * of the storage once the tag object name is no longer needed.
1689 * Errors: If the tag object cannot be duplicated, the process exits
1693 smlDup(SML_TAG
*tag
)
1695 SML_TAG
*rtag
= SML_TAG__NULL
;
1698 /* entry assertions */
1700 assert(SML_TAG__ISVALID(tag
));
1702 /* allocate zeroed storage for the tag object */
1704 rtag
= (SML_TAG
*)calloc(1, sizeof (SML_TAG
));
1705 assert(rtag
!= SML_TAG__NULL
);
1707 /* duplicate all parameters of the tag */
1709 rtag
->name
= (tag
->name
? strdup(tag
->name
) : (char *)NULL
);
1710 rtag
->params_num
= tag
->params_num
;
1711 if (tag
->params
!= (SML_PARAM
*)NULL
) {
1712 rtag
->params
= (SML_PARAM
*)
1713 calloc(1, sizeof (SML_PARAM
)*rtag
->params_num
);
1714 bzero(rtag
->params
, sizeof (SML_PARAM
)*rtag
->params_num
);
1715 for (i
= 0; i
< rtag
->params_num
; i
++) {
1716 rtag
->params
[i
].name
= tag
->params
[i
].name
?
1717 strdup(tag
->params
[i
].name
) :
1719 rtag
->params
[i
].value
= tag
->params
[i
].value
?
1720 strdup(tag
->params
[i
].value
) :
1725 /* duplicate all elements of the tag */
1727 rtag
->tags_num
= tag
->tags_num
;
1729 if (tag
->tags
!= SML_TAG__NULL
) {
1730 rtag
->tags
= (SML_TAG
*)
1731 calloc(1, sizeof (SML_TAG
)*rtag
->tags_num
);
1732 bzero(rtag
->tags
, sizeof (SML_TAG
)*rtag
->tags_num
);
1733 for (i
= 0; i
< rtag
->tags_num
; i
++) {
1735 stag
= smlDup(&tag
->tags
[i
]);
1736 (void) memcpy(&rtag
->tags
[i
], stag
,
1742 /* exit assertions */
1744 assert(SML_TAG__ISVALID(rtag
));
1752 * Name: smlSetFileStatInfo
1753 * Description; Given a file status structure and path name, encode the
1754 * structure and place it and the name into the specified tag
1755 * in a "_sml_fileStatInfoTag" (private) element
1756 * Arguments: tag - [RO, *RO] - (SML_TAG *)
1757 * The tag object to deposit the information into
1758 * statbuf - [RO, *RO] - (struct stat *)
1759 * Pointer to file status structure to encode
1760 * path - [RO, *RO] - (char *)
1761 * Pointer to path name of file to encode
1763 * The information is placed into the specified tag object
1767 smlSetFileStatInfo(SML_TAG
**tag
, struct stat
*statbuf
, char *path
)
1771 /* entry assertions */
1773 assert(SML_TAG__R_ISVALID(tag
));
1774 assert(SML_TAG__ISVALID(*tag
));
1775 assert(statbuf
!= (struct stat
*)NULL
);
1777 /* if stat info exists, delete it */
1779 (void) smlFindAndDelTag(*tag
, _sml_fileStatInfoTag
);
1781 /* create the file stat info inside of the top level tag */
1783 assert(smlGetTagByName(*tag
, 0, _sml_fileStatInfoTag
)
1785 rtag
= smlNewTag(_sml_fileStatInfoTag
);
1786 assert(SML_TAG__ISVALID(rtag
));
1787 (void) smlAddTag(tag
, 0, rtag
);
1790 /* obtain handle on newly created file stat info tag */
1792 rtag
= smlGetTagByName(*tag
, 0, _sml_fileStatInfoTag
);
1793 assert(SML_TAG__ISVALID(rtag
));
1795 /* add file info as parameters to the tag */
1797 if (path
!= (char *)NULL
) {
1798 smlSetParam(rtag
, "st_path", path
);
1801 smlSetParamF(rtag
, "st_ino", "0x%llx",
1802 (unsigned long long)statbuf
->st_ino
);
1803 smlSetParamF(rtag
, "st_mode", "0x%llx",
1804 (unsigned long long)statbuf
->st_mode
);
1805 smlSetParamF(rtag
, "st_mtime", "0x%llx",
1806 (unsigned long long)statbuf
->st_mtime
);
1807 smlSetParamF(rtag
, "st_ctime", "0x%llx",
1808 (unsigned long long)statbuf
->st_ctime
);
1809 smlSetParamF(rtag
, "st_size", "0x%llx",
1810 (unsigned long long)statbuf
->st_size
);
1814 * Name: smlFstatCompareEQ
1815 * Description: Given a file status structure and path name, look for the
1816 * information placed into a tag object via smlSetFileStatInfo
1817 * and if present compare the encoded information with the
1818 * arguments provided
1819 * Arguments: statbuf - [RO, *RO] - (struct stat *)
1820 * Pointer to file status structure to compare
1821 * tag - [RO, *RO] - (SML_TAG *)
1822 * The tag object to compare against
1823 * path - [RO, *RO] - (char *)
1824 * Pointer to path name of file to compare
1825 * Returns: boolean_t
1826 * B_TRUE - both status structures are identical
1827 * B_FALSE - the status structures are not equal
1831 smlFstatCompareEq(struct stat
*statbuf
, SML_TAG
*tag
, char *path
)
1833 if (tag
== SML_TAG__NULL
) {
1837 assert(SML_TAG__ISVALID(tag
));
1839 if (statbuf
== (struct stat
*)NULL
) {
1843 if (path
!= (char *)NULL
) {
1845 _sml_fileStatInfoTag
, "st_path", path
) != B_TRUE
) {
1850 if (smlParamEqF(tag
, _sml_fileStatInfoTag
, "st_ino",
1851 "0x%llx", (unsigned long long)statbuf
->st_ino
) != B_TRUE
) {
1855 if (smlParamEqF(tag
, _sml_fileStatInfoTag
, "st_mode",
1856 "0x%llx", (unsigned long long)statbuf
->st_mode
) != B_TRUE
) {
1860 if (smlParamEqF(tag
, _sml_fileStatInfoTag
, "st_mtime",
1861 "0x%llx", (unsigned long long)statbuf
->st_mtime
) != B_TRUE
) {
1865 if (smlParamEqF(tag
, _sml_fileStatInfoTag
, "st_ctime",
1866 "0x%llx", (unsigned long long)statbuf
->st_ctime
) != B_TRUE
) {
1870 if (smlParamEqF(tag
, _sml_fileStatInfoTag
, "st_size",
1871 "0x%llx", (unsigned long long)statbuf
->st_size
) != B_TRUE
) {
1880 * Description: Turns on verbose output
1882 * Arguments: verbose = B_TRUE indicates verbose mode
1886 smlSetVerbose(boolean_t setting
)
1893 * Description: Returns whether or not to output verbose messages
1896 * Returns: B_TRUE - verbose messages should be output
1905 * Name: sml_strPrintf
1906 * Synopsis: Create string from printf style format and arguments
1907 * Description: Call to convert a printf style format and arguments into a
1908 * string of characters placed in allocated storage
1909 * Arguments: format - [RO, RO*] (char *)
1910 * printf-style format for string to be formatted
1912 * arguments as appropriate to 'format' specified
1914 * A string representing the printf conversion results
1915 * NOTE: Any string returned is placed in new storage for the
1916 * calling method. The caller must use 'free' to dispose
1917 * of the storage once the string is no longer needed.
1918 * Errors: If the string cannot be created, the process exits
1923 sml_strPrintf(char *a_format
, ...)
1928 char *rstr
= (char *)NULL
;
1930 /* entry assertions */
1932 assert(a_format
!= (char *)NULL
);
1933 assert(*a_format
!= '\0');
1935 /* determine size of the message in bytes */
1937 va_start(ap
, a_format
);
1938 vres
= vsnprintf(bfr
, 1, a_format
, ap
);
1943 /* allocate storage to hold the message */
1945 rstr
= (char *)calloc(1, vres
+2);
1946 assert(rstr
!= (char *)NULL
);
1948 /* generate the results of the printf conversion */
1950 va_start(ap
, a_format
);
1951 vres
= vsnprintf(rstr
, vres
+1, a_format
, ap
);
1955 assert(*rstr
!= '\0');
1957 /* return the results */
1963 * Name: sml_strPrintf_r
1964 * Synopsis: Create string from printf style format and arguments
1965 * Description: Call to convert a printf style format and arguments into a
1966 * string of characters placed in allocated storage
1967 * Arguments: a_buf - [RO, *RW] - (char *)
1968 * - Pointer to buffer used as storage space for the
1969 * returned string created
1970 * a_bufLen - [RO, *RO] - (int)
1971 * - Size of 'a_buf' in bytes - a maximum of 'a_bufLen-1'
1972 * bytes will be placed in 'a_buf' - the returned
1973 * string is always null terminated
1974 * a_format - [RO, RO*] (char *)
1975 * printf-style format for string to be formatted
1976 * VARG_LIST - [RO] (?)
1977 * arguments as appropriate to 'format' specified
1983 sml_strPrintf_r(char *a_buf
, int a_bufLen
, char *a_format
, ...)
1988 /* entry assertions */
1990 assert(a_format
!= (char *)NULL
);
1991 assert(*a_format
!= '\0');
1992 assert(a_buf
!= (char *)NULL
);
1993 assert(a_bufLen
> 1);
1995 /* generate the results of the printf conversion */
1997 va_start(ap
, a_format
);
1998 vres
= vsnprintf(a_buf
, a_bufLen
-1, a_format
, ap
);
2002 assert(vres
< a_bufLen
);
2004 a_buf
[a_bufLen
-1] = '\0';
2008 * Name: sml_XmlEncodeString
2009 * Description: Given a plain text string, convert that string into one that
2010 * encoded using the XML character reference encoding format.
2011 * Arguments: a_plain_text_string - [RO, *RO] (char *)
2012 * The plain text string to convert (encode)
2014 * The encoded form of the plain text string provided
2015 * NOTE: Any string returned is placed in new storage for the
2016 * calling method. The caller must use 'lu_memFree' to dispose
2017 * of the storage once the string is no longer needed.
2021 sml_XmlEncodeString(char *a_plainTextString
)
2023 char *stringHead
; /* -> start of string containing encoded data */
2024 long stringTail
; /* byte pos of first free byte in stringHead */
2025 long stringLength
; /* total bytes allocd starting at stringHead */
2026 char *p
; /* temp -> to retrieve bytes from src string */
2027 long textLength
= 0; /* length of the string to convert */
2029 /* entry assertions */
2031 assert(a_plainTextString
!= (char *)NULL
);
2033 textLength
= strlen(a_plainTextString
);
2035 /* Allocate initial string buffer to hold results */
2037 stringLength
= textLength
*2;
2039 stringHead
= (char *)calloc(1, (size_t)stringLength
+2);
2040 assert(stringHead
!= (char *)NULL
);
2042 /* Add in the encoded message text */
2044 for (p
= a_plainTextString
; textLength
> 0; p
++, textLength
--) {
2046 * Must have at least 12 bytes: this must be at least the
2047 * maximum number of bytes that can be added for a single
2048 * byte as the last byte of the stream. Assuming the byte
2049 * needs to be encoded, it could be:
2051 * If not that many bytes left, grow the buffer.
2054 if ((stringLength
-stringTail
) < 12) {
2055 stringLength
+= (textLength
*2)+12;
2058 (size_t)stringLength
+2);
2059 assert(stringHead
!= (char *)NULL
);
2063 * See if this byte is a 'printable 7-bit ascii value'.
2064 * If so just add it to the new string; otherwise, must
2065 * output an XML character value encoding for the byte.
2160 * It is a printable 7-bit ascii character:
2161 * just add it to the end of the new string.
2164 stringHead
[stringTail
++] = *p
;
2168 * It is not a printable 7-bit ascii character:
2169 * add it as an xml character value encoding.
2172 stringTail
+= sprintf(&stringHead
[stringTail
], "&#%x;",
2178 /* Terminate the new string */
2180 stringHead
[stringTail
] = '\0';
2182 /* realloc the string so it is only as big as it needs to be */
2184 stringHead
= realloc(stringHead
, stringTail
+1);
2185 assert(stringHead
!= (char *)NULL
);
2187 return (stringHead
);
2191 * Name: sml_XmlDecodeString
2192 * Description: Given a string encoded using the XML character reference format,
2193 * convert that string into a plain text (unencoded) string.
2194 * Arguments: a_xml_encoded_string - [RO, *RO] (char *)
2195 * The XML encoded string to convert to plain text
2197 * The unencoded (plain text) form of the encoded string
2198 * NOTE: Any string returned is placed in new storage for the
2199 * calling method. The caller must use 'lu_memFree' to dispose
2200 * of the storage once the string is no longer needed.
2204 sml_XmlDecodeString(char *a_xmlEncodedString
)
2206 char *s
= NULL
; /* -> index into encoded bytes string */
2207 char *d
= NULL
; /* -> index into decoded bytes string */
2208 char *rs
= NULL
; /* -> string holding ref bytes allocated */
2209 char *ri
= NULL
; /* -> index into string holding reference */
2210 long textLength
= 0; /* length of encoded string to decode */
2211 unsigned long rv
= 0; /* temp to hold scanf results of byte conv */
2212 char *i
= NULL
; /* temp to hold strchr results */
2213 char *stringHead
= NULL
; /* -> plain test buffer */
2217 * A finite state machine is used to convert the xml encoded string
2218 * into plain text. The states of the machine are defined below.
2221 int fsmsState
= -1; /* Finite state machine state */
2222 #define fsms_text 0 /* Decoding plain text */
2223 #define fsms_seenAmp 1 /* Found & */
2224 #define fsms_seenPound 2 /* Found # following & */
2225 #define fsms_collect 3 /* Collecting character reference bytes */
2227 /* entry assertions */
2229 assert(a_xmlEncodedString
!= (char *)NULL
);
2231 textLength
= strlen(a_xmlEncodedString
);
2234 * Allocate string that can contain the decoded string.
2235 * Since decoding always results in a shorter string (bytes encoded
2236 * using the XML character reference are larger in the encoded form)
2237 * we can allocate a string the same size as the encoded string.
2240 stringHead
= (char *)calloc(1, textLength
+1);
2241 assert(stringHead
!= (char *)NULL
);
2244 * Convert all bytes.
2247 /* Decoding plain text */
2248 fsmsState
= fsms_text
;
2250 for (s
= a_xmlEncodedString
, d
= stringHead
; textLength
> 0;
2251 s
++, textLength
--) {
2252 switch (fsmsState
) {
2253 case fsms_text
: /* Decoding plain text */
2261 fsmsState
= fsms_seenAmp
;
2267 case fsms_seenAmp
: /* Found & */
2269 /* Found # following & */
2270 fsmsState
= fsms_seenPound
;
2273 fsmsState
= fsms_text
; /* Decoding plain text */
2278 case fsms_seenPound
: /* Found # following & */
2281 /* Decoding plain text */
2282 fsmsState
= fsms_text
;
2288 tmpdiff
= (ptrdiff_t)i
- (ptrdiff_t)s
;
2289 rs
= (char *)calloc(1, tmpdiff
+ 1);
2290 assert(rs
!= (char *)NULL
);
2292 /* Collecting character reference bytes */
2293 fsmsState
= fsms_collect
;
2297 /* Collecting character reference bytes */
2329 tmpdiff
= (ptrdiff_t)ri
- (ptrdiff_t)rs
;
2330 (void) strncpy(d
, rs
, tmpdiff
-1);
2332 /* Decoding plain text */
2333 fsmsState
= fsms_text
;
2339 if (sscanf(rs
, "%lx", &rv
) != 1) {
2344 /* Decoding plain text */
2345 fsmsState
= fsms_text
;
2349 /* Done converting bytes - deallocate reference byte storage */
2353 /* terminate the converted (plain text) string */
2357 /* exit assertions */
2359 assert(stringHead
!= (char *)NULL
);
2361 return (stringHead
);
2370 * Description: read complete tag from a datastream
2371 * Arguments: err - [RO, *RW] (LU_ERR)
2372 * Error object - used to contain any errors encountered
2373 * and return those errors to this methods caller
2374 * r_tag - [RW, *RW] - (SML_TAG **)
2375 * Pointer to handle to place new tag object
2376 * == SML_TAG__NULL if empty tag found (not an error)
2377 * ds - [RO, *RO] - (LU_DS)
2378 * Handle to datastream to read tag from
2379 * parent - [RO, *RO] - (char *)
2380 * Name for parent of tag (NONE if top of tag)
2382 * RESULT_OK - tag successfully read
2383 * RESULT_ERR - problem reading tag
2384 * NOTE: Any tag object returned is placed in new storage for the
2385 * calling method. The caller must use 'smlFreeTag' to dispose
2386 * of the storage once the tag object name is no longer needed.
2387 * Errors: If the tag object cannot be duplicated, the process exits
2391 _smlReadTag(SML_TAG
**r_tag
, char **a_str
, char *parent
)
2396 char name
[MAX_SML_COMPONENT_LENGTH
];
2401 /* entry assertions */
2403 assert(SML_TAG__R_ISVALID(r_tag
));
2404 assert(a_str
!= (char **)NULL
);
2406 /* entry debugging info */
2408 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_READ_TAG
,
2409 parent
? parent
: "<<TOP TAG>>");
2411 /* reset return tag */
2413 *r_tag
= SML_TAG__NULL
;
2415 /* allocate zeroed storage for the tag object */
2417 tag
= (SML_TAG
*)calloc(1, sizeof (SML_TAG
));
2418 assert(tag
!= SML_TAG__NULL
);
2420 /* reset name accumulator storage */
2422 bzero(name
, sizeof (name
));
2424 /* ignore delimters before tag */
2427 /* read tag character - handle failure/EOF */
2429 if ((*p
== '\0') || ((c
= (*p
++)) == '\0')) {
2430 if (parent
== NULL
) {
2431 _smlLogMsg(LOG_MSG_DEBUG
,
2432 DBG_SML_READTAG_EXPECTED_EOF
,
2439 /* EOF in middle of processing tag */
2441 _smlLogMsg(LOG_MSG_ERR
,
2442 DBG_SML_READTAG_UNEXPECTED_EOF
,
2446 return (RESULT_ERR
);
2449 /* if beginning of tag, break out */
2455 /* not tag beginning: ignore delimiters if not inside tag yet */
2457 if (parent
== (char *)NULL
) {
2458 /* ignore delimters */
2460 if (strchr(" \t", c
) != (char *)NULL
) {
2464 /* on blank lines, return no tag object */
2467 _smlLogMsg(LOG_MSG_DEBUG
,
2468 DBG_SML_READTAG_BLANKLINE
,
2475 /* invalid character before tag start */
2477 _smlLogMsg(LOG_MSG_ERR
, ERR_SML_READTAG_BAD_START_CHAR
,
2478 c
, (unsigned int)c
);
2480 return (RESULT_ERR
);
2485 * all delimiters have been ignored and opening tag character seen;
2496 /* handle EOF after tag opening character found */
2499 _smlLogMsg(LOG_MSG_ERR
,
2500 ERR_SML_EOF_BEFORE_TAG_NAME
,
2501 parent
? parent
: "<<NONE>>");
2504 return (RESULT_ERR
);
2507 /* is this a tag closure? */
2510 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_START_CLOSE_TAG
,
2511 parent
? parent
: "<<NONE>>");
2514 /* get next character of tag name */
2521 /* EOF inside tag name? */
2524 _smlLogMsg(LOG_MSG_ERR
,
2525 ERR_SML_READTAG_CLOSE_TAG_EOF
,
2526 parent
? parent
: "<<NONE>>");
2529 return (RESULT_ERR
);
2532 /* tag close: break out of collection loop */
2538 /* see if illegal character in tag name */
2541 if (strchr("/ \t\n\":<?$'\\`!@#%^&*()+=|[]{};,", c
)
2543 _smlLogMsg(LOG_MSG_ERR
,
2544 ERR_SML_READTAG_CLOSE_TAG_ILLCHAR
,
2545 c
, (unsigned int)c
, name
);
2548 return (RESULT_ERR
);
2551 /* valid character - add to name if room left */
2553 if (pos
< sizeof (name
)-1) {
2554 name
[pos
] = (c
&0xFF);
2558 assert(pos
< sizeof (name
));
2561 /* close of tag found */
2565 /* is the tag empty? If so that's an error */
2567 if (*name
== '\0') {
2568 _smlLogMsg(LOG_MSG_ERR
,
2569 ERR_SML_READTAG_CLOSE_EMPTY_TAG
);
2572 return (RESULT_ERR
);
2575 /* if no parent, a close tag outside of any open tag */
2577 if (parent
== (char *)NULL
) {
2578 _smlLogMsg(LOG_MSG_ERR
,
2579 ERR_SML_READTAG_CLOSE_NO_PARENT
,
2583 return (RESULT_ERR
);
2586 /* if not close to current parent, error */
2588 if (!streq(parent
, name
)) {
2589 _smlLogMsg(LOG_MSG_ERR
,
2590 ERR_SML_READTAG_CLOSE_WRONG_TAG
,
2594 return (RESULT_ERR
);
2597 /* close of current tag found - success */
2599 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_READTAG_CLOSE_TAG
,
2606 /* not starting a close tag */
2611 /* at start of tag - input tag name */
2613 bzero(name
, sizeof (name
));
2618 /* EOF inside of tag name? */
2621 _smlLogMsg(LOG_MSG_ERR
,
2622 ERR_SML_READTAG_TAG_EOF
,
2623 name
, parent
? parent
: "<<NONE>>");
2626 return (RESULT_ERR
);
2629 /* if separator or end of line then tag name collected */
2631 if (strchr(" >\t\n", c
) != NULL
) {
2635 /* see if illegal character in tag name */
2638 if (strchr("\":<>?$'\\`!@#%^&*()+=|[]{};,", c
) != NULL
) {
2639 _smlLogMsg(LOG_MSG_ERR
,
2640 ERR_SML_READTAG_TAG_ILLCHAR
,
2641 c
, (unsigned int)c
, name
);
2644 return (RESULT_ERR
);
2647 /* close current tag? */
2650 /* get next character of tag name */
2657 /* tag close not found? */
2660 _smlLogMsg(LOG_MSG_ERR
,
2661 ERR_SML_READTAG_BADTAG_CLOSE
,
2662 name
, parent
? parent
: "<<NONE>>");
2665 return (RESULT_ERR
);
2668 /* is the tag empty? If so that's an error */
2670 if (*name
== '\0') {
2671 _smlLogMsg(LOG_MSG_ERR
,
2672 ERR_SML_READTAG_EMPTY_TAG
,
2673 parent
? parent
: "<<NONE>>");
2676 return (RESULT_ERR
);
2681 _smlLogMsg(LOG_MSG_DEBUG
,
2682 DBG_SML_READTAG_CLOSED_TAG
,
2683 name
, parent
? parent
: "<<NONE>>");
2685 tag
->name
= strdup(name
);
2691 /* valid character - add to name if room left */
2693 if (pos
< sizeof (name
)-1) {
2694 name
[pos
] = (c
&0xFF);
2698 assert(pos
< sizeof (name
));
2700 /* get next character to parse */
2708 /* have a valid tag name: <tagname */
2710 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_HAVE_TAG_NAME
,
2711 name
, parent
? parent
: "<<NONE>>");
2713 assert(*name
!= '\0');
2715 /* place tag name inside of tag object */
2717 tag
->name
= strdup(name
);
2719 /* clear out name accumulator to get parameters */
2721 bzero(name
, sizeof (name
));
2724 /* input parameters */
2731 SML_PARAM
*parameter
;
2733 /* pass spaces before parameter name */
2737 /* get next character of parameter name */
2744 /* EOF inside parameter name? */
2747 _smlLogMsg(LOG_MSG_ERR
,
2748 ERR_SML_READTAG_PARM_EOF
,
2750 parent
? parent
: "<<NONE>>");
2753 return (RESULT_ERR
);
2756 /* if separator/end of line tag parameter collected */
2758 if (strchr(" \t\n", c
) != NULL
) {
2762 /* see if illegal character in parameter name */
2765 if (strchr("\":<?$'\\`!@#%^&*()+=|[]{};,.", c
) !=
2767 _smlLogMsg(LOG_MSG_ERR
,
2768 ERR_SML_READTAG_PARMNAME_ILLCHAR
,
2769 c
, (unsigned int)c
, name
, tag
->name
,
2770 parent
? parent
: "<<NONE>>");
2773 return (RESULT_ERR
);
2776 /* tag close found? */
2782 /* close tag found ? */
2790 _smlLogMsg(LOG_MSG_DEBUG
,
2798 /* / not followed by > */
2799 _smlLogMsg(LOG_MSG_ERR
,
2800 ERR_SML_READTAG_BADPARMNAME_CLOSE
,
2802 parent
? parent
: "<<NONE>>");
2805 return (RESULT_ERR
);
2808 /* valid character - add to name if room left */
2810 if (pos
< sizeof (name
)-1) {
2811 name
[pos
] = (c
&0xFF);
2815 assert(pos
< sizeof (name
));
2823 /* input parameter name */
2831 /* EOF inside of parameter name? */
2834 _smlLogMsg(LOG_MSG_ERR
,
2835 ERR_SML_READTAG_PARM_EOF
,
2837 parent
? parent
: "<<NONE>>");
2840 return (RESULT_ERR
);
2844 if (strchr("\t \n\":<>?$'\\`!@%^*()+|[]{},./", c
) != NULL
) {
2845 _smlLogMsg(LOG_MSG_ERR
,
2846 ERR_SML_READTAG_PARMNAME_ILLCHAR
,
2847 c
, (unsigned int)c
, name
, tag
->name
,
2848 parent
? parent
: "<<NONE>>");
2851 return (RESULT_ERR
);
2854 /* name - value separator found ? */
2860 /* valid character - add to name if room left */
2862 if (pos
< sizeof (name
)-1) {
2863 name
[pos
] = (c
&0xFF);
2867 assert(pos
< sizeof (name
));
2870 /* is the parameter name empty? If so that's an error */
2872 if (*name
== '\0') {
2873 _smlLogMsg(LOG_MSG_ERR
,
2874 ERR_SML_READTAG_EMPTY_PARMNAME
,
2875 tag
->name
, parent
? parent
: "<<NONE>>");
2878 return (RESULT_ERR
);
2881 /* have a parameter name */
2883 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_HAVE_PARM_NAME
,
2886 /* duplicate (save) parameter name */
2888 pname
= strdup(name
);
2890 /* clear out name accumulator to get parameters */
2892 bzero(name
, sizeof (name
));
2901 _smlLogMsg(LOG_MSG_ERR
,
2902 ERR_SML_PARM_SEP_BAD
,
2903 c
, (unsigned int)c
);
2907 return (RESULT_ERR
);
2910 /* input parameter value */
2918 /* EOF inside of parameter value? */
2921 _smlLogMsg(LOG_MSG_ERR
,
2922 ERR_SML_READTAG_PARMVAL_EOF
,
2924 parent
? parent
: "<<NONE>>");
2928 return (RESULT_ERR
);
2931 /* close of parameter value? */
2937 if (strchr("\n", c
) != NULL
) {
2938 _smlLogMsg(LOG_MSG_ERR
,
2939 ERR_SML_READTAG_PARMVAL_NL
,
2941 parent
? parent
: "<<NONE>>");
2945 return (RESULT_ERR
);
2948 /* valid character - add to value if room left */
2950 if (pos
< sizeof (name
)-1) {
2951 name
[pos
] = (c
&0xFF);
2955 assert(pos
< sizeof (name
));
2960 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_HAVE_PARM_VALUE
,
2961 pname
, name
, tag
->name
);
2963 pvalue
= sml_XmlDecodeString(name
);
2964 bzero(name
, sizeof (name
));
2967 parameter
= (SML_PARAM
*)calloc(1, sizeof (SML_PARAM
));
2968 bzero(parameter
, sizeof (SML_PARAM
));
2969 parameter
->name
= pname
;
2970 parameter
->value
= pvalue
;
2972 tag
->params
= (SML_PARAM
*)
2973 realloc(tag
->params
,
2974 sizeof (SML_PARAM
) *tag
->params_num
);
2975 (void) memcpy(&(tag
->params
[tag
->params_num
- 1]), parameter
,
2976 sizeof (SML_PARAM
));
2984 /* finished processing this tag element entry */
2986 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_TAG_HEAD_DONE
,
2987 tag
->name
, parent
? parent
: "<<NULL>>");
2991 while (((r
= _smlReadTag(&tmp_tag
, &p
, tag
->name
))
2992 == RESULT_OK
) && (tmp_tag
!= NULL
)) {
2994 tag
->tags
= (SML_TAG
*)realloc(tag
->tags
,
2995 sizeof (SML_TAG
) *tag
->tags_num
);
2996 (void) memcpy(&(tag
->tags
[tag
->tags_num
- 1]), tmp_tag
,
3012 * Name: _smlWriteParamValue
3013 * Description: XML Encode a plain text parameter value and write to datastream
3014 * Arguments: ds - [RO, *RO] - (LU_DS)
3015 * Handle to datastream to write parameter value to
3016 * value - [RO, *RO] - (char *)
3017 * Parameter value to be encoded and written
3019 * RESULT_OK - tag successfully read
3020 * RESULT_ERR - problem reading tag
3024 _smlWriteParamValue(char **a_str
, char *value
)
3029 /* entry assertions */
3031 assert(a_str
!= (char **)NULL
);
3032 assert(value
!= (char *)NULL
);
3034 /* xml encode the plain text string */
3036 p
= sml_XmlEncodeString(value
);
3037 assert(p
!= (char *)NULL
);
3039 /* write the xml encoded parameter value to the datastream */
3041 ns
= sml_strPrintf("%s\"%s\"", *a_str
? *a_str
: "", p
);
3043 /* free up xml encoded value storage */
3048 return (RESULT_ERR
);
3051 if (*a_str
!= NULL
) {
3056 /* return results */
3062 _smlWriteSimpleTag(char **a_str
, SML_TAG
*tag
)
3074 if (*a_str
== NULL
) {
3075 *a_str
= strdup("");
3078 if (tag
->params_num
== 0) {
3079 if (tag
->tags_num
== 0) {
3080 ns
= sml_strPrintf("%s<%s/>\n", *a_str
, tag
->name
);
3085 ns
= sml_strPrintf("%s<%s>\n", *a_str
, tag
->name
);
3087 return (RESULT_ERR
);
3093 ns
= sml_strPrintf("%s<%s %s=", *a_str
? *a_str
: "", tag
->name
,
3094 tag
->params
[0].name
);
3096 return (RESULT_ERR
);
3102 r
= _smlWriteParamValue(&np0
, tag
->params
[0].value
);
3103 if ((np0
== NULL
) || (r
!= RESULT_OK
)) {
3104 return (RESULT_ERR
);
3107 ns
= sml_strPrintf("%s%s", *a_str
, np0
);
3109 return (RESULT_ERR
);
3116 for (k
= 1; k
< tag
->params_num
; k
++) {
3117 np0
= sml_strPrintf(" %s=", tag
->params
[k
].name
);
3119 return (RESULT_ERR
);
3122 r
= _smlWriteParamValue(&np1
, tag
->params
[k
].value
);
3123 if ((np1
== NULL
) || (r
!= RESULT_OK
)) {
3124 return (RESULT_ERR
);
3127 ns
= sml_strPrintf("%s%s%s", *a_str
, np0
, np1
);
3129 return (RESULT_ERR
);
3138 if (tag
->tags_num
== 0) {
3139 np0
= sml_strPrintf("/>\n");
3141 return (RESULT_ERR
);
3143 ns
= sml_strPrintf("%s%s", *a_str
, np0
);
3145 return (RESULT_ERR
);
3151 np0
= sml_strPrintf(">\n");
3153 return (RESULT_ERR
);
3155 ns
= sml_strPrintf("%s%s", *a_str
, np0
);
3157 return (RESULT_ERR
);
3165 for (k
= 0; k
< tag
->tags_num
; k
++) {
3166 r
= _smlWriteSimpleTag(a_str
, &(tag
->tags
[k
]));
3167 if (r
!= RESULT_OK
) {
3172 if (tag
->tags_num
> 0) {
3173 np0
= sml_strPrintf("</%s>\n", tag
->name
);
3175 return (RESULT_ERR
);
3177 ns
= sml_strPrintf("%s%s", *a_str
? *a_str
: "", np0
);
3179 return (RESULT_ERR
);
3190 _smlFreeTag(SML_TAG
*tag
)
3194 /* entry assertions */
3196 assert(tag
!= SML_TAG__NULL
);
3198 /* entry debugging info */
3200 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_INT_FREE_TAG
,
3202 tag
->name
? tag
->name
: "<<NONE>>",
3203 tag
->params_num
, tag
->tags_num
);
3205 for (k
= 0; k
< tag
->params_num
; k
++) {
3206 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_INT_FREE_PARAM_NAME
,
3207 (unsigned long)(&tag
->params
[k
]),
3208 (unsigned long)(tag
->params
[k
].name
),
3209 tag
->params
[k
].name
);
3210 free(tag
->params
[k
].name
);
3211 tag
->params
[k
].name
= (char *)NULL
;
3212 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_INT_FREE_PARAM_VALUE
,
3213 (unsigned long)(&tag
->params
[k
]),
3214 (unsigned long)(tag
->params
[k
].value
),
3215 tag
->params
[k
].value
);
3216 free(tag
->params
[k
].value
);
3217 tag
->params
[k
].value
= (char *)NULL
;
3220 for (k
= 0; k
< tag
->tags_num
; k
++) {
3221 _smlFreeTag(&tag
->tags
[k
]);
3224 if (tag
->name
!= NULL
) {
3225 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_INT_FREE_TAG_NAME
,
3226 (unsigned long)tag
->name
, tag
->name
);
3232 if (tag
->params
!= NULL
) {
3233 assert(tag
->params_num
> 0);
3234 bzero(tag
->params
, sizeof (SML_PARAM
)*tag
->params_num
);
3235 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_INT_FREE_PARAMS
,
3236 (unsigned long)tag
->params
);
3239 tag
->params_num
= 0;
3242 if (tag
->tags
!= NULL
) {
3243 assert(tag
->tags_num
> 0);
3244 bzero(tag
->tags
, sizeof (SML_TAG
)*tag
->tags_num
);
3245 _smlLogMsg(LOG_MSG_DEBUG
, DBG_SML_INT_FREE_TAGS
,
3246 (unsigned long)tag
->tags
);
3255 * Description: Outputs messages to logging facility.
3257 * Arguments: type - the severity of the message
3258 * out - where to output the message.
3259 * fmt - the printf format, plus its arguments
3265 _smlLogMsg(LogMsgType a_type
, const char *a_format
, ...)
3270 char *rstr
= (char *)NULL
;
3278 prefix
= MSG_LOG_ERROR
;
3282 prefix
= MSG_LOG_WARNING
;
3289 if (!smlGetVerbose()) {
3290 /* no debug messages if not verbose mode */
3294 prefix
= MSG_LOG_DEBUG
;
3298 if (prefix
!= NULL
) {
3299 (void) fprintf(out
, "%s: ", prefix
);
3302 /* determine size of the message in bytes */
3304 va_start(ap
, a_format
);
3305 vres
= vsnprintf(bfr
, 1, a_format
, ap
);
3308 /* allocate storage to hold the message */
3310 rstr
= (char *)malloc(vres
+2);
3312 /* generate the results of the printf conversion */
3314 va_start(ap
, a_format
);
3315 vres
= vsnprintf(rstr
, vres
+1, a_format
, ap
);
3318 if (fprintf(out
, "%s\n", rstr
) < 0) {
3320 * nothing output, try stderr as a
3323 (void) fprintf(stderr
, ERR_LOG_FAIL
, a_format
);