4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * inetadm - administer services controlled by inetd and print out inetd
29 * service related information.
35 #include <libscf_priv.h>
46 #define TEXT_DOMAIN "SUNW_OST_OSCMD"
47 #endif /* TEXT_DOMAIN */
49 /* Strings for output to the user, and checking user's input */
51 #define INETADM_TRUE_STR "TRUE"
52 #define INETADM_FALSE_STR "FALSE"
53 #define INETADM_ENABLED_STR "enabled"
54 #define INETADM_DISABLED_STR "disabled"
55 #define INETADM_DEFAULT_STR "default"
57 /* String for checking if an instance is under inetd's control. */
59 #define INETADM_INETD_STR "network/inetd"
62 * Used to hold a list of scf_value_t's whilst performing a transaction
63 * to write a proto list back.
65 typedef struct scf_val_el
{
71 * Structure used to encapsulate argc and argv so they can be passed using the
72 * single data argument supplied by scf_walk_fmri() for the consumption of
73 * modify_inst_props_cb().
75 typedef struct arglist
{
80 static scf_handle_t
*h
;
85 uu_die(gettext("Unexpected libscf error: %s. Exiting.\n"),
86 scf_strerror(scf_error()));
90 usage(boolean_t detailed
)
98 " inetadm -l {FMRI | pattern}...\n"
99 " inetadm -e {FMRI | pattern}...\n"
100 " inetadm -d {FMRI | pattern}...\n"
101 " inetadm -m {FMRI | pattern}... {name=value}...\n"
102 " inetadm -M {name=value}...\n"));
107 (void) fprintf(stdout
, gettext(
109 "Without any options inetadm lists all inetd managed services.\n"
113 " -p List all default inetd property values.\n"
114 " -l List all inetd property values for the inet "
116 " -e Enable the inet service(s).\n"
117 " -d Disable the inet service(s).\n"
118 " -m Modify the inet service(s) inetd property values.\n"
119 " -M Modify default inetd property values.\n"));
123 * Add the proto list contained in array 'plist' to entry 'entry', storing
124 * aside the scf_value_t's created and added to the entry in a list that the
125 * pointer referenced by sv_list is made to point at.
128 add_proto_list(scf_transaction_entry_t
*entry
, scf_handle_t
*hdl
,
129 char **plist
, uu_list_t
**sv_list
)
134 static uu_list_pool_t
*sv_pool
= NULL
;
136 if ((sv_pool
== NULL
) &&
137 ((sv_pool
= uu_list_pool_create("sv_pool",
138 sizeof (scf_val_el_t
), offsetof(scf_val_el_t
, link
), NULL
,
139 UU_LIST_POOL_DEBUG
)) == NULL
))
140 uu_die(gettext("Error: %s.\n"), uu_strerror(uu_error()));
142 if ((*sv_list
= uu_list_create(sv_pool
, NULL
, 0)) == NULL
)
143 uu_die(gettext("Error: %s.\n"), uu_strerror(uu_error()));
145 for (i
= 0; plist
[i
] != NULL
; i
++) {
146 if ((sv_el
= malloc(sizeof (scf_val_el_t
))) == NULL
)
147 uu_die(gettext("Error:"));
149 if (((sv_el
->val
= scf_value_create(hdl
)) == NULL
) ||
150 (scf_value_set_astring(sv_el
->val
, plist
[i
]) != 0) ||
151 (scf_entry_add_value(entry
, sv_el
->val
) != 0))
154 uu_list_node_init(sv_el
, &sv_el
->link
, sv_pool
);
155 (void) uu_list_insert_after(*sv_list
, NULL
, sv_el
);
160 * A counterpart to add_proto_list(), this function removes and frees the
161 * scf_value_t's it added to entry 'entry'.
164 remove_proto_list(scf_transaction_entry_t
*entry
, uu_list_t
*sv_list
)
169 scf_entry_reset(entry
);
171 while ((sv_el
= uu_list_teardown(sv_list
, &cookie
)) != NULL
) {
172 scf_value_destroy(sv_el
->val
);
176 uu_list_destroy(sv_list
);
180 * modify_prop takes an instance, property group, property name, type, and
181 * value, and modifies the specified property in the repository to the
186 modify_prop(const scf_instance_t
*inst
, const char *pg
, const char *prop
,
187 scf_type_t type
, void *value
)
189 scf_transaction_t
*tx
;
190 scf_transaction_entry_t
*ent
;
191 scf_propertygroup_t
*gpg
;
192 scf_property_t
*eprop
;
196 ssize_t max_fmri_len
;
198 if ((gpg
= scf_pg_create(h
)) == NULL
||
199 (eprop
= scf_property_create(h
)) == NULL
||
200 (v
= scf_value_create(h
)) == NULL
)
203 /* Get the property group or create it if it is missing. */
204 if (scf_instance_get_pg(inst
, pg
, gpg
) == -1) {
205 if (scf_error() != SCF_ERROR_NOT_FOUND
)
208 max_fmri_len
= scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH
);
209 if ((fmri
= malloc(max_fmri_len
+ 1)) == NULL
)
210 uu_die(gettext("Error: Out of memory.\n"));
212 if (scf_instance_to_fmri(inst
, fmri
, max_fmri_len
+ 1) < 0)
215 syslog(LOG_NOTICE
, "inetadm: Property group \"%s\" missing "
216 "from \"%s\", attempting to add it.\n", pg
, fmri
);
219 if (scf_instance_add_pg(inst
, pg
, SCF_GROUP_FRAMEWORK
, 0,
221 switch (scf_error()) {
222 case SCF_ERROR_EXISTS
:
224 case SCF_ERROR_PERMISSION_DENIED
:
225 uu_die(gettext("Error: Permission denied.\n"));
232 if (scf_pg_get_property(gpg
, prop
, eprop
) == -1) {
233 if (scf_error() != SCF_ERROR_NOT_FOUND
)
239 if ((tx
= scf_transaction_create(h
)) == NULL
||
240 (ent
= scf_entry_create(h
)) == NULL
)
246 if (scf_transaction_start(tx
, gpg
) == -1) {
247 if (scf_error() != SCF_ERROR_PERMISSION_DENIED
)
250 uu_die(gettext("Error: Permission denied.\n"));
253 /* Modify the property or create it if it is missing */
255 ret
= scf_transaction_property_new(tx
, ent
, prop
, type
);
257 ret
= scf_transaction_property_change_type(tx
, ent
,
263 case SCF_TYPE_BOOLEAN
:
264 scf_value_set_boolean(v
, *(uint8_t *)value
);
266 case SCF_TYPE_INTEGER
:
267 scf_value_set_integer(v
, *(int64_t *)value
);
269 case SCF_TYPE_ASTRING
:
270 if (strcmp(prop
, PR_PROTO_NAME
) == 0) {
271 add_proto_list(ent
, h
, (char **)value
,
273 } else if (scf_value_set_astring(v
, value
) == -1) {
278 uu_die(gettext("Error: Internal inetadm error"));
281 if ((strcmp(prop
, PR_PROTO_NAME
) != 0) &&
282 (scf_entry_add_value(ent
, v
) == -1))
285 ret
= scf_transaction_commit(tx
);
287 if (scf_error() != SCF_ERROR_PERMISSION_DENIED
)
290 uu_die(gettext("Error: Permission denied.\n"));
293 scf_transaction_reset(tx
);
296 if (scf_pg_update(gpg
) == -1)
300 if (strcmp(prop
, PR_PROTO_NAME
) == 0)
301 remove_proto_list(ent
, sv_list
);
305 scf_value_destroy(v
);
306 scf_entry_destroy(ent
);
307 scf_transaction_destroy(tx
);
308 scf_property_destroy(eprop
);
313 * delete_prop takes an instance, property group name and property, and
314 * deletes the specified property from the repository.
318 delete_prop(const scf_instance_t
*inst
, const char *pg
, const char *prop
)
320 scf_transaction_t
*tx
;
321 scf_transaction_entry_t
*ent
;
322 scf_propertygroup_t
*gpg
;
323 scf_property_t
*eprop
;
326 if ((gpg
= scf_pg_create(h
)) == NULL
||
327 (eprop
= scf_property_create(h
)) == NULL
||
328 (tx
= scf_transaction_create(h
)) == NULL
||
329 (ent
= scf_entry_create(h
)) == NULL
)
332 if (scf_instance_get_pg(inst
, pg
, gpg
) != SCF_SUCCESS
) {
333 if (scf_error() != SCF_ERROR_NOT_FOUND
)
336 uu_die(gettext("Error: \"%s\" property group missing.\n"), pg
);
340 if (scf_transaction_start(tx
, gpg
) != SCF_SUCCESS
) {
341 if (scf_error() != SCF_ERROR_PERMISSION_DENIED
)
344 uu_die(gettext("Error: Permission denied.\n"));
347 if (scf_transaction_property_delete(tx
, ent
,
348 prop
) != SCF_SUCCESS
) {
349 if (scf_error() != SCF_ERROR_NOT_FOUND
)
353 gettext("Error: \"%s\" property does not exist.\n"),
357 ret
= scf_transaction_commit(tx
);
359 if (scf_error() != SCF_ERROR_PERMISSION_DENIED
)
362 uu_die(gettext("Error: Permission denied.\n"));
365 scf_transaction_reset(tx
);
366 if (scf_pg_update(gpg
) == -1)
371 (void) scf_entry_destroy(ent
);
372 scf_transaction_destroy(tx
);
373 scf_property_destroy(eprop
);
378 * commit_props evaluates an entire property list that has been created
379 * based on command line options, and either deletes or modifies properties
384 commit_props(const scf_instance_t
*inst
, inetd_prop_t
*mod
, boolean_t defaults
)
389 for (i
= 0; mod
[i
].ip_name
!= NULL
; i
++) {
390 switch (mod
[i
].ip_error
) {
394 delete_prop(inst
, mod
[i
].ip_pg
, mod
[i
].ip_name
);
397 switch (mod
[i
].ip_type
) {
398 case INET_TYPE_STRING
:
400 defaults
? PG_NAME_SERVICE_DEFAULTS
:
401 mod
[i
].ip_pg
, mod
[i
].ip_name
,
403 mod
[i
].ip_value
.iv_string
);
405 case INET_TYPE_STRING_LIST
:
407 defaults
? PG_NAME_SERVICE_DEFAULTS
:
408 mod
[i
].ip_pg
, mod
[i
].ip_name
,
410 mod
[i
].ip_value
.iv_string_list
);
412 case INET_TYPE_INTEGER
:
414 defaults
? PG_NAME_SERVICE_DEFAULTS
:
415 mod
[i
].ip_pg
, mod
[i
].ip_name
,
416 SCF_TYPE_INTEGER
, &mod
[i
].ip_value
.iv_int
);
418 case INET_TYPE_BOOLEAN
:
419 new_bool
= (mod
[i
].ip_value
.iv_boolean
) ? 1 : 0;
422 defaults
? PG_NAME_SERVICE_DEFAULTS
:
423 mod
[i
].ip_pg
, mod
[i
].ip_name
,
424 SCF_TYPE_BOOLEAN
, &new_bool
);
432 * list_callback is the callback function to be handed to simple_walk_instances
433 * in list_services. It is called once on every instance on a machine. If
434 * that instance is controlled by inetd, it prints enabled/disabled, state,
440 list_callback(scf_handle_t
*hin
, scf_instance_t
*inst
, void *buf
)
442 ssize_t max_name_length
;
444 scf_simple_prop_t
*prop
= NULL
, *prop2
= NULL
;
445 const uint8_t *enabled
;
446 const char *state
, *restart_str
;
448 max_name_length
= scf_limit(SCF_LIMIT_MAX_NAME_LENGTH
);
449 if ((inst_name
= malloc(max_name_length
+ 1)) == NULL
)
450 uu_die(gettext("Error: Out of memory.\n"));
453 * Get the FMRI of the instance, and check if its delegated restarter
457 if (scf_instance_to_fmri(inst
, inst_name
, max_name_length
+ 1) < 0)
460 if ((prop
= scf_simple_prop_get(hin
, inst_name
, SCF_PG_GENERAL
,
461 SCF_PROPERTY_RESTARTER
)) == NULL
)
464 if ((restart_str
= scf_simple_prop_next_ustring(prop
)) == NULL
)
467 if (strstr(restart_str
, INETADM_INETD_STR
) == NULL
)
470 /* Free restarter prop so it can be reused below */
471 scf_simple_prop_free(prop
);
474 * We know that this instance is managed by inetd.
475 * Now get the enabled and state properties.
478 if (((prop
= scf_simple_prop_get(hin
, inst_name
, SCF_PG_GENERAL
,
479 SCF_PROPERTY_ENABLED
)) == NULL
) ||
480 ((enabled
= scf_simple_prop_next_boolean(prop
)) == NULL
)) {
481 (void) uu_warn(gettext("Error: Instance %s is missing enabled "
482 "property.\n"), inst_name
);
486 if (((prop2
= scf_simple_prop_get(hin
, inst_name
, SCF_PG_RESTARTER
,
487 SCF_PROPERTY_STATE
)) == NULL
) ||
488 ((state
= scf_simple_prop_next_astring(prop2
)) == NULL
)) {
489 (void) uu_warn(gettext("Error: Instance %s is missing state "
490 "property.\n"), inst_name
);
494 /* Print enabled/disabled, state, and FMRI for the instance. */
497 (void) printf("%-10s%-15s%s\n", INETADM_ENABLED_STR
, state
,
500 (void) printf("%-10s%-15s%s\n", INETADM_DISABLED_STR
, state
,
505 scf_simple_prop_free(prop
);
506 scf_simple_prop_free(prop2
);
507 return (SCF_SUCCESS
);
511 * list_services calls list_callback on every instance on the machine.
517 (void) printf("%-10s%-15s%s\n", "ENABLED", "STATE", "FMRI");
519 if (scf_simple_walk_instances(SCF_STATE_ALL
, NULL
, list_callback
) ==
525 print_prop_val(inetd_prop_t
*prop
)
527 switch (prop
->ip_type
) {
528 case INET_TYPE_STRING
:
529 (void) printf("\"%s\"\n", prop
->ip_value
.iv_string
);
531 case INET_TYPE_STRING_LIST
:
534 char **cpp
= prop
->ip_value
.iv_string_list
;
537 * Print string list as comma separated list.
540 (void) printf("\"%s", cpp
[j
]);
541 while (cpp
[++j
] != NULL
)
542 (void) printf(",%s", cpp
[j
]);
543 (void) printf("\"\n");
546 case INET_TYPE_INTEGER
:
547 (void) printf("%lld\n", prop
->ip_value
.iv_int
);
549 case INET_TYPE_BOOLEAN
:
550 if (prop
->ip_value
.iv_boolean
)
551 (void) printf("%s\n", INETADM_TRUE_STR
);
553 (void) printf("%s\n", INETADM_FALSE_STR
);
559 * list_props_cb is a callback function for scf_walk_fmri that lists all
560 * relevant inetd properties for an instance managed by inetd.
565 list_props_cb(void *data
, scf_walkinfo_t
*wip
)
568 const char *instname
= wip
->fmri
;
569 scf_simple_prop_t
*prop
;
570 inetd_prop_t
*proplist
;
571 const char *restart_str
;
572 boolean_t is_rpc
= B_FALSE
;
577 if (((h
= scf_handle_create(SCF_VERSION
)) == NULL
) ||
578 (scf_handle_bind(h
) == -1))
582 * Get the property that holds the name of this instance's
583 * restarter, and make sure that it is inetd.
585 if ((prop
= scf_simple_prop_get(h
, instname
, SCF_PG_GENERAL
,
586 SCF_PROPERTY_RESTARTER
)) == NULL
) {
587 if (scf_error() == SCF_ERROR_NOT_FOUND
)
588 uu_die(gettext("Error: Specified service instance "
589 "\"%s\" has no restarter property. inetd is not "
590 "the delegated restarter of this instance.\n"),
592 if (scf_error() == SCF_ERROR_INVALID_ARGUMENT
)
593 uu_die(gettext("Error: \"%s\" is not a valid service "
594 "instance.\n"), instname
);
599 if (((restart_str
= scf_simple_prop_next_ustring(prop
)) == NULL
) ||
600 (strstr(restart_str
, INETADM_INETD_STR
) == NULL
)) {
601 uu_die(gettext("Error: inetd is not the delegated restarter of "
602 "specified service instance \"%s\".\n"), instname
);
605 scf_simple_prop_free(prop
);
608 * This instance is controlled by inetd, so now we display all
609 * of its properties. First the mandatory properties, and then
610 * the properties that have default values, substituting the
611 * default values inherited from inetd as necessary (this is done
612 * for us by read_instance_props()).
615 if ((proplist
= read_instance_props(h
, instname
, &numprops
, &err
)) ==
617 uu_die(gettext("Unexpected libscf error: %s. Exiting.\n"),
620 scf_handle_destroy(h
);
622 (void) printf("%-9s%s\n", "SCOPE", "NAME=VALUE");
624 for (i
= 0; i
< numprops
; i
++) {
625 /* Skip rpc version properties if it's not an RPC service */
626 if ((strcmp(PR_RPC_LW_VER_NAME
, proplist
[i
].ip_name
) == 0) ||
627 (strcmp(PR_RPC_HI_VER_NAME
, proplist
[i
].ip_name
) == 0))
631 /* If it's not an unset property, print it out. */
632 if (proplist
[i
].ip_error
!= IVE_UNSET
) {
633 if (strcmp(PR_ISRPC_NAME
, proplist
[i
].ip_name
) == 0)
634 is_rpc
= proplist
[i
].ip_value
.iv_boolean
;
636 (void) printf("%-9s%s=",
637 proplist
[i
].from_inetd
? INETADM_DEFAULT_STR
: "",
638 proplist
[i
].ip_name
);
639 print_prop_val(&proplist
[i
]);
643 /* arg0 is non-default, but also doesn't have to be set. */
645 if (i
== PT_ARG0_INDEX
)
648 /* all other properties should have values. */
649 if (proplist
[i
].ip_default
) {
650 (void) uu_warn(gettext("Error: Property %s is missing "
651 "and has no defined default value.\n"),
652 proplist
[i
].ip_name
);
654 (void) uu_warn(gettext("Error: Required property %s is "
655 "missing.\n"), proplist
[i
].ip_name
);
659 free_instance_props(proplist
);
664 * set_svc_enable_cb is a callback function for scf_walk_fmri that sets the
665 * enabled property in the repository for an instance based on the value given
670 set_svc_enable_cb(void *data
, scf_walkinfo_t
*wip
)
672 uint8_t desired
= *(uint8_t *)data
;
673 const char *instname
= wip
->fmri
;
676 if (smf_enable_instance(instname
, 0) == 0)
679 if (smf_disable_instance(instname
, 0) == 0)
683 switch (scf_error()) {
684 case SCF_ERROR_INVALID_ARGUMENT
:
685 uu_die(gettext("Error: \"%s\" is not a valid service "
686 "instance.\n"), instname
);
688 case SCF_ERROR_NOT_FOUND
:
689 uu_die(gettext("Error: Service instance \"%s\" not found.\n"),
700 * list_defaults lists all the default property values being provided by
710 inetd_prop_t
*proptable
;
713 if (((h
= scf_handle_create(SCF_VERSION
)) == NULL
) ||
714 (scf_handle_bind(h
) == -1))
717 if ((proptable
= read_default_props(h
, &numprops
, &err
)) == NULL
) {
718 uu_die(gettext("Unexpected libscf error: %s. Exiting.\n"),
722 (void) printf("NAME=VALUE\n");
724 for (i
= 0; i
< numprops
; i
++) {
725 if (!proptable
[i
].ip_default
)
728 if (proptable
[i
].ip_error
== IVE_UNSET
) {
729 (void) uu_warn(gettext("Error: Default property %s "
730 "missing.\n"), proptable
[i
].ip_name
);
734 (void) printf("%s=", proptable
[i
].ip_name
);
735 print_prop_val(&proptable
[i
]);
738 free_instance_props(proptable
);
742 * modify_inst_props_cb is a callback function for scf_walk_fmri that modifies
743 * the properties that are given as name=value pairs on the command line
744 * to the requested value.
748 modify_inst_props_cb(void *data
, scf_walkinfo_t
*wip
)
752 const char *fmri
= wip
->fmri
;
753 scf_instance_t
*inst
= wip
->inst
;
754 inetd_prop_t
*mod
, *prop_table
;
758 int argc
= ((arglist_t
*)data
)->argc
;
759 char **argv
= ((arglist_t
*)data
)->argv
;
761 if ((max_val
= scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH
)) < 0)
764 prop_table
= get_prop_table(&numprops
);
766 if ((mod
= malloc(numprops
* sizeof (inetd_prop_t
))) == NULL
)
767 uu_die(gettext("Error: Out of memory.\n"));
769 (void) memcpy(mod
, prop_table
, numprops
* sizeof (inetd_prop_t
));
772 * For each property to be changed, look up the property name in the
773 * property table. Change each property in the mod array, and then
774 * write the entire thing back.
776 for (i
= 0; i
< argc
; i
++) {
777 /* Separate argument into name and value pair */
778 if ((value
= strchr(argv
[i
], '=')) == NULL
)
779 uu_die(gettext("Error: Malformed name=value pair "
780 "\"%s\"\n"), argv
[i
]);
785 /* Find property name in array of properties */
786 for (j
= 0; mod
[j
].ip_name
!= NULL
; j
++) {
787 if (strcmp(mod
[j
].ip_name
, argv
[i
]) == 0)
791 if (mod
[j
].ip_name
== NULL
)
792 uu_die(gettext("Error: \"%s\" is not a valid "
793 "property.\n"), argv
[i
]);
795 if (*value
== '\0') {
796 if ((mod
[j
].ip_default
) || (j
== PT_ARG0_INDEX
)) {
797 /* mark property for deletion */
798 mod
[j
].ip_error
= IVE_INVALID
;
800 /* return the '=' taken out above */
805 uu_die(gettext("\"%s\" is a mandatory "
806 "property and can not be deleted.\n"),
811 switch (mod
[j
].ip_type
) {
812 case INET_TYPE_INTEGER
:
813 if (uu_strtoint(value
, &new_int
, sizeof (new_int
), 0,
815 uu_die(gettext("Error: \"%s\" is not a valid "
816 "integer value.\n"), value
);
818 mod
[j
].ip_value
.iv_int
= new_int
;
820 case INET_TYPE_STRING
:
821 if (strlen(value
) >= max_val
) {
822 uu_die(gettext("Error: String value is longer "
823 "than %l characters.\n"), max_val
);
824 } else if ((mod
[j
].ip_value
.iv_string
= strdup(value
))
826 uu_die(gettext("Error: Out of memory.\n"));
829 case INET_TYPE_STRING_LIST
:
830 if ((mod
[j
].ip_value
.iv_string_list
=
831 get_protos(value
)) == NULL
) {
832 if (errno
== ENOMEM
) {
834 "Error: Out of memory.\n"));
835 } else if (errno
== E2BIG
) {
837 "Error: String value in "
838 "%s property longer than "
840 PR_PROTO_NAME
, max_val
);
850 case INET_TYPE_BOOLEAN
:
851 if (strcasecmp(value
, INETADM_TRUE_STR
) == 0)
852 mod
[j
].ip_value
.iv_boolean
= B_TRUE
;
853 else if (strcasecmp(value
, INETADM_FALSE_STR
) == 0)
854 mod
[j
].ip_value
.iv_boolean
= B_FALSE
;
856 uu_die(gettext("Error: \"%s\" is not a valid "
857 "boolean value. (TRUE or FALSE)\n"), value
);
859 /* mark property for modification */
860 mod
[j
].ip_error
= IVE_VALID
;
862 /* return the '=' taken out above */
866 commit_props(inst
, mod
, B_FALSE
);
868 if (smf_refresh_instance(fmri
) != 0)
869 uu_die(gettext("Error: Unable to refresh instance %s.\n"),
876 * modify_defaults takes n name=value pairs for inetd default property values,
877 * parses them, and then modifies the values in the repository.
881 modify_defaults(int argc
, char *argv
[])
885 scf_instance_t
*inst
;
886 inetd_prop_t
*mod
, *prop_table
;
891 if ((inst
= scf_instance_create(h
)) == NULL
)
894 if (scf_handle_decode_fmri(h
, INETD_INSTANCE_FMRI
, NULL
, NULL
,
895 inst
, NULL
, NULL
, SCF_DECODE_FMRI_EXACT
) == -1) {
896 if (scf_error() == SCF_ERROR_NOT_FOUND
) {
897 uu_die(gettext("inetd instance missing in repository."
904 if ((max_val
= scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH
)) < 0)
907 prop_table
= get_prop_table(&numprops
);
909 if ((mod
= malloc(numprops
* sizeof (inetd_prop_t
))) == NULL
)
910 uu_die(gettext("Error: Out of memory.\n"));
912 (void) memcpy(mod
, prop_table
, numprops
* sizeof (inetd_prop_t
));
914 for (i
= 0; i
< argc
; i
++) {
915 /* Separate argument into name and value pair */
916 if ((value
= strchr(argv
[i
], '=')) == NULL
)
917 uu_die(gettext("Error: Malformed name=value pair \"%s"
923 /* Find property name in array of defaults */
924 for (j
= 0; mod
[j
].ip_name
!= NULL
; j
++) {
925 if (!mod
[j
].ip_default
)
927 if (strcmp(mod
[j
].ip_name
, argv
[i
]) == 0)
931 if (mod
[j
].ip_name
== NULL
)
932 uu_die(gettext("Error: \"%s\" is not a default inetd "
933 "property.\n"), argv
[i
]);
936 uu_die(gettext("Cannot accept NULL values for default "
939 switch (mod
[j
].ip_type
) {
940 case INET_TYPE_INTEGER
:
941 if (uu_strtoint(value
, &new_int
, sizeof (new_int
), 0,
943 uu_die(gettext("Error: \"%s\" is not a valid "
944 "integer value.\n"), value
);
946 mod
[j
].ip_value
.iv_int
= new_int
;
948 case INET_TYPE_STRING
:
949 if (strlen(value
) >= max_val
)
950 uu_die(gettext("Error: String value is longer "
951 "than %l characters.\n"), max_val
);
952 if ((mod
[j
].ip_value
.iv_string
= strdup(value
))
954 uu_die(gettext("Error: Out of memory.\n"));
956 case INET_TYPE_BOOLEAN
:
957 if (strcasecmp(value
, INETADM_TRUE_STR
) == 0)
958 mod
[j
].ip_value
.iv_boolean
= B_TRUE
;
959 else if (strcasecmp(value
, INETADM_FALSE_STR
) == 0)
960 mod
[j
].ip_value
.iv_boolean
= B_FALSE
;
962 uu_die(gettext("Error: \"%s\" is not a valid "
963 "boolean value. (TRUE or FALSE)\n"), value
);
965 /* mark property for modification */
966 mod
[j
].ip_error
= IVE_VALID
;
969 commit_props(inst
, mod
, B_TRUE
);
971 scf_instance_destroy(inst
);
972 if (refresh_inetd() != 0)
973 uu_warn(gettext("Warning: Unable to refresh inetd.\n"));
977 main(int argc
, char *argv
[])
980 uint_t lflag
, eflag
, dflag
, pflag
, mflag
, Mflag
;
985 (void) setlocale(LC_ALL
, "");
986 (void) textdomain(TEXT_DOMAIN
);
988 if ((h
= scf_handle_create(SCF_VERSION
)) == NULL
)
991 if (scf_handle_bind(h
) == -1)
992 uu_die(gettext("Error: Couldn't bind to svc.configd.\n"));
999 lflag
= eflag
= dflag
= pflag
= mflag
= Mflag
= 0;
1000 while ((opt
= getopt(argc
, argv
, "ledpMm?")) != -1) {
1021 if (optopt
== '?') {
1033 * All options are mutually exclusive, and we must have an option
1034 * if we reached here.
1036 if (lflag
+ eflag
+ dflag
+ pflag
+ mflag
+ Mflag
!= 1)
1041 if ((pflag
== 0) && (argc
== 0))
1046 serr
= scf_walk_fmri(h
, argc
, argv
, 0, list_props_cb
, NULL
,
1047 &exit_status
, uu_warn
);
1050 serr
= scf_walk_fmri(h
, argc
, argv
, 0, set_svc_enable_cb
,
1051 &enable
, &exit_status
, uu_warn
);
1054 serr
= scf_walk_fmri(h
, argc
, argv
, 0, set_svc_enable_cb
,
1055 &enable
, &exit_status
, uu_warn
);
1059 uint_t fmri_args
= 0;
1061 /* count number of fmri arguments */
1062 while ((fmri_args
< argc
) && (strchr(*cpp
, '=') == NULL
)) {
1067 /* if no x=y args or no fmri, show usage */
1068 if ((fmri_args
== argc
) || (fmri_args
== 0))
1071 /* setup args for modify_inst_props_cb */
1072 args
.argc
= argc
- fmri_args
;
1073 args
.argv
= argv
+ fmri_args
;
1075 serr
= scf_walk_fmri(h
, fmri_args
, argv
, 0,
1076 modify_inst_props_cb
, &args
, &exit_status
, uu_warn
);
1078 modify_defaults(argc
, argv
);
1080 /* ensure there's no trailing garbage */
1086 uu_warn(gettext("failed to iterate over instances: %s"),
1087 scf_strerror(serr
));
1088 exit(UU_EXIT_FATAL
);
1092 (void) scf_handle_unbind(h
);
1093 scf_handle_destroy(h
);
1095 return (exit_status
);