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 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * Copyright (c) 2011, Joyent, Inc. All rights reserved.
32 * svcprop - report service configuration properties
38 #include <libscf_priv.h>
49 #define TEXT_DOMAIN "SUNW_OST_OSCMD"
50 #endif /* TEXT_DOMAIN */
53 * Error functions. These can change if the quiet (-q) option is used.
55 static void (*warn
)(const char *, ...) = uu_warn
;
56 static void (*die
)(const char *, ...) = uu_die
;
59 * Entity encapsulation. This allows me to treat services and instances
60 * similarly, and avoid duplicating process_ent().
63 char type
; /* !=0: service, 0: instance */
70 #define ENT_INSTANCE 0
72 #define SCF_ENTITY_SET_TO_SERVICE(ent, s) { ent.type = 1; ent.u.svc = s; }
74 #define SCF_ENTITY_SET_TO_INSTANCE(ent, i) \
75 { ent.type = ENT_INSTANCE; ent.u.inst = i; }
77 #define scf_entity_get_pg(ent, name, pg) \
78 (ent.type ? scf_service_get_pg(ent.u.svc, name, pg) : \
79 scf_instance_get_pg(ent.u.inst, name, pg))
81 #define scf_entity_to_fmri(ent, buf, buf_sz) \
82 (ent.type ? scf_service_to_fmri(ent.u.svc, buf, buf_sz) : \
83 scf_instance_to_fmri(ent.u.inst, buf, buf_sz))
85 #define SCF_ENTITY_TYPE_NAME(ent) (ent.type ? "service" : "instance")
88 * Data structure for -p arguments. Since they may be name or name/name, we
89 * just track the components.
91 typedef struct svcprop_prop_node
{
92 uu_list_node_t spn_list_node
;
93 const char *spn_comp1
;
94 const char *spn_comp2
;
95 } svcprop_prop_node_t
;
97 static uu_list_pool_t
*prop_pool
;
98 static uu_list_t
*prop_list
;
100 static scf_handle_t
*hndl
;
101 static ssize_t max_scf_name_length
;
102 static ssize_t max_scf_value_length
;
103 static ssize_t max_scf_fmri_length
;
106 static int quiet
= 0; /* No output. Nothing found, exit(1) */
107 static int types
= 0; /* Display types of properties. */
108 static int verbose
= 0; /* Print not found errors to stderr. */
109 static int fmris
= 0; /* Display full FMRIs for properties. */
110 static int wait
= 0; /* Wait mode. */
111 static char *snapshot
= "running"; /* Snapshot to use. */
112 static int Cflag
= 0; /* C option supplied */
113 static int cflag
= 0; /* c option supplied */
114 static int sflag
= 0; /* s option supplied */
115 static int return_code
; /* main's return code */
117 #define PRINT_NOPROP_ERRORS (!quiet || verbose)
120 * For unexpected libscf errors. The ending newline is necessary to keep
121 * uu_die() from appending the errno error.
126 die(gettext("Unexpected libscf error: %s. Exiting.\n"),
127 scf_strerror(scf_error()));
131 safe_malloc(size_t sz
)
137 die(gettext("Could not allocate memory"));
145 (void) fprintf(stderr
, gettext("Usage: %1$s [-fqtv] "
146 "[-C | -c | -s snapshot] [-z zone] "
147 "[-p [name/]name]... \n"
148 " {FMRI | pattern}...\n"
149 " %1$s -w [-fqtv] [-z zone] [-p [name/]name] "
150 "{FMRI | pattern}\n"), uu_getpname());
155 * Return an allocated copy of str, with the Bourne shell's metacharacters
158 * What about unicode?
161 quote_for_shell(const char *str
)
167 const char * const metachars
= ";&()|^<>\n \t\\\"\'`";
170 return (strdup("\"\""));
173 for (sp
= str
; *sp
!= '\0'; ++sp
) {
176 if (strchr(metachars
, *sp
) != NULL
)
180 if (sp
- str
== dst_len
)
181 return (strdup(str
));
183 dst
= safe_malloc(dst_len
+ 1);
185 for (dp
= dst
, sp
= str
; *sp
!= '\0'; ++dp
, ++sp
) {
186 if (strchr(metachars
, *sp
) != NULL
)
197 print_value(scf_value_t
*val
)
202 bufsz
= scf_value_get_as_string(val
, NULL
, 0) + 1;
206 buf
= safe_malloc(bufsz
);
208 r
= scf_value_get_as_string(val
, buf
, bufsz
);
209 assert(r
+ 1 == bufsz
);
211 qbuf
= quote_for_shell(buf
);
212 (void) fputs(qbuf
, stdout
);
219 * Display a property's values on a line. If types is true, prepend
220 * identification (the FMRI if fmris is true, pg/prop otherwise) and the type
224 display_prop(scf_propertygroup_t
*pg
, scf_property_t
*prop
)
230 const char * const permission_denied_emsg
=
231 gettext("Permission denied.\n");
239 buf_sz
= max_scf_fmri_length
+ 1;
240 buf
= safe_malloc(buf_sz
);
242 if (scf_property_to_fmri(prop
, buf
, buf_sz
) == -1)
244 (void) fputs(buf
, stdout
);
248 buf_sz
= max_scf_name_length
+ 1;
249 buf
= safe_malloc(buf_sz
);
251 if (scf_pg_get_name(pg
, buf
, buf_sz
) < 0)
253 (void) fputs(buf
, stdout
);
256 if (scf_property_get_name(prop
, buf
, buf_sz
) < 0)
258 (void) fputs(buf
, stdout
);
265 if (scf_property_type(prop
, &ty
) == -1)
267 (void) fputs(scf_type_to_string(ty
), stdout
);
271 if ((iter
= scf_iter_create(hndl
)) == NULL
||
272 (val
= scf_value_create(hndl
)) == NULL
)
275 if (scf_iter_property_values(iter
, prop
) == -1)
279 while ((ret
= scf_iter_next_value(iter
, val
)) == 1) {
288 if (err
== SCF_ERROR_PERMISSION_DENIED
) {
289 if (uu_list_numnodes(prop_list
) > 0)
290 die(permission_denied_emsg
);
296 (void) putchar('\n');
298 scf_iter_destroy(iter
);
299 (void) scf_value_destroy(val
);
303 * display_prop() all of the properties in the given property group. Force
304 * types to true so identification will be displayed.
307 display_pg(scf_propertygroup_t
*pg
)
309 scf_property_t
*prop
;
313 types
= 1; /* Always display types for whole propertygroups. */
315 if ((prop
= scf_property_create(hndl
)) == NULL
||
316 (iter
= scf_iter_create(hndl
)) == NULL
)
319 if (scf_iter_pg_properties(iter
, pg
) == -1)
322 while ((ret
= scf_iter_next_property(iter
, prop
)) == 1)
323 display_prop(pg
, prop
);
327 scf_iter_destroy(iter
);
328 scf_property_destroy(prop
);
332 * Common code to execute when a nonexistant property is encountered.
335 noprop_common_action()
337 if (!PRINT_NOPROP_ERRORS
)
338 /* We're not printing errors, so we can cut out early. */
341 return_code
= UU_EXIT_FATAL
;
345 * Iterate the properties of a service or an instance when no snapshot
349 scf_iter_entity_pgs(scf_iter_t
*iter
, scf_entityp_t ent
)
355 * If we are displaying properties for a service,
356 * treat it as though it were a composed, current
357 * lookup. (implicit cflag) However, if a snapshot
358 * was specified, fail.
361 die(gettext("Only instances have "
363 ret
= scf_iter_service_pgs(iter
, ent
.u
.svc
);
366 ret
= scf_iter_instance_pgs(iter
, ent
.u
.inst
);
368 ret
= scf_iter_instance_pgs_composed(iter
, ent
.u
.inst
,
375 * Return a snapshot for the supplied instance and snapshot name.
377 static scf_snapshot_t
*
378 get_snapshot(const scf_instance_t
*inst
, const char *snapshot
)
380 scf_snapshot_t
*snap
= scf_snapshot_create(hndl
);
385 if (scf_instance_get_snapshot(inst
, snapshot
, snap
) == -1) {
386 switch (scf_error()) {
387 case SCF_ERROR_INVALID_ARGUMENT
:
388 die(gettext("Invalid snapshot name.\n"));
391 case SCF_ERROR_NOT_FOUND
:
393 scf_snapshot_destroy(snap
);
396 die(gettext("No such snapshot.\n"));
408 * Entity (service or instance): If there are -p options,
409 * display_{pg,prop}() the named property groups and/or properties. Otherwise
410 * display_pg() all property groups.
413 process_ent(scf_entityp_t ent
)
415 scf_snapshot_t
*snap
= NULL
;
416 scf_propertygroup_t
*pg
;
417 scf_property_t
*prop
;
419 svcprop_prop_node_t
*spn
;
422 if (uu_list_numnodes(prop_list
) == 0) {
426 if ((pg
= scf_pg_create(hndl
)) == NULL
||
427 (iter
= scf_iter_create(hndl
)) == NULL
)
430 if (cflag
|| Cflag
|| ent
.type
!= ENT_INSTANCE
) {
431 if (scf_iter_entity_pgs(iter
, ent
) == -1)
434 if (snapshot
!= NULL
)
435 snap
= get_snapshot(ent
.u
.inst
, snapshot
);
437 if (scf_iter_instance_pgs_composed(iter
, ent
.u
.inst
,
441 scf_snapshot_destroy(snap
);
444 while ((ret
= scf_iter_next_pg(iter
, pg
)) == 1)
450 * In normal usage, i.e. against the running snapshot,
451 * we must iterate over the current non-persistent
454 if (sflag
== 0 && snap
!= NULL
) {
455 scf_iter_reset(iter
);
456 if (scf_iter_instance_pgs_composed(iter
, ent
.u
.inst
,
459 while ((ret
= scf_iter_next_pg(iter
, pg
)) == 1) {
462 if (scf_pg_get_flags(pg
, &flags
) == -1)
464 if (flags
& SCF_PG_FLAG_NONPERSISTENT
)
471 scf_iter_destroy(iter
);
477 if ((pg
= scf_pg_create(hndl
)) == NULL
||
478 (prop
= scf_property_create(hndl
)) == NULL
)
481 if (ent
.type
== ENT_INSTANCE
&& snapshot
!= NULL
)
482 snap
= get_snapshot(ent
.u
.inst
, snapshot
);
484 for (spn
= uu_list_first(prop_list
);
486 spn
= uu_list_next(prop_list
, spn
)) {
487 if (ent
.type
== ENT_INSTANCE
) {
489 ret
= scf_instance_get_pg(ent
.u
.inst
,
492 ret
= scf_instance_get_pg_composed(ent
.u
.inst
,
493 snap
, spn
->spn_comp1
, pg
);
497 * If we didn't find it in the specified snapshot, use
498 * the current values if the pg is nonpersistent.
500 if (ret
== -1 && !Cflag
&&snap
!= NULL
&& err
==
501 SCF_ERROR_NOT_FOUND
) {
502 ret
= scf_instance_get_pg_composed(
503 ent
.u
.inst
, NULL
, spn
->spn_comp1
,
509 if (scf_pg_get_flags(pg
, &flags
) == -1)
511 if ((flags
& SCF_PG_FLAG_NONPERSISTENT
)
519 * If we are displaying properties for a service,
520 * treat it as though it were a composed, current
521 * lookup. (implicit cflag) However, if a snapshot
522 * was specified, fail.
525 die(gettext("Only instances have "
527 ret
= scf_entity_get_pg(ent
, spn
->spn_comp1
, pg
);
531 if (err
!= SCF_ERROR_NOT_FOUND
)
534 if (PRINT_NOPROP_ERRORS
) {
537 buf
= safe_malloc(max_scf_fmri_length
+ 1);
538 if (scf_entity_to_fmri(ent
, buf
,
539 max_scf_fmri_length
+ 1) == -1)
542 uu_warn(gettext("Couldn't find property group "
543 "`%s' for %s `%s'.\n"), spn
->spn_comp1
,
544 SCF_ENTITY_TYPE_NAME(ent
), buf
);
549 noprop_common_action();
554 if (spn
->spn_comp2
== NULL
) {
560 if (scf_pg_get_property(pg
, spn
->spn_comp2
, prop
) == -1) {
561 if (scf_error() != SCF_ERROR_NOT_FOUND
)
564 if (PRINT_NOPROP_ERRORS
) {
567 buf
= safe_malloc(max_scf_fmri_length
+ 1);
568 if (scf_entity_to_fmri(ent
, buf
,
569 max_scf_fmri_length
+ 1) == -1)
572 /* FMRI syntax knowledge */
573 uu_warn(gettext("Couldn't find property "
574 "`%s/%s' for %s `%s'.\n"), spn
->spn_comp1
,
575 spn
->spn_comp2
, SCF_ENTITY_TYPE_NAME(ent
),
581 noprop_common_action();
587 display_prop(pg
, prop
);
590 scf_property_destroy(prop
);
593 scf_snapshot_destroy(snap
);
597 * Without -p options, just call display_pg(). Otherwise display_prop() the
598 * named properties of the property group.
601 process_pg(scf_propertygroup_t
*pg
)
603 scf_property_t
*prop
;
604 svcprop_prop_node_t
*spn
;
606 if (uu_list_first(prop_list
) == NULL
) {
614 prop
= scf_property_create(hndl
);
618 for (spn
= uu_list_first(prop_list
);
620 spn
= uu_list_next(prop_list
, spn
)) {
621 if (spn
->spn_comp2
!= NULL
) {
624 buf
= safe_malloc(max_scf_fmri_length
+ 1);
625 if (scf_pg_to_fmri(pg
, buf
, max_scf_fmri_length
+ 1) ==
629 uu_xdie(UU_EXIT_USAGE
, gettext("-p argument `%s/%s' "
630 "has too many components for property "
631 "group `%s'.\n"), spn
->spn_comp1
, spn
->spn_comp2
,
637 if (scf_pg_get_property(pg
, spn
->spn_comp1
, prop
) == 0) {
639 display_prop(pg
, prop
);
643 if (scf_error() != SCF_ERROR_NOT_FOUND
)
646 if (PRINT_NOPROP_ERRORS
) {
649 buf
= safe_malloc(max_scf_fmri_length
+ 1);
650 if (scf_pg_to_fmri(pg
, buf
, max_scf_fmri_length
+ 1) ==
654 uu_warn(gettext("Couldn't find property `%s' in "
655 "property group `%s'.\n"), spn
->spn_comp1
, buf
);
660 noprop_common_action();
665 * If there are -p options, show the error. Otherwise just call
669 process_prop(scf_propertygroup_t
*pg
, scf_property_t
*prop
)
671 if (uu_list_first(prop_list
) != NULL
) {
672 uu_warn(gettext("The -p option cannot be used with property "
680 display_prop(pg
, prop
);
683 /* Decode an operand & dispatch. */
686 process_fmri(void *unused
, scf_walkinfo_t
*wip
)
690 /* Multiple matches imply multiple entities. */
694 if (wip
->prop
!= NULL
) {
695 process_prop(wip
->pg
, wip
->prop
);
696 } else if (wip
->pg
!= NULL
) {
698 } else if (wip
->inst
!= NULL
) {
699 SCF_ENTITY_SET_TO_INSTANCE(ent
, wip
->inst
);
702 /* scf_walk_fmri() won't let this happen */
703 assert(wip
->svc
!= NULL
);
704 SCF_ENTITY_SET_TO_SERVICE(ent
, wip
->svc
);
712 add_prop(char *property
)
714 svcprop_prop_node_t
*p
, *last
;
717 const char * const invalid_component_emsg
=
718 gettext("Invalid component name `%s'.\n");
720 /* FMRI syntax knowledge. */
721 slash
= strchr(property
, '/');
723 if (strchr(slash
+ 1, '/') != NULL
) {
724 uu_warn(gettext("-p argument `%s' has too many "
725 "components.\n"), property
);
733 p
= safe_malloc(sizeof (svcprop_prop_node_t
));
734 uu_list_node_init(p
, &p
->spn_list_node
, prop_pool
);
736 p
->spn_comp1
= property
;
737 p
->spn_comp2
= (slash
== NULL
) ? NULL
: slash
+ 1;
739 if (uu_check_name(p
->spn_comp1
, UU_NAME_DOMAIN
) == -1)
740 uu_xdie(UU_EXIT_USAGE
, invalid_component_emsg
, p
->spn_comp1
);
741 if (p
->spn_comp2
!= NULL
&&
742 uu_check_name(p
->spn_comp2
, UU_NAME_DOMAIN
) == -1)
743 uu_xdie(UU_EXIT_USAGE
, invalid_component_emsg
, p
->spn_comp2
);
745 last
= uu_list_last(prop_list
);
747 if ((last
->spn_comp2
== NULL
) ^ (p
->spn_comp2
== NULL
)) {
749 * The -p options have mixed numbers of components.
750 * If they both turn out to be valid, then the
751 * single-component ones will specify property groups,
752 * so we need to turn on types to keep the output of
753 * display_prop() consistent with display_pg().
759 (void) uu_list_insert_after(prop_list
, NULL
, p
);
764 * Wait for a property group or property change.
766 * Extract a pg and optionally a property name from fmri & prop_list.
767 * _scf_pg_wait() for the pg, and display_pg(pg) or display_prop(pg, prop)
772 do_wait(void *unused
, scf_walkinfo_t
*wip
)
774 scf_property_t
*prop
;
775 scf_propertygroup_t
*lpg
, *pg
;
776 const char *propname
;
777 svcprop_prop_node_t
*p
;
779 const char *emsg_not_found
= gettext("Not found.\n");
781 if ((lpg
= scf_pg_create(hndl
)) == NULL
||
782 (prop
= scf_property_create(hndl
)) == NULL
)
785 if (wip
->prop
!= NULL
) {
786 if (uu_list_numnodes(prop_list
) > 0)
787 uu_xdie(UU_EXIT_USAGE
, gettext("-p cannot be used with "
788 "property FMRIs.\n"));
791 assert(strrchr(wip
->fmri
, '/') != NULL
);
792 propname
= strrchr(wip
->fmri
, '/') + 1;
794 } else if (wip
->pg
!= NULL
) {
795 p
= uu_list_first(prop_list
);
798 if (p
->spn_comp2
!= NULL
)
799 uu_xdie(UU_EXIT_USAGE
, gettext("-p argument "
800 "\"%s/%s\" has too many components for "
801 "property group %s.\n"),
802 p
->spn_comp1
, p
->spn_comp2
, wip
->fmri
);
804 propname
= p
->spn_comp1
;
806 if (scf_pg_get_property(wip
->pg
, propname
, prop
) !=
808 switch (scf_error()) {
809 case SCF_ERROR_INVALID_ARGUMENT
:
810 uu_xdie(UU_EXIT_USAGE
,
811 gettext("Invalid property name "
812 "\"%s\".\n"), propname
);
816 case SCF_ERROR_NOT_FOUND
:
831 } else if (wip
->inst
!= NULL
) {
833 p
= uu_list_first(prop_list
);
835 uu_xdie(UU_EXIT_USAGE
,
836 gettext("Cannot wait for an instance.\n"));
838 if (scf_instance_get_pg(wip
->inst
, p
->spn_comp1
, lpg
) !=
840 switch (scf_error()) {
841 case SCF_ERROR_INVALID_ARGUMENT
:
842 uu_xdie(UU_EXIT_USAGE
, gettext("Invalid "
843 "property group name \"%s\".\n"),
846 case SCF_ERROR_NOT_FOUND
:
856 propname
= p
->spn_comp2
;
858 if (propname
!= NULL
) {
859 if (scf_pg_get_property(lpg
, propname
, prop
) !=
861 switch (scf_error()) {
862 case SCF_ERROR_INVALID_ARGUMENT
:
863 uu_xdie(UU_EXIT_USAGE
,
864 gettext("Invalid property name "
865 "\"%s\".\n"), propname
);
867 case SCF_ERROR_NOT_FOUND
:
880 } else if (wip
->svc
!= NULL
) {
882 p
= uu_list_first(prop_list
);
884 uu_xdie(UU_EXIT_USAGE
,
885 gettext("Cannot wait for a service.\n"));
887 if (scf_service_get_pg(wip
->svc
, p
->spn_comp1
, lpg
) !=
889 switch (scf_error()) {
890 case SCF_ERROR_INVALID_ARGUMENT
:
891 uu_xdie(UU_EXIT_USAGE
, gettext("Invalid "
892 "property group name \"%s\".\n"),
895 case SCF_ERROR_NOT_FOUND
:
903 propname
= p
->spn_comp2
;
905 if (propname
!= NULL
) {
906 if (scf_pg_get_property(lpg
, propname
, prop
) !=
908 switch (scf_error()) {
909 case SCF_ERROR_INVALID_ARGUMENT
:
910 uu_xdie(UU_EXIT_USAGE
,
911 gettext("Invalid property name "
912 "\"%s\".\n"), propname
);
916 case SCF_ERROR_NOT_FOUND
:
930 uu_xdie(UU_EXIT_USAGE
, gettext("FMRI must specify an entity, "
931 "property group, or property.\n"));
937 ret
= _scf_pg_wait(pg
, -1);
938 if (ret
!= SCF_SUCCESS
)
941 ret
= scf_pg_update(pg
);
943 if (scf_error() != SCF_ERROR_DELETED
)
948 if (ret
== SCF_COMPLETE
)
952 if (propname
!= NULL
) {
953 if (scf_pg_get_property(pg
, propname
, prop
) == SCF_SUCCESS
) {
955 display_prop(pg
, prop
);
957 if (scf_error() != SCF_ERROR_NOT_FOUND
)
960 if (PRINT_NOPROP_ERRORS
)
961 uu_warn(emsg_not_found
);
963 return_code
= UU_EXIT_FATAL
;
970 scf_property_destroy(prop
);
977 * These functions replace uu_warn() and uu_die() when the quiet (-q) option is
978 * used, and silently ignore any output.
983 quiet_warn(const char *fmt
, ...)
990 quiet_die(const char *fmt
, ...)
996 main(int argc
, char *argv
[])
999 scf_walk_callback callback
;
1003 (void) setlocale(LC_ALL
, "");
1004 (void) textdomain(TEXT_DOMAIN
);
1006 return_code
= UU_EXIT_OK
;
1008 (void) uu_setpname(argv
[0]);
1010 prop_pool
= uu_list_pool_create("properties",
1011 sizeof (svcprop_prop_node_t
),
1012 offsetof(svcprop_prop_node_t
, spn_list_node
), NULL
, 0);
1013 if (prop_pool
== NULL
)
1014 uu_die("%s\n", uu_strerror(uu_error()));
1016 prop_list
= uu_list_create(prop_pool
, NULL
, 0);
1018 hndl
= scf_handle_create(SCF_VERSION
);
1022 while ((c
= getopt(argc
, argv
, "Ccfp:qs:tvwz:")) != -1) {
1025 if (cflag
|| sflag
|| wait
)
1026 usage(); /* Not with -c, -s or -w */
1032 if (Cflag
|| sflag
|| wait
)
1033 usage(); /* Not with -C, -s or -w */
1054 if (Cflag
|| cflag
|| wait
)
1055 usage(); /* Not with -C, -c or -w */
1069 if (Cflag
|| cflag
|| sflag
)
1070 usage(); /* Not with -C, -c or -s */
1076 scf_handle_t
*h
= hndl
;
1078 if (getzoneid() != GLOBAL_ZONEID
)
1079 uu_die(gettext("svcprop -z may only be used "
1080 "from the global zone\n"));
1082 if ((zone
= scf_value_create(h
)) == NULL
)
1085 if (scf_value_set_astring(zone
, optarg
) != SCF_SUCCESS
)
1088 if (scf_handle_decorate(h
, "zone", zone
) != SCF_SUCCESS
)
1089 uu_die(gettext("invalid zone '%s'\n"), optarg
);
1091 scf_value_destroy(zone
);
1114 max_scf_name_length
= scf_limit(SCF_LIMIT_MAX_NAME_LENGTH
);
1115 max_scf_value_length
= scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH
);
1116 max_scf_fmri_length
= scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH
);
1117 if (max_scf_name_length
== -1 || max_scf_value_length
== -1 ||
1118 max_scf_fmri_length
== -1)
1121 if (scf_handle_bind(hndl
) == -1)
1122 die(gettext("Could not connect to configuration repository: "
1123 "%s.\n"), scf_strerror(scf_error()));
1125 flags
= SCF_WALK_PROPERTY
| SCF_WALK_SERVICE
| SCF_WALK_EXPLICIT
;
1128 if (uu_list_numnodes(prop_list
) > 1)
1131 if (argc
- optind
> 1)
1137 callback
= process_fmri
;
1139 flags
|= SCF_WALK_MULTIPLE
;
1142 if ((err
= scf_walk_fmri(hndl
, argc
- optind
, argv
+ optind
, flags
,
1143 callback
, NULL
, &return_code
, warn
)) != 0) {
1144 warn(gettext("failed to iterate over instances: %s\n"),
1146 return_code
= UU_EXIT_FATAL
;
1149 scf_handle_destroy(hndl
);
1151 return (return_code
);