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

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/svc/svccfg/svccfg_xml.c
          +++ new/usr/src/cmd/svc/svccfg/svccfg_xml.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   */
       24 +/*
       25 + * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
       26 + */
       27 +
  24   28  
  25   29  /*
  26   30   * XML document manipulation routines
  27   31   *
  28   32   * These routines provide translation to and from the internal representation to
  29   33   * XML.  Directionally-oriented verbs are with respect to the external source,
  30   34   * so lxml_get_service() fetches a service from the XML file into the
  31   35   * internal representation.
  32   36   */
  33   37  
↓ open down ↓ 539 lines elided ↑ open up ↑
 573  577          case SC_NET_ADDR:
 574  578          case SC_NET_ADDR_V4:
 575  579          case SC_NET_ADDR_V6:
 576  580          case SC_FMRI:
 577  581          case SC_URI:
 578  582          case SC_TIME:
 579  583          case SC_ASTRING:
 580  584          case SC_USTRING:
 581  585                  scf_type = lxml_element_to_type(type);
 582  586  
 583      -                if ((v->sc_u.sc_string = strdup((char *)value)) == NULL)
 584      -                        uu_die(gettext("string duplication failed (%s)\n"),
 585      -                            strerror(errno));
      587 +                v->sc_u.sc_string = safe_strdup((const char *)value);
 586  588                  if (lxml_validate_string_value(scf_type,
 587  589                      v->sc_u.sc_string) != 0)
 588  590                          uu_die(gettext("illegal value \"%s\" for "
 589  591                              "%s (%s)\n"), (char *)value,
 590  592                              lxml_prop_types[type],
 591  593                              (scf_error()) ? scf_strerror(scf_error()) :
 592  594                              gettext("Illegal format"));
 593  595                  v->sc_free = lxml_free_str;
 594  596                  break;
 595  597          case SC_BOOLEAN:
↓ open down ↓ 767 lines elided ↑ open up ↑
1363 1365  static int
1364 1366  lxml_get_entity_stability(entity_t *entity, xmlNodePtr rstr)
1365 1367  {
1366 1368          pgroup_t *pg;
1367 1369          property_t *p;
1368 1370          xmlChar *stabval;
1369 1371  
1370 1372          if (((stabval = xmlGetProp(rstr, (xmlChar *)value_attr)) == NULL) ||
1371 1373              (*stabval == 0)) {
1372 1374                  uu_warn(gettext("no stability value found\n"));
1373      -                stabval = (xmlChar *)strdup("External");
     1375 +                stabval = (xmlChar *)safe_strdup("External");
1374 1376          }
1375 1377  
1376 1378          pg = internal_pgroup_find_or_create(entity, (char *)scf_pg_general,
1377 1379              (char *)scf_group_framework);
1378 1380  
1379 1381          p = internal_property_create(SCF_PROPERTY_ENTITY_STABILITY,
1380 1382              SCF_TYPE_ASTRING, 1, stabval);
1381 1383  
1382 1384          return (internal_attach_property(pg, p));
1383 1385  }
↓ open down ↓ 47 lines elided ↑ open up ↑
1431 1433          return (0);
1432 1434  }
1433 1435  
1434 1436  static void
1435 1437  lxml_get_paramval(pgroup_t *pgrp, const char *propname, xmlNodePtr pval)
1436 1438  {
1437 1439          property_t *p;
1438 1440          char *value;
1439 1441          char *prop;
1440 1442  
1441      -        if ((prop = strdup(propname)) == NULL)
1442      -                uu_die(gettext("Out of memory.\n"));
     1443 +        prop = safe_strdup(propname);
1443 1444  
1444 1445          value = (char *)xmlGetProp(pval, (xmlChar *)value_attr);
1445 1446          if (value == NULL || *value == '\0')
1446 1447                  uu_die(gettext("property value missing for property '%s/%s'\n"),
1447 1448                      pgrp->sc_pgroup_name, propname);
1448 1449          p = internal_property_create(prop, SCF_TYPE_ASTRING, 1, value);
1449 1450  
1450 1451          (void) internal_attach_property(pgrp, p);
1451 1452  }
1452 1453  
1453 1454  static void
1454 1455  lxml_get_parameter(pgroup_t *pgrp, const char *propname, xmlNodePtr param)
1455 1456  {
1456 1457          property_t *p = internal_property_new();
1457 1458  
1458      -        if ((p->sc_property_name = strdup(propname)) == NULL)
1459      -                uu_die(gettext("Out of memory.\n"));
     1459 +        p->sc_property_name = safe_strdup(propname);
1460 1460          p->sc_value_type = SCF_TYPE_ASTRING;
1461 1461  
1462 1462          (void) lxml_get_value(p, SC_ASTRING, param);
1463 1463  
1464 1464          (void) internal_attach_property(pgrp, p);
1465 1465  }
1466 1466  
1467 1467  static void
1468 1468  lxml_get_type(pgroup_t *pgrp, xmlNodePtr type)
1469 1469  {
↓ open down ↓ 230 lines elided ↑ open up ↑
1700 1700          }
1701 1701  
1702 1702          if (cursor == NULL) {
1703 1703                  uu_die(gettext("loctext element has no content for \"%s\"\n"),
1704 1704                      service->sc_name);
1705 1705          }
1706 1706  
1707 1707          /*
1708 1708           * Remove leading and trailing whitespace.
1709 1709           */
1710      -        if ((stripped = strdup((const char *)cursor->content)) == NULL)
1711      -                uu_die(gettext("Out of memory\n"));
     1710 +        stripped = safe_strdup((const char *)cursor->content);
1712 1711  
1713 1712          for (; isspace(*stripped); stripped++)
1714 1713                  ;
1715 1714          for (cp = stripped + strlen(stripped) - 1; isspace(*cp); cp--)
1716 1715                  ;
1717 1716          *(cp + 1) = '\0';
1718 1717  
1719 1718          p = internal_property_create(prop_name, SCF_TYPE_USTRING, 1,
1720 1719              stripped);
1721 1720  
↓ open down ↓ 215 lines elided ↑ open up ↑
1937 1936          return (lxml_get_all_loctext(service, pg, description,
1938 1937              LOCALE_ONLY_FMT, "description"));
1939 1938  }
1940 1939  
1941 1940  static char *
1942 1941  lxml_label_to_groupname(const char *prefix, const char *in)
1943 1942  {
1944 1943          char *out, *cp;
1945 1944          size_t len, piece_len;
1946 1945  
1947      -        out = uu_zalloc(2 * scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) + 1);
     1946 +        out = uu_zalloc(2 * max_scf_name_len + 1);
1948 1947          if (out == NULL)
1949 1948                  return (NULL);
1950 1949  
1951      -        (void) strcpy(out, prefix);
1952      -        (void) strcat(out, in);
     1950 +        (void) strlcpy(out, prefix, 2 * max_scf_name_len + 1);
1953 1951  
1954      -        len = strlen(out);
     1952 +        len = strlcat(out, in, 2 * max_scf_name_len + 1);
1955 1953          if (len > max_scf_name_len) {
1956 1954                  /* Use the first half and the second half. */
1957 1955                  piece_len = (max_scf_name_len - 2) / 2;
1958 1956  
1959 1957                  (void) strncpy(out + piece_len, "..", 2);
1960 1958  
1961 1959                  (void) strcpy(out + piece_len + 2, out + (len - piece_len));
1962      -
1963      -                len = strlen(out);
1964 1960          }
1965 1961  
1966 1962          /*
1967 1963           * Translate non-property characters to '_'.
1968 1964           */
1969 1965          for (cp = out; *cp != '\0'; ++cp) {
1970 1966                  if (!(isalnum(*cp) || *cp == '_' || *cp == '-'))
1971 1967                          *cp = '_';
1972 1968          }
1973 1969  
1974      -        *cp = '\0';
1975      -
1976 1970          return (out);
1977 1971  }
1978 1972  
1979 1973  /*
1980 1974   * If *p is NULL, astring_prop_value() first creates a property with the
1981 1975   * name specified in prop_name.  The address of the newly created property
1982 1976   * is placed in *p.
1983 1977   *
1984 1978   * In either case, newly created property or existing property, a new
1985 1979   * SCF_TYPE_ASTRING value will created and attached to the property at *p.
↓ open down ↓ 43 lines elided ↑ open up ↑
2029 2023                  (*p)->sc_value_type = SCF_TYPE_ASTRING;
2030 2024          }
2031 2025  
2032 2026          /* Add the values to the property's list. */
2033 2027          val_str[1] = 0;         /* Terminate the string. */
2034 2028          for (; *seps != 0; seps++) {
2035 2029                  v = internal_value_new();
2036 2030                  v->sc_type = (*p)->sc_value_type;
2037 2031                  v->sc_free = lxml_free_str;
2038 2032                  val_str[0] = *seps;
2039      -                v->sc_u.sc_string = strdup(val_str);
2040      -                if (v->sc_u.sc_string == NULL)
2041      -                        uu_die(gettext("Out of memory\n"));
     2033 +                v->sc_u.sc_string = safe_strdup(val_str);
2042 2034                  internal_attach_value(*p, v);
2043 2035          }
2044 2036  }
2045 2037  
2046 2038  /*
2047 2039   * Create an internal_separators property and attach it to the property
2048 2040   * group at pg.  The separator characters are provided in the text nodes
2049 2041   * that are the children of seps.  Each separator character is stored as a
2050 2042   * property value in the internal_separators property.
2051 2043   */
↓ open down ↓ 24 lines elided ↑ open up ↑
2076 2068          if (r != 0)
2077 2069                  internal_property_free(prop);
2078 2070          return (r);
2079 2071  }
2080 2072  
2081 2073  static int
2082 2074  lxml_get_tm_manpage(entity_t *service, xmlNodePtr manpage)
2083 2075  {
2084 2076          pgroup_t *pg;
2085 2077          char *pgname;
     2078 +        char *name;
2086 2079          xmlChar *title;
     2080 +        xmlChar *section;
2087 2081  
2088 2082          /*
2089      -         * Fetch title attribute, convert to something sanitized, and create
2090      -         * property group.
     2083 +         * Fetch title and section attributes, convert to something sanitized,
     2084 +         * and create property group.
2091 2085           */
2092 2086          title = xmlGetProp(manpage, (xmlChar *)title_attr);
2093      -        pgname = (char *)lxml_label_to_groupname(SCF_PG_TM_MAN_PREFIX,
2094      -            (const char *)title);
     2087 +        if (title == NULL)
     2088 +                return (-1);
     2089 +        section = xmlGetProp(manpage, (xmlChar *)section_attr);
     2090 +        if (section == NULL) {
     2091 +                xmlFree(title);
     2092 +                return (-1);
     2093 +        }
     2094 +
     2095 +        name = safe_malloc(max_scf_name_len + 1);
     2096 +
     2097 +        /* Find existing property group with underscore separators */
     2098 +        (void) snprintf(name, max_scf_name_len + 1, "%s_%s", title, section);
     2099 +        pgname = lxml_label_to_groupname(SCF_PG_TM_MAN_PREFIX, name);
     2100 +        pg = internal_pgroup_find(service, pgname, SCF_GROUP_TEMPLATE);
     2101 +
     2102 +        uu_free(pgname);
     2103 +        (void) snprintf(name, max_scf_name_len + 1, "%s%s", title, section);
     2104 +        pgname = lxml_label_to_groupname(SCF_PG_TM_MAN_PREFIX, name);
     2105 +
     2106 +        if (pg == NULL) {
     2107 +                pg = internal_pgroup_find_or_create(service, pgname,
     2108 +                    SCF_GROUP_TEMPLATE);
     2109 +        } else {
     2110 +                /* Rename property group */
     2111 +                free((char *)pg->sc_pgroup_name);
     2112 +                pg->sc_pgroup_name = safe_strdup(pgname);
     2113 +        }
     2114 +
     2115 +        uu_free(pgname);
     2116 +        free(name);
     2117 +        xmlFree(section);
2095 2118          xmlFree(title);
2096 2119  
2097      -        pg = internal_pgroup_find_or_create(service, pgname,
2098      -            (char *)SCF_GROUP_TEMPLATE);
2099 2120  
2100 2121          /*
2101 2122           * Each attribute is an astring property within the group.
2102 2123           */
2103 2124          if (new_str_prop_from_attr(pg, SCF_PROPERTY_TM_TITLE,
2104 2125              SCF_TYPE_ASTRING, manpage, title_attr) != 0 ||
2105 2126              new_str_prop_from_attr(pg, SCF_PROPERTY_TM_SECTION,
2106 2127              SCF_TYPE_ASTRING, manpage, section_attr) != 0 ||
2107 2128              new_str_prop_from_attr(pg, SCF_PROPERTY_TM_MANPATH,
2108 2129              SCF_TYPE_ASTRING, manpage, manpath_attr) != 0)
↓ open down ↓ 7 lines elided ↑ open up ↑
2116 2137  {
2117 2138          pgroup_t *pg;
2118 2139          char *pgname;
2119 2140          xmlChar *name;
2120 2141  
2121 2142          /*
2122 2143           * Fetch name attribute, convert name to something sanitized, and create
2123 2144           * property group.
2124 2145           */
2125 2146          name = xmlGetProp(doc_link, (xmlChar *)name_attr);
     2147 +        if (name == NULL)
     2148 +                return (-1);
2126 2149  
2127 2150          pgname = (char *)lxml_label_to_groupname(SCF_PG_TM_DOC_PREFIX,
2128 2151              (const char *)name);
2129 2152  
2130 2153          pg = internal_pgroup_find_or_create(service, pgname,
2131 2154              (char *)SCF_GROUP_TEMPLATE);
     2155 +
     2156 +        uu_free(pgname);
2132 2157          xmlFree(name);
2133 2158  
2134 2159          /*
2135 2160           * Each attribute is an astring property within the group.
2136 2161           */
2137 2162          if (new_str_prop_from_attr(pg, SCF_PROPERTY_TM_NAME, SCF_TYPE_ASTRING,
2138 2163              doc_link, name_attr) != 0 ||
2139 2164              new_str_prop_from_attr(pg, SCF_PROPERTY_TM_URI, SCF_TYPE_ASTRING,
2140 2165              doc_link, uri_attr) != 0)
2141 2166                  return (-1);
↓ open down ↓ 1519 lines elided ↑ open up ↑
3661 3686                  dtdpath = getenv("SVCCFG_DTD");
3662 3687  
3663 3688          if (dtdpath != NULL)
3664 3689                  xmlLoadExtDtdDefaultValue = 0;
3665 3690  
3666 3691          if ((document = xmlReadFile(filename, NULL, 0)) == NULL) {
3667 3692                  semerr(gettext("couldn't parse document\n"));
3668 3693                  return (-1);
3669 3694          }
3670 3695  
3671      -        document->name = strdup(filename);
     3696 +        document->name = safe_strdup(filename);
3672 3697  
3673 3698          /*
3674 3699           * Verify that this is a document type we understand.
3675 3700           */
3676 3701          if ((dtd = xmlGetIntSubset(document)) == NULL) {
3677 3702                  semerr(gettext("document has no DTD\n"));
3678 3703                  return (-1);
3679 3704          } else if (dtdpath == NULL && !do_validate) {
3680 3705                  /*
3681 3706                   * If apply then setup so that some validation
↓ open down ↓ 118 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX