1*5088Sab196087 /* 2*5088Sab196087 * CDDL HEADER START 3*5088Sab196087 * 4*5088Sab196087 * The contents of this file are subject to the terms of the 5*5088Sab196087 * Common Development and Distribution License (the "License"). 6*5088Sab196087 * You may not use this file except in compliance with the License. 7*5088Sab196087 * 8*5088Sab196087 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5088Sab196087 * or http://www.opensolaris.org/os/licensing. 10*5088Sab196087 * See the License for the specific language governing permissions 11*5088Sab196087 * and limitations under the License. 12*5088Sab196087 * 13*5088Sab196087 * When distributing Covered Code, include this CDDL HEADER in each 14*5088Sab196087 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5088Sab196087 * If applicable, add the following below this CDDL HEADER, with the 16*5088Sab196087 * fields enclosed by brackets "[]" replaced with your own identifying 17*5088Sab196087 * information: Portions Copyright [yyyy] [name of copyright owner] 18*5088Sab196087 * 19*5088Sab196087 * CDDL HEADER END 20*5088Sab196087 */ 21*5088Sab196087 22*5088Sab196087 /* 23*5088Sab196087 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24*5088Sab196087 * Use is subject to license terms. 25*5088Sab196087 */ 26*5088Sab196087 #pragma ident "%Z%%M% %I% %E% SMI" 27*5088Sab196087 28*5088Sab196087 #include <fcntl.h> 29*5088Sab196087 #include <sys/types.h> 30*5088Sab196087 #include <sys/stat.h> 31*5088Sab196087 #include <unistd.h> 32*5088Sab196087 #include <strings.h> 33*5088Sab196087 #include <elfedit.h> 34*5088Sab196087 #include "_elfedit.h" 35*5088Sab196087 #include "msg.h" 36*5088Sab196087 37*5088Sab196087 38*5088Sab196087 39*5088Sab196087 40*5088Sab196087 /* 41*5088Sab196087 * This file provides the builtin sys module. It is similar to the 42*5088Sab196087 * other modules, but differs in several important ways: 43*5088Sab196087 * 44*5088Sab196087 * - It is built as a static part of elfedit, and not 45*5088Sab196087 * as a sharable object. 46*5088Sab196087 * - It must be avaialble before the ELFCLASS of the object 47*5088Sab196087 * is known, so it is not ELFCLASS specific. We don't build 48*5088Sab196087 * it twice with machdep.h, as we do for the loadable modules. 49*5088Sab196087 * This means that commands need to test for the type 50*5088Sab196087 * of their obj_state argument at runtime. 51*5088Sab196087 * - The init function signature is different. We build an entire 52*5088Sab196087 * module definition statically. 53*5088Sab196087 */ 54*5088Sab196087 55*5088Sab196087 56*5088Sab196087 57*5088Sab196087 /* 58*5088Sab196087 * This function is supplied to elfedit through our elfedit_module_t 59*5088Sab196087 * definition. It translates the opaque elfedit_i18nhdl_t handles 60*5088Sab196087 * in our module interface into the actual strings for elfedit to 61*5088Sab196087 * use. 62*5088Sab196087 * 63*5088Sab196087 * note: 64*5088Sab196087 * This module uses Msg codes for its i18n handle type. 65*5088Sab196087 * So the translation is simply to use MSG_INTL() to turn 66*5088Sab196087 * it into a string and return it. 67*5088Sab196087 */ 68*5088Sab196087 static const char * 69*5088Sab196087 mod_i18nhdl_to_str(elfedit_i18nhdl_t hdl) 70*5088Sab196087 { 71*5088Sab196087 Msg msg = (Msg)hdl; 72*5088Sab196087 73*5088Sab196087 return (MSG_INTL(msg)); 74*5088Sab196087 } 75*5088Sab196087 76*5088Sab196087 77*5088Sab196087 78*5088Sab196087 /* 79*5088Sab196087 * The sys_opt_t enum specifies a bit value for every optional argument 80*5088Sab196087 * allowed by a command in this module. 81*5088Sab196087 */ 82*5088Sab196087 typedef enum { 83*5088Sab196087 SYS_OPT_F_ALL = 1, /* -a */ 84*5088Sab196087 SYS_OPT_F_FORCE = 2, /* -f */ 85*5088Sab196087 SYS_OPT_F_SYNOPSIS = 4, /* -s */ 86*5088Sab196087 } dyn_opt_t; 87*5088Sab196087 88*5088Sab196087 89*5088Sab196087 /* 90*5088Sab196087 * Given a generic (void *) pointer to an obj_state argument, determine 91*5088Sab196087 * which type it is, and return the st_file, st_fd and st_elf fields. 92*5088Sab196087 */ 93*5088Sab196087 static void 94*5088Sab196087 get_obj_state_info(void *obj_state, const char **file, int *fd, Elf **elf) 95*5088Sab196087 { 96*5088Sab196087 if (state.elf.elfclass == ELFCLASS32) { 97*5088Sab196087 elfedit32_obj_state_t *s = (elfedit32_obj_state_t *)obj_state; 98*5088Sab196087 99*5088Sab196087 *file = s->os_file; 100*5088Sab196087 *fd = s->os_fd; 101*5088Sab196087 *elf = s->os_elf; 102*5088Sab196087 } else { 103*5088Sab196087 elfedit64_obj_state_t *s = (elfedit64_obj_state_t *)obj_state; 104*5088Sab196087 105*5088Sab196087 *file = s->os_file; 106*5088Sab196087 *fd = s->os_fd; 107*5088Sab196087 *elf = s->os_elf; 108*5088Sab196087 } 109*5088Sab196087 } 110*5088Sab196087 111*5088Sab196087 112*5088Sab196087 113*5088Sab196087 /* 114*5088Sab196087 * Helper for cmd_help(). Displays synopsis information for one command. 115*5088Sab196087 */ 116*5088Sab196087 static void 117*5088Sab196087 cmd_help_synopsis(elfeditGC_module_t *mod, elfeditGC_cmd_t *cmd) 118*5088Sab196087 { 119*5088Sab196087 char name_buf[128]; 120*5088Sab196087 const char *name; 121*5088Sab196087 const char **cmd_name; 122*5088Sab196087 123*5088Sab196087 if (cmd->cmd_name[1] == NULL) { /* One name */ 124*5088Sab196087 name = *cmd->cmd_name; 125*5088Sab196087 } else { 126*5088Sab196087 const char *cname; 127*5088Sab196087 int need_comma = 0; 128*5088Sab196087 129*5088Sab196087 name = name_buf; 130*5088Sab196087 (void) snprintf(name_buf, sizeof (name_buf), 131*5088Sab196087 MSG_ORIG(MSG_HLPFMT_MULTNAM), cmd->cmd_name[0]); 132*5088Sab196087 for (cmd_name = cmd->cmd_name + 1; 133*5088Sab196087 *cmd_name; cmd_name++) { 134*5088Sab196087 if (need_comma) 135*5088Sab196087 (void) strlcat(name_buf, 136*5088Sab196087 MSG_ORIG(MSG_STR_COMMA_SP), 137*5088Sab196087 sizeof (name_buf)); 138*5088Sab196087 need_comma = 1; 139*5088Sab196087 cname = (cmd_name[0][0] == '\0') ? 140*5088Sab196087 MSG_INTL(MSG_HLPFMT_MODDEFCMD) : *cmd_name; 141*5088Sab196087 (void) strlcat(name_buf, cname, 142*5088Sab196087 sizeof (name_buf)); 143*5088Sab196087 } 144*5088Sab196087 (void) strlcat(name_buf, MSG_ORIG(MSG_STR_CPAREN), 145*5088Sab196087 sizeof (name_buf)); 146*5088Sab196087 } 147*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_HLPFMT_NAMSUMHDR), name, 148*5088Sab196087 (* mod->mod_i18nhdl_to_str)(cmd->cmd_desc)); 149*5088Sab196087 elfedit_printf(MSG_INTL(MSG_HLPFMT_SUMSYNOPSIS), 150*5088Sab196087 elfedit_format_command_usage(mod, cmd, 151*5088Sab196087 MSG_ORIG(MSG_STR_HLPSUMINDENT), 152*5088Sab196087 strlen(MSG_ORIG(MSG_STR_HLPSUMINDENT)))); 153*5088Sab196087 } 154*5088Sab196087 155*5088Sab196087 156*5088Sab196087 /* 157*5088Sab196087 * Helper for cmd_help(). Displays synopsis information for one module. 158*5088Sab196087 */ 159*5088Sab196087 static void 160*5088Sab196087 cmd_help_showmod(elfeditGC_module_t *mod) 161*5088Sab196087 { 162*5088Sab196087 elfeditGC_cmd_t *cmd; 163*5088Sab196087 164*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_HLPFMT_NAMDSCHDR), 165*5088Sab196087 mod->mod_name, (* mod->mod_i18nhdl_to_str)(mod->mod_desc)); 166*5088Sab196087 for (cmd = mod->mod_cmds; cmd->cmd_func != NULL; cmd++) { 167*5088Sab196087 if (cmd != mod->mod_cmds) 168*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_STR_NL)); 169*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_STR_NL)); 170*5088Sab196087 cmd_help_synopsis(mod, cmd); 171*5088Sab196087 } 172*5088Sab196087 } 173*5088Sab196087 174*5088Sab196087 175*5088Sab196087 /* 176*5088Sab196087 * Given a string containing newline characters, break it into 177*5088Sab196087 * individual lines, and output each line with the given 178*5088Sab196087 * prefix string in front. 179*5088Sab196087 */ 180*5088Sab196087 static void 181*5088Sab196087 write_help_str(const char *str, const char *prefix) 182*5088Sab196087 { 183*5088Sab196087 size_t i; 184*5088Sab196087 185*5088Sab196087 if (str == NULL) 186*5088Sab196087 return; 187*5088Sab196087 while (*str) { 188*5088Sab196087 i = strcspn(str, MSG_ORIG(MSG_STR_NL)); 189*5088Sab196087 if (*(str + i) != '\0') 190*5088Sab196087 i++; 191*5088Sab196087 elfedit_printf(prefix); 192*5088Sab196087 elfedit_write(str, i); 193*5088Sab196087 str += i; 194*5088Sab196087 } 195*5088Sab196087 } 196*5088Sab196087 197*5088Sab196087 198*5088Sab196087 /* 199*5088Sab196087 * Given a title, and a NULL terminated list of option/argument 200*5088Sab196087 * descriptors, output the list contents. 201*5088Sab196087 */ 202*5088Sab196087 static void 203*5088Sab196087 write_optarg(elfeditGC_module_t *mod, const char *title, 204*5088Sab196087 elfedit_cmd_optarg_t *optarg) 205*5088Sab196087 { 206*5088Sab196087 int cnt; 207*5088Sab196087 int len; 208*5088Sab196087 const char *help; 209*5088Sab196087 elfedit_optarg_item_t item; 210*5088Sab196087 211*5088Sab196087 elfedit_printf(title); 212*5088Sab196087 for (cnt = 0; optarg->oa_name != NULL; cnt++) { 213*5088Sab196087 elfedit_next_optarg(&optarg, &item); 214*5088Sab196087 215*5088Sab196087 /* Insert a blank line between items */ 216*5088Sab196087 if (cnt > 0) 217*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_STR_NL)); 218*5088Sab196087 219*5088Sab196087 /* Indentation */ 220*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_STR_HLPINDENT)); 221*5088Sab196087 len = strlen(item.oai_name); 222*5088Sab196087 help = elfedit_optarg_helpstr(mod, &item); 223*5088Sab196087 if (item.oai_flags & ELFEDIT_CMDOA_F_VALUE) { 224*5088Sab196087 len += 1 + strlen(item.oai_vname); 225*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_STR_HLPOPTARG2), 226*5088Sab196087 item.oai_name, item.oai_vname); 227*5088Sab196087 } else { 228*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_STR_HLPOPTARG), 229*5088Sab196087 item.oai_name); 230*5088Sab196087 } 231*5088Sab196087 232*5088Sab196087 /* 233*5088Sab196087 * If name is too long, inject a newline to avoid 234*5088Sab196087 * crowding the help text. 235*5088Sab196087 */ 236*5088Sab196087 if (len > 3) 237*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_STR_NL)); 238*5088Sab196087 239*5088Sab196087 /* Output the help text with a tab prefix */ 240*5088Sab196087 write_help_str(help, MSG_ORIG(MSG_STR_TAB)); 241*5088Sab196087 } 242*5088Sab196087 } 243*5088Sab196087 244*5088Sab196087 245*5088Sab196087 /* 246*5088Sab196087 * Implementation of sys:help 247*5088Sab196087 */ 248*5088Sab196087 /*ARGSUSED*/ 249*5088Sab196087 static elfedit_cmdret_t 250*5088Sab196087 cmd_help(void *obj_state, int argc, const char *argv[]) 251*5088Sab196087 { 252*5088Sab196087 #define INITIAL_ITEM_ALLOC 4 253*5088Sab196087 254*5088Sab196087 255*5088Sab196087 /* 256*5088Sab196087 * An array of this type is used to collect the data needed to 257*5088Sab196087 * generate help output. 258*5088Sab196087 */ 259*5088Sab196087 typedef struct { 260*5088Sab196087 elfeditGC_cmd_t *cmd; 261*5088Sab196087 elfeditGC_module_t *cmd_mod; /* Used with cmd */ 262*5088Sab196087 elfeditGC_module_t *mod; 263*5088Sab196087 } ITEM; 264*5088Sab196087 265*5088Sab196087 static ITEM *item; 266*5088Sab196087 static int item_cnt; 267*5088Sab196087 268*5088Sab196087 MODLIST_T *modlist; 269*5088Sab196087 int dispcnt; 270*5088Sab196087 size_t i; 271*5088Sab196087 elfeditGC_module_t *mod; 272*5088Sab196087 elfeditGC_cmd_t *cmd; 273*5088Sab196087 int minus_s = 0; 274*5088Sab196087 elfedit_getopt_state_t getopt_state; 275*5088Sab196087 ITEM *cur_item; 276*5088Sab196087 277*5088Sab196087 /* 278*5088Sab196087 * Process options. The only option accepted is -s, so we 279*5088Sab196087 * don't even have to check the idmask to know. 280*5088Sab196087 */ 281*5088Sab196087 elfedit_getopt_init(&getopt_state, &argc, &argv); 282*5088Sab196087 while (elfedit_getopt(&getopt_state) != NULL) 283*5088Sab196087 minus_s = 1; 284*5088Sab196087 285*5088Sab196087 /* 286*5088Sab196087 * This command can produce an arbitrary amount of output, so 287*5088Sab196087 * run a pager. 288*5088Sab196087 */ 289*5088Sab196087 elfedit_pager_init(); 290*5088Sab196087 291*5088Sab196087 if (argc == 0) { 292*5088Sab196087 if (minus_s) { 293*5088Sab196087 /* Force all modules to load so we have data */ 294*5088Sab196087 elfedit_load_modpath(); 295*5088Sab196087 for (modlist = state.modlist; modlist; 296*5088Sab196087 modlist = modlist->ml_next) { 297*5088Sab196087 cmd_help_showmod(modlist->ml_mod); 298*5088Sab196087 if (modlist->ml_next != NULL) { 299*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_STR_NL)); 300*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_STR_NL)); 301*5088Sab196087 } 302*5088Sab196087 } 303*5088Sab196087 return (ELFEDIT_CMDRET_NONE); 304*5088Sab196087 } 305*5088Sab196087 306*5088Sab196087 /* 307*5088Sab196087 * If no arguments are present, we display a simple 308*5088Sab196087 * "how to use help" tutorial, which will hopefully 309*5088Sab196087 * bootstrap the user into a position where they 310*5088Sab196087 * know how to run the help command, and then find 311*5088Sab196087 * what they're really after. 312*5088Sab196087 */ 313*5088Sab196087 elfedit_printf(MSG_INTL(MSG_SYS_HELP_HELP_NOARG)); 314*5088Sab196087 return (ELFEDIT_CMDRET_NONE); 315*5088Sab196087 } 316*5088Sab196087 317*5088Sab196087 318*5088Sab196087 /* 319*5088Sab196087 * As we process the arguments, we are willing to treat each 320*5088Sab196087 * one as either a module or a command: 321*5088Sab196087 * 1) An item without a colon can be a module, 322*5088Sab196087 * or a command from the sys: module. 323*5088Sab196087 * 2) An item with a colon, and no command part is 324*5088Sab196087 * a module, and it can also be the default 325*5088Sab196087 * command for the module, if it has one. We choose 326*5088Sab196087 * to only display the module info in this case, since 327*5088Sab196087 * the use of "" to represent the default command is 328*5088Sab196087 * an implementation detail, not a user-facing concept. 329*5088Sab196087 * 3) An item with a colon and a command part can only be 330*5088Sab196087 * a command. 331*5088Sab196087 * 332*5088Sab196087 * Note that there are cases where one argument can have two 333*5088Sab196087 * valid interpretations. In this case, we display them both. 334*5088Sab196087 * 335*5088Sab196087 * Pass over the arguments and determine how many distinct 336*5088Sab196087 * "things" we need to display. At the same time, force any 337*5088Sab196087 * needed modules to load so that the debug load messages won't 338*5088Sab196087 * show up in between the displayed items, and save the command 339*5088Sab196087 * and module definitions we will need to generate the output. 340*5088Sab196087 */ 341*5088Sab196087 if (argc > item_cnt) { 342*5088Sab196087 int n = (item_cnt == 0) ? INITIAL_ITEM_ALLOC : item_cnt; 343*5088Sab196087 344*5088Sab196087 while (n < argc) 345*5088Sab196087 n *= 2; 346*5088Sab196087 347*5088Sab196087 item = elfedit_realloc(MSG_INTL(MSG_ALLOC_HELPITEM), item, 348*5088Sab196087 n * sizeof (*item)); 349*5088Sab196087 item_cnt = n; 350*5088Sab196087 } 351*5088Sab196087 352*5088Sab196087 dispcnt = 0; 353*5088Sab196087 for (i = 0; i < argc; i++) { 354*5088Sab196087 const char *colon = strchr(argv[i], ':'); 355*5088Sab196087 356*5088Sab196087 if (colon == NULL) { /* No colon: sys: cmd or module */ 357*5088Sab196087 item[i].cmd = 358*5088Sab196087 elfedit_find_command(argv[i], 0, &item[i].cmd_mod); 359*5088Sab196087 if (item[i].cmd != NULL) 360*5088Sab196087 dispcnt++; 361*5088Sab196087 362*5088Sab196087 /* 363*5088Sab196087 * Also try to load it as a module. If a command 364*5088Sab196087 * was found, then this need not succeed. Otherwise, 365*5088Sab196087 * it has to be a module, and we cause an error 366*5088Sab196087 * to be issued if not. 367*5088Sab196087 */ 368*5088Sab196087 item[i].mod = elfedit_load_module(argv[i], 369*5088Sab196087 item[i].cmd == NULL, 0); 370*5088Sab196087 if (item[i].mod != NULL) 371*5088Sab196087 dispcnt++; 372*5088Sab196087 } else if (*(colon + 1) == '\0') { 373*5088Sab196087 /* Just colon: Module (and maybe default command) */ 374*5088Sab196087 char buf[ELFEDIT_MAXMODNAM + 1]; 375*5088Sab196087 const char *str = argv[i]; 376*5088Sab196087 int len = colon - str; 377*5088Sab196087 378*5088Sab196087 item[i].cmd = NULL; 379*5088Sab196087 /* Strip off the colon */ 380*5088Sab196087 if (len < sizeof (buf)) { 381*5088Sab196087 (void) strncpy(buf, str, len); 382*5088Sab196087 buf[len] = '\0'; 383*5088Sab196087 str = buf; 384*5088Sab196087 } 385*5088Sab196087 item[i].mod = elfedit_load_module(str, 1, 0); 386*5088Sab196087 dispcnt++; 387*5088Sab196087 } else { /* A command */ 388*5088Sab196087 item[i].cmd = 389*5088Sab196087 elfedit_find_command(argv[i], 1, &item[i].cmd_mod); 390*5088Sab196087 dispcnt++; 391*5088Sab196087 item[i].mod = NULL; 392*5088Sab196087 } 393*5088Sab196087 } 394*5088Sab196087 395*5088Sab196087 /* 396*5088Sab196087 * Having validated the items, loop over them again and produce 397*5088Sab196087 * the required help output. 398*5088Sab196087 */ 399*5088Sab196087 for (cur_item = item; argc--; argv++, cur_item++) { 400*5088Sab196087 401*5088Sab196087 402*5088Sab196087 /* Help for a module? */ 403*5088Sab196087 if (cur_item->mod != NULL) { 404*5088Sab196087 if (dispcnt > 1) 405*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_HLPFMT_MULTIHDR), 406*5088Sab196087 *argv); 407*5088Sab196087 cmd_help_showmod(cur_item->mod); 408*5088Sab196087 if ((dispcnt > 1) && (argc > 0)) 409*5088Sab196087 elfedit_printf(MSG_INTL(MSG_HLPFMT_MULTIEND), 410*5088Sab196087 argv[0], argv[1]); 411*5088Sab196087 /* An empty line after the last line of output */ 412*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_STR_NL)); 413*5088Sab196087 } 414*5088Sab196087 415*5088Sab196087 /* Help for a command? */ 416*5088Sab196087 if (cur_item->cmd == NULL) 417*5088Sab196087 continue; 418*5088Sab196087 cmd = cur_item->cmd; 419*5088Sab196087 mod = cur_item->cmd_mod; 420*5088Sab196087 if (dispcnt > 1) 421*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_HLPFMT_MULTIHDR), *argv); 422*5088Sab196087 423*5088Sab196087 /* If -s, display quick synopsis rather than the whole thing */ 424*5088Sab196087 if (minus_s) { 425*5088Sab196087 cmd_help_synopsis(mod, cmd); 426*5088Sab196087 continue; 427*5088Sab196087 } 428*5088Sab196087 429*5088Sab196087 elfedit_printf(MSG_INTL(MSG_HLPFMT_MOD), mod->mod_name, 430*5088Sab196087 (* mod->mod_i18nhdl_to_str)(mod->mod_desc)); 431*5088Sab196087 elfedit_printf(MSG_INTL(MSG_HLPFMT_NAME), 432*5088Sab196087 *cmd->cmd_name, 433*5088Sab196087 (* mod->mod_i18nhdl_to_str)(cmd->cmd_desc)); 434*5088Sab196087 elfedit_printf(MSG_INTL(MSG_HLPFMT_SYNOPSIS), 435*5088Sab196087 elfedit_format_command_usage(mod, cmd, 436*5088Sab196087 MSG_ORIG(MSG_STR_HLPUSEINDENT), 437*5088Sab196087 strlen(MSG_ORIG(MSG_STR_HLPINDENT)))); 438*5088Sab196087 /* If there are alias names, show them */ 439*5088Sab196087 if (cmd->cmd_name[1] != NULL) { 440*5088Sab196087 const char **alias = cmd->cmd_name + 1; 441*5088Sab196087 442*5088Sab196087 elfedit_printf(MSG_INTL(MSG_HLPFMT_ALIASES)); 443*5088Sab196087 do { 444*5088Sab196087 elfedit_printf( 445*5088Sab196087 MSG_ORIG(MSG_STR_HLPINDENT)); 446*5088Sab196087 elfedit_printf( 447*5088Sab196087 MSG_ORIG(MSG_FMT_MODCMD), 448*5088Sab196087 mod->mod_name, *alias); 449*5088Sab196087 if (**alias == '\0') 450*5088Sab196087 elfedit_printf( 451*5088Sab196087 MSG_INTL(MSG_HLPFMT_DEFCMD)); 452*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_STR_NL)); 453*5088Sab196087 alias++; 454*5088Sab196087 } while (*alias); 455*5088Sab196087 } 456*5088Sab196087 elfedit_printf(MSG_INTL(MSG_HLPFMT_DESC)); 457*5088Sab196087 write_help_str( 458*5088Sab196087 (* mod->mod_i18nhdl_to_str)(cmd->cmd_help), 459*5088Sab196087 MSG_ORIG(MSG_STR_HLPINDENT)); 460*5088Sab196087 if (cmd->cmd_args != NULL) 461*5088Sab196087 write_optarg(mod, MSG_INTL(MSG_HLPFMT_ARGS), 462*5088Sab196087 cmd->cmd_args); 463*5088Sab196087 if (cmd->cmd_opt != NULL) 464*5088Sab196087 write_optarg(mod, MSG_INTL(MSG_HLPFMT_OPT), 465*5088Sab196087 cmd->cmd_opt); 466*5088Sab196087 if ((dispcnt > 1) && (argc > 0)) 467*5088Sab196087 elfedit_printf(MSG_INTL(MSG_HLPFMT_MULTIEND), 468*5088Sab196087 argv[0], argv[1]); 469*5088Sab196087 /* An empty line after the last line of output */ 470*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_STR_NL)); 471*5088Sab196087 } 472*5088Sab196087 473*5088Sab196087 return (ELFEDIT_CMDRET_NONE); 474*5088Sab196087 475*5088Sab196087 #undef INITIAL_ITEM_ALLOC 476*5088Sab196087 } 477*5088Sab196087 478*5088Sab196087 479*5088Sab196087 /* 480*5088Sab196087 * Command completion function for sys:help 481*5088Sab196087 */ 482*5088Sab196087 /*ARGSUSED*/ 483*5088Sab196087 static void 484*5088Sab196087 cpl_help(void *obj_state, void *cpldata, int argc, const char *argv[], 485*5088Sab196087 int num_opt) 486*5088Sab196087 { 487*5088Sab196087 /* 488*5088Sab196087 * The arguments can be any module or command. Supplying the 489*5088Sab196087 * commands implicitly supplies the modules too. 490*5088Sab196087 */ 491*5088Sab196087 elfedit_cpl_command(cpldata); 492*5088Sab196087 } 493*5088Sab196087 494*5088Sab196087 495*5088Sab196087 /* 496*5088Sab196087 * Implementation of sys:load 497*5088Sab196087 */ 498*5088Sab196087 /*ARGSUSED*/ 499*5088Sab196087 static elfedit_cmdret_t 500*5088Sab196087 cmd_load(void *obj_state, int argc, const char *argv[]) 501*5088Sab196087 { 502*5088Sab196087 elfedit_getopt_state_t getopt_state; 503*5088Sab196087 elfedit_getopt_ret_t *getopt_ret; 504*5088Sab196087 struct stat statbuf; 505*5088Sab196087 506*5088Sab196087 elfedit_getopt_init(&getopt_state, &argc, &argv); 507*5088Sab196087 while ((getopt_ret = elfedit_getopt(&getopt_state)) != NULL) { 508*5088Sab196087 switch (getopt_ret->gor_idmask) { 509*5088Sab196087 case SYS_OPT_F_ALL: 510*5088Sab196087 elfedit_load_modpath(); 511*5088Sab196087 break; 512*5088Sab196087 } 513*5088Sab196087 } 514*5088Sab196087 515*5088Sab196087 /* For each remaining argument, load them individually */ 516*5088Sab196087 for (; argc-- > 0; argv++) { 517*5088Sab196087 /* Is it a directory? Load everything in it */ 518*5088Sab196087 if ((stat(*argv, &statbuf) == 0) && 519*5088Sab196087 (statbuf.st_mode & S_IFDIR)) { 520*5088Sab196087 elfedit_load_moddir(*argv, 1, 1); 521*5088Sab196087 } else { /* Not a directory. Normal load */ 522*5088Sab196087 (void) elfedit_load_module(*argv, 1, 1); 523*5088Sab196087 } 524*5088Sab196087 } 525*5088Sab196087 526*5088Sab196087 return (0); 527*5088Sab196087 } 528*5088Sab196087 529*5088Sab196087 530*5088Sab196087 /* 531*5088Sab196087 * Command completion function for sys:load 532*5088Sab196087 */ 533*5088Sab196087 /*ARGSUSED*/ 534*5088Sab196087 static void 535*5088Sab196087 cpl_load(void *obj_state, void *cpldata, int argc, const char *argv[], 536*5088Sab196087 int num_opt) 537*5088Sab196087 { 538*5088Sab196087 /* 539*5088Sab196087 * Module names. Note that this causes elfedit to load all 540*5088Sab196087 * of the modules, which probably makes the current load 541*5088Sab196087 * operation unnecessary. This could be improved, but I don't 542*5088Sab196087 * see it as worth the complexity. Explicit load calls are 543*5088Sab196087 * rare, and the user will usually not use command completion. 544*5088Sab196087 */ 545*5088Sab196087 elfedit_cpl_module(cpldata, 1); 546*5088Sab196087 } 547*5088Sab196087 548*5088Sab196087 549*5088Sab196087 /* 550*5088Sab196087 * Implementation of sys:quit 551*5088Sab196087 */ 552*5088Sab196087 /*ARGSUSED*/ 553*5088Sab196087 static elfedit_cmdret_t 554*5088Sab196087 cmd_quit(void *obj_state, int argc, const char *argv[]) 555*5088Sab196087 { 556*5088Sab196087 elfedit_getopt_state_t getopt_state; 557*5088Sab196087 elfedit_getopt_ret_t *getopt_ret; 558*5088Sab196087 int force = 0; 559*5088Sab196087 const char *file; 560*5088Sab196087 int fd; 561*5088Sab196087 Elf *elf; 562*5088Sab196087 563*5088Sab196087 elfedit_getopt_init(&getopt_state, &argc, &argv); 564*5088Sab196087 while ((getopt_ret = elfedit_getopt(&getopt_state)) != NULL) { 565*5088Sab196087 switch (getopt_ret->gor_idmask) { 566*5088Sab196087 case SYS_OPT_F_FORCE: 567*5088Sab196087 force = 1; 568*5088Sab196087 break; 569*5088Sab196087 } 570*5088Sab196087 } 571*5088Sab196087 if (argc != 0) 572*5088Sab196087 elfedit_command_usage(); 573*5088Sab196087 574*5088Sab196087 if (state.file.present) { 575*5088Sab196087 /* 576*5088Sab196087 * If session is not READONLY, then refuse to quit if file 577*5088Sab196087 * needs flushing and -f option was not used. 578*5088Sab196087 */ 579*5088Sab196087 if (!(state.flags & ELFEDIT_F_READONLY) && state.file.dirty && 580*5088Sab196087 !force) 581*5088Sab196087 elfedit_msg(ELFEDIT_MSG_ERR, 582*5088Sab196087 MSG_INTL(MSG_ERR_NODIRTYQUIT)); 583*5088Sab196087 584*5088Sab196087 get_obj_state_info(obj_state, &file, &fd, &elf); 585*5088Sab196087 (void) close(fd); 586*5088Sab196087 (void) elf_end(elf); 587*5088Sab196087 free(obj_state); 588*5088Sab196087 } 589*5088Sab196087 590*5088Sab196087 elfedit_exit(0); 591*5088Sab196087 /*NOTREACHED*/ 592*5088Sab196087 return (0); 593*5088Sab196087 } 594*5088Sab196087 595*5088Sab196087 596*5088Sab196087 /* 597*5088Sab196087 * Implementation of sys:status 598*5088Sab196087 */ 599*5088Sab196087 /*ARGSUSED*/ 600*5088Sab196087 static elfedit_cmdret_t 601*5088Sab196087 cmd_status(void *obj_state, int argc, const char *argv[]) 602*5088Sab196087 { 603*5088Sab196087 MODLIST_T *modlist; 604*5088Sab196087 const char *s; 605*5088Sab196087 size_t i; 606*5088Sab196087 607*5088Sab196087 if (argc > 0) 608*5088Sab196087 elfedit_command_usage(); 609*5088Sab196087 610*5088Sab196087 /* 611*5088Sab196087 * This command can produce an arbitrary amount of output, so 612*5088Sab196087 * run a pager. 613*5088Sab196087 */ 614*5088Sab196087 elfedit_pager_init(); 615*5088Sab196087 616*5088Sab196087 /* Files */ 617*5088Sab196087 if (state.file.present == 0) { 618*5088Sab196087 elfedit_printf(MSG_INTL(MSG_HLPFMT_INFILENONE)); 619*5088Sab196087 } else if (state.flags & ELFEDIT_F_READONLY) { 620*5088Sab196087 elfedit_printf(MSG_INTL(MSG_HLPFMT_INFILERO), 621*5088Sab196087 state.file.infile); 622*5088Sab196087 } else { 623*5088Sab196087 elfedit_printf(MSG_INTL(MSG_HLPFMT_INFILE), state.file.infile); 624*5088Sab196087 elfedit_printf(MSG_INTL(MSG_HLPFMT_OUTFILE), 625*5088Sab196087 state.file.outfile); 626*5088Sab196087 } 627*5088Sab196087 if (state.file.dirty) 628*5088Sab196087 elfedit_printf(MSG_INTL(MSG_HLPFMT_CNGPENDING)); 629*5088Sab196087 630*5088Sab196087 /* Option Variables */ 631*5088Sab196087 elfedit_printf(MSG_INTL(MSG_HLPFMT_VARHDR)); 632*5088Sab196087 elfedit_printf(MSG_INTL(MSG_HLPFMT_AFLG), 633*5088Sab196087 (state.flags & ELFEDIT_F_AUTOPRINT) ? MSG_ORIG(MSG_STR_ON) : 634*5088Sab196087 MSG_ORIG(MSG_STR_OFF)); 635*5088Sab196087 elfedit_printf(MSG_INTL(MSG_HLPFMT_DFLG), 636*5088Sab196087 (state.flags & ELFEDIT_F_DEBUG) ? MSG_ORIG(MSG_STR_ON) : 637*5088Sab196087 MSG_ORIG(MSG_STR_OFF)); 638*5088Sab196087 elfedit_printf(MSG_INTL(MSG_HLPFMT_OFLG), 639*5088Sab196087 elfedit_atoconst_value_to_str(ELFEDIT_CONST_OUTSTYLE, 640*5088Sab196087 state.outstyle, 1)); 641*5088Sab196087 642*5088Sab196087 /* Module Load Path */ 643*5088Sab196087 elfedit_printf(MSG_INTL(MSG_HLPFMT_PATHHDR)); 644*5088Sab196087 for (i = 0; i < state.modpath.n; i++) 645*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_HLPFMT_PATHELT), 646*5088Sab196087 state.modpath.seg[i]); 647*5088Sab196087 648*5088Sab196087 /* Currently Loaded Modules */ 649*5088Sab196087 elfedit_printf(MSG_INTL(MSG_HLPFMT_MODHDR)); 650*5088Sab196087 for (modlist = state.modlist; modlist; 651*5088Sab196087 modlist = modlist->ml_next) { 652*5088Sab196087 s = modlist->ml_path ? modlist->ml_path : 653*5088Sab196087 MSG_INTL(MSG_FMT_BUILTIN); 654*5088Sab196087 elfedit_printf(MSG_ORIG(MSG_HLPFMT_NAMDSCCOL), 655*5088Sab196087 modlist->ml_mod->mod_name, s); 656*5088Sab196087 } 657*5088Sab196087 658*5088Sab196087 return (ELFEDIT_CMDRET_NONE); 659*5088Sab196087 } 660*5088Sab196087 661*5088Sab196087 /* 662*5088Sab196087 * Implementation of sys:set 663*5088Sab196087 */ 664*5088Sab196087 /*ARGSUSED*/ 665*5088Sab196087 static elfedit_cmdret_t 666*5088Sab196087 cmd_set(void *obj_state, int argc, const char *argv[]) 667*5088Sab196087 { 668*5088Sab196087 if ((argc != 2) || (strlen(argv[0]) > 1)) 669*5088Sab196087 elfedit_command_usage(); 670*5088Sab196087 671*5088Sab196087 switch (**argv) { 672*5088Sab196087 case 'a': 673*5088Sab196087 case 'A': 674*5088Sab196087 if (elfedit_atobool(argv[1], MSG_INTL(MSG_SYSSET_A))) 675*5088Sab196087 state.flags |= ELFEDIT_F_AUTOPRINT; 676*5088Sab196087 else 677*5088Sab196087 state.flags &= ~ELFEDIT_F_AUTOPRINT; 678*5088Sab196087 break; 679*5088Sab196087 680*5088Sab196087 case 'd': 681*5088Sab196087 case 'D': 682*5088Sab196087 if (elfedit_atobool(argv[1], MSG_INTL(MSG_SYSSET_D))) 683*5088Sab196087 state.flags |= ELFEDIT_F_DEBUG; 684*5088Sab196087 else 685*5088Sab196087 state.flags &= ~ELFEDIT_F_DEBUG; 686*5088Sab196087 break; 687*5088Sab196087 688*5088Sab196087 case 'o': 689*5088Sab196087 case 'O': 690*5088Sab196087 if (elfedit_atooutstyle(argv[1], &state.outstyle) == 0) 691*5088Sab196087 elfedit_msg(ELFEDIT_MSG_ERR, 692*5088Sab196087 MSG_INTL(MSG_ERR_BADOSTYLE), argv[1]); 693*5088Sab196087 break; 694*5088Sab196087 695*5088Sab196087 default: 696*5088Sab196087 elfedit_command_usage(); 697*5088Sab196087 } 698*5088Sab196087 699*5088Sab196087 return (0); 700*5088Sab196087 } 701*5088Sab196087 702*5088Sab196087 703*5088Sab196087 /* 704*5088Sab196087 * Command completion function for sys:set 705*5088Sab196087 */ 706*5088Sab196087 /*ARGSUSED*/ 707*5088Sab196087 static void 708*5088Sab196087 cpl_set(void *obj_state, void *cpldata, int argc, const char *argv[], 709*5088Sab196087 int num_opt) 710*5088Sab196087 { 711*5088Sab196087 const char *s; 712*5088Sab196087 713*5088Sab196087 /* 714*5088Sab196087 * This command doesn't accept options, so num_opt should be 715*5088Sab196087 * 0. This is a defensive measure, in case that should change. 716*5088Sab196087 */ 717*5088Sab196087 argc -= num_opt; 718*5088Sab196087 argv += num_opt; 719*5088Sab196087 720*5088Sab196087 if ((argc < 1) || (argc > 2)) 721*5088Sab196087 return; 722*5088Sab196087 723*5088Sab196087 if (argc == 1) { /* The first argument is a variable letter */ 724*5088Sab196087 elfedit_cpl_match(cpldata, MSG_ORIG(MSG_STR_A), 1); 725*5088Sab196087 elfedit_cpl_match(cpldata, MSG_ORIG(MSG_STR_D), 1); 726*5088Sab196087 elfedit_cpl_match(cpldata, MSG_ORIG(MSG_STR_O), 1); 727*5088Sab196087 elfedit_cpl_match(cpldata, MSG_ORIG(MSG_STR_W), 1); 728*5088Sab196087 return; 729*5088Sab196087 } 730*5088Sab196087 731*5088Sab196087 /* We're dealing with the second argument, the value */ 732*5088Sab196087 s = argv[0]; 733*5088Sab196087 if (strlen(s) > 1) /* One letter variables */ 734*5088Sab196087 return; 735*5088Sab196087 switch (*s) { 736*5088Sab196087 case 'a': /* Booleans */ 737*5088Sab196087 case 'A': 738*5088Sab196087 case 'd': 739*5088Sab196087 case 'D': 740*5088Sab196087 case 'w': 741*5088Sab196087 case 'W': 742*5088Sab196087 /* The second argument is a boolean */ 743*5088Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_BOOL); 744*5088Sab196087 745*5088Sab196087 /* The numbers are not symbolic, but we want them in the list */ 746*5088Sab196087 elfedit_cpl_match(cpldata, MSG_ORIG(MSG_STR_0), 1); 747*5088Sab196087 elfedit_cpl_match(cpldata, MSG_ORIG(MSG_STR_1), 1); 748*5088Sab196087 break; 749*5088Sab196087 750*5088Sab196087 case 'o': /* Output style */ 751*5088Sab196087 case 'O': 752*5088Sab196087 elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_OUTSTYLE); 753*5088Sab196087 break; 754*5088Sab196087 } 755*5088Sab196087 } 756*5088Sab196087 757*5088Sab196087 758*5088Sab196087 /* 759*5088Sab196087 * Implementation of sys:unload 760*5088Sab196087 */ 761*5088Sab196087 /*ARGSUSED*/ 762*5088Sab196087 static elfedit_cmdret_t 763*5088Sab196087 cmd_unload(void *obj_state, int argc, const char *argv[]) 764*5088Sab196087 { 765*5088Sab196087 elfedit_getopt_state_t getopt_state; 766*5088Sab196087 elfedit_getopt_ret_t *getopt_ret; 767*5088Sab196087 MODLIST_T *moddef; 768*5088Sab196087 int do_all = 0; 769*5088Sab196087 770*5088Sab196087 elfedit_getopt_init(&getopt_state, &argc, &argv); 771*5088Sab196087 while ((getopt_ret = elfedit_getopt(&getopt_state)) != NULL) { 772*5088Sab196087 switch (getopt_ret->gor_idmask) { 773*5088Sab196087 case SYS_OPT_F_ALL: 774*5088Sab196087 do_all = 1; 775*5088Sab196087 break; 776*5088Sab196087 } 777*5088Sab196087 } 778*5088Sab196087 779*5088Sab196087 /* 780*5088Sab196087 * If -a is specified, unload everything except builtins. Don't 781*5088Sab196087 * allow plain arguments in this case because there is nothing 782*5088Sab196087 * left to unload after -a. 783*5088Sab196087 */ 784*5088Sab196087 if (do_all) { 785*5088Sab196087 if (argc > 0) 786*5088Sab196087 elfedit_command_usage(); 787*5088Sab196087 /* 788*5088Sab196087 * Until we run out of non-builtin modules, take the first 789*5088Sab196087 * one from the list and unload it. Each removal alters 790*5088Sab196087 * the list, so we always start at the beginning, but this 791*5088Sab196087 * is efficient since we always remove the first available item 792*5088Sab196087 */ 793*5088Sab196087 while (state.modlist != NULL) { 794*5088Sab196087 for (moddef = state.modlist; moddef != NULL; 795*5088Sab196087 moddef = moddef->ml_next) 796*5088Sab196087 if (moddef->ml_dl_hdl != NULL) break; 797*5088Sab196087 798*5088Sab196087 /* If we made it to the end, then the list is empty */ 799*5088Sab196087 if (moddef == NULL) 800*5088Sab196087 break; 801*5088Sab196087 802*5088Sab196087 elfedit_unload_module(moddef->ml_mod->mod_name); 803*5088Sab196087 } 804*5088Sab196087 return (0); 805*5088Sab196087 } 806*5088Sab196087 807*5088Sab196087 /* Unload each module individually */ 808*5088Sab196087 for (; argc-- > 0; argv++) 809*5088Sab196087 elfedit_unload_module(*argv); 810*5088Sab196087 811*5088Sab196087 return (0); 812*5088Sab196087 } 813*5088Sab196087 814*5088Sab196087 815*5088Sab196087 /* 816*5088Sab196087 * Command completion function for sys:unload 817*5088Sab196087 */ 818*5088Sab196087 /*ARGSUSED*/ 819*5088Sab196087 static void 820*5088Sab196087 cpl_unload(void *obj_state, void *cpldata, int argc, const char *argv[], 821*5088Sab196087 int num_opt) 822*5088Sab196087 { 823*5088Sab196087 /* 824*5088Sab196087 * Module names. Don't allow elfedit to load all the modules, 825*5088Sab196087 * as the only modules we want to unload are those already 826*5088Sab196087 * in memory. 827*5088Sab196087 */ 828*5088Sab196087 elfedit_cpl_module(cpldata, 0); 829*5088Sab196087 } 830*5088Sab196087 831*5088Sab196087 832*5088Sab196087 /* 833*5088Sab196087 * Implementation of sys:write 834*5088Sab196087 */ 835*5088Sab196087 /*ARGSUSED2*/ 836*5088Sab196087 static elfedit_cmdret_t 837*5088Sab196087 cmd_write(void *obj_state, int argc, const char *argv[]) 838*5088Sab196087 { 839*5088Sab196087 const char *file; 840*5088Sab196087 int fd; 841*5088Sab196087 Elf *elf; 842*5088Sab196087 843*5088Sab196087 if (argc != 0) 844*5088Sab196087 elfedit_command_usage(); 845*5088Sab196087 846*5088Sab196087 if (state.file.present != 0) { 847*5088Sab196087 if (state.flags & ELFEDIT_F_READONLY) 848*5088Sab196087 elfedit_msg(ELFEDIT_MSG_ERR, 849*5088Sab196087 MSG_INTL(MSG_ERR_READONLY)); 850*5088Sab196087 851*5088Sab196087 get_obj_state_info(obj_state, &file, &fd, &elf); 852*5088Sab196087 if (elf_update(elf, ELF_C_WRITE) == -1) 853*5088Sab196087 elfedit_msg(ELFEDIT_MSG_ERR, MSG_INTL(MSG_ERR_LIBELF), 854*5088Sab196087 file, MSG_ORIG(MSG_ELF_UPDATE), 855*5088Sab196087 elf_errmsg(elf_errno())); 856*5088Sab196087 857*5088Sab196087 /* 858*5088Sab196087 * An update has succeeded for this file, so revoke the need 859*5088Sab196087 * to unlink it on exit. 860*5088Sab196087 */ 861*5088Sab196087 state.file.unlink_on_exit = 0; 862*5088Sab196087 } 863*5088Sab196087 864*5088Sab196087 return (ELFEDIT_CMDRET_FLUSH); 865*5088Sab196087 } 866*5088Sab196087 867*5088Sab196087 868*5088Sab196087 869*5088Sab196087 870*5088Sab196087 871*5088Sab196087 /*ARGSUSED*/ 872*5088Sab196087 MODLIST_T * 873*5088Sab196087 elfedit_sys_init(elfedit_module_version_t version) 874*5088Sab196087 { 875*5088Sab196087 /* sys:help */ 876*5088Sab196087 static const char *name_help[] = { MSG_ORIG(MSG_SYS_CMD_HELP), 877*5088Sab196087 MSG_ORIG(MSG_SYS_CMD_HELP_A1), MSG_ORIG(MSG_SYS_CMD_HELP_A2), 878*5088Sab196087 NULL }; 879*5088Sab196087 static elfedit_cmd_optarg_t opt_help[] = { 880*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_S), 881*5088Sab196087 /* MSG_INTL(MSG_SYS_OPTDESC_HELP_S) */ 882*5088Sab196087 ELFEDIT_I18NHDL(MSG_SYS_OPTDESC_HELP_S), 0, 883*5088Sab196087 SYS_OPT_F_SYNOPSIS, 0 }, 884*5088Sab196087 { NULL } 885*5088Sab196087 }; 886*5088Sab196087 static elfedit_cmd_optarg_t arg_help[] = { 887*5088Sab196087 { MSG_ORIG(MSG_STR_ARG), 888*5088Sab196087 /* MSG_INTL(MSG_ARGDESC_HELP_ARG) */ 889*5088Sab196087 ELFEDIT_I18NHDL(MSG_ARGDESC_HELP_ARG), 890*5088Sab196087 ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT }, 891*5088Sab196087 { NULL } 892*5088Sab196087 }; 893*5088Sab196087 894*5088Sab196087 /* sys:load */ 895*5088Sab196087 static const char *name_load[] = { 896*5088Sab196087 MSG_ORIG(MSG_SYS_CMD_LOAD), NULL }; 897*5088Sab196087 static elfedit_cmd_optarg_t opt_load[] = { 898*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_A), 899*5088Sab196087 /* MSG_INTL(MSG_SYS_OPTDESC_LOAD_A) */ 900*5088Sab196087 ELFEDIT_I18NHDL(MSG_SYS_OPTDESC_LOAD_A), 0, 901*5088Sab196087 SYS_OPT_F_ALL, 0 }, 902*5088Sab196087 { NULL } 903*5088Sab196087 }; 904*5088Sab196087 static elfedit_cmd_optarg_t arg_load[] = { 905*5088Sab196087 { MSG_ORIG(MSG_STR_MODNAME), 906*5088Sab196087 /* MSG_INTL(MSG_ARGDESC_LOAD_MODNAME) */ 907*5088Sab196087 ELFEDIT_I18NHDL(MSG_ARGDESC_LOAD_MODNAME), 908*5088Sab196087 ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT }, 909*5088Sab196087 { NULL } 910*5088Sab196087 }; 911*5088Sab196087 912*5088Sab196087 /* sys:quit */ 913*5088Sab196087 static const char *name_quit[] = { MSG_ORIG(MSG_SYS_CMD_QUIT), 914*5088Sab196087 MSG_ORIG(MSG_SYS_CMD_QUIT_A1), MSG_ORIG(MSG_SYS_CMD_QUIT_A2), 915*5088Sab196087 NULL }; 916*5088Sab196087 static elfedit_cmd_optarg_t opt_quit[] = { 917*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_F), 918*5088Sab196087 /* MSG_INTL(MSG_SYS_OPTDESC_QUIT_F) */ 919*5088Sab196087 ELFEDIT_I18NHDL(MSG_SYS_OPTDESC_QUIT_F), 0, 920*5088Sab196087 SYS_OPT_F_FORCE, 0 }, 921*5088Sab196087 { NULL } 922*5088Sab196087 }; 923*5088Sab196087 924*5088Sab196087 /* sys:status */ 925*5088Sab196087 static const char *name_status[] = { 926*5088Sab196087 MSG_ORIG(MSG_SYS_CMD_STATUS), NULL }; 927*5088Sab196087 928*5088Sab196087 /* sys:set */ 929*5088Sab196087 static const char *name_set[] = { 930*5088Sab196087 MSG_ORIG(MSG_SYS_CMD_SET), NULL }; 931*5088Sab196087 static elfedit_cmd_optarg_t arg_set[] = { 932*5088Sab196087 { MSG_ORIG(MSG_STR_OPTION), 933*5088Sab196087 /* MSG_INTL(MSG_ARGDESC_SET_OPTION) */ 934*5088Sab196087 ELFEDIT_I18NHDL(MSG_ARGDESC_SET_OPTION), 0 }, 935*5088Sab196087 { MSG_ORIG(MSG_STR_VALUE), 936*5088Sab196087 /* MSG_INTL(MSG_ARGDESC_SET_VALUE) */ 937*5088Sab196087 ELFEDIT_I18NHDL(MSG_ARGDESC_SET_VALUE), 0 }, 938*5088Sab196087 { NULL } 939*5088Sab196087 }; 940*5088Sab196087 941*5088Sab196087 /* sys:unload */ 942*5088Sab196087 static const char *name_unload[] = { 943*5088Sab196087 MSG_ORIG(MSG_SYS_CMD_UNLOAD), NULL }; 944*5088Sab196087 static elfedit_cmd_optarg_t opt_unload[] = { 945*5088Sab196087 { MSG_ORIG(MSG_STR_MINUS_A), 946*5088Sab196087 /* MSG_INTL(MSG_SYS_OPTDESC_UNLOAD_A) */ 947*5088Sab196087 ELFEDIT_I18NHDL(MSG_SYS_OPTDESC_UNLOAD_A), 0, 948*5088Sab196087 SYS_OPT_F_ALL, 0}, 949*5088Sab196087 { NULL } 950*5088Sab196087 }; 951*5088Sab196087 static elfedit_cmd_optarg_t arg_unload[] = { 952*5088Sab196087 { MSG_ORIG(MSG_STR_MODNAME), 953*5088Sab196087 /* MSG_INTL(MSG_ARGDESC_UNLOAD_MODNAME) */ 954*5088Sab196087 ELFEDIT_I18NHDL(MSG_ARGDESC_UNLOAD_MODNAME), 955*5088Sab196087 ELFEDIT_CMDOA_F_OPT | ELFEDIT_CMDOA_F_MULT }, 956*5088Sab196087 { NULL } 957*5088Sab196087 }; 958*5088Sab196087 959*5088Sab196087 /* sys:write */ 960*5088Sab196087 static const char *name_write[] = { MSG_ORIG(MSG_SYS_CMD_WRITE), 961*5088Sab196087 MSG_ORIG(MSG_SYS_CMD_WRITE_A1), MSG_ORIG(MSG_SYS_CMD_WRITE_A2), 962*5088Sab196087 NULL }; 963*5088Sab196087 964*5088Sab196087 static elfedit_cmd_t cmds[] = { 965*5088Sab196087 /* sym:help */ 966*5088Sab196087 { (elfedit_cmd_func_t *)cmd_help, 967*5088Sab196087 (elfedit_cmdcpl_func_t *)cpl_help, name_help, 968*5088Sab196087 /* MSG_INTL(MSG_SYS_DESC_HELP) */ 969*5088Sab196087 ELFEDIT_I18NHDL(MSG_SYS_DESC_HELP), 970*5088Sab196087 /* MSG_INTL(MSG_SYS_HELP_HELP) */ 971*5088Sab196087 ELFEDIT_I18NHDL(MSG_SYS_HELP_HELP), 972*5088Sab196087 opt_help, arg_help }, 973*5088Sab196087 974*5088Sab196087 /* sym:load */ 975*5088Sab196087 { (elfedit_cmd_func_t *)cmd_load, 976*5088Sab196087 (elfedit_cmdcpl_func_t *)cpl_load, name_load, 977*5088Sab196087 /* MSG_INTL(MSG_SYS_DESC_LOAD) */ 978*5088Sab196087 ELFEDIT_I18NHDL(MSG_SYS_DESC_LOAD), 979*5088Sab196087 /* MSG_INTL(MSG_SYS_HELP_LOAD) */ 980*5088Sab196087 ELFEDIT_I18NHDL(MSG_SYS_HELP_LOAD), 981*5088Sab196087 opt_load, arg_load }, 982*5088Sab196087 983*5088Sab196087 /* sym:quit */ 984*5088Sab196087 { (elfedit_cmd_func_t *)cmd_quit, NULL, name_quit, 985*5088Sab196087 /* MSG_INTL(MSG_SYS_DESC_QUIT) */ 986*5088Sab196087 ELFEDIT_I18NHDL(MSG_SYS_DESC_QUIT), 987*5088Sab196087 /* MSG_INTL(MSG_SYS_HELP_QUIT) */ 988*5088Sab196087 ELFEDIT_I18NHDL(MSG_SYS_HELP_QUIT), 989*5088Sab196087 opt_quit, NULL }, 990*5088Sab196087 991*5088Sab196087 /* sym:status */ 992*5088Sab196087 { (elfedit_cmd_func_t *)cmd_status, NULL, name_status, 993*5088Sab196087 /* MSG_INTL(MSG_SYS_DESC_STATUS) */ 994*5088Sab196087 ELFEDIT_I18NHDL(MSG_SYS_DESC_STATUS), 995*5088Sab196087 /* MSG_INTL(MSG_SYS_HELP_STATUS) */ 996*5088Sab196087 ELFEDIT_I18NHDL(MSG_SYS_HELP_STATUS), 997*5088Sab196087 NULL, NULL }, 998*5088Sab196087 999*5088Sab196087 /* sym:set */ 1000*5088Sab196087 { (elfedit_cmd_func_t *)cmd_set, 1001*5088Sab196087 (elfedit_cmdcpl_func_t *)cpl_set, name_set, 1002*5088Sab196087 /* MSG_INTL(MSG_SYS_DESC_SET) */ 1003*5088Sab196087 ELFEDIT_I18NHDL(MSG_SYS_DESC_SET), 1004*5088Sab196087 /* MSG_INTL(MSG_SYS_HELP_SET) */ 1005*5088Sab196087 ELFEDIT_I18NHDL(MSG_SYS_HELP_SET), 1006*5088Sab196087 NULL, arg_set }, 1007*5088Sab196087 1008*5088Sab196087 /* sym:unload */ 1009*5088Sab196087 { (elfedit_cmd_func_t *)cmd_unload, 1010*5088Sab196087 (elfedit_cmdcpl_func_t *)cpl_unload, name_unload, 1011*5088Sab196087 /* MSG_INTL(MSG_SYS_DESC_UNLOAD) */ 1012*5088Sab196087 ELFEDIT_I18NHDL(MSG_SYS_DESC_UNLOAD), 1013*5088Sab196087 /* MSG_INTL(MSG_SYS_HELP_UNLOAD) */ 1014*5088Sab196087 ELFEDIT_I18NHDL(MSG_SYS_HELP_UNLOAD), 1015*5088Sab196087 opt_unload, arg_unload }, 1016*5088Sab196087 1017*5088Sab196087 /* sym:write */ 1018*5088Sab196087 { (elfedit_cmd_func_t *)cmd_write, NULL, name_write, 1019*5088Sab196087 /* MSG_INTL(MSG_SYS_DESC_WRITE) */ 1020*5088Sab196087 ELFEDIT_I18NHDL(MSG_SYS_DESC_WRITE), 1021*5088Sab196087 /* MSG_INTL(MSG_SYS_HELP_WRITE) */ 1022*5088Sab196087 ELFEDIT_I18NHDL(MSG_SYS_HELP_WRITE), 1023*5088Sab196087 NULL, NULL}, 1024*5088Sab196087 1025*5088Sab196087 { NULL } 1026*5088Sab196087 }; 1027*5088Sab196087 1028*5088Sab196087 static elfedit_module_t module = { 1029*5088Sab196087 ELFEDIT_VER_CURRENT, MSG_ORIG(MSG_MOD_SYS), 1030*5088Sab196087 /* MSG_INTL(MSG_MOD_SYS_DESC) */ 1031*5088Sab196087 ELFEDIT_I18NHDL(MSG_MOD_SYS_DESC), 1032*5088Sab196087 cmds, mod_i18nhdl_to_str }; 1033*5088Sab196087 1034*5088Sab196087 static MODLIST_T moddef = { 1035*5088Sab196087 NULL, /* next */ 1036*5088Sab196087 (elfeditGC_module_t *)&module, /* Module definition */ 1037*5088Sab196087 NULL, /* Didn't dlopen() it, so NULL handle */ 1038*5088Sab196087 NULL /* Didn't dlopen() it, so no file path */ 1039*5088Sab196087 }; 1040*5088Sab196087 1041*5088Sab196087 return (&moddef); 1042*5088Sab196087 } 1043