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 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <sys/types.h>
41 * This file provides the builtin sys module. It is similar to the
42 * other modules, but differs in several important ways:
44 * - It is built as a static part of elfedit, and not
45 * as a sharable object.
46 * - It must be avaialble before the ELFCLASS of the object
47 * is known, so it is not ELFCLASS specific. We don't build
48 * it twice with <sys/machelf.h>, as we do for the loadable
49 * modules. This means that commands need to test for the type
50 * of their obj_state argument at runtime.
51 * - The init function signature is different. We build an entire
52 * module definition statically.
58 * This function is supplied to elfedit through our elfedit_module_t
59 * definition. It translates the opaque elfedit_i18nhdl_t handles
60 * in our module interface into the actual strings for elfedit to
64 * This module uses Msg codes for its i18n handle type.
65 * So the translation is simply to use MSG_INTL() to turn
66 * it into a string and return it.
69 mod_i18nhdl_to_str(elfedit_i18nhdl_t hdl
)
73 return (MSG_INTL(msg
));
79 * The sys_opt_t enum specifies a bit value for every optional argument
80 * allowed by a command in this module.
83 SYS_OPT_F_ALL
= 1, /* -a */
84 SYS_OPT_F_FORCE
= 2, /* -f */
85 SYS_OPT_F_SYNOPSIS
= 4, /* -s */
90 * Given a generic (void *) pointer to an obj_state argument, determine
91 * which type it is, and return the st_file, st_fd and st_elf fields.
94 get_obj_state_info(void *obj_state
, const char **file
, int *fd
, Elf
**elf
)
96 if (state
.elf
.elfclass
== ELFCLASS32
) {
97 elfedit32_obj_state_t
*s
= (elfedit32_obj_state_t
*)obj_state
;
103 elfedit64_obj_state_t
*s
= (elfedit64_obj_state_t
*)obj_state
;
114 * Helper for cmd_help(). Displays synopsis information for one command.
117 cmd_help_synopsis(elfeditGC_module_t
*mod
, elfeditGC_cmd_t
*cmd
)
121 const char **cmd_name
;
123 if (cmd
->cmd_name
[1] == NULL
) { /* One name */
124 name
= *cmd
->cmd_name
;
130 (void) snprintf(name_buf
, sizeof (name_buf
),
131 MSG_ORIG(MSG_HLPFMT_MULTNAM
), cmd
->cmd_name
[0]);
132 for (cmd_name
= cmd
->cmd_name
+ 1;
133 *cmd_name
; cmd_name
++) {
135 (void) strlcat(name_buf
,
136 MSG_ORIG(MSG_STR_COMMA_SP
),
139 cname
= (cmd_name
[0][0] == '\0') ?
140 MSG_INTL(MSG_HLPFMT_MODDEFCMD
) : *cmd_name
;
141 (void) strlcat(name_buf
, cname
,
144 (void) strlcat(name_buf
, MSG_ORIG(MSG_STR_CPAREN
),
147 elfedit_printf(MSG_ORIG(MSG_HLPFMT_NAMSUMHDR
), name
,
148 (* mod
->mod_i18nhdl_to_str
)(cmd
->cmd_desc
));
149 elfedit_printf(MSG_INTL(MSG_HLPFMT_SUMSYNOPSIS
),
150 elfedit_format_command_usage(mod
, cmd
,
151 MSG_ORIG(MSG_STR_HLPSUMINDENT
),
152 strlen(MSG_ORIG(MSG_STR_HLPSUMINDENT
))));
157 * Helper for cmd_help(). Displays synopsis information for one module.
160 cmd_help_showmod(elfeditGC_module_t
*mod
)
162 elfeditGC_cmd_t
*cmd
;
164 elfedit_printf(MSG_ORIG(MSG_HLPFMT_NAMDSCHDR
),
165 mod
->mod_name
, (* mod
->mod_i18nhdl_to_str
)(mod
->mod_desc
));
166 for (cmd
= mod
->mod_cmds
; cmd
->cmd_func
!= NULL
; cmd
++) {
167 if (cmd
!= mod
->mod_cmds
)
168 elfedit_printf(MSG_ORIG(MSG_STR_NL
));
169 elfedit_printf(MSG_ORIG(MSG_STR_NL
));
170 cmd_help_synopsis(mod
, cmd
);
176 * Given a string containing newline characters, break it into
177 * individual lines, and output each line with the given
178 * prefix string in front.
181 write_help_str(const char *str
, const char *prefix
)
188 i
= strcspn(str
, MSG_ORIG(MSG_STR_NL
));
189 if (*(str
+ i
) != '\0')
191 elfedit_printf(prefix
);
192 elfedit_write(str
, i
);
199 * Given a title, and a NULL terminated list of option/argument
200 * descriptors, output the list contents.
203 write_optarg(elfeditGC_module_t
*mod
, const char *title
,
204 elfedit_cmd_optarg_t
*optarg
)
209 elfedit_optarg_item_t item
;
211 elfedit_printf(title
);
212 for (cnt
= 0; optarg
->oa_name
!= NULL
; cnt
++) {
213 elfedit_next_optarg(&optarg
, &item
);
215 /* Insert a blank line between items */
217 elfedit_printf(MSG_ORIG(MSG_STR_NL
));
220 elfedit_printf(MSG_ORIG(MSG_STR_HLPINDENT
));
221 len
= strlen(item
.oai_name
);
222 help
= elfedit_optarg_helpstr(mod
, &item
);
223 if (item
.oai_flags
& ELFEDIT_CMDOA_F_VALUE
) {
224 len
+= 1 + strlen(item
.oai_vname
);
225 elfedit_printf(MSG_ORIG(MSG_STR_HLPOPTARG2
),
226 item
.oai_name
, item
.oai_vname
);
228 elfedit_printf(MSG_ORIG(MSG_STR_HLPOPTARG
),
233 * If name is too long, inject a newline to avoid
234 * crowding the help text.
237 elfedit_printf(MSG_ORIG(MSG_STR_NL
));
239 /* Output the help text with a tab prefix */
240 write_help_str(help
, MSG_ORIG(MSG_STR_TAB
));
246 * Implementation of sys:help
249 static elfedit_cmdret_t
250 cmd_help(void *obj_state
, int argc
, const char *argv
[])
252 #define INITIAL_ITEM_ALLOC 4
256 * An array of this type is used to collect the data needed to
257 * generate help output.
260 elfeditGC_cmd_t
*cmd
;
261 elfeditGC_module_t
*cmd_mod
; /* Used with cmd */
262 elfeditGC_module_t
*mod
;
271 elfeditGC_module_t
*mod
;
272 elfeditGC_cmd_t
*cmd
;
274 elfedit_getopt_state_t getopt_state
;
278 * Process options. The only option accepted is -s, so we
279 * don't even have to check the idmask to know.
281 elfedit_getopt_init(&getopt_state
, &argc
, &argv
);
282 while (elfedit_getopt(&getopt_state
) != NULL
)
286 * This command can produce an arbitrary amount of output, so
289 elfedit_pager_init();
293 /* Force all modules to load so we have data */
294 elfedit_load_modpath();
295 for (modlist
= state
.modlist
; modlist
;
296 modlist
= modlist
->ml_next
) {
297 cmd_help_showmod(modlist
->ml_mod
);
298 if (modlist
->ml_next
!= NULL
) {
299 elfedit_printf(MSG_ORIG(MSG_STR_NL
));
300 elfedit_printf(MSG_ORIG(MSG_STR_NL
));
303 return (ELFEDIT_CMDRET_NONE
);
307 * If no arguments are present, we display a simple
308 * "how to use help" tutorial, which will hopefully
309 * bootstrap the user into a position where they
310 * know how to run the help command, and then find
311 * what they're really after.
313 elfedit_printf(MSG_INTL(MSG_SYS_HELP_HELP_NOARG
));
314 return (ELFEDIT_CMDRET_NONE
);
319 * As we process the arguments, we are willing to treat each
320 * one as either a module or a command:
321 * 1) An item without a colon can be a module,
322 * or a command from the sys: module.
323 * 2) An item with a colon, and no command part is
324 * a module, and it can also be the default
325 * command for the module, if it has one. We choose
326 * to only display the module info in this case, since
327 * the use of "" to represent the default command is
328 * an implementation detail, not a user-facing concept.
329 * 3) An item with a colon and a command part can only be
332 * Note that there are cases where one argument can have two
333 * valid interpretations. In this case, we display them both.
335 * Pass over the arguments and determine how many distinct
336 * "things" we need to display. At the same time, force any
337 * needed modules to load so that the debug load messages won't
338 * show up in between the displayed items, and save the command
339 * and module definitions we will need to generate the output.
341 if (argc
> item_cnt
) {
342 int n
= (item_cnt
== 0) ? INITIAL_ITEM_ALLOC
: item_cnt
;
347 item
= elfedit_realloc(MSG_INTL(MSG_ALLOC_HELPITEM
), item
,
353 for (i
= 0; i
< argc
; i
++) {
354 const char *colon
= strchr(argv
[i
], ':');
356 if (colon
== NULL
) { /* No colon: sys: cmd or module */
358 elfedit_find_command(argv
[i
], 0, &item
[i
].cmd_mod
);
359 if (item
[i
].cmd
!= NULL
)
363 * Also try to load it as a module. If a command
364 * was found, then this need not succeed. Otherwise,
365 * it has to be a module, and we cause an error
366 * to be issued if not.
368 item
[i
].mod
= elfedit_load_module(argv
[i
],
369 item
[i
].cmd
== NULL
, 0);
370 if (item
[i
].mod
!= NULL
)
372 } else if (*(colon
+ 1) == '\0') {
373 /* Just colon: Module (and maybe default command) */
374 char buf
[ELFEDIT_MAXMODNAM
+ 1];
375 const char *str
= argv
[i
];
376 int len
= colon
- str
;
379 /* Strip off the colon */
380 if (len
< sizeof (buf
)) {
381 (void) strncpy(buf
, str
, len
);
385 item
[i
].mod
= elfedit_load_module(str
, 1, 0);
387 } else { /* A command */
389 elfedit_find_command(argv
[i
], 1, &item
[i
].cmd_mod
);
396 * Having validated the items, loop over them again and produce
397 * the required help output.
399 for (cur_item
= item
; argc
--; argv
++, cur_item
++) {
402 /* Help for a module? */
403 if (cur_item
->mod
!= NULL
) {
405 elfedit_printf(MSG_ORIG(MSG_HLPFMT_MULTIHDR
),
407 cmd_help_showmod(cur_item
->mod
);
408 if ((dispcnt
> 1) && (argc
> 0))
409 elfedit_printf(MSG_INTL(MSG_HLPFMT_MULTIEND
),
411 /* An empty line after the last line of output */
412 elfedit_printf(MSG_ORIG(MSG_STR_NL
));
415 /* Help for a command? */
416 if (cur_item
->cmd
== NULL
)
419 mod
= cur_item
->cmd_mod
;
421 elfedit_printf(MSG_ORIG(MSG_HLPFMT_MULTIHDR
), *argv
);
423 /* If -s, display quick synopsis rather than the whole thing */
425 cmd_help_synopsis(mod
, cmd
);
429 elfedit_printf(MSG_INTL(MSG_HLPFMT_MOD
), mod
->mod_name
,
430 (* mod
->mod_i18nhdl_to_str
)(mod
->mod_desc
));
431 elfedit_printf(MSG_INTL(MSG_HLPFMT_NAME
),
433 (* mod
->mod_i18nhdl_to_str
)(cmd
->cmd_desc
));
434 elfedit_printf(MSG_INTL(MSG_HLPFMT_SYNOPSIS
),
435 elfedit_format_command_usage(mod
, cmd
,
436 MSG_ORIG(MSG_STR_HLPUSEINDENT
),
437 strlen(MSG_ORIG(MSG_STR_HLPINDENT
))));
438 /* If there are alias names, show them */
439 if (cmd
->cmd_name
[1] != NULL
) {
440 const char **alias
= cmd
->cmd_name
+ 1;
442 elfedit_printf(MSG_INTL(MSG_HLPFMT_ALIASES
));
445 MSG_ORIG(MSG_STR_HLPINDENT
));
447 MSG_ORIG(MSG_FMT_MODCMD
),
448 mod
->mod_name
, *alias
);
451 MSG_INTL(MSG_HLPFMT_DEFCMD
));
452 elfedit_printf(MSG_ORIG(MSG_STR_NL
));
456 elfedit_printf(MSG_INTL(MSG_HLPFMT_DESC
));
458 (* mod
->mod_i18nhdl_to_str
)(cmd
->cmd_help
),
459 MSG_ORIG(MSG_STR_HLPINDENT
));
460 if (cmd
->cmd_args
!= NULL
)
461 write_optarg(mod
, MSG_INTL(MSG_HLPFMT_ARGS
),
463 if (cmd
->cmd_opt
!= NULL
)
464 write_optarg(mod
, MSG_INTL(MSG_HLPFMT_OPT
),
466 if ((dispcnt
> 1) && (argc
> 0))
467 elfedit_printf(MSG_INTL(MSG_HLPFMT_MULTIEND
),
469 /* An empty line after the last line of output */
470 elfedit_printf(MSG_ORIG(MSG_STR_NL
));
473 return (ELFEDIT_CMDRET_NONE
);
475 #undef INITIAL_ITEM_ALLOC
480 * Command completion function for sys:help
484 cpl_help(void *obj_state
, void *cpldata
, int argc
, const char *argv
[],
488 * The arguments can be any module or command. Supplying the
489 * commands implicitly supplies the modules too.
491 elfedit_cpl_command(cpldata
);
496 * Implementation of sys:load
499 static elfedit_cmdret_t
500 cmd_load(void *obj_state
, int argc
, const char *argv
[])
502 elfedit_getopt_state_t getopt_state
;
503 elfedit_getopt_ret_t
*getopt_ret
;
506 elfedit_getopt_init(&getopt_state
, &argc
, &argv
);
507 while ((getopt_ret
= elfedit_getopt(&getopt_state
)) != NULL
) {
508 switch (getopt_ret
->gor_idmask
) {
510 elfedit_load_modpath();
515 /* For each remaining argument, load them individually */
516 for (; argc
-- > 0; argv
++) {
517 /* Is it a directory? Load everything in it */
518 if ((stat(*argv
, &statbuf
) == 0) &&
519 (statbuf
.st_mode
& S_IFDIR
)) {
520 elfedit_load_moddir(*argv
, 1, 1);
521 } else { /* Not a directory. Normal load */
522 (void) elfedit_load_module(*argv
, 1, 1);
531 * Command completion function for sys:load
535 cpl_load(void *obj_state
, void *cpldata
, int argc
, const char *argv
[],
539 * Module names. Note that this causes elfedit to load all
540 * of the modules, which probably makes the current load
541 * operation unnecessary. This could be improved, but I don't
542 * see it as worth the complexity. Explicit load calls are
543 * rare, and the user will usually not use command completion.
545 elfedit_cpl_module(cpldata
, 1);
550 * Implementation of sys:quit
553 static elfedit_cmdret_t
554 cmd_quit(void *obj_state
, int argc
, const char *argv
[])
556 elfedit_getopt_state_t getopt_state
;
557 elfedit_getopt_ret_t
*getopt_ret
;
563 elfedit_getopt_init(&getopt_state
, &argc
, &argv
);
564 while ((getopt_ret
= elfedit_getopt(&getopt_state
)) != NULL
) {
565 switch (getopt_ret
->gor_idmask
) {
566 case SYS_OPT_F_FORCE
:
572 elfedit_command_usage();
574 if (state
.file
.present
) {
576 * If session is not READONLY, then refuse to quit if file
577 * needs flushing and -f option was not used.
579 if (!(state
.flags
& ELFEDIT_F_READONLY
) && state
.file
.dirty
&&
581 elfedit_msg(ELFEDIT_MSG_ERR
,
582 MSG_INTL(MSG_ERR_NODIRTYQUIT
));
584 get_obj_state_info(obj_state
, &file
, &fd
, &elf
);
597 * Implementation of sys:status
600 static elfedit_cmdret_t
601 cmd_status(void *obj_state
, int argc
, const char *argv
[])
608 elfedit_command_usage();
611 * This command can produce an arbitrary amount of output, so
614 elfedit_pager_init();
617 if (state
.file
.present
== 0) {
618 elfedit_printf(MSG_INTL(MSG_HLPFMT_INFILENONE
));
619 } else if (state
.flags
& ELFEDIT_F_READONLY
) {
620 elfedit_printf(MSG_INTL(MSG_HLPFMT_INFILERO
),
623 elfedit_printf(MSG_INTL(MSG_HLPFMT_INFILE
), state
.file
.infile
);
624 elfedit_printf(MSG_INTL(MSG_HLPFMT_OUTFILE
),
627 if (state
.file
.dirty
)
628 elfedit_printf(MSG_INTL(MSG_HLPFMT_CNGPENDING
));
630 /* Option Variables */
631 elfedit_printf(MSG_INTL(MSG_HLPFMT_VARHDR
));
632 elfedit_printf(MSG_INTL(MSG_HLPFMT_AFLG
),
633 (state
.flags
& ELFEDIT_F_AUTOPRINT
) ? MSG_ORIG(MSG_STR_ON
) :
634 MSG_ORIG(MSG_STR_OFF
));
635 elfedit_printf(MSG_INTL(MSG_HLPFMT_DFLG
),
636 (state
.flags
& ELFEDIT_F_DEBUG
) ? MSG_ORIG(MSG_STR_ON
) :
637 MSG_ORIG(MSG_STR_OFF
));
638 elfedit_printf(MSG_INTL(MSG_HLPFMT_OFLG
),
639 elfedit_atoconst_value_to_str(ELFEDIT_CONST_OUTSTYLE
,
642 /* Module Load Path */
643 elfedit_printf(MSG_INTL(MSG_HLPFMT_PATHHDR
));
644 for (i
= 0; i
< state
.modpath
.n
; i
++)
645 elfedit_printf(MSG_ORIG(MSG_HLPFMT_PATHELT
),
646 state
.modpath
.seg
[i
]);
648 /* Currently Loaded Modules */
649 elfedit_printf(MSG_INTL(MSG_HLPFMT_MODHDR
));
650 for (modlist
= state
.modlist
; modlist
;
651 modlist
= modlist
->ml_next
) {
652 s
= modlist
->ml_path
? modlist
->ml_path
:
653 MSG_INTL(MSG_FMT_BUILTIN
);
654 elfedit_printf(MSG_ORIG(MSG_HLPFMT_NAMDSCCOL
),
655 modlist
->ml_mod
->mod_name
, s
);
658 return (ELFEDIT_CMDRET_NONE
);
662 * Implementation of sys:set
665 static elfedit_cmdret_t
666 cmd_set(void *obj_state
, int argc
, const char *argv
[])
668 if ((argc
!= 2) || (strlen(argv
[0]) > 1))
669 elfedit_command_usage();
674 if (elfedit_atobool(argv
[1], MSG_INTL(MSG_SYSSET_A
)))
675 state
.flags
|= ELFEDIT_F_AUTOPRINT
;
677 state
.flags
&= ~ELFEDIT_F_AUTOPRINT
;
682 if (elfedit_atobool(argv
[1], MSG_INTL(MSG_SYSSET_D
)))
683 state
.flags
|= ELFEDIT_F_DEBUG
;
685 state
.flags
&= ~ELFEDIT_F_DEBUG
;
690 if (elfedit_atooutstyle(argv
[1], &state
.outstyle
) == 0)
691 elfedit_msg(ELFEDIT_MSG_ERR
,
692 MSG_INTL(MSG_ERR_BADOSTYLE
), argv
[1]);
696 elfedit_command_usage();
704 * Command completion function for sys:set
708 cpl_set(void *obj_state
, void *cpldata
, int argc
, const char *argv
[],
714 * This command doesn't accept options, so num_opt should be
715 * 0. This is a defensive measure, in case that should change.
720 if ((argc
< 1) || (argc
> 2))
723 if (argc
== 1) { /* The first argument is a variable letter */
724 elfedit_cpl_match(cpldata
, MSG_ORIG(MSG_STR_A
), 1);
725 elfedit_cpl_match(cpldata
, MSG_ORIG(MSG_STR_D
), 1);
726 elfedit_cpl_match(cpldata
, MSG_ORIG(MSG_STR_O
), 1);
727 elfedit_cpl_match(cpldata
, MSG_ORIG(MSG_STR_W
), 1);
731 /* We're dealing with the second argument, the value */
733 if (strlen(s
) > 1) /* One letter variables */
736 case 'a': /* Booleans */
742 /* The second argument is a boolean */
743 elfedit_cpl_atoconst(cpldata
, ELFEDIT_CONST_BOOL
);
745 /* The numbers are not symbolic, but we want them in the list */
746 elfedit_cpl_match(cpldata
, MSG_ORIG(MSG_STR_0
), 1);
747 elfedit_cpl_match(cpldata
, MSG_ORIG(MSG_STR_1
), 1);
750 case 'o': /* Output style */
752 elfedit_cpl_atoconst(cpldata
, ELFEDIT_CONST_OUTSTYLE
);
759 * Implementation of sys:unload
762 static elfedit_cmdret_t
763 cmd_unload(void *obj_state
, int argc
, const char *argv
[])
765 elfedit_getopt_state_t getopt_state
;
766 elfedit_getopt_ret_t
*getopt_ret
;
770 elfedit_getopt_init(&getopt_state
, &argc
, &argv
);
771 while ((getopt_ret
= elfedit_getopt(&getopt_state
)) != NULL
) {
772 switch (getopt_ret
->gor_idmask
) {
780 * If -a is specified, unload everything except builtins. Don't
781 * allow plain arguments in this case because there is nothing
782 * left to unload after -a.
786 elfedit_command_usage();
788 * Until we run out of non-builtin modules, take the first
789 * one from the list and unload it. Each removal alters
790 * the list, so we always start at the beginning, but this
791 * is efficient since we always remove the first available item
793 while (state
.modlist
!= NULL
) {
794 for (moddef
= state
.modlist
; moddef
!= NULL
;
795 moddef
= moddef
->ml_next
)
796 if (moddef
->ml_dl_hdl
!= NULL
) break;
798 /* If we made it to the end, then the list is empty */
802 elfedit_unload_module(moddef
->ml_mod
->mod_name
);
807 /* Unload each module individually */
808 for (; argc
-- > 0; argv
++)
809 elfedit_unload_module(*argv
);
816 * Command completion function for sys:unload
820 cpl_unload(void *obj_state
, void *cpldata
, int argc
, const char *argv
[],
824 * Module names. Don't allow elfedit to load all the modules,
825 * as the only modules we want to unload are those already
828 elfedit_cpl_module(cpldata
, 0);
833 * Implementation of sys:write
836 static elfedit_cmdret_t
837 cmd_write(void *obj_state
, int argc
, const char *argv
[])
844 elfedit_command_usage();
846 if (state
.file
.present
!= 0) {
847 if (state
.flags
& ELFEDIT_F_READONLY
)
848 elfedit_msg(ELFEDIT_MSG_ERR
,
849 MSG_INTL(MSG_ERR_READONLY
));
851 get_obj_state_info(obj_state
, &file
, &fd
, &elf
);
852 if (elf_update(elf
, ELF_C_WRITE
) == -1)
853 elfedit_msg(ELFEDIT_MSG_ERR
, MSG_INTL(MSG_ERR_LIBELF
),
854 file
, MSG_ORIG(MSG_ELF_UPDATE
),
855 elf_errmsg(elf_errno()));
858 * An update has succeeded for this file, so revoke the need
859 * to unlink it on exit.
861 state
.file
.unlink_on_exit
= 0;
864 return (ELFEDIT_CMDRET_FLUSH
);
873 elfedit_sys_init(elfedit_module_version_t version
)
876 static const char *name_help
[] = { MSG_ORIG(MSG_SYS_CMD_HELP
),
877 MSG_ORIG(MSG_SYS_CMD_HELP_A1
), MSG_ORIG(MSG_SYS_CMD_HELP_A2
),
879 static elfedit_cmd_optarg_t opt_help
[] = {
880 { MSG_ORIG(MSG_STR_MINUS_S
),
881 /* MSG_INTL(MSG_SYS_OPTDESC_HELP_S) */
882 ELFEDIT_I18NHDL(MSG_SYS_OPTDESC_HELP_S
), 0,
883 SYS_OPT_F_SYNOPSIS
, 0 },
886 static elfedit_cmd_optarg_t arg_help
[] = {
887 { MSG_ORIG(MSG_STR_ARG
),
888 /* MSG_INTL(MSG_ARGDESC_HELP_ARG) */
889 ELFEDIT_I18NHDL(MSG_ARGDESC_HELP_ARG
),
890 ELFEDIT_CMDOA_F_OPT
| ELFEDIT_CMDOA_F_MULT
},
895 static const char *name_load
[] = {
896 MSG_ORIG(MSG_SYS_CMD_LOAD
), NULL
};
897 static elfedit_cmd_optarg_t opt_load
[] = {
898 { MSG_ORIG(MSG_STR_MINUS_A
),
899 /* MSG_INTL(MSG_SYS_OPTDESC_LOAD_A) */
900 ELFEDIT_I18NHDL(MSG_SYS_OPTDESC_LOAD_A
), 0,
904 static elfedit_cmd_optarg_t arg_load
[] = {
905 { MSG_ORIG(MSG_STR_MODNAME
),
906 /* MSG_INTL(MSG_ARGDESC_LOAD_MODNAME) */
907 ELFEDIT_I18NHDL(MSG_ARGDESC_LOAD_MODNAME
),
908 ELFEDIT_CMDOA_F_OPT
| ELFEDIT_CMDOA_F_MULT
},
913 static const char *name_quit
[] = { MSG_ORIG(MSG_SYS_CMD_QUIT
),
914 MSG_ORIG(MSG_SYS_CMD_QUIT_A1
), MSG_ORIG(MSG_SYS_CMD_QUIT_A2
),
916 static elfedit_cmd_optarg_t opt_quit
[] = {
917 { MSG_ORIG(MSG_STR_MINUS_F
),
918 /* MSG_INTL(MSG_SYS_OPTDESC_QUIT_F) */
919 ELFEDIT_I18NHDL(MSG_SYS_OPTDESC_QUIT_F
), 0,
920 SYS_OPT_F_FORCE
, 0 },
925 static const char *name_status
[] = {
926 MSG_ORIG(MSG_SYS_CMD_STATUS
), NULL
};
929 static const char *name_set
[] = {
930 MSG_ORIG(MSG_SYS_CMD_SET
), NULL
};
931 static elfedit_cmd_optarg_t arg_set
[] = {
932 { MSG_ORIG(MSG_STR_OPTION
),
933 /* MSG_INTL(MSG_ARGDESC_SET_OPTION) */
934 ELFEDIT_I18NHDL(MSG_ARGDESC_SET_OPTION
), 0 },
935 { MSG_ORIG(MSG_STR_VALUE
),
936 /* MSG_INTL(MSG_ARGDESC_SET_VALUE) */
937 ELFEDIT_I18NHDL(MSG_ARGDESC_SET_VALUE
), 0 },
942 static const char *name_unload
[] = {
943 MSG_ORIG(MSG_SYS_CMD_UNLOAD
), NULL
};
944 static elfedit_cmd_optarg_t opt_unload
[] = {
945 { MSG_ORIG(MSG_STR_MINUS_A
),
946 /* MSG_INTL(MSG_SYS_OPTDESC_UNLOAD_A) */
947 ELFEDIT_I18NHDL(MSG_SYS_OPTDESC_UNLOAD_A
), 0,
951 static elfedit_cmd_optarg_t arg_unload
[] = {
952 { MSG_ORIG(MSG_STR_MODNAME
),
953 /* MSG_INTL(MSG_ARGDESC_UNLOAD_MODNAME) */
954 ELFEDIT_I18NHDL(MSG_ARGDESC_UNLOAD_MODNAME
),
955 ELFEDIT_CMDOA_F_OPT
| ELFEDIT_CMDOA_F_MULT
},
960 static const char *name_write
[] = { MSG_ORIG(MSG_SYS_CMD_WRITE
),
961 MSG_ORIG(MSG_SYS_CMD_WRITE_A1
), MSG_ORIG(MSG_SYS_CMD_WRITE_A2
),
964 static elfedit_cmd_t cmds
[] = {
966 { (elfedit_cmd_func_t
*)cmd_help
,
967 (elfedit_cmdcpl_func_t
*)cpl_help
, name_help
,
968 /* MSG_INTL(MSG_SYS_DESC_HELP) */
969 ELFEDIT_I18NHDL(MSG_SYS_DESC_HELP
),
970 /* MSG_INTL(MSG_SYS_HELP_HELP) */
971 ELFEDIT_I18NHDL(MSG_SYS_HELP_HELP
),
972 opt_help
, arg_help
},
975 { (elfedit_cmd_func_t
*)cmd_load
,
976 (elfedit_cmdcpl_func_t
*)cpl_load
, name_load
,
977 /* MSG_INTL(MSG_SYS_DESC_LOAD) */
978 ELFEDIT_I18NHDL(MSG_SYS_DESC_LOAD
),
979 /* MSG_INTL(MSG_SYS_HELP_LOAD) */
980 ELFEDIT_I18NHDL(MSG_SYS_HELP_LOAD
),
981 opt_load
, arg_load
},
984 { (elfedit_cmd_func_t
*)cmd_quit
, NULL
, name_quit
,
985 /* MSG_INTL(MSG_SYS_DESC_QUIT) */
986 ELFEDIT_I18NHDL(MSG_SYS_DESC_QUIT
),
987 /* MSG_INTL(MSG_SYS_HELP_QUIT) */
988 ELFEDIT_I18NHDL(MSG_SYS_HELP_QUIT
),
992 { (elfedit_cmd_func_t
*)cmd_status
, NULL
, name_status
,
993 /* MSG_INTL(MSG_SYS_DESC_STATUS) */
994 ELFEDIT_I18NHDL(MSG_SYS_DESC_STATUS
),
995 /* MSG_INTL(MSG_SYS_HELP_STATUS) */
996 ELFEDIT_I18NHDL(MSG_SYS_HELP_STATUS
),
1000 { (elfedit_cmd_func_t
*)cmd_set
,
1001 (elfedit_cmdcpl_func_t
*)cpl_set
, name_set
,
1002 /* MSG_INTL(MSG_SYS_DESC_SET) */
1003 ELFEDIT_I18NHDL(MSG_SYS_DESC_SET
),
1004 /* MSG_INTL(MSG_SYS_HELP_SET) */
1005 ELFEDIT_I18NHDL(MSG_SYS_HELP_SET
),
1009 { (elfedit_cmd_func_t
*)cmd_unload
,
1010 (elfedit_cmdcpl_func_t
*)cpl_unload
, name_unload
,
1011 /* MSG_INTL(MSG_SYS_DESC_UNLOAD) */
1012 ELFEDIT_I18NHDL(MSG_SYS_DESC_UNLOAD
),
1013 /* MSG_INTL(MSG_SYS_HELP_UNLOAD) */
1014 ELFEDIT_I18NHDL(MSG_SYS_HELP_UNLOAD
),
1015 opt_unload
, arg_unload
},
1018 { (elfedit_cmd_func_t
*)cmd_write
, NULL
, name_write
,
1019 /* MSG_INTL(MSG_SYS_DESC_WRITE) */
1020 ELFEDIT_I18NHDL(MSG_SYS_DESC_WRITE
),
1021 /* MSG_INTL(MSG_SYS_HELP_WRITE) */
1022 ELFEDIT_I18NHDL(MSG_SYS_HELP_WRITE
),
1028 static elfedit_module_t module
= {
1029 ELFEDIT_VER_CURRENT
, MSG_ORIG(MSG_MOD_SYS
),
1030 /* MSG_INTL(MSG_MOD_SYS_DESC) */
1031 ELFEDIT_I18NHDL(MSG_MOD_SYS_DESC
),
1032 cmds
, mod_i18nhdl_to_str
};
1034 static MODLIST_T moddef
= {
1036 (elfeditGC_module_t
*)&module
, /* Module definition */
1037 NULL
, /* Didn't dlopen() it, so NULL handle */
1038 NULL
/* Didn't dlopen() it, so no file path */