Print this page
335 service manifest does not support multiple manpage references for the same keyword

@@ -19,10 +19,14 @@
  * CDDL HEADER END
  */
 /*
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  */
+/*
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
+ */
+
 
 /*
  * XML document manipulation routines
  *
  * These routines provide translation to and from the internal representation to

@@ -578,13 +582,11 @@
         case SC_TIME:
         case SC_ASTRING:
         case SC_USTRING:
                 scf_type = lxml_element_to_type(type);
 
-                if ((v->sc_u.sc_string = strdup((char *)value)) == NULL)
-                        uu_die(gettext("string duplication failed (%s)\n"),
-                            strerror(errno));
+                v->sc_u.sc_string = safe_strdup((const char *)value);
                 if (lxml_validate_string_value(scf_type,
                     v->sc_u.sc_string) != 0)
                         uu_die(gettext("illegal value \"%s\" for "
                             "%s (%s)\n"), (char *)value,
                             lxml_prop_types[type],

@@ -1368,11 +1370,11 @@
         xmlChar *stabval;
 
         if (((stabval = xmlGetProp(rstr, (xmlChar *)value_attr)) == NULL) ||
             (*stabval == 0)) {
                 uu_warn(gettext("no stability value found\n"));
-                stabval = (xmlChar *)strdup("External");
+                stabval = (xmlChar *)safe_strdup("External");
         }
 
         pg = internal_pgroup_find_or_create(entity, (char *)scf_pg_general,
             (char *)scf_group_framework);
 

@@ -1436,12 +1438,11 @@
 {
         property_t *p;
         char *value;
         char *prop;
 
-        if ((prop = strdup(propname)) == NULL)
-                uu_die(gettext("Out of memory.\n"));
+        prop = safe_strdup(propname);
 
         value = (char *)xmlGetProp(pval, (xmlChar *)value_attr);
         if (value == NULL || *value == '\0')
                 uu_die(gettext("property value missing for property '%s/%s'\n"),
                     pgrp->sc_pgroup_name, propname);

@@ -1453,12 +1454,11 @@
 static void
 lxml_get_parameter(pgroup_t *pgrp, const char *propname, xmlNodePtr param)
 {
         property_t *p = internal_property_new();
 
-        if ((p->sc_property_name = strdup(propname)) == NULL)
-                uu_die(gettext("Out of memory.\n"));
+        p->sc_property_name = safe_strdup(propname);
         p->sc_value_type = SCF_TYPE_ASTRING;
 
         (void) lxml_get_value(p, SC_ASTRING, param);
 
         (void) internal_attach_property(pgrp, p);

@@ -1705,12 +1705,11 @@
         }
 
         /*
          * Remove leading and trailing whitespace.
          */
-        if ((stripped = strdup((const char *)cursor->content)) == NULL)
-                uu_die(gettext("Out of memory\n"));
+        stripped = safe_strdup((const char *)cursor->content);
 
         for (; isspace(*stripped); stripped++)
                 ;
         for (cp = stripped + strlen(stripped) - 1; isspace(*cp); cp--)
                 ;

@@ -1942,39 +1941,34 @@
 lxml_label_to_groupname(const char *prefix, const char *in)
 {
         char *out, *cp;
         size_t len, piece_len;
 
-        out = uu_zalloc(2 * scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) + 1);
+        out = uu_zalloc(2 * max_scf_name_len + 1);
         if (out == NULL)
                 return (NULL);
 
-        (void) strcpy(out, prefix);
-        (void) strcat(out, in);
+        (void) strlcpy(out, prefix, 2 * max_scf_name_len + 1);
 
-        len = strlen(out);
+        len = strlcat(out, in, 2 * max_scf_name_len + 1);
         if (len > max_scf_name_len) {
                 /* Use the first half and the second half. */
                 piece_len = (max_scf_name_len - 2) / 2;
 
                 (void) strncpy(out + piece_len, "..", 2);
 
                 (void) strcpy(out + piece_len + 2, out + (len - piece_len));
-
-                len = strlen(out);
         }
 
         /*
          * Translate non-property characters to '_'.
          */
         for (cp = out; *cp != '\0'; ++cp) {
                 if (!(isalnum(*cp) || *cp == '_' || *cp == '-'))
                         *cp = '_';
         }
 
-        *cp = '\0';
-
         return (out);
 }
 
 /*
  * If *p is NULL, astring_prop_value() first creates a property with the

@@ -2034,13 +2028,11 @@
         for (; *seps != 0; seps++) {
                 v = internal_value_new();
                 v->sc_type = (*p)->sc_value_type;
                 v->sc_free = lxml_free_str;
                 val_str[0] = *seps;
-                v->sc_u.sc_string = strdup(val_str);
-                if (v->sc_u.sc_string == NULL)
-                        uu_die(gettext("Out of memory\n"));
+                v->sc_u.sc_string = safe_strdup(val_str);
                 internal_attach_value(*p, v);
         }
 }
 
 /*

@@ -2081,23 +2073,52 @@
 static int
 lxml_get_tm_manpage(entity_t *service, xmlNodePtr manpage)
 {
         pgroup_t *pg;
         char *pgname;
+        char *name;
         xmlChar *title;
+        xmlChar *section;
 
         /*
-         * Fetch title attribute, convert to something sanitized, and create
-         * property group.
+         * Fetch title and section attributes, convert to something sanitized,
+         * and create property group.
          */
         title = xmlGetProp(manpage, (xmlChar *)title_attr);
-        pgname = (char *)lxml_label_to_groupname(SCF_PG_TM_MAN_PREFIX,
-            (const char *)title);
+        if (title == NULL)
+                return (-1);
+        section = xmlGetProp(manpage, (xmlChar *)section_attr);
+        if (section == NULL) {
         xmlFree(title);
+                return (-1);
+        }
 
+        name = safe_malloc(max_scf_name_len + 1);
+
+        /* Find existing property group with underscore separators */
+        (void) snprintf(name, max_scf_name_len + 1, "%s_%s", title, section);
+        pgname = lxml_label_to_groupname(SCF_PG_TM_MAN_PREFIX, name);
+        pg = internal_pgroup_find(service, pgname, SCF_GROUP_TEMPLATE);
+
+        uu_free(pgname);
+        (void) snprintf(name, max_scf_name_len + 1, "%s%s", title, section);
+        pgname = lxml_label_to_groupname(SCF_PG_TM_MAN_PREFIX, name);
+
+        if (pg == NULL) {
         pg = internal_pgroup_find_or_create(service, pgname,
-            (char *)SCF_GROUP_TEMPLATE);
+                    SCF_GROUP_TEMPLATE);
+        } else {
+                /* Rename property group */
+                free((char *)pg->sc_pgroup_name);
+                pg->sc_pgroup_name = safe_strdup(pgname);
+        }
+
+        uu_free(pgname);
+        free(name);
+        xmlFree(section);
+        xmlFree(title);
+
 
         /*
          * Each attribute is an astring property within the group.
          */
         if (new_str_prop_from_attr(pg, SCF_PROPERTY_TM_TITLE,

@@ -2121,16 +2142,20 @@
         /*
          * Fetch name attribute, convert name to something sanitized, and create
          * property group.
          */
         name = xmlGetProp(doc_link, (xmlChar *)name_attr);
+        if (name == NULL)
+                return (-1);
 
         pgname = (char *)lxml_label_to_groupname(SCF_PG_TM_DOC_PREFIX,
             (const char *)name);
 
         pg = internal_pgroup_find_or_create(service, pgname,
             (char *)SCF_GROUP_TEMPLATE);
+
+        uu_free(pgname);
         xmlFree(name);
 
         /*
          * Each attribute is an astring property within the group.
          */

@@ -3666,11 +3691,11 @@
         if ((document = xmlReadFile(filename, NULL, 0)) == NULL) {
                 semerr(gettext("couldn't parse document\n"));
                 return (-1);
         }
 
-        document->name = strdup(filename);
+        document->name = safe_strdup(filename);
 
         /*
          * Verify that this is a document type we understand.
          */
         if ((dtd = xmlGetIntSubset(document)) == NULL) {