From ce01d13e98db612f0f61acde6c285c259f33374c Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Wed, 20 Apr 2005 21:05:45 +0000 Subject: [PATCH] move option parsing and command handling to its own file for reuse --- ipmitool/include/ipmitool/ipmi_main.h | 46 +++ ipmitool/lib/ipmi_main.c | 552 ++++++++++++++++++++++++++ ipmitool/src/ipmitool.c | 465 +--------------------- 3 files changed, 612 insertions(+), 451 deletions(-) create mode 100644 ipmitool/include/ipmitool/ipmi_main.h create mode 100644 ipmitool/lib/ipmi_main.c diff --git a/ipmitool/include/ipmitool/ipmi_main.h b/ipmitool/include/ipmitool/ipmi_main.h new file mode 100644 index 0000000..f9c7603 --- /dev/null +++ b/ipmitool/include/ipmitool/ipmi_main.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. + * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE + * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING + * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL + * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, + * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR + * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF + * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + */ + +#ifndef IPMI_MAIN_H +#define IPMI_MAIN_H + +#include + +int ipmi_main(int argc, char ** argv, struct ipmi_cmd * cmdlist, struct ipmi_intf_support * intflist); +void ipmi_cmd_print(struct ipmi_intf * intf); +int ipmi_cmd_run(struct ipmi_intf * intf, char * name, int argc, char ** argv); + +#endif /* IPMI_MAIN_H */ diff --git a/ipmitool/lib/ipmi_main.c b/ipmitool/lib/ipmi_main.c new file mode 100644 index 0000000..2a4fc46 --- /dev/null +++ b/ipmitool/lib/ipmi_main.c @@ -0,0 +1,552 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. + * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE + * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING + * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL + * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, + * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR + * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF + * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef __sun_hide_options +# define OPTION_STRING "I:hVvcH:f:U:p:" +#else +# define OPTION_STRING "I:hVvcgsEao:H:P:f:U:p:C:L:A:t:m:" +#endif + +extern int verbose; +extern int csv_output; +extern const struct valstr ipmi_privlvl_vals[]; +extern const struct valstr ipmi_authtype_session_vals[]; + +/* defined in ipmishell.c */ +#ifdef HAVE_READLINE +extern int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv); +#endif +extern int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv); +extern int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv); + + +/* ipmi_password_file_read - Open file and read password from it + * + * @filename: file name to read from + * + * returns pointer to allocated buffer containing password + * (caller is expected to free when finished) + * returns NULL on error + */ +static char * +ipmi_password_file_read(char * filename) +{ + FILE * fp; + char * pass = NULL; + int l; + + pass = malloc(16); + if (pass == NULL) { + lprintf(LOG_ERR, "ipmitool: malloc failure"); + return NULL; + } + + fp = ipmi_open_file_read((const char *)filename); + if (fp == NULL) { + lprintf(LOG_ERR, "Unable to open password file %s", + filename); + return NULL; + } + + /* read in id */ + if (fgets(pass, 16, fp) == NULL) { + lprintf(LOG_ERR, "Unable to read password from file %s", + filename); + fclose(fp); + return NULL; + } + + /* remove trailing whitespace */ + l = strcspn(pass, " \r\n\t"); + if (l > 0) { + pass[l] = '\0'; + } + + fclose(fp); + return pass; +} + + +/* + * Print all the commands in the above table to stderr + * used for help text on command line and shell + */ +void +ipmi_cmd_print(struct ipmi_cmd * cmdlist) +{ + struct ipmi_cmd * cmd; + if (cmdlist == NULL) + return; + lprintf(LOG_NOTICE, "Commands:"); + for (cmd=cmdlist; cmd->func != NULL; cmd++) { + if (cmd->desc == NULL) + continue; + lprintf(LOG_NOTICE, "\t%-12s %s", cmd->name, cmd->desc); + } + lprintf(LOG_NOTICE, ""); +} + +/* ipmi_cmd_run - run a command from list based on parameters + * called from main() + * + * 1. iterate through ipmi_cmd_list matching on name + * 2. call func() for that command + * + * @intf: ipmi interface + * @name: command name + * @argc: command argument count + * @argv: command argument list + * + * returns value from func() of that commnad if found + * returns -1 if command is not found + */ +int +ipmi_cmd_run(struct ipmi_intf * intf, char * name, int argc, char ** argv) +{ + struct ipmi_cmd * cmd; + + for (cmd=intf->cmdlist; cmd->func != NULL; cmd++) { + if (strncmp(name, cmd->name, strlen(cmd->name)) == 0) + break; + } + if (cmd->func == NULL) { + lprintf(LOG_ERR, "Invalid command: %s", name); + return -1; + } + return cmd->func(intf, argc, argv); +} + +static void +ipmi_option_usage(const char * progname, struct ipmi_cmd * cmdlist, struct ipmi_intf_support * intflist) +{ + lprintf(LOG_NOTICE, "%s version %s\n", progname, VERSION); + lprintf(LOG_NOTICE, "usage: %s [options...] \n", progname); + lprintf(LOG_NOTICE, " -h This help"); + lprintf(LOG_NOTICE, " -V Show version information"); + lprintf(LOG_NOTICE, " -v Verbose (can use multiple times)"); + lprintf(LOG_NOTICE, " -c Display output in comma separated format"); + lprintf(LOG_NOTICE, " -I intf Interface to use"); + lprintf(LOG_NOTICE, " -H hostname Remote host name for LAN interface"); + lprintf(LOG_NOTICE, " -p port Remote RMCP port [default=623]"); + lprintf(LOG_NOTICE, " -U username Remote session username"); + lprintf(LOG_NOTICE, " -f file Read remote session password from file"); +#ifndef __sun_hide_options + lprintf(LOG_NOTICE, " -a Prompt for remote password"); + lprintf(LOG_NOTICE, " -C ciphersuite Cipher suite to be used by lanplus interface"); + lprintf(LOG_NOTICE, " -L level Remote session privilege level [default=USER]"); + lprintf(LOG_NOTICE, " -A authtype Force use of auth type NONE, PASSWORD, MD2, MD5 or OEM"); + lprintf(LOG_NOTICE, " -P password Remote session password"); + lprintf(LOG_NOTICE, " -E Read password from IPMI_PASSWORD environment variable"); + lprintf(LOG_NOTICE, " -m address Set local IPMB address"); + lprintf(LOG_NOTICE, " -t address Bridge request to remote target address"); + lprintf(LOG_NOTICE, " -o oemtype Setup for OEM (use 'list' to see available OEM types)"); +#endif + lprintf(LOG_NOTICE, ""); + + ipmi_intf_print(intflist); + + if (cmdlist != NULL) + ipmi_cmd_print(cmdlist); +} + + +/* ipmi_parse_options - helper function to handle parsing command line options + * + * @argc: count of options + * @argv: list of options + * @cmdlist: list of supported commands + * @intflist: list of supported interfaces + * + * returns 0 on success + * returns -1 on error + */ +int +ipmi_main(int argc, char ** argv, + struct ipmi_cmd * cmdlist, + struct ipmi_intf_support * intflist) +{ + struct ipmi_intf * intf = NULL; + struct ipmi_intf_support * sup; + struct ipmi_cmd * cmd; + int privlvl = 0; + uint8_t target_addr = 0; + uint8_t my_addr = 0; + int authtype = -1; + char * tmp = NULL; + char * hostname = NULL; + char * username = NULL; + char * password = NULL; + char * intfname = NULL; + char * progname = NULL; + char * oemtype = NULL; + int port = 0; + int cipher_suite_id = 3; /* See table 22-19 of the IPMIv2 spec */ + int argflag, i, found; + int rc = -1; + + /* save program name */ + progname = strrchr(argv[0], '/') + 1; + progname = ((progname == NULL) ? argv[0] : progname); + + while ((argflag = getopt(argc, (char **)argv, OPTION_STRING)) != -1) + { + switch (argflag) { + case 'I': + intfname = strdup(optarg); + if (intfname == NULL) { + lprintf(LOG_ERR, "%s: malloc failure", progname); + goto out_free; + } + if (intflist != NULL) { + found = 0; + for (sup=intflist; sup->name != NULL; sup++) { + if (strncmp(sup->name, intfname, strlen(intfname)) == 0 && + strncmp(sup->name, intfname, strlen(sup->name)) == 0 && + sup->supported == 1) + found = 1; + } + if (!found) { + lprintf(LOG_ERR, "Interface %s not supported", intfname); + goto out_free; + } + } + break; + case 'h': + ipmi_option_usage(progname, cmdlist, intflist); + rc = 0; + goto out_free; + break; + case 'V': + printf("%s version %s\n", progname, VERSION); + rc = 0; + goto out_free; + break; + case 'p': + port = atoi(optarg); + break; + case 'C': + cipher_suite_id = atoi(optarg); + break; + case 'v': + verbose++; + break; + case 'c': + csv_output = 1; + break; + case 'H': + hostname = strdup(optarg); + if (hostname == NULL) { + lprintf(LOG_ERR, "%s: malloc failure", progname); + goto out_free; + } + break; + case 'f': + if (password) + free(password); + password = ipmi_password_file_read(optarg); + if (password == NULL) + lprintf(LOG_ERR, "Unable to read password " + "from file %s", optarg); + break; + case 'a': +#ifdef HAVE_GETPASSPHRASE + tmp = getpassphrase("Password: "); +#else + tmp = getpass("Password: "); +#endif + if (tmp != NULL) { + if (password) + free(password); + password = strdup(tmp); + if (password == NULL) { + lprintf(LOG_ERR, "%s: malloc failure", progname); + goto out_free; + } + } + break; + case 'U': + username = strdup(optarg); + if (username == NULL) { + lprintf(LOG_ERR, "%s: malloc failure", progname); + goto out_free; + } + break; +#ifndef __sun_hide_options + case 'o': + oemtype = strdup(optarg); + if (oemtype == NULL) { + lprintf(LOG_ERR, "%s: malloc failure", progname); + goto out_free; + } + if (strncmp(oemtype, "list", 4) == 0 || + strncmp(oemtype, "help", 4) == 0) { + ipmi_oem_print(); + goto out_free; + } + break; + case 'g': + /* backwards compatible oem hack */ + oemtype = strdup("intelwv2"); + break; + case 's': + /* backwards compatible oem hack */ + oemtype = strdup("supermicro"); + break; + case 'P': + if (password) + free(password); + password = strdup(optarg); + if (password == NULL) { + lprintf(LOG_ERR, "%s: malloc failure", progname); + goto out_free; + } + + /* Prevent password snooping with ps */ + i = strlen(optarg); + memset(optarg, 'X', i); + break; + case 'E': + if ((tmp = getenv("IPMITOOL_PASSWORD"))) + { + if (password) + free(password); + password = strdup(tmp); + if (password == NULL) { + lprintf(LOG_ERR, "%s: malloc failure", progname); + goto out_free; + } + } + else if ((tmp = getenv("IPMI_PASSWORD"))) + { + if (password) + free(password); + password = strdup(tmp); + if (password == NULL) { + lprintf(LOG_ERR, "%s: malloc failure", progname); + goto out_free; + } + } + else { + lprintf(LOG_WARN, "Unable to read password from environment"); + } + break; + case 'L': + privlvl = str2val(optarg, ipmi_privlvl_vals); + if (privlvl < 0) + lprintf(LOG_WARN, "Invalid privilege level %s", optarg); + break; + case 'A': + authtype = str2val(optarg, ipmi_authtype_session_vals); + break; + case 't': + target_addr = (uint8_t)strtol(optarg, NULL, 0); + break; + case 'm': + my_addr = (uint8_t)strtol(optarg, NULL, 0); + break; +#endif + default: + ipmi_option_usage(progname, cmdlist, intflist); + goto out_free; + } + } + + /* check for command before doing anything */ + if (argc-optind <= 0) { + lprintf(LOG_ERR, "No command provided!"); + ipmi_option_usage(progname, cmdlist, intflist); + goto out_free; + } + if (strncmp(argv[optind], "help", 4) == 0) { + ipmi_cmd_print(cmdlist); + rc = 0; + goto out_free; + } + + /* + * If the user has specified a hostname (-H option) + * then this is a remote access session. + * + * If no password was specified by any other method + * and the authtype was not explicitly set to NONE + * then prompt the user. + */ + if (hostname != NULL && password == NULL && + (authtype != IPMI_SESSION_AUTHTYPE_NONE || authtype < 0)) { +#ifdef HAVE_GETPASSPHRASE + tmp = getpassphrase("Password: "); +#else + tmp = getpass("Password: "); +#endif + if (tmp != NULL) { + password = strdup(tmp); + if (password == NULL) { + lprintf(LOG_ERR, "%s: malloc failure", progname); + goto out_free; + } + } + } + + /* if no interface was specified but a + * hostname was then use LAN by default + * otherwise the default is hardcoded + * to use the first entry in the list + */ + if (intfname == NULL && hostname != NULL) { + intfname = strdup("lan"); + if (intfname == NULL) { + lprintf(LOG_ERR, "%s: malloc failure", progname); + goto out_free; + } + } + + /* load interface */ + intf = ipmi_intf_load(intfname); + if (intf == NULL) { + lprintf(LOG_ERR, "Error loading interface %s", intfname); + goto out_free; + } + + /* setup log */ + log_init(progname, 0, verbose); + + /* run OEM setup if found */ + if (oemtype != NULL && + ipmi_oem_setup(intf, oemtype) < 0) { + lprintf(LOG_ERR, "OEM setup for \"%s\" failed", oemtype); + goto out_free; + } + + /* set session variables */ + if (hostname != NULL) + ipmi_intf_session_set_hostname(intf, hostname); + if (username != NULL) + ipmi_intf_session_set_username(intf, username); + if (password != NULL) + ipmi_intf_session_set_password(intf, password); + if (port > 0) + ipmi_intf_session_set_port(intf, port); + if (authtype >= 0) + ipmi_intf_session_set_authtype(intf, (uint8_t)authtype); + if (privlvl > 0) + ipmi_intf_session_set_privlvl(intf, (uint8_t)privlvl); + else + ipmi_intf_session_set_privlvl(intf, + IPMI_SESSION_PRIV_ADMIN); /* default */ + + ipmi_intf_session_set_cipher_suite_id(intf, cipher_suite_id); + + /* setup IPMB local and target address if given */ + intf->my_addr = my_addr ? : IPMI_BMC_SLAVE_ADDR; + if (target_addr > 0) { + /* need to open the interface first */ + if (intf->open != NULL) + intf->open(intf); + intf->target_addr = target_addr; + /* must be admin level to do this over lan */ + ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN); + } + + intf->cmdlist = cmdlist; + + /* now we finally run the command */ + rc = ipmi_cmd_run(intf, + argv[optind], + argc-optind-1, + &(argv[optind+1])); + + /* clean repository caches */ + ipmi_cleanup(intf); + + /* call interface close function if available */ + if (intf->opened > 0 && intf->close != NULL) + intf->close(intf); + + out_free: + log_halt(); + + if (intfname != NULL) + free(intfname); + if (hostname != NULL) + free(hostname); + if (username != NULL) + free(username); + if (password != NULL) + free(password); + if (oemtype != NULL) + free(oemtype); + + return rc; +} diff --git a/ipmitool/src/ipmitool.c b/ipmitool/src/ipmitool.c index 824625c..b3447ab 100644 --- a/ipmitool/src/ipmitool.c +++ b/ipmitool/src/ipmitool.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved. * Use is subject to license terms. */ @@ -37,18 +37,10 @@ * facility. */ -#include -#include -#include -#include -#include -#include - -#include -#include #include #include -#include +#include + #include #include #include @@ -70,31 +62,19 @@ # include #endif -#ifdef __sun -# define OPTION_STRING "I:hVvcH:f:U:p:" -#else -# define OPTION_STRING "I:hVvcgsEao:H:P:f:U:p:C:L:A:t:m:" -#endif - -int csv_output = 0; -int verbose = 0; - -extern const struct valstr ipmi_privlvl_vals[]; -extern const struct valstr ipmi_authtype_session_vals[]; - -/* defined in ipmishell.c */ #ifdef HAVE_READLINE extern int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv); #endif extern int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv); extern int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv); -struct ipmi_cmd { - int (*func)(struct ipmi_intf * intf, int argc, char ** argv); - const char * name; - const char * desc; -} ipmi_cmd_list[] = { + +int csv_output = 0; +int verbose = 0; + +struct ipmi_cmd ipmitool_cmd_list[] = { { ipmi_raw_main, "raw", "Send a RAW IPMI request and print response" }, + { ipmi_rawi2c_main, "i2c", "Send an I2C Master Write-Read command and print response" }, { ipmi_lanp_main, "lan", "Configure LAN Channels" }, { ipmi_chassis_main, "chassis", "Get chassis status and set power state" }, { ipmi_event_main, "event", "Send pre-defined events to MC" }, @@ -118,432 +98,15 @@ struct ipmi_cmd { { NULL }, }; -/* - * Print all the commands in the above table to stderr - * used for help text on command line and shell - */ -void -ipmi_cmd_print(void) -{ - struct ipmi_cmd * cmd; - lprintf(LOG_NOTICE, "Commands:"); - for (cmd=ipmi_cmd_list; cmd->func != NULL; cmd++) { - if (cmd->desc == NULL) - continue; - lprintf(LOG_NOTICE, "\t%-12s %s", cmd->name, cmd->desc); - } - lprintf(LOG_NOTICE, ""); -} - -/* ipmi_cmd_run - run a command from list based on parameters - * called from main() - * - * 1. iterate through ipmi_cmd_list matching on name - * 2. call func() for that command - * - * @intf: ipmi interface - * @name: command name - * @argc: command argument count - * @argv: command argument list - * - * returns value from func() of that commnad if found - * returns -1 if command is not found - */ -int -ipmi_cmd_run(struct ipmi_intf * intf, char * name, int argc, char ** argv) -{ - struct ipmi_cmd * cmd; - - for (cmd=ipmi_cmd_list; cmd->func != NULL; cmd++) { - if (strncmp(name, cmd->name, strlen(cmd->name)) == 0) - break; - } - if (cmd->func == NULL) { - lprintf(LOG_ERR, "Invalid command: %s", name); - return -1; - } - return cmd->func(intf, argc, argv); -} - -/* ipmitool_usage - print usage help - */ -static void -ipmitool_usage(void) -{ - lprintf(LOG_NOTICE, "ipmitool version %s\n", VERSION); - lprintf(LOG_NOTICE, "usage: ipmitool [options...] \n"); - lprintf(LOG_NOTICE, " -h This help"); - lprintf(LOG_NOTICE, " -V Show version information"); - lprintf(LOG_NOTICE, " -v Verbose (can use multiple times)"); - lprintf(LOG_NOTICE, " -c Display output in comma separated format"); - lprintf(LOG_NOTICE, " -I intf Interface to use"); - lprintf(LOG_NOTICE, " -H hostname Remote host name for LAN interface"); - lprintf(LOG_NOTICE, " -p port Remote RMCP port [default=623]"); - lprintf(LOG_NOTICE, " -U username Remote session username"); - lprintf(LOG_NOTICE, " -f file Read remote session password from file"); - lprintf(LOG_NOTICE, " -C ciphersuite Cipher suite to be used by lanplus interface"); -#ifndef __sun - lprintf(LOG_NOTICE, " -L level Remote session privilege level [default=USER]"); - lprintf(LOG_NOTICE, " -A authtype Force use of auth type NONE, PASSWORD, MD2, MD5 or OEM"); - lprintf(LOG_NOTICE, " -P password Remote session password"); - lprintf(LOG_NOTICE, " -a Prompt for remote password"); - lprintf(LOG_NOTICE, " -E Read password from IPMI_PASSWORD environment variable"); - lprintf(LOG_NOTICE, " -m address Set local IPMB address"); - lprintf(LOG_NOTICE, " -t address Bridge request to remote target address"); - lprintf(LOG_NOTICE, " -o oemtype Setup for OEM (use 'list' to see available OEM types)"); -#endif - lprintf(LOG_NOTICE, ""); - ipmi_intf_print(); - ipmi_cmd_print(); -} - -/* ipmi_password_file_read - Open file and read password from it - * - * @filename: file name to read from - * - * returns pointer to allocated buffer containing password - * (caller is expected to free when finished) - * returns NULL on error - */ -static char * -ipmi_password_file_read(char * filename) -{ - FILE * fp; - char * pass = NULL; - int l; - - pass = malloc(16); - if (pass == NULL) { - lprintf(LOG_ERR, "ipmitool: malloc failure"); - return NULL; - } - - fp = ipmi_open_file_read((const char *)filename); - if (fp == NULL) { - lprintf(LOG_ERR, "Unable to open password file %s", - filename); - return NULL; - } - - /* read in id */ - if (fgets(pass, 16, fp) == NULL) { - lprintf(LOG_ERR, "Unable to read password from file %s", - filename); - fclose(fp); - return NULL; - } - - /* remove trailing whitespace */ - l = strcspn(pass, " \r\n\t"); - if (l > 0) { - pass[l] = '\0'; - } - - fclose(fp); - return pass; -} - - int main(int argc, char ** argv) { - struct ipmi_intf * intf = NULL; - uint8_t privlvl = 0; - uint8_t target_addr = 0; - uint8_t my_addr = 0; - int authtype = -1; - char * tmp = NULL; - char * hostname = NULL; - char * username = NULL; - char * password = NULL; - char * intfname = NULL; - char * progname = NULL; - char * oemtype = NULL; - int port = 0; - int cipher_suite_id = 3; /* See table 22-19 of the IPMIv2 spec */ - int argflag, i; - int rc = -1; + int rc; - /* save program name */ - progname = strrchr(argv[0], '/'); - progname = ((progname == NULL) ? argv[0] : progname); + rc = ipmi_main(argc, argv, ipmitool_cmd_list, NULL); - while ((argflag = getopt(argc, (char **)argv, OPTION_STRING)) != -1) - { - switch (argflag) { - case 'I': - intfname = strdup(optarg); - if (intfname == NULL) { - lprintf(LOG_ERR, "ipmitool: malloc failure"); - goto out_free; - } - break; - case 'h': - ipmitool_usage(); - rc = 0; - goto out_free; - break; - case 'V': - printf("%s version %s\n", progname, VERSION); - rc = 0; - goto out_free; - break; - case 'p': - port = atoi(optarg); - break; - case 'C': - cipher_suite_id = atoi(optarg); - break; - case 'v': - verbose++; - break; - case 'c': - csv_output = 1; - break; - case 'H': - hostname = strdup(optarg); - if (hostname == NULL) { - lprintf(LOG_ERR, "ipmitool: malloc failure"); - goto out_free; - } - break; - case 'f': - if (password) - free(password); - password = ipmi_password_file_read(optarg); - if (password == NULL) - lprintf(LOG_ERR, "Unable to read password " - "from file %s", optarg); - break; - case 'a': -#ifdef HAVE_GETPASSPHRASE - tmp = getpassphrase("Password: "); -#else - tmp = getpass("Password: "); -#endif - if (tmp != NULL) { - if (password) - free(password); - password = strdup(tmp); - if (password == NULL) { - lprintf(LOG_ERR, "ipmitool: malloc failure"); - goto out_free; - } - } - break; - case 'U': - username = strdup(optarg); - if (username == NULL) { - lprintf(LOG_ERR, "ipmitool: malloc failure"); - goto out_free; - } - break; -#ifndef __sun /* some options not enabled on solaris yet */ - case 'o': - oemtype = strdup(optarg); - if (oemtype == NULL) { - lprintf(LOG_ERR, "ipmitool: malloc failure"); - goto out_free; - } - if (strncmp(oemtype, "list", 4) == 0) { - ipmi_oem_print(); - goto out_free; - } - break; - case 'g': - /* backwards compatible oem hack */ - oemtype = strdup("intelwv2"); - break; - case 's': - /* backwards compatible oem hack */ - oemtype = strdup("supermicro"); - break; - case 'P': - if (password) - free(password); - password = strdup(optarg); - if (password == NULL) { - lprintf(LOG_ERR, "ipmitool: malloc failure"); - goto out_free; - } - - /* Prevent password snooping with ps */ - i = strlen(optarg); - memset(optarg, 'X', i); - break; - case 'E': - if ((tmp = getenv("IPMITOOL_PASSWORD"))) - { - if (password) - free(password); - password = strdup(tmp); - if (password == NULL) { - lprintf(LOG_ERR, "ipmitool: malloc failure"); - goto out_free; - } - } - else if ((tmp = getenv("IPMI_PASSWORD"))) - { - if (password) - free(password); - password = strdup(tmp); - if (password == NULL) { - lprintf(LOG_ERR, "ipmitool: malloc failure"); - goto out_free; - } - } - else { - lprintf(LOG_WARN, "Unable to read password from environment"); - } - break; - case 'L': - privlvl = (uint8_t)str2val(optarg, ipmi_privlvl_vals); - if (!privlvl) - lprintf(LOG_WARN, "Invalid privilege level %s", optarg); - break; - case 'A': - authtype = (int)str2val(optarg, ipmi_authtype_session_vals); - break; - case 't': - target_addr = (uint8_t)strtol(optarg, NULL, 0); - break; - case 'm': - my_addr = (uint8_t)strtol(optarg, NULL, 0); - break; -#endif - default: - ipmitool_usage(); - goto out_free; - } - } - - /* check for command before doing anything */ - if (argc-optind <= 0) { - lprintf(LOG_ERR, "No command provided!"); - ipmitool_usage(); - goto out_free; - } - if (strncmp(argv[optind], "help", 4) == 0) { - ipmi_cmd_print(); - rc = 0; - goto out_free; - } - - - - /* - * If the user has specified a hostname (-H option) - * then this is a remote access session. - * - * If no password was specified by any other method - * and the authtype was not explicitly set to NONE - * then prompt the user. - */ - if (hostname != NULL && password == NULL && - (authtype != IPMI_SESSION_AUTHTYPE_NONE || authtype < 0)) { -#ifdef HAVE_GETPASSPHRASE - tmp = getpassphrase("Password: "); -#else - tmp = getpass("Password: "); -#endif - if (tmp != NULL) { - password = strdup(tmp); - if (password == NULL) { - lprintf(LOG_ERR, "ipmitool: malloc failure"); - goto out_free; - } - } - } - - /* if no interface was specified but a - * hostname was then use LAN by default - * otherwise the default is hardcoded - * to use the first entry in the list - */ - if (intfname == NULL && hostname != NULL) { - intfname = strdup("lan"); - if (intfname == NULL) { - lprintf(LOG_ERR, "ipmitool: malloc failure"); - goto out_free; - } - } - - /* load interface */ - intf = ipmi_intf_load(intfname); - if (intf == NULL) { - lprintf(LOG_ERR, "Error loading interface %s", intfname); - goto out_free; - } - - /* setup log */ - log_init(progname, 0, verbose); - - /* run OEM setup if found */ - if (oemtype != NULL && - ipmi_oem_setup(intf, oemtype) < 0) { - lprintf(LOG_ERR, "OEM setup for \"%s\" failed", oemtype); - goto out_free; - } - - /* set session variables */ - if (hostname != NULL) - ipmi_intf_session_set_hostname(intf, hostname); - if (username != NULL) - ipmi_intf_session_set_username(intf, username); - if (password != NULL) - ipmi_intf_session_set_password(intf, password); - if (port > 0) - ipmi_intf_session_set_port(intf, port); - if (authtype >= 0) - ipmi_intf_session_set_authtype(intf, (uint8_t)authtype); - if (privlvl > 0) - ipmi_intf_session_set_privlvl(intf, privlvl); - else - ipmi_intf_session_set_privlvl(intf, - IPMI_SESSION_PRIV_ADMIN); /* default */ - - ipmi_intf_session_set_cipher_suite_id(intf, cipher_suite_id); - - /* setup IPMB local and target address if given */ - intf->my_addr = my_addr ? : IPMI_BMC_SLAVE_ADDR; - if (target_addr > 0) { - /* need to open the interface first */ - if (intf->open != NULL) - intf->open(intf); - intf->target_addr = target_addr; - /* must be admin level to do this over lan */ - ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN); - } - - /* now we finally run the command */ - rc = ipmi_cmd_run(intf, - argv[optind], - argc-optind-1, - &(argv[optind+1])); - - /* clean repository caches */ - ipmi_cleanup(intf); - - /* call interface close function if available */ - if (intf->opened > 0 && intf->close != NULL) - intf->close(intf); - - out_free: - log_halt(); - - if (intfname != NULL) - free(intfname); - if (hostname != NULL) - free(hostname); - if (username != NULL) - free(username); - if (password != NULL) - free(password); - if (oemtype != NULL) - free(oemtype); - - if (rc >= 0) - exit(EXIT_SUCCESS); - else + if (rc < 0) exit(EXIT_FAILURE); + else + exit(EXIT_SUCCESS); }