9064 * service_fmri's must be first, so we can add them
9065 * here.
9066 */
9067 ch = xmlNewChild(n, NULL, (xmlChar *)"service_fmri",
9068 NULL);
9069 if (ch == NULL)
9070 uu_die(emsg_create_xml);
9071
9072 safe_setprop(ch, value_attr, exp_str);
9073 }
9074 if (ret2 == -1)
9075 scfdie();
9076
9077 scf_iter_destroy(eiter);
9078 } else
9079 err = 1;
9080
9081 if (err) {
9082 xmlFreeNode(n);
9083
9084 export_pg(pg, eelts, 0);
9085
9086 return;
9087 }
9088
9089 /* Iterate through the properties & handle each. */
9090 if (scf_iter_pg_properties(exp_prop_iter, pg) != SCF_SUCCESS)
9091 scfdie();
9092
9093 (void) memset(&elts, 0, sizeof (elts));
9094
9095 while ((ret = scf_iter_next_property(exp_prop_iter, exp_prop)) == 1) {
9096 if (scf_property_get_name(exp_prop, exp_str, exp_str_sz) < 0)
9097 scfdie();
9098
9099 if (strcmp(exp_str, SCF_PROPERTY_GROUPING) == 0 ||
9100 strcmp(exp_str, SCF_PROPERTY_RESTART_ON) == 0 ||
9101 strcmp(exp_str, SCF_PROPERTY_TYPE) == 0 ||
9102 strcmp(exp_str, SCF_PROPERTY_ENTITIES) == 0) {
9103 continue;
9104 } else if (strcmp(exp_str, SCF_PROPERTY_STABILITY) == 0) {
9105 xmlNodePtr m;
9106
9107 m = xmlNewNode(NULL, (xmlChar *)"stability");
9108 if (m == NULL)
9109 uu_die(emsg_create_xml);
9110
9111 if (set_attr_from_prop(exp_prop, m, value_attr) == 0) {
9112 elts.stability = m;
9113 continue;
9114 }
9115
9116 xmlFreeNode(m);
9117 }
9118
9119 export_property(exp_prop, exp_str, &elts, 0);
9120 }
9121 if (ret == -1)
9122 scfdie();
9123
9124 (void) xmlAddChild(n, elts.stability);
9125 (void) xmlAddChildList(n, elts.propvals);
9126 (void) xmlAddChildList(n, elts.properties);
9127
9128 if (eelts->dependencies == NULL)
9129 eelts->dependencies = n;
9130 else
9131 (void) xmlAddSibling(eelts->dependencies, n);
9132 }
9133
9134 static xmlNodePtr
9135 export_method_environment(scf_propertygroup_t *pg)
9136 {
9137 xmlNodePtr env;
9138 int ret;
9139 int children = 0;
9227 if (pg_get_prop(pg, SCF_PROPERTY_TIMEOUT, exp_prop) == 0 &&
9228 prop_check_type(exp_prop, SCF_TYPE_COUNT) == 0 &&
9229 prop_get_val(exp_prop, exp_val) == 0) {
9230 uint64_t c;
9231
9232 if (scf_value_get_count(exp_val, &c) != SCF_SUCCESS)
9233 scfdie();
9234
9235 str = uu_msprintf("%llu", c);
9236 if (str == NULL)
9237 uu_die(gettext("Could not create string"));
9238
9239 safe_setprop(n, "timeout_seconds", str);
9240 free(str);
9241 } else
9242 err = 1;
9243
9244 if (err) {
9245 xmlFreeNode(n);
9246
9247 export_pg(pg, eelts, 0);
9248
9249 return;
9250 }
9251
9252
9253 /*
9254 * If we're going to have a method_context child, we need to know
9255 * before we iterate through the properties. Since method_context's
9256 * are optional, we don't want to complain about any properties
9257 * missing if none of them are there. Thus we can't use the
9258 * convenience functions.
9259 */
9260 nonenv =
9261 scf_pg_get_property(pg, SCF_PROPERTY_WORKING_DIRECTORY, NULL) ==
9262 SCF_SUCCESS ||
9263 scf_pg_get_property(pg, SCF_PROPERTY_PROJECT, NULL) ==
9264 SCF_SUCCESS ||
9265 scf_pg_get_property(pg, SCF_PROPERTY_RESOURCE_POOL, NULL) ==
9266 SCF_SUCCESS ||
9267 scf_pg_get_property(pg, SCF_PROPERTY_USE_PROFILE, NULL) ==
9404 strcmp(exp_str, SCF_PROPERTY_PROJECT) == 0 ||
9405 strcmp(exp_str, SCF_PROPERTY_RESOURCE_POOL) == 0 ||
9406 strcmp(exp_str, SCF_PROPERTY_USE_PROFILE) == 0) {
9407 if (nonenv)
9408 continue;
9409 } else if (strcmp(exp_str, SCF_PROPERTY_USER) == 0 ||
9410 strcmp(exp_str, SCF_PROPERTY_GROUP) == 0 ||
9411 strcmp(exp_str, SCF_PROPERTY_SUPP_GROUPS) == 0 ||
9412 strcmp(exp_str, SCF_PROPERTY_PRIVILEGES) == 0 ||
9413 strcmp(exp_str, SCF_PROPERTY_LIMIT_PRIVILEGES) == 0) {
9414 if (nonenv && !use_profile)
9415 continue;
9416 } else if (strcmp(exp_str, SCF_PROPERTY_PROFILE) == 0) {
9417 if (nonenv && use_profile)
9418 continue;
9419 } else if (strcmp(exp_str, SCF_PROPERTY_ENVIRONMENT) == 0) {
9420 if (env != NULL)
9421 continue;
9422 }
9423
9424 export_property(exp_prop, exp_str, &elts, 0);
9425 }
9426 if (ret == -1)
9427 scfdie();
9428
9429 (void) xmlAddChild(n, elts.stability);
9430 (void) xmlAddChildList(n, elts.propvals);
9431 (void) xmlAddChildList(n, elts.properties);
9432
9433 if (eelts->exec_methods == NULL)
9434 eelts->exec_methods = n;
9435 else
9436 (void) xmlAddSibling(eelts->exec_methods, n);
9437 }
9438
9439 static void
9440 export_pg_elts(struct pg_elts *elts, const char *name, const char *type,
9441 struct entity_elts *eelts)
9442 {
9443 xmlNodePtr pgnode;
9444
9520 continue;
9521 }
9522
9523 xmlFreeNode(rnode);
9524 } else if (strcmp(exp_str, SCF_PROPERTY_ENTITY_STABILITY) ==
9525 0) {
9526 xmlNodePtr s;
9527
9528 s = xmlNewNode(NULL, (xmlChar *)"stability");
9529 if (s == NULL)
9530 uu_die(emsg_create_xml);
9531
9532 if (set_attr_from_prop(exp_prop, s, value_attr) == 0) {
9533 selts->stability = s;
9534 continue;
9535 }
9536
9537 xmlFreeNode(s);
9538 }
9539
9540 export_property(exp_prop, exp_str, &elts, 0);
9541 }
9542 if (ret == -1)
9543 scfdie();
9544
9545 if (elts.propvals != NULL || elts.properties != NULL)
9546 export_pg_elts(&elts, scf_pg_general, scf_group_framework,
9547 selts);
9548 }
9549
9550 static void
9551 export_method_context(scf_propertygroup_t *pg, struct entity_elts *elts)
9552 {
9553 xmlNodePtr n, prof, cred, env;
9554 uint8_t use_profile;
9555 int ret, err = 0;
9556
9557 n = xmlNewNode(NULL, (xmlChar *)"method_context");
9558
9559 env = export_method_environment(pg);
9560
9616 err = 1;
9617 } else if (strcmp(exp_str, SCF_PROPERTY_LIMIT_PRIVILEGES) ==
9618 0) {
9619 if (use_profile || set_attr_from_prop(exp_prop, cred,
9620 "limit_privileges") != 0)
9621 err = 1;
9622 } else if (strcmp(exp_str, SCF_PROPERTY_PROFILE) == 0) {
9623 if (!use_profile || set_attr_from_prop(exp_prop,
9624 prof, name_attr) != 0)
9625 err = 1;
9626 } else {
9627 /* Can't have generic properties in method_context's */
9628 err = 1;
9629 }
9630 }
9631 if (ret == -1)
9632 scfdie();
9633
9634 if (err && env == NULL) {
9635 xmlFreeNode(n);
9636 export_pg(pg, elts, 0);
9637 return;
9638 }
9639
9640 elts->method_context = n;
9641 }
9642
9643 /*
9644 * Given a dependency property group in the tfmri entity (target fmri), return
9645 * a dependent element which represents it.
9646 */
9647 static xmlNodePtr
9648 export_dependent(scf_propertygroup_t *pg, const char *name, const char *tfmri)
9649 {
9650 uint8_t b;
9651 xmlNodePtr n, sf;
9652 int err = 0, ret;
9653 struct pg_elts pgelts;
9654
9655 /*
9656 * If external isn't set to true then exporting the service will
9730 scfdie();
9731
9732 if (strcmp(type, "service") == 0)
9733 continue;
9734 }
9735 } else if (strcmp(exp_str, SCF_PROPERTY_STABILITY) == 0) {
9736 xmlNodePtr s;
9737
9738 s = xmlNewNode(NULL, (xmlChar *)"stability");
9739 if (s == NULL)
9740 uu_die(emsg_create_xml);
9741
9742 if (set_attr_from_prop(exp_prop, s, value_attr) == 0) {
9743 pgelts.stability = s;
9744 continue;
9745 }
9746
9747 xmlFreeNode(s);
9748 }
9749
9750 export_property(exp_prop, exp_str, &pgelts, 0);
9751 }
9752 if (ret == -1)
9753 scfdie();
9754
9755 (void) xmlAddChild(n, pgelts.stability);
9756 (void) xmlAddChildList(n, pgelts.propvals);
9757 (void) xmlAddChildList(n, pgelts.properties);
9758
9759 return (n);
9760 }
9761
9762 static void
9763 export_dependents(scf_propertygroup_t *pg, struct entity_elts *eelts)
9764 {
9765 scf_propertygroup_t *opg;
9766 scf_iter_t *iter;
9767 char *type, *fmri;
9768 int ret;
9769 struct pg_elts pgelts;
9770 xmlNodePtr n;
9779 scfdie();
9780
9781 type = safe_malloc(max_scf_pg_type_len + 1);
9782
9783 /* Get an extra byte so we can tell if values are too long. */
9784 fmri = safe_malloc(max_scf_fmri_len + 2);
9785
9786 (void) memset(&pgelts, 0, sizeof (pgelts));
9787
9788 while ((ret = scf_iter_next_property(iter, exp_prop)) == 1) {
9789 void *entity;
9790 int isservice;
9791 scf_type_t ty;
9792
9793 if (scf_property_type(exp_prop, &ty) != SCF_SUCCESS)
9794 scfdie();
9795
9796 if ((ty != SCF_TYPE_ASTRING &&
9797 prop_check_type(exp_prop, SCF_TYPE_FMRI) != 0) ||
9798 prop_get_val(exp_prop, exp_val) != 0) {
9799 export_property(exp_prop, NULL, &pgelts, 0);
9800 continue;
9801 }
9802
9803 if (scf_property_get_name(exp_prop, exp_str, exp_str_sz) < 0)
9804 scfdie();
9805
9806 if (scf_value_get_astring(exp_val, fmri,
9807 max_scf_fmri_len + 2) < 0)
9808 scfdie();
9809
9810 /* Look for a dependency group in the target fmri. */
9811 serr = fmri_to_entity(g_hndl, fmri, &entity, &isservice);
9812 switch (serr) {
9813 case SCF_ERROR_NONE:
9814 break;
9815
9816 case SCF_ERROR_NO_MEMORY:
9817 uu_die(gettext("Out of memory.\n"));
9818 /* NOTREACHED */
9819
9820 case SCF_ERROR_INVALID_ARGUMENT:
9821 if (g_verbose) {
9822 if (scf_property_to_fmri(exp_prop, fmri,
9823 max_scf_fmri_len + 2) < 0)
9824 scfdie();
9825
9826 warn(gettext("The value of %s is not a valid "
9827 "FMRI.\n"), fmri);
9828 }
9829
9830 export_property(exp_prop, exp_str, &pgelts, 0);
9831 continue;
9832
9833 case SCF_ERROR_CONSTRAINT_VIOLATED:
9834 if (g_verbose) {
9835 if (scf_property_to_fmri(exp_prop, fmri,
9836 max_scf_fmri_len + 2) < 0)
9837 scfdie();
9838
9839 warn(gettext("The value of %s does not specify "
9840 "a service or an instance.\n"), fmri);
9841 }
9842
9843 export_property(exp_prop, exp_str, &pgelts, 0);
9844 continue;
9845
9846 case SCF_ERROR_NOT_FOUND:
9847 if (g_verbose) {
9848 if (scf_property_to_fmri(exp_prop, fmri,
9849 max_scf_fmri_len + 2) < 0)
9850 scfdie();
9851
9852 warn(gettext("The entity specified by %s does "
9853 "not exist.\n"), fmri);
9854 }
9855
9856 export_property(exp_prop, exp_str, &pgelts, 0);
9857 continue;
9858
9859 default:
9860 #ifndef NDEBUG
9861 (void) fprintf(stderr, "%s:%d: %s() failed with "
9862 "unexpected error %d.\n", __FILE__, __LINE__,
9863 "fmri_to_entity", serr);
9864 #endif
9865 abort();
9866 }
9867
9868 if (entity_get_pg(entity, isservice, exp_str, opg) != 0) {
9869 if (scf_error() != SCF_ERROR_NOT_FOUND)
9870 scfdie();
9871
9872 warn(gettext("Entity %s is missing dependency property "
9873 "group %s.\n"), fmri, exp_str);
9874
9875 export_property(exp_prop, NULL, &pgelts, 0);
9876 continue;
9877 }
9878
9879 if (scf_pg_get_type(opg, type, max_scf_pg_type_len + 1) < 0)
9880 scfdie();
9881
9882 if (strcmp(type, SCF_GROUP_DEPENDENCY) != 0) {
9883 if (scf_pg_to_fmri(opg, fmri, max_scf_fmri_len + 2) < 0)
9884 scfdie();
9885
9886 warn(gettext("Property group %s is not of "
9887 "expected type %s.\n"), fmri, SCF_GROUP_DEPENDENCY);
9888
9889 export_property(exp_prop, NULL, &pgelts, 0);
9890 continue;
9891 }
9892
9893 n = export_dependent(opg, exp_str, fmri);
9894 if (n == NULL)
9895 export_property(exp_prop, exp_str, &pgelts, 0);
9896 else {
9897 if (eelts->dependents == NULL)
9898 eelts->dependents = n;
9899 else
9900 (void) xmlAddSibling(eelts->dependents,
9901 n);
9902 }
9903 }
9904 if (ret == -1)
9905 scfdie();
9906
9907 free(fmri);
9908 free(type);
9909
9910 scf_iter_destroy(iter);
9911 scf_pg_destroy(opg);
9912
9913 if (pgelts.propvals != NULL || pgelts.properties != NULL)
9914 export_pg_elts(&pgelts, SCF_PG_DEPENDENTS, scf_group_framework,
9915 eelts);
9916 }
10000 return (doc_link);
10001 }
10002
10003 /*
10004 * Process template information for a service or instances.
10005 */
10006 static void
10007 export_template(scf_propertygroup_t *pg, struct entity_elts *elts,
10008 struct template_elts *telts)
10009 {
10010 size_t mansz = strlen(SCF_PG_TM_MAN_PREFIX);
10011 size_t docsz = strlen(SCF_PG_TM_DOC_PREFIX);
10012 xmlNodePtr child = NULL;
10013
10014 if (scf_pg_get_name(pg, exp_str, exp_str_sz) < 0)
10015 scfdie();
10016
10017 if (strcmp(exp_str, SCF_PG_TM_COMMON_NAME) == 0) {
10018 telts->common_name = export_tm_loctext(pg, "common_name");
10019 if (telts->common_name == NULL)
10020 export_pg(pg, elts, 0);
10021 return;
10022 } else if (strcmp(exp_str, SCF_PG_TM_DESCRIPTION) == 0) {
10023 telts->description = export_tm_loctext(pg, "description");
10024 if (telts->description == NULL)
10025 export_pg(pg, elts, 0);
10026 return;
10027 }
10028
10029 if (strncmp(exp_str, SCF_PG_TM_MAN_PREFIX, mansz) == 0) {
10030 child = export_tm_manpage(pg);
10031 } else if (strncmp(exp_str, SCF_PG_TM_DOC_PREFIX, docsz) == 0) {
10032 child = export_tm_doc_link(pg);
10033 }
10034
10035 if (child != NULL) {
10036 make_node(&telts->documentation, "documentation");
10037 (void) xmlAddChild(telts->documentation, child);
10038 } else {
10039 export_pg(pg, elts, 0);
10040 }
10041 }
10042
10043 /*
10044 * Process parameter and paramval elements
10045 */
10046 static void
10047 export_parameter(scf_property_t *prop, const char *name,
10048 struct params_elts *elts)
10049 {
10050 xmlNodePtr param;
10051 scf_error_t err = 0;
10052 int ret;
10053
10054 if (scf_property_get_value(prop, exp_val) == SCF_SUCCESS) {
10055 if ((param = xmlNewNode(NULL, (xmlChar *)"paramval")) == NULL)
10056 uu_die(emsg_create_xml);
10057
10058 safe_setprop(param, name_attr, name);
10059
10172 active_attr) != 0) {
10173 err = 1;
10174 break;
10175 }
10176 continue;
10177 }
10178 /*
10179 * We export the parameter
10180 */
10181 export_parameter(exp_prop, p, &eelts[i]);
10182 }
10183
10184 if (ret == -1)
10185 scfdie();
10186
10187 if (err == 1) {
10188 for (i = 0; i < URI_SCHEME_NUM; ++i)
10189 xmlFree(type[i]);
10190 free(type);
10191
10192 export_pg(pg, elts, 0);
10193
10194 return;
10195 } else {
10196 for (i = 0; i < URI_SCHEME_NUM; ++i)
10197 if (type[i] != NULL) {
10198 (void) xmlAddChildList(type[i],
10199 eelts[i].paramval);
10200 (void) xmlAddChildList(type[i],
10201 eelts[i].parameter);
10202 (void) xmlAddSibling(event, type[i]);
10203 }
10204 }
10205 free(type);
10206
10207 if (elts->notify_params == NULL)
10208 elts->notify_params = n;
10209 else
10210 (void) xmlAddSibling(elts->notify_params, n);
10211 }
10212
10248 xmlNodePtr rnode, sfnode;
10249
10250 rnode = xmlNewNode(NULL, (xmlChar *)"restarter");
10251 if (rnode == NULL)
10252 uu_die(emsg_create_xml);
10253
10254 sfnode = xmlNewChild(rnode, NULL,
10255 (xmlChar *)"service_fmri", NULL);
10256 if (sfnode == NULL)
10257 uu_die(emsg_create_xml);
10258
10259 if (set_attr_from_prop(exp_prop, sfnode,
10260 value_attr) == 0) {
10261 elts->restarter = rnode;
10262 continue;
10263 }
10264
10265 xmlFreeNode(rnode);
10266 }
10267
10268 export_property(exp_prop, exp_str, &pgelts, 0);
10269 }
10270 if (ret == -1)
10271 scfdie();
10272
10273 if (pgelts.propvals != NULL || pgelts.properties != NULL)
10274 export_pg_elts(&pgelts, scf_pg_general, scf_group_framework,
10275 elts);
10276 }
10277
10278 /*
10279 * Put an instance element for the given instance into selts.
10280 */
10281 static void
10282 export_instance(scf_instance_t *inst, struct entity_elts *selts, int flags)
10283 {
10284 xmlNodePtr n;
10285 boolean_t isdefault;
10286 struct entity_elts elts;
10287 struct template_elts template_elts;
10288 int ret;
|
9064 * service_fmri's must be first, so we can add them
9065 * here.
9066 */
9067 ch = xmlNewChild(n, NULL, (xmlChar *)"service_fmri",
9068 NULL);
9069 if (ch == NULL)
9070 uu_die(emsg_create_xml);
9071
9072 safe_setprop(ch, value_attr, exp_str);
9073 }
9074 if (ret2 == -1)
9075 scfdie();
9076
9077 scf_iter_destroy(eiter);
9078 } else
9079 err = 1;
9080
9081 if (err) {
9082 xmlFreeNode(n);
9083
9084 export_pg(pg, eelts, SCE_ALL_VALUES);
9085
9086 return;
9087 }
9088
9089 /* Iterate through the properties & handle each. */
9090 if (scf_iter_pg_properties(exp_prop_iter, pg) != SCF_SUCCESS)
9091 scfdie();
9092
9093 (void) memset(&elts, 0, sizeof (elts));
9094
9095 while ((ret = scf_iter_next_property(exp_prop_iter, exp_prop)) == 1) {
9096 if (scf_property_get_name(exp_prop, exp_str, exp_str_sz) < 0)
9097 scfdie();
9098
9099 if (strcmp(exp_str, SCF_PROPERTY_GROUPING) == 0 ||
9100 strcmp(exp_str, SCF_PROPERTY_RESTART_ON) == 0 ||
9101 strcmp(exp_str, SCF_PROPERTY_TYPE) == 0 ||
9102 strcmp(exp_str, SCF_PROPERTY_ENTITIES) == 0) {
9103 continue;
9104 } else if (strcmp(exp_str, SCF_PROPERTY_STABILITY) == 0) {
9105 xmlNodePtr m;
9106
9107 m = xmlNewNode(NULL, (xmlChar *)"stability");
9108 if (m == NULL)
9109 uu_die(emsg_create_xml);
9110
9111 if (set_attr_from_prop(exp_prop, m, value_attr) == 0) {
9112 elts.stability = m;
9113 continue;
9114 }
9115
9116 xmlFreeNode(m);
9117 }
9118
9119 export_property(exp_prop, exp_str, &elts, SCE_ALL_VALUES);
9120 }
9121 if (ret == -1)
9122 scfdie();
9123
9124 (void) xmlAddChild(n, elts.stability);
9125 (void) xmlAddChildList(n, elts.propvals);
9126 (void) xmlAddChildList(n, elts.properties);
9127
9128 if (eelts->dependencies == NULL)
9129 eelts->dependencies = n;
9130 else
9131 (void) xmlAddSibling(eelts->dependencies, n);
9132 }
9133
9134 static xmlNodePtr
9135 export_method_environment(scf_propertygroup_t *pg)
9136 {
9137 xmlNodePtr env;
9138 int ret;
9139 int children = 0;
9227 if (pg_get_prop(pg, SCF_PROPERTY_TIMEOUT, exp_prop) == 0 &&
9228 prop_check_type(exp_prop, SCF_TYPE_COUNT) == 0 &&
9229 prop_get_val(exp_prop, exp_val) == 0) {
9230 uint64_t c;
9231
9232 if (scf_value_get_count(exp_val, &c) != SCF_SUCCESS)
9233 scfdie();
9234
9235 str = uu_msprintf("%llu", c);
9236 if (str == NULL)
9237 uu_die(gettext("Could not create string"));
9238
9239 safe_setprop(n, "timeout_seconds", str);
9240 free(str);
9241 } else
9242 err = 1;
9243
9244 if (err) {
9245 xmlFreeNode(n);
9246
9247 export_pg(pg, eelts, SCE_ALL_VALUES);
9248
9249 return;
9250 }
9251
9252
9253 /*
9254 * If we're going to have a method_context child, we need to know
9255 * before we iterate through the properties. Since method_context's
9256 * are optional, we don't want to complain about any properties
9257 * missing if none of them are there. Thus we can't use the
9258 * convenience functions.
9259 */
9260 nonenv =
9261 scf_pg_get_property(pg, SCF_PROPERTY_WORKING_DIRECTORY, NULL) ==
9262 SCF_SUCCESS ||
9263 scf_pg_get_property(pg, SCF_PROPERTY_PROJECT, NULL) ==
9264 SCF_SUCCESS ||
9265 scf_pg_get_property(pg, SCF_PROPERTY_RESOURCE_POOL, NULL) ==
9266 SCF_SUCCESS ||
9267 scf_pg_get_property(pg, SCF_PROPERTY_USE_PROFILE, NULL) ==
9404 strcmp(exp_str, SCF_PROPERTY_PROJECT) == 0 ||
9405 strcmp(exp_str, SCF_PROPERTY_RESOURCE_POOL) == 0 ||
9406 strcmp(exp_str, SCF_PROPERTY_USE_PROFILE) == 0) {
9407 if (nonenv)
9408 continue;
9409 } else if (strcmp(exp_str, SCF_PROPERTY_USER) == 0 ||
9410 strcmp(exp_str, SCF_PROPERTY_GROUP) == 0 ||
9411 strcmp(exp_str, SCF_PROPERTY_SUPP_GROUPS) == 0 ||
9412 strcmp(exp_str, SCF_PROPERTY_PRIVILEGES) == 0 ||
9413 strcmp(exp_str, SCF_PROPERTY_LIMIT_PRIVILEGES) == 0) {
9414 if (nonenv && !use_profile)
9415 continue;
9416 } else if (strcmp(exp_str, SCF_PROPERTY_PROFILE) == 0) {
9417 if (nonenv && use_profile)
9418 continue;
9419 } else if (strcmp(exp_str, SCF_PROPERTY_ENVIRONMENT) == 0) {
9420 if (env != NULL)
9421 continue;
9422 }
9423
9424 export_property(exp_prop, exp_str, &elts, SCE_ALL_VALUES);
9425 }
9426 if (ret == -1)
9427 scfdie();
9428
9429 (void) xmlAddChild(n, elts.stability);
9430 (void) xmlAddChildList(n, elts.propvals);
9431 (void) xmlAddChildList(n, elts.properties);
9432
9433 if (eelts->exec_methods == NULL)
9434 eelts->exec_methods = n;
9435 else
9436 (void) xmlAddSibling(eelts->exec_methods, n);
9437 }
9438
9439 static void
9440 export_pg_elts(struct pg_elts *elts, const char *name, const char *type,
9441 struct entity_elts *eelts)
9442 {
9443 xmlNodePtr pgnode;
9444
9520 continue;
9521 }
9522
9523 xmlFreeNode(rnode);
9524 } else if (strcmp(exp_str, SCF_PROPERTY_ENTITY_STABILITY) ==
9525 0) {
9526 xmlNodePtr s;
9527
9528 s = xmlNewNode(NULL, (xmlChar *)"stability");
9529 if (s == NULL)
9530 uu_die(emsg_create_xml);
9531
9532 if (set_attr_from_prop(exp_prop, s, value_attr) == 0) {
9533 selts->stability = s;
9534 continue;
9535 }
9536
9537 xmlFreeNode(s);
9538 }
9539
9540 export_property(exp_prop, exp_str, &elts, SCE_ALL_VALUES);
9541 }
9542 if (ret == -1)
9543 scfdie();
9544
9545 if (elts.propvals != NULL || elts.properties != NULL)
9546 export_pg_elts(&elts, scf_pg_general, scf_group_framework,
9547 selts);
9548 }
9549
9550 static void
9551 export_method_context(scf_propertygroup_t *pg, struct entity_elts *elts)
9552 {
9553 xmlNodePtr n, prof, cred, env;
9554 uint8_t use_profile;
9555 int ret, err = 0;
9556
9557 n = xmlNewNode(NULL, (xmlChar *)"method_context");
9558
9559 env = export_method_environment(pg);
9560
9616 err = 1;
9617 } else if (strcmp(exp_str, SCF_PROPERTY_LIMIT_PRIVILEGES) ==
9618 0) {
9619 if (use_profile || set_attr_from_prop(exp_prop, cred,
9620 "limit_privileges") != 0)
9621 err = 1;
9622 } else if (strcmp(exp_str, SCF_PROPERTY_PROFILE) == 0) {
9623 if (!use_profile || set_attr_from_prop(exp_prop,
9624 prof, name_attr) != 0)
9625 err = 1;
9626 } else {
9627 /* Can't have generic properties in method_context's */
9628 err = 1;
9629 }
9630 }
9631 if (ret == -1)
9632 scfdie();
9633
9634 if (err && env == NULL) {
9635 xmlFreeNode(n);
9636 export_pg(pg, elts, SCE_ALL_VALUES);
9637 return;
9638 }
9639
9640 elts->method_context = n;
9641 }
9642
9643 /*
9644 * Given a dependency property group in the tfmri entity (target fmri), return
9645 * a dependent element which represents it.
9646 */
9647 static xmlNodePtr
9648 export_dependent(scf_propertygroup_t *pg, const char *name, const char *tfmri)
9649 {
9650 uint8_t b;
9651 xmlNodePtr n, sf;
9652 int err = 0, ret;
9653 struct pg_elts pgelts;
9654
9655 /*
9656 * If external isn't set to true then exporting the service will
9730 scfdie();
9731
9732 if (strcmp(type, "service") == 0)
9733 continue;
9734 }
9735 } else if (strcmp(exp_str, SCF_PROPERTY_STABILITY) == 0) {
9736 xmlNodePtr s;
9737
9738 s = xmlNewNode(NULL, (xmlChar *)"stability");
9739 if (s == NULL)
9740 uu_die(emsg_create_xml);
9741
9742 if (set_attr_from_prop(exp_prop, s, value_attr) == 0) {
9743 pgelts.stability = s;
9744 continue;
9745 }
9746
9747 xmlFreeNode(s);
9748 }
9749
9750 export_property(exp_prop, exp_str, &pgelts, SCE_ALL_VALUES);
9751 }
9752 if (ret == -1)
9753 scfdie();
9754
9755 (void) xmlAddChild(n, pgelts.stability);
9756 (void) xmlAddChildList(n, pgelts.propvals);
9757 (void) xmlAddChildList(n, pgelts.properties);
9758
9759 return (n);
9760 }
9761
9762 static void
9763 export_dependents(scf_propertygroup_t *pg, struct entity_elts *eelts)
9764 {
9765 scf_propertygroup_t *opg;
9766 scf_iter_t *iter;
9767 char *type, *fmri;
9768 int ret;
9769 struct pg_elts pgelts;
9770 xmlNodePtr n;
9779 scfdie();
9780
9781 type = safe_malloc(max_scf_pg_type_len + 1);
9782
9783 /* Get an extra byte so we can tell if values are too long. */
9784 fmri = safe_malloc(max_scf_fmri_len + 2);
9785
9786 (void) memset(&pgelts, 0, sizeof (pgelts));
9787
9788 while ((ret = scf_iter_next_property(iter, exp_prop)) == 1) {
9789 void *entity;
9790 int isservice;
9791 scf_type_t ty;
9792
9793 if (scf_property_type(exp_prop, &ty) != SCF_SUCCESS)
9794 scfdie();
9795
9796 if ((ty != SCF_TYPE_ASTRING &&
9797 prop_check_type(exp_prop, SCF_TYPE_FMRI) != 0) ||
9798 prop_get_val(exp_prop, exp_val) != 0) {
9799 export_property(exp_prop, NULL, &pgelts,
9800 SCE_ALL_VALUES);
9801 continue;
9802 }
9803
9804 if (scf_property_get_name(exp_prop, exp_str, exp_str_sz) < 0)
9805 scfdie();
9806
9807 if (scf_value_get_astring(exp_val, fmri,
9808 max_scf_fmri_len + 2) < 0)
9809 scfdie();
9810
9811 /* Look for a dependency group in the target fmri. */
9812 serr = fmri_to_entity(g_hndl, fmri, &entity, &isservice);
9813 switch (serr) {
9814 case SCF_ERROR_NONE:
9815 break;
9816
9817 case SCF_ERROR_NO_MEMORY:
9818 uu_die(gettext("Out of memory.\n"));
9819 /* NOTREACHED */
9820
9821 case SCF_ERROR_INVALID_ARGUMENT:
9822 if (g_verbose) {
9823 if (scf_property_to_fmri(exp_prop, fmri,
9824 max_scf_fmri_len + 2) < 0)
9825 scfdie();
9826
9827 warn(gettext("The value of %s is not a valid "
9828 "FMRI.\n"), fmri);
9829 }
9830
9831 export_property(exp_prop, exp_str, &pgelts,
9832 SCE_ALL_VALUES);
9833 continue;
9834
9835 case SCF_ERROR_CONSTRAINT_VIOLATED:
9836 if (g_verbose) {
9837 if (scf_property_to_fmri(exp_prop, fmri,
9838 max_scf_fmri_len + 2) < 0)
9839 scfdie();
9840
9841 warn(gettext("The value of %s does not specify "
9842 "a service or an instance.\n"), fmri);
9843 }
9844
9845 export_property(exp_prop, exp_str, &pgelts,
9846 SCE_ALL_VALUES);
9847 continue;
9848
9849 case SCF_ERROR_NOT_FOUND:
9850 if (g_verbose) {
9851 if (scf_property_to_fmri(exp_prop, fmri,
9852 max_scf_fmri_len + 2) < 0)
9853 scfdie();
9854
9855 warn(gettext("The entity specified by %s does "
9856 "not exist.\n"), fmri);
9857 }
9858
9859 export_property(exp_prop, exp_str, &pgelts,
9860 SCE_ALL_VALUES);
9861 continue;
9862
9863 default:
9864 #ifndef NDEBUG
9865 (void) fprintf(stderr, "%s:%d: %s() failed with "
9866 "unexpected error %d.\n", __FILE__, __LINE__,
9867 "fmri_to_entity", serr);
9868 #endif
9869 abort();
9870 }
9871
9872 if (entity_get_pg(entity, isservice, exp_str, opg) != 0) {
9873 if (scf_error() != SCF_ERROR_NOT_FOUND)
9874 scfdie();
9875
9876 warn(gettext("Entity %s is missing dependency property "
9877 "group %s.\n"), fmri, exp_str);
9878
9879 export_property(exp_prop, NULL, &pgelts,
9880 SCE_ALL_VALUES);
9881 continue;
9882 }
9883
9884 if (scf_pg_get_type(opg, type, max_scf_pg_type_len + 1) < 0)
9885 scfdie();
9886
9887 if (strcmp(type, SCF_GROUP_DEPENDENCY) != 0) {
9888 if (scf_pg_to_fmri(opg, fmri, max_scf_fmri_len + 2) < 0)
9889 scfdie();
9890
9891 warn(gettext("Property group %s is not of "
9892 "expected type %s.\n"), fmri, SCF_GROUP_DEPENDENCY);
9893
9894 export_property(exp_prop, NULL, &pgelts,
9895 SCE_ALL_VALUES);
9896 continue;
9897 }
9898
9899 n = export_dependent(opg, exp_str, fmri);
9900 if (n == NULL) {
9901 export_property(exp_prop, exp_str, &pgelts,
9902 SCE_ALL_VALUES);
9903 } else {
9904 if (eelts->dependents == NULL)
9905 eelts->dependents = n;
9906 else
9907 (void) xmlAddSibling(eelts->dependents,
9908 n);
9909 }
9910 }
9911 if (ret == -1)
9912 scfdie();
9913
9914 free(fmri);
9915 free(type);
9916
9917 scf_iter_destroy(iter);
9918 scf_pg_destroy(opg);
9919
9920 if (pgelts.propvals != NULL || pgelts.properties != NULL)
9921 export_pg_elts(&pgelts, SCF_PG_DEPENDENTS, scf_group_framework,
9922 eelts);
9923 }
10007 return (doc_link);
10008 }
10009
10010 /*
10011 * Process template information for a service or instances.
10012 */
10013 static void
10014 export_template(scf_propertygroup_t *pg, struct entity_elts *elts,
10015 struct template_elts *telts)
10016 {
10017 size_t mansz = strlen(SCF_PG_TM_MAN_PREFIX);
10018 size_t docsz = strlen(SCF_PG_TM_DOC_PREFIX);
10019 xmlNodePtr child = NULL;
10020
10021 if (scf_pg_get_name(pg, exp_str, exp_str_sz) < 0)
10022 scfdie();
10023
10024 if (strcmp(exp_str, SCF_PG_TM_COMMON_NAME) == 0) {
10025 telts->common_name = export_tm_loctext(pg, "common_name");
10026 if (telts->common_name == NULL)
10027 export_pg(pg, elts, SCE_ALL_VALUES);
10028 return;
10029 } else if (strcmp(exp_str, SCF_PG_TM_DESCRIPTION) == 0) {
10030 telts->description = export_tm_loctext(pg, "description");
10031 if (telts->description == NULL)
10032 export_pg(pg, elts, SCE_ALL_VALUES);
10033 return;
10034 }
10035
10036 if (strncmp(exp_str, SCF_PG_TM_MAN_PREFIX, mansz) == 0) {
10037 child = export_tm_manpage(pg);
10038 } else if (strncmp(exp_str, SCF_PG_TM_DOC_PREFIX, docsz) == 0) {
10039 child = export_tm_doc_link(pg);
10040 }
10041
10042 if (child != NULL) {
10043 make_node(&telts->documentation, "documentation");
10044 (void) xmlAddChild(telts->documentation, child);
10045 } else {
10046 export_pg(pg, elts, SCE_ALL_VALUES);
10047 }
10048 }
10049
10050 /*
10051 * Process parameter and paramval elements
10052 */
10053 static void
10054 export_parameter(scf_property_t *prop, const char *name,
10055 struct params_elts *elts)
10056 {
10057 xmlNodePtr param;
10058 scf_error_t err = 0;
10059 int ret;
10060
10061 if (scf_property_get_value(prop, exp_val) == SCF_SUCCESS) {
10062 if ((param = xmlNewNode(NULL, (xmlChar *)"paramval")) == NULL)
10063 uu_die(emsg_create_xml);
10064
10065 safe_setprop(param, name_attr, name);
10066
10179 active_attr) != 0) {
10180 err = 1;
10181 break;
10182 }
10183 continue;
10184 }
10185 /*
10186 * We export the parameter
10187 */
10188 export_parameter(exp_prop, p, &eelts[i]);
10189 }
10190
10191 if (ret == -1)
10192 scfdie();
10193
10194 if (err == 1) {
10195 for (i = 0; i < URI_SCHEME_NUM; ++i)
10196 xmlFree(type[i]);
10197 free(type);
10198
10199 export_pg(pg, elts, SCE_ALL_VALUES);
10200
10201 return;
10202 } else {
10203 for (i = 0; i < URI_SCHEME_NUM; ++i)
10204 if (type[i] != NULL) {
10205 (void) xmlAddChildList(type[i],
10206 eelts[i].paramval);
10207 (void) xmlAddChildList(type[i],
10208 eelts[i].parameter);
10209 (void) xmlAddSibling(event, type[i]);
10210 }
10211 }
10212 free(type);
10213
10214 if (elts->notify_params == NULL)
10215 elts->notify_params = n;
10216 else
10217 (void) xmlAddSibling(elts->notify_params, n);
10218 }
10219
10255 xmlNodePtr rnode, sfnode;
10256
10257 rnode = xmlNewNode(NULL, (xmlChar *)"restarter");
10258 if (rnode == NULL)
10259 uu_die(emsg_create_xml);
10260
10261 sfnode = xmlNewChild(rnode, NULL,
10262 (xmlChar *)"service_fmri", NULL);
10263 if (sfnode == NULL)
10264 uu_die(emsg_create_xml);
10265
10266 if (set_attr_from_prop(exp_prop, sfnode,
10267 value_attr) == 0) {
10268 elts->restarter = rnode;
10269 continue;
10270 }
10271
10272 xmlFreeNode(rnode);
10273 }
10274
10275 export_property(exp_prop, exp_str, &pgelts, SCE_ALL_VALUES);
10276 }
10277 if (ret == -1)
10278 scfdie();
10279
10280 if (pgelts.propvals != NULL || pgelts.properties != NULL)
10281 export_pg_elts(&pgelts, scf_pg_general, scf_group_framework,
10282 elts);
10283 }
10284
10285 /*
10286 * Put an instance element for the given instance into selts.
10287 */
10288 static void
10289 export_instance(scf_instance_t *inst, struct entity_elts *selts, int flags)
10290 {
10291 xmlNodePtr n;
10292 boolean_t isdefault;
10293 struct entity_elts elts;
10294 struct template_elts template_elts;
10295 int ret;
|