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]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
33 #include <libhotplug.h>
34 #include <sys/types.h>
35 #include <sys/sunddi.h>
36 #include <sys/ddi_hp.h>
38 #if !defined(TEXT_DOMAIN) /* should be defined by cc -D */
39 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */
43 * Function prototypes.
45 static int cmd_list(int, char **, const char *);
46 static int cmd_online(int, char **, const char *);
47 static int cmd_offline(int, char **, const char *);
48 static int cmd_enable(int, char **, const char *);
49 static int cmd_disable(int, char **, const char *);
50 static int cmd_poweron(int, char **, const char *);
51 static int cmd_poweroff(int, char **, const char *);
52 static int cmd_getpriv(int, char **, const char *);
53 static int cmd_setpriv(int, char **, const char *);
54 static int cmd_changestate(int, char **, const char *);
55 static void parse_common(int, char **, const char *);
56 static void parse_flags(int, char **, int *, const char *);
57 static void parse_target(int, char **, char **, char **, const char *);
58 static void parse_options(int, char **, char **, const char *);
59 static void bad_option(int, int, const char *);
60 static void usage(const char *);
61 static int list_cb(hp_node_t
, void *);
62 static int list_long_cb(hp_node_t
, void *);
63 static int error_cb(hp_node_t
, void *);
64 static void print_options(const char *);
65 static void print_error(int);
66 static int state_atoi(char *);
67 static char *state_itoa(int);
68 static short valid_target(int);
71 * Define a conversion table for hotplug states.
79 static hpstate_t hpstates
[] = {
80 { DDI_HP_CN_STATE_EMPTY
, "EMPTY", 0 },
81 { DDI_HP_CN_STATE_PRESENT
, "PRESENT", 1 },
82 { DDI_HP_CN_STATE_POWERED
, "POWERED", 1 },
83 { DDI_HP_CN_STATE_ENABLED
, "ENABLED", 1 },
84 { DDI_HP_CN_STATE_PORT_EMPTY
, "PORT-EMPTY", 0 },
85 { DDI_HP_CN_STATE_PORT_PRESENT
, "PORT-PRESENT", 1 },
86 { DDI_HP_CN_STATE_OFFLINE
, "OFFLINE", 1 },
87 { DDI_HP_CN_STATE_ATTACHED
, "ATTACHED", 0 },
88 { DDI_HP_CN_STATE_MAINTENANCE
, "MAINTENANCE", 0 },
89 { DDI_HP_CN_STATE_ONLINE
, "ONLINE", 1 },
94 * Define tables of supported subcommands.
99 int (*func
)(int argc
, char *argv
[], const char *usage_str
);
102 static subcmd_t subcmds
[] = {
103 { "list [-l] [-v] [<path> [<connection>]]", "list", cmd_list
},
104 { "online <path> <port>", "online", cmd_online
},
105 { "offline [-f] [-q] <path> <port>", "offline", cmd_offline
},
106 { "enable <path> <connector>", "enable", cmd_enable
},
107 { "disable [-f] [-q] <path> <connector>", "disable", cmd_disable
},
108 { "poweron <path> <connector>", "poweron", cmd_poweron
},
109 { "poweroff [-f] [-q] <path> <connector>", "poweroff", cmd_poweroff
},
110 { "get -o <options> <path> <connector>", "get", cmd_getpriv
},
111 { "set -o <options> <path> <connector>", "set", cmd_setpriv
}
114 static subcmd_t hidden_subcmds
[] = {
115 { "changestate [-f] [-q] -s <state> <path> <connection>",
116 "changestate", cmd_changestate
}
120 * Define tables of command line options.
122 static const struct option common_opts
[] = {
123 { "help", no_argument
, 0, '?' },
124 { "version", no_argument
, 0, 'V' },
128 static const struct option list_opts
[] = {
129 { "list-path", no_argument
, 0, 'l' },
130 { "verbose", no_argument
, 0, 'v' },
134 static const struct option flag_opts
[] = {
135 { "force", no_argument
, 0, 'f' },
136 { "query", no_argument
, 0, 'q' },
140 static const struct option private_opts
[] = {
141 { "options", required_argument
, 0, 'o' },
145 static const struct option changestate_opts
[] = {
146 { "force", no_argument
, 0, 'f' },
147 { "query", no_argument
, 0, 'q' },
148 { "state", required_argument
, 0, 's' },
156 #define EXIT_EINVAL 1 /* invalid arguments */
157 #define EXIT_ENOENT 2 /* path or connection doesn't exist */
158 #define EXIT_FAILED 3 /* operation failed */
159 #define EXIT_UNAVAIL 4 /* service not available */
165 static char version
[] = "1.0";
171 * The main routine determines which subcommand is used,
172 * and dispatches control to the corresponding function.
175 main(int argc
, char *argv
[])
179 (void) setlocale(LC_ALL
, "");
180 (void) textdomain(TEXT_DOMAIN
);
182 if ((prog
= strrchr(argv
[0], '/')) == NULL
)
189 return (EXIT_EINVAL
);
192 parse_common(argc
, argv
, NULL
);
194 /* Check the list of defined subcommands. */
195 for (i
= 0; i
< (sizeof (subcmds
) / sizeof (subcmd_t
)); i
++) {
196 if (strcmp(argv
[1], subcmds
[i
].cmd_str
) == 0) {
197 rv
= subcmds
[i
].func(argc
- 1, &argv
[1],
198 subcmds
[i
].usage_str
);
203 /* Check the list of hidden subcommands. */
204 for (i
= 0; i
< (sizeof (hidden_subcmds
) / sizeof (subcmd_t
)); i
++) {
205 if (strcmp(argv
[1], hidden_subcmds
[i
].cmd_str
) == 0) {
206 rv
= hidden_subcmds
[i
].func(argc
- 1, &argv
[1],
207 hidden_subcmds
[i
].usage_str
);
212 /* No matching subcommand found. */
213 (void) fprintf(stderr
, gettext("ERROR: %s: unknown subcommand '%s'\n"),
219 /* Determine exit code */
224 return (EXIT_EINVAL
);
227 return (EXIT_ENOENT
);
229 return (EXIT_UNAVAIL
);
231 return (EXIT_FAILED
);
240 * Subcommand to list hotplug information.
243 cmd_list(int argc
, char *argv
[], const char *usage_str
)
247 char *connection
= NULL
;
248 boolean_t long_flag
= B_FALSE
;
252 /* Parse command line options */
253 parse_common(argc
, argv
, usage_str
);
254 while ((opt
= getopt_clip(argc
, argv
, "lv", list_opts
, NULL
)) != -1) {
260 flags
|= HPINFOUSAGE
;
263 bad_option(opt
, optopt
, usage_str
);
267 parse_target(argc
, argv
, &path
, &connection
, usage_str
);
269 /* Default path is "/" */
273 /* Get hotplug information snapshot */
274 if ((root
= hp_init(path
, connection
, flags
)) == NULL
) {
279 /* Display hotplug information */
280 (void) hp_traverse(root
, NULL
, long_flag
? list_long_cb
: list_cb
);
282 /* Discard hotplug information snapshot */
291 * Subcommand to online a hotplug port.
294 cmd_online(int argc
, char *argv
[], const char *usage_str
)
297 hp_node_t results
= NULL
;
299 char *connection
= NULL
;
302 /* Parse command line options */
303 parse_common(argc
, argv
, usage_str
);
304 parse_target(argc
, argv
, &path
, &connection
, usage_str
);
306 /* Path and connection are required */
307 if ((path
== NULL
) || (connection
== NULL
)) {
308 (void) fprintf(stderr
, gettext("ERROR: too few arguments.\n"));
313 /* Get hotplug information snapshot */
314 if ((root
= hp_init(path
, connection
, 0)) == NULL
) {
319 /* Verify target is a port */
320 if (hp_type(root
) != HP_NODE_PORT
) {
321 (void) fprintf(stderr
,
322 gettext("ERROR: invalid target (must be a port).\n"));
327 /* Do state change */
328 rv
= hp_set_state(root
, 0, DDI_HP_CN_STATE_ONLINE
, &results
);
330 /* Display results */
332 (void) fprintf(stderr
, gettext("ERROR: failed to attach device "
333 "drivers or other internal errors.\n"));
334 } else if (rv
!= 0) {
337 if (results
!= NULL
) {
338 (void) hp_traverse(results
, NULL
, error_cb
);
342 /* Discard hotplug information snapshot */
351 * Subcommand to offline a hotplug port.
354 cmd_offline(int argc
, char *argv
[], const char *usage_str
)
357 hp_node_t results
= NULL
;
359 char *connection
= NULL
;
363 /* Parse command line options */
364 parse_common(argc
, argv
, usage_str
);
365 parse_flags(argc
, argv
, &flags
, usage_str
);
366 parse_target(argc
, argv
, &path
, &connection
, usage_str
);
368 /* Path and connection are required */
369 if ((path
== NULL
) || (connection
== NULL
)) {
370 (void) fprintf(stderr
, gettext("ERROR: too few arguments.\n"));
375 /* Get hotplug information snapshot */
376 if ((root
= hp_init(path
, connection
, 0)) == NULL
) {
381 /* Verify target is a port */
382 if (hp_type(root
) != HP_NODE_PORT
) {
383 (void) fprintf(stderr
,
384 gettext("ERROR: invalid target (must be a port).\n"));
389 /* Do state change */
390 rv
= hp_set_state(root
, flags
, DDI_HP_CN_STATE_OFFLINE
, &results
);
392 /* Display results */
394 if (results
!= NULL
) {
395 (void) hp_traverse(results
, NULL
, error_cb
);
399 /* Discard hotplug information snapshot */
408 * Subcommand to enable a hotplug connector.
411 cmd_enable(int argc
, char *argv
[], const char *usage_str
)
414 hp_node_t results
= NULL
;
416 char *connection
= NULL
;
419 /* Parse command line options */
420 parse_common(argc
, argv
, usage_str
);
421 parse_target(argc
, argv
, &path
, &connection
, usage_str
);
423 /* Path and connection are required */
424 if ((path
== NULL
) || (connection
== NULL
)) {
425 (void) fprintf(stderr
, gettext("ERROR: too few arguments.\n"));
430 /* Get hotplug information snapshot */
431 if ((root
= hp_init(path
, connection
, 0)) == NULL
) {
436 /* Verify target is a connector */
437 if (hp_type(root
) != HP_NODE_CONNECTOR
) {
438 (void) fprintf(stderr
,
439 gettext("ERROR: invalid target (must be a connector).\n"));
444 /* Do state change */
445 rv
= hp_set_state(root
, 0, DDI_HP_CN_STATE_ENABLED
, &results
);
447 /* Display results */
449 if (results
!= NULL
) {
450 (void) hp_traverse(results
, NULL
, error_cb
);
454 /* Discard hotplug information snapshot */
463 * Subcommand to disable a hotplug connector.
466 cmd_disable(int argc
, char *argv
[], const char *usage_str
)
469 hp_node_t results
= NULL
;
471 char *connection
= NULL
;
475 /* Parse command line options */
476 parse_common(argc
, argv
, usage_str
);
477 parse_flags(argc
, argv
, &flags
, usage_str
);
478 parse_target(argc
, argv
, &path
, &connection
, usage_str
);
480 /* Path and connection are required */
481 if ((path
== NULL
) || (connection
== NULL
)) {
482 (void) fprintf(stderr
, gettext("ERROR: too few arguments.\n"));
487 /* Get hotplug information snapshot */
488 if ((root
= hp_init(path
, connection
, 0)) == NULL
) {
493 /* Verify target is a connector */
494 if (hp_type(root
) != HP_NODE_CONNECTOR
) {
495 (void) fprintf(stderr
,
496 gettext("ERROR: invalid target (must be a connector).\n"));
502 * Do nothing unless the connector is in the ENABLED state.
503 * Otherwise this subcommand becomes an alias for 'poweron.'
505 if (hp_state(root
) != DDI_HP_CN_STATE_ENABLED
) {
510 /* Do state change */
511 rv
= hp_set_state(root
, flags
, DDI_HP_CN_STATE_POWERED
, &results
);
513 /* Display results */
515 if (results
!= NULL
) {
516 (void) hp_traverse(results
, NULL
, error_cb
);
520 /* Discard hotplug information snapshot */
529 * Subcommand to power on a hotplug connector.
532 cmd_poweron(int argc
, char *argv
[], const char *usage_str
)
535 hp_node_t results
= NULL
;
537 char *connection
= NULL
;
540 /* Parse command line options */
541 parse_common(argc
, argv
, usage_str
);
542 parse_target(argc
, argv
, &path
, &connection
, usage_str
);
544 /* Path and connection are required */
545 if ((path
== NULL
) || (connection
== NULL
)) {
546 (void) fprintf(stderr
, gettext("ERROR: too few arguments.\n"));
551 /* Get hotplug information snapshot */
552 if ((root
= hp_init(path
, connection
, 0)) == NULL
) {
557 /* Verify target is a connector */
558 if (hp_type(root
) != HP_NODE_CONNECTOR
) {
559 (void) fprintf(stderr
,
560 gettext("ERROR: invalid target (must be a connector).\n"));
566 * Do nothing if the connector is already powered.
567 * Otherwise this subcommand becomes an alias for 'disable.'
569 if (hp_state(root
) >= DDI_HP_CN_STATE_POWERED
) {
574 /* Do state change */
575 rv
= hp_set_state(root
, 0, DDI_HP_CN_STATE_POWERED
, &results
);
577 /* Display results */
579 if (results
!= NULL
) {
580 (void) hp_traverse(results
, NULL
, error_cb
);
584 /* Discard hotplug information snapshot */
593 * Subcommand to power off a hotplug connector.
596 cmd_poweroff(int argc
, char *argv
[], const char *usage_str
)
599 hp_node_t results
= NULL
;
601 char *connection
= NULL
;
605 /* Parse command line options */
606 parse_common(argc
, argv
, usage_str
);
607 parse_flags(argc
, argv
, &flags
, usage_str
);
608 parse_target(argc
, argv
, &path
, &connection
, usage_str
);
610 /* Path and connection are required */
611 if ((path
== NULL
) || (connection
== NULL
)) {
612 (void) fprintf(stderr
, gettext("ERROR: too few arguments.\n"));
617 /* Get hotplug information snapshot */
618 if ((root
= hp_init(path
, connection
, 0)) == NULL
) {
623 /* Verify target is a connector */
624 if (hp_type(root
) != HP_NODE_CONNECTOR
) {
625 (void) fprintf(stderr
,
626 gettext("ERROR: invalid target (must be a connector).\n"));
631 /* Do state change */
632 rv
= hp_set_state(root
, flags
, DDI_HP_CN_STATE_PRESENT
, &results
);
634 /* Display results */
636 if (results
!= NULL
) {
637 (void) hp_traverse(results
, NULL
, error_cb
);
641 /* Discard hotplug information snapshot */
650 * Subcommand to get and display bus private options.
653 cmd_getpriv(int argc
, char *argv
[], const char *usage_str
)
657 char *connection
= NULL
;
658 char *options
= NULL
;
659 char *results
= NULL
;
662 /* Parse command line options */
663 parse_common(argc
, argv
, usage_str
);
664 parse_options(argc
, argv
, &options
, usage_str
);
665 parse_target(argc
, argv
, &path
, &connection
, usage_str
);
667 /* Options, path, and connection are all required */
668 if ((options
== NULL
) || (path
== NULL
) || (connection
== NULL
)) {
669 (void) fprintf(stderr
, gettext("ERROR: too few arguments.\n"));
674 /* Get hotplug information snapshot */
675 if ((root
= hp_init(path
, connection
, 0)) == NULL
) {
680 /* Verify target is a connector */
681 if (hp_type(root
) != HP_NODE_CONNECTOR
) {
682 (void) fprintf(stderr
,
683 gettext("ERROR: invalid target (must be a connector).\n"));
688 /* Do the operation */
689 rv
= hp_get_private(root
, options
, &results
);
691 /* Display results */
693 (void) fprintf(stderr
,
694 gettext("ERROR: unsupported property name or value.\n"));
695 (void) fprintf(stderr
,
696 gettext("(Properties may depend upon connector state.)\n"));
697 } else if (rv
!= 0) {
700 if (results
!= NULL
) {
701 print_options(results
);
705 /* Discard hotplug information snapshot */
714 * Subcommand to set bus private options.
717 cmd_setpriv(int argc
, char *argv
[], const char *usage_str
)
721 char *connection
= NULL
;
722 char *options
= NULL
;
723 char *results
= NULL
;
726 /* Parse command line options */
727 parse_common(argc
, argv
, usage_str
);
728 parse_options(argc
, argv
, &options
, usage_str
);
729 parse_target(argc
, argv
, &path
, &connection
, usage_str
);
731 /* Options, path, and connection are all required */
732 if ((options
== NULL
) || (path
== NULL
) || (connection
== NULL
)) {
733 (void) fprintf(stderr
, gettext("ERROR: too few arguments.\n"));
738 /* Get hotplug information snapshot */
739 if ((root
= hp_init(path
, connection
, 0)) == NULL
) {
744 /* Verify target is a connector */
745 if (hp_type(root
) != HP_NODE_CONNECTOR
) {
746 (void) fprintf(stderr
,
747 gettext("ERROR: invalid target (must be a connector).\n"));
752 /* Do the operation */
753 rv
= hp_set_private(root
, options
, &results
);
755 /* Display results */
757 (void) fprintf(stderr
,
758 gettext("ERROR: unsupported property name or value.\n"));
759 (void) fprintf(stderr
,
760 gettext("(Properties may depend upon connector state.)\n"));
761 } else if (rv
!= 0) {
764 if (results
!= NULL
) {
765 print_options(results
);
769 /* Discard hotplug information snapshot */
778 * Subcommand to initiate a state change operation. This is
779 * a hidden subcommand to directly set a connector or port to
780 * a specific target state.
783 cmd_changestate(int argc
, char *argv
[], const char *usage_str
)
786 hp_node_t results
= NULL
;
788 char *connection
= NULL
;
793 /* Parse command line options */
794 parse_common(argc
, argv
, usage_str
);
795 while ((opt
= getopt_clip(argc
, argv
, "fqs:", changestate_opts
,
805 if ((state
= state_atoi(optarg
)) == -1) {
806 (void) printf("ERROR: invalid target state\n");
811 bad_option(opt
, optopt
, usage_str
);
815 parse_target(argc
, argv
, &path
, &connection
, usage_str
);
817 /* State, path, and connection are all required */
818 if ((state
== -1) || (path
== NULL
) || (connection
== NULL
)) {
819 (void) fprintf(stderr
, gettext("ERROR: too few arguments.\n"));
824 /* Check that target state is valid */
825 if (valid_target(state
) == 0) {
826 (void) fprintf(stderr
,
827 gettext("ERROR: invalid target state\n"));
831 /* Get hotplug information snapshot */
832 if ((root
= hp_init(path
, connection
, 0)) == NULL
) {
837 /* Initiate state change operation on root of snapshot */
838 rv
= hp_set_state(root
, flags
, state
, &results
);
840 /* Display results */
843 (void) hp_traverse(results
, NULL
, error_cb
);
847 /* Discard hotplug information snapshot */
856 * Parse command line options that are common to the
857 * entire program, and to each of its subcommands.
860 parse_common(int argc
, char *argv
[], const char *usage_str
)
866 /* Turn off error reporting */
869 while ((opt
= getopt_clip(argc
, argv
, "?V", common_opts
, NULL
)) != -1) {
878 (void) printf(gettext("%s: Version %s\n"),
886 /* Reset option index */
893 * Parse command line flags common to all downward state
894 * change operations (offline, disable, poweoff).
897 parse_flags(int argc
, char *argv
[], int *flagsp
, const char *usage_str
)
902 while ((opt
= getopt_clip(argc
, argv
, "fq", flag_opts
, NULL
)) != -1) {
911 bad_option(opt
, optopt
, usage_str
);
922 * Parse command line options common to the bus private set and
926 parse_options(int argc
, char *argv
[], char **optionsp
, const char *usage_str
)
930 while ((opt
= getopt_clip(argc
, argv
, "o:", private_opts
,
937 bad_option(opt
, optopt
, usage_str
);
946 * Parse the target path and connection name from the command line.
949 parse_target(int argc
, char *argv
[], char **pathp
, char **connectionp
,
950 const char *usage_str
)
955 *pathp
= argv
[optind
++];
958 *connectionp
= argv
[optind
++];
961 (void) fprintf(stderr
, gettext("ERROR: too many arguments.\n"));
970 * Routine to handle bad command line options.
973 bad_option(int opt
, int optopt
, const char *usage_str
)
977 (void) fprintf(stderr
,
978 gettext("ERROR: option '%c' requires an argument.\n"),
986 (void) fprintf(stderr
,
987 gettext("ERROR: unrecognized option '%c'.\n"), optopt
);
999 * Display general usage of the command. Including
1000 * the usage synopsis of each defined subcommand.
1003 usage(const char *usage_str
)
1007 if (usage_str
!= NULL
) {
1008 (void) fprintf(stderr
, gettext("Usage: %s %s\n\n"),
1013 (void) fprintf(stderr
, gettext("Usage: %s <subcommand> [<args>]\n\n"),
1016 (void) fprintf(stderr
, gettext("Subcommands:\n\n"));
1018 for (i
= 0; i
< (sizeof (subcmds
) / sizeof (subcmd_t
)); i
++)
1019 (void) fprintf(stderr
, " %s\n\n", subcmds
[i
].usage_str
);
1025 * Callback function for hp_traverse(), to display nodes
1026 * of a hotplug information snapshot. (Short version.)
1030 list_cb(hp_node_t node
, void *arg
)
1035 for (parent
= hp_parent(node
); parent
; parent
= hp_parent(parent
))
1036 if (hp_type(parent
) == HP_NODE_DEVICE
)
1039 switch (hp_type(node
)) {
1040 case HP_NODE_DEVICE
:
1041 (void) printf("%s\n", hp_name(node
));
1044 case HP_NODE_CONNECTOR
:
1045 (void) printf("[%s]", hp_name(node
));
1046 (void) printf(" (%s)", state_itoa(hp_state(node
)));
1047 (void) printf("\n");
1051 (void) printf("<%s>", hp_name(node
));
1052 (void) printf(" (%s)", state_itoa(hp_state(node
)));
1053 (void) printf("\n");
1057 (void) printf("{ %s }\n", hp_usage(node
));
1061 return (HP_WALK_CONTINUE
);
1067 * Callback function for hp_traverse(), to display nodes
1068 * of a hotplug information snapshot. (Long version.)
1072 list_long_cb(hp_node_t node
, void *arg
)
1074 char path
[MAXPATHLEN
];
1075 char connection
[MAXPATHLEN
];
1077 if (hp_type(node
) != HP_NODE_USAGE
) {
1078 if (hp_path(node
, path
, connection
) != 0)
1079 return (HP_WALK_CONTINUE
);
1080 (void) printf("%s", path
);
1083 switch (hp_type(node
)) {
1084 case HP_NODE_CONNECTOR
:
1085 (void) printf(" [%s]", connection
);
1086 (void) printf(" (%s)", state_itoa(hp_state(node
)));
1090 (void) printf(" <%s>", connection
);
1091 (void) printf(" (%s)", state_itoa(hp_state(node
)));
1095 (void) printf(" { %s }", hp_usage(node
));
1099 (void) printf("\n");
1101 return (HP_WALK_CONTINUE
);
1107 * Callback function for hp_traverse(), to display
1108 * error results from a state change operation.
1112 error_cb(hp_node_t node
, void *arg
)
1116 static char path
[MAXPATHLEN
];
1117 static char connection
[MAXPATHLEN
];
1119 if (((child
= hp_child(node
)) != NULL
) &&
1120 (hp_type(child
) == HP_NODE_USAGE
)) {
1121 if (hp_path(node
, path
, connection
) == 0)
1122 (void) printf("%s:\n", path
);
1123 return (HP_WALK_CONTINUE
);
1126 if ((hp_type(node
) == HP_NODE_USAGE
) &&
1127 ((usage_str
= hp_usage(node
)) != NULL
))
1128 (void) printf(" { %s }\n", usage_str
);
1130 return (HP_WALK_CONTINUE
);
1136 * Parse and display bus private options. The options are
1137 * formatted as a string which conforms to the getsubopt(3C)
1138 * format. This routine only splits the string elements as
1139 * separated by commas, and displays each portion on its own
1140 * separate line of output.
1143 print_options(const char *options
)
1145 char *buf
, *curr
, *next
;
1148 /* Do nothing if options string is empty */
1149 if ((len
= strlen(options
)) == 0)
1152 /* To avoid modifying the input string, make a copy on the stack */
1153 if ((buf
= (char *)alloca(len
+ 1)) == NULL
) {
1154 (void) printf("%s\n", options
);
1157 (void) strlcpy(buf
, options
, len
+ 1);
1159 /* Iterate through each comma-separated name/value pair */
1162 if ((next
= strchr(curr
, ',')) != NULL
) {
1166 (void) printf("%s\n", curr
);
1167 } while ((curr
= next
) != NULL
);
1173 * Common routine to print error numbers in an appropriate way.
1174 * Prints nothing if error code is 0.
1177 print_error(int error
)
1184 (void) fprintf(stderr
,
1185 gettext("ERROR: operation not authorized.\n"));
1188 (void) fprintf(stderr
,
1189 gettext("ERROR: hotplug service is not available.\n"));
1192 (void) fprintf(stderr
,
1193 gettext("ERROR: devices or resources are busy.\n"));
1196 (void) fprintf(stderr
,
1197 gettext("ERROR: resource already exists.\n"));
1200 (void) fprintf(stderr
,
1201 gettext("ERROR: internal failure in hotplug service.\n"));
1204 (void) fprintf(stderr
,
1205 gettext("ERROR: invalid arguments.\n"));
1208 (void) fprintf(stderr
,
1209 gettext("ERROR: there are no connections to display.\n"));
1210 (void) fprintf(stderr
,
1211 gettext("(See hotplug(1m) for more information.)\n"));
1214 (void) fprintf(stderr
,
1215 gettext("ERROR: no such path or connection.\n"));
1218 (void) fprintf(stderr
,
1219 gettext("ERROR: not enough memory.\n"));
1222 (void) fprintf(stderr
,
1223 gettext("ERROR: operation not supported.\n"));
1226 (void) fprintf(stderr
,
1227 gettext("ERROR: hardware or driver specific failure.\n"));
1230 (void) fprintf(stderr
, gettext("ERROR: operation failed: %s\n"),
1239 * Convert a hotplug state from a string to an integer.
1242 state_atoi(char *state
)
1246 for (i
= 0; hpstates
[i
].state_str
!= NULL
; i
++)
1247 if (strcasecmp(state
, hpstates
[i
].state_str
) == 0)
1248 return (hpstates
[i
].state
);
1256 * Convert a hotplug state from an integer to a string.
1259 state_itoa(int state
)
1261 static char unknown
[] = "UNKNOWN";
1264 for (i
= 0; hpstates
[i
].state_str
!= NULL
; i
++)
1265 if (state
== hpstates
[i
].state
)
1266 return (hpstates
[i
].state_str
);
1274 * Check if a state is a valid target for a changestate command.
1277 valid_target(int state
)
1281 for (i
= 0; hpstates
[i
].state_str
!= NULL
; i
++)
1282 if (state
== hpstates
[i
].state
)
1283 return (hpstates
[i
].valid_target
);