Blame src/ipmishell.c

Packit d14fb6
/*
Packit d14fb6
 * Copyright (c) 2003, 2004 Sun Microsystems, Inc.  All Rights Reserved.
Packit d14fb6
 * 
Packit d14fb6
 * Redistribution and use in source and binary forms, with or without
Packit d14fb6
 * modification, are permitted provided that the following conditions
Packit d14fb6
 * are met:
Packit d14fb6
 * 
Packit d14fb6
 * Redistribution of source code must retain the above copyright
Packit d14fb6
 * notice, this list of conditions and the following disclaimer.
Packit d14fb6
 * 
Packit d14fb6
 * Redistribution in binary form must reproduce the above copyright
Packit d14fb6
 * notice, this list of conditions and the following disclaimer in the
Packit d14fb6
 * documentation and/or other materials provided with the distribution.
Packit d14fb6
 * 
Packit d14fb6
 * Neither the name of Sun Microsystems, Inc. or the names of
Packit d14fb6
 * contributors may be used to endorse or promote products derived
Packit d14fb6
 * from this software without specific prior written permission.
Packit d14fb6
 * 
Packit d14fb6
 * This software is provided "AS IS," without a warranty of any kind.
Packit d14fb6
 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
Packit d14fb6
 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
Packit d14fb6
 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
Packit d14fb6
 * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
Packit d14fb6
 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
Packit d14fb6
 * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL
Packit d14fb6
 * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
Packit d14fb6
 * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
Packit d14fb6
 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
Packit d14fb6
 * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
Packit d14fb6
 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
Packit d14fb6
 */
Packit d14fb6
#define _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500 || \
Packit d14fb6
	_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED || \
Packit d14fb6
	/* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L
Packit d14fb6
Packit d14fb6
#include <stdio.h>
Packit d14fb6
#include <unistd.h>
Packit d14fb6
#include <errno.h>
Packit d14fb6
#include <stdlib.h>
Packit d14fb6
#include <string.h>
Packit d14fb6
#include <ctype.h>
Packit d14fb6
Packit d14fb6
#include <ipmitool/helper.h>
Packit d14fb6
#include <ipmitool/log.h>
Packit d14fb6
#include <ipmitool/ipmi.h>
Packit d14fb6
#include <ipmitool/ipmi_intf.h>
Packit d14fb6
#include <ipmitool/ipmi_session.h>
Packit d14fb6
#include <ipmitool/ipmi_main.h>
Packit d14fb6
Packit d14fb6
#ifdef HAVE_CONFIG_H
Packit d14fb6
# include <config.h>
Packit d14fb6
#endif
Packit d14fb6
Packit d14fb6
#define EXEC_BUF_SIZE	2048
Packit d14fb6
#define EXEC_ARG_SIZE	64
Packit d14fb6
#define MAX_PORT	65535
Packit d14fb6
Packit d14fb6
extern const struct valstr ipmi_privlvl_vals[];
Packit d14fb6
extern const struct valstr ipmi_authtype_session_vals[];
Packit d14fb6
Packit d14fb6
#ifdef HAVE_READLINE
Packit d14fb6
Packit d14fb6
/* avoid warnings errors due to non-ANSI type declarations in readline.h */
Packit d14fb6
#define _FUNCTION_DEF
Packit d14fb6
#define USE_VARARGS
Packit d14fb6
#define PREFER_STDARG
Packit d14fb6
Packit d14fb6
#include <readline/readline.h>
Packit d14fb6
#include <readline/history.h>
Packit d14fb6
#define RL_PROMPT		"ipmitool> "
Packit d14fb6
#define RL_TIMEOUT		30
Packit d14fb6
Packit d14fb6
static struct ipmi_intf * shell_intf;
Packit d14fb6
Packit d14fb6
/* This function attempts to keep lan sessions active
Packit d14fb6
 * so they do not time out waiting for user input.  The
Packit d14fb6
 * readline timeout is set to 1 second but lan session
Packit d14fb6
 * timeout is ~60 seconds.
Packit d14fb6
 */
Packit d14fb6
static int rl_event_keepalive(void)
Packit d14fb6
{
Packit d14fb6
	static int internal_timer = 0;
Packit d14fb6
Packit d14fb6
	if (shell_intf == NULL)
Packit d14fb6
		return -1;
Packit d14fb6
	if (shell_intf->keepalive == NULL)
Packit d14fb6
		return 0;
Packit d14fb6
#if defined (RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0402
Packit d14fb6
	if (internal_timer++ < RL_TIMEOUT)
Packit d14fb6
#else
Packit d14fb6
	/* In readline < 4.2 keyboard timeout hardcoded to 0.1 second */
Packit d14fb6
	if (internal_timer++ < RL_TIMEOUT * 10)
Packit d14fb6
#endif
Packit d14fb6
		return 0;
Packit d14fb6
Packit d14fb6
	internal_timer = 0;
Packit d14fb6
	shell_intf->keepalive(shell_intf);
Packit d14fb6
Packit d14fb6
	return 0;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
Packit d14fb6
{
Packit d14fb6
	char *ptr, *pbuf, **ap, *__argv[EXEC_ARG_SIZE];
Packit d14fb6
	int __argc, rc=0;
Packit d14fb6
Packit d14fb6
	rl_readline_name = "ipmitool";
Packit d14fb6
Packit d14fb6
	/* this essentially disables command completion
Packit d14fb6
	 * until its implemented right, otherwise we get
Packit d14fb6
	 * the current directory contents... */
Packit d14fb6
	rl_bind_key('\t', rl_insert);
Packit d14fb6
Packit d14fb6
	if (intf->keepalive) {
Packit d14fb6
		/* hook to keep lan sessions active */
Packit d14fb6
		shell_intf = intf;
Packit d14fb6
		rl_event_hook = rl_event_keepalive;
Packit d14fb6
#if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0402
Packit d14fb6
		/* There is a bug in readline 4.2 and later (at least on FreeBSD and NetBSD):
Packit d14fb6
		 * timeout equal or greater than 1 second causes an infinite loop. */
Packit d14fb6
		rl_set_keyboard_input_timeout(1000 * 1000 - 1);
Packit d14fb6
#endif
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	while ((pbuf = (char *)readline(RL_PROMPT)) != NULL) {
Packit d14fb6
		if (strlen(pbuf) == 0) {
Packit d14fb6
			free(pbuf);
Packit d14fb6
			pbuf = NULL;
Packit d14fb6
			continue;
Packit d14fb6
		}
Packit d14fb6
		if (strncmp(pbuf, "quit", 4) == 0 ||
Packit d14fb6
		    strncmp(pbuf, "exit", 4) == 0) {
Packit d14fb6
			free(pbuf);
Packit d14fb6
			pbuf = NULL;
Packit d14fb6
			return 0;
Packit d14fb6
		}
Packit d14fb6
		if (strncmp(pbuf, "help", 4) == 0 ||
Packit d14fb6
		    strncmp(pbuf, "?", 1) == 0) {
Packit d14fb6
			ipmi_cmd_print(intf->cmdlist);
Packit d14fb6
			free(pbuf);
Packit d14fb6
			pbuf = NULL;
Packit d14fb6
			continue;
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		/* for the all-important up arrow :) */
Packit d14fb6
		add_history(pbuf);
Packit d14fb6
Packit d14fb6
		/* change "" and '' with spaces in the middle to ~ */
Packit d14fb6
		ptr = pbuf;
Packit d14fb6
		while (*ptr != '\0') {
Packit d14fb6
			if (*ptr == '"') {
Packit d14fb6
				ptr++;
Packit d14fb6
				while (*ptr != '"' && *ptr != '\0') {
Packit d14fb6
					if (isspace((int)*ptr))
Packit d14fb6
						*ptr = '~';
Packit d14fb6
					ptr++;
Packit d14fb6
				}
Packit d14fb6
			}
Packit d14fb6
			if (*ptr == '\'') {
Packit d14fb6
				ptr++;
Packit d14fb6
				while (*ptr != '\'' && *ptr != '\0') {
Packit d14fb6
					if (isspace((int)*ptr))
Packit d14fb6
						*ptr = '~';
Packit d14fb6
					ptr++;
Packit d14fb6
				}
Packit d14fb6
			}
Packit d14fb6
			ptr++;
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		__argc = 0;
Packit d14fb6
		ap = __argv;
Packit d14fb6
Packit d14fb6
		for (*ap = strtok(pbuf, " \t");
Packit d14fb6
		     *ap != NULL;
Packit d14fb6
		     *ap = strtok(NULL, " \t")) {
Packit d14fb6
			__argc++;
Packit d14fb6
Packit d14fb6
			ptr = *ap;
Packit d14fb6
			if (*ptr == '\'') {
Packit d14fb6
				memmove(ptr, ptr+1, strlen(ptr));
Packit d14fb6
				while (*ptr != '\'' && *ptr != '\0') {
Packit d14fb6
					if (*ptr == '~')
Packit d14fb6
						*ptr = ' ';
Packit d14fb6
					ptr++;
Packit d14fb6
				}
Packit d14fb6
				*ptr = '\0';
Packit d14fb6
			}
Packit d14fb6
			if (*ptr == '"') {
Packit d14fb6
				memmove(ptr, ptr+1, strlen(ptr));
Packit d14fb6
				while (*ptr != '"' && *ptr != '\0') {
Packit d14fb6
					if (*ptr == '~')
Packit d14fb6
						*ptr = ' ';
Packit d14fb6
					ptr++;
Packit d14fb6
				}
Packit d14fb6
				*ptr = '\0';
Packit d14fb6
			}
Packit d14fb6
Packit d14fb6
			if (**ap != '\0') {
Packit d14fb6
				if (++ap >= &__argv[EXEC_ARG_SIZE])
Packit d14fb6
					break;
Packit d14fb6
			}
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		if (__argc && __argv[0])
Packit d14fb6
			rc = ipmi_cmd_run(intf,
Packit d14fb6
					  __argv[0],
Packit d14fb6
					  __argc-1,
Packit d14fb6
					  &(__argv[1]));
Packit d14fb6
Packit d14fb6
		free(pbuf);
Packit d14fb6
		pbuf = NULL;
Packit d14fb6
	}
Packit d14fb6
	printf("\n");
Packit d14fb6
	return rc;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
#else  /* HAVE_READLINE */
Packit d14fb6
Packit d14fb6
int
Packit d14fb6
ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
Packit d14fb6
{
Packit d14fb6
	lprintf(LOG_ERR, "Compiled without readline, shell is disabled");
Packit d14fb6
	return -1;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
#endif /* HAVE_READLINE */
Packit d14fb6
Packit d14fb6
int ipmi_echo_main(struct ipmi_intf * intf, int argc, char ** argv)
Packit d14fb6
{
Packit d14fb6
	int i;
Packit d14fb6
Packit d14fb6
	for (i=0; i
Packit d14fb6
		printf("%s ", argv[i]);
Packit d14fb6
	}
Packit d14fb6
	printf("\n");
Packit d14fb6
Packit d14fb6
	return 0;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
static void
Packit d14fb6
ipmi_set_usage(void)
Packit d14fb6
{
Packit d14fb6
	lprintf(LOG_NOTICE, "Usage: set <option> <value>\n");
Packit d14fb6
	lprintf(LOG_NOTICE, "Options are:");
Packit d14fb6
	lprintf(LOG_NOTICE, "    hostname <host>        Session hostname");
Packit d14fb6
	lprintf(LOG_NOTICE, "    username <user>        Session username");
Packit d14fb6
	lprintf(LOG_NOTICE, "    password <pass>        Session password");
Packit d14fb6
	lprintf(LOG_NOTICE, "    privlvl <level>        Session privilege level force");
Packit d14fb6
	lprintf(LOG_NOTICE, "    authtype <type>        Authentication type force");
Packit d14fb6
	lprintf(LOG_NOTICE, "    localaddr <addr>       Local IPMB address");
Packit d14fb6
	lprintf(LOG_NOTICE, "    targetaddr <addr>      Remote target IPMB address");
Packit d14fb6
	lprintf(LOG_NOTICE, "    port <port>            Remote RMCP port");
Packit d14fb6
	lprintf(LOG_NOTICE, "    csv [level]            enable output in comma separated format");
Packit d14fb6
	lprintf(LOG_NOTICE, "    verbose [level]        Verbose level");
Packit d14fb6
	lprintf(LOG_NOTICE, "");
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv)
Packit d14fb6
{
Packit d14fb6
	if (argc == 0 || strncmp(argv[0], "help", 4) == 0) {
Packit d14fb6
		ipmi_set_usage();
Packit d14fb6
		return -1;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	/* these options can have no arguments */
Packit d14fb6
	if (strncmp(argv[0], "verbose", 7) == 0) {
Packit d14fb6
		if (argc > 1) {
Packit d14fb6
			if (str2int(argv[1], &verbose) != 0) {
Packit d14fb6
				lprintf(LOG_ERR,
Packit d14fb6
						"Given verbose '%s' argument is invalid.",
Packit d14fb6
						argv[1]);
Packit d14fb6
				return (-1);
Packit d14fb6
			}
Packit d14fb6
		} else {
Packit d14fb6
			verbose = verbose + 1;
Packit d14fb6
		}
Packit d14fb6
		return 0;
Packit d14fb6
	}
Packit d14fb6
	if (strncmp(argv[0], "csv", 3) == 0) {
Packit d14fb6
		if (argc > 1) {
Packit d14fb6
			if (str2int(argv[1], &csv_output) != 0) {
Packit d14fb6
				lprintf(LOG_ERR,
Packit d14fb6
						"Given csv '%s' argument is invalid.",
Packit d14fb6
						argv[1]);
Packit d14fb6
				return (-1);
Packit d14fb6
			}
Packit d14fb6
		} else {
Packit d14fb6
			csv_output = 1;
Packit d14fb6
		}
Packit d14fb6
		return 0;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	/* the rest need an argument */
Packit d14fb6
	if (argc == 1) {
Packit d14fb6
		ipmi_set_usage();
Packit d14fb6
		return -1;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	if (strncmp(argv[0], "host", 4) == 0 ||
Packit d14fb6
	    strncmp(argv[0], "hostname", 8) == 0) {
Packit d14fb6
		ipmi_intf_session_set_hostname(intf, argv[1]);
Packit d14fb6
		if (intf->session == NULL) {
Packit d14fb6
			lprintf(LOG_ERR, "Failed to set session hostname.");
Packit d14fb6
			return (-1);
Packit d14fb6
		}
Packit d14fb6
		printf("Set session hostname to %s\n",
Packit d14fb6
				intf->ssn_params.hostname);
Packit d14fb6
	}
Packit d14fb6
	else if (strncmp(argv[0], "user", 4) == 0 ||
Packit d14fb6
		 strncmp(argv[0], "username", 8) == 0) {
Packit d14fb6
		ipmi_intf_session_set_username(intf, argv[1]);
Packit d14fb6
		if (intf->session == NULL) {
Packit d14fb6
			lprintf(LOG_ERR, "Failed to set session username.");
Packit d14fb6
			return (-1);
Packit d14fb6
		}
Packit d14fb6
		printf("Set session username to %s\n",
Packit d14fb6
				intf->ssn_params.username);
Packit d14fb6
	}
Packit d14fb6
	else if (strncmp(argv[0], "pass", 4) == 0 ||
Packit d14fb6
		 strncmp(argv[0], "password", 8) == 0) {
Packit d14fb6
		ipmi_intf_session_set_password(intf, argv[1]);
Packit d14fb6
		if (intf->session == NULL) {
Packit d14fb6
			lprintf(LOG_ERR, "Failed to set session password.");
Packit d14fb6
			return (-1);
Packit d14fb6
		}
Packit d14fb6
		printf("Set session password\n");
Packit d14fb6
	}
Packit d14fb6
	else if (strncmp(argv[0], "authtype", 8) == 0) {
Packit d14fb6
		int authtype;
Packit d14fb6
		authtype = str2val(argv[1], ipmi_authtype_session_vals);
Packit d14fb6
		if (authtype == 0xFF) {
Packit d14fb6
			lprintf(LOG_ERR, "Invalid authtype: %s",
Packit d14fb6
					argv[1]);
Packit d14fb6
			return (-1);
Packit d14fb6
		}
Packit d14fb6
		ipmi_intf_session_set_authtype(intf, authtype);
Packit d14fb6
		if (intf->session == NULL) {
Packit d14fb6
			lprintf(LOG_ERR, "Failed to set session authtype.");
Packit d14fb6
			return (-1);
Packit d14fb6
		}
Packit d14fb6
		printf("Set session authtype to %s\n",
Packit d14fb6
		       val2str(intf->ssn_params.authtype_set,
Packit d14fb6
				   ipmi_authtype_session_vals));
Packit d14fb6
	}
Packit d14fb6
	else if (strncmp(argv[0], "privlvl", 7) == 0) {
Packit d14fb6
		int privlvl;
Packit d14fb6
		privlvl = str2val(argv[1], ipmi_privlvl_vals);
Packit d14fb6
		if (privlvl == 0xFF) {
Packit d14fb6
			lprintf(LOG_ERR, "Invalid privilege level: %s",
Packit d14fb6
					argv[1]);
Packit d14fb6
			return (-1);
Packit d14fb6
		}
Packit d14fb6
		ipmi_intf_session_set_privlvl(intf, privlvl);
Packit d14fb6
		if (intf->session == NULL) {
Packit d14fb6
			lprintf(LOG_ERR,
Packit d14fb6
					"Failed to set session privilege level.");
Packit d14fb6
			return (-1);
Packit d14fb6
		}
Packit d14fb6
		printf("Set session privilege level to %s\n",
Packit d14fb6
		       val2str(intf->ssn_params.privlvl,
Packit d14fb6
				   ipmi_privlvl_vals));
Packit d14fb6
	}
Packit d14fb6
	else if (strncmp(argv[0], "port", 4) == 0) {
Packit d14fb6
		int port = 0;
Packit d14fb6
		if (str2int(argv[1], &port) != 0 || port > MAX_PORT) {
Packit d14fb6
			lprintf(LOG_ERR, "Given port '%s' is invalid.",
Packit d14fb6
					argv[1]);
Packit d14fb6
			return (-1);
Packit d14fb6
		}
Packit d14fb6
		ipmi_intf_session_set_port(intf, port);
Packit d14fb6
		if (intf->session == NULL) {
Packit d14fb6
			lprintf(LOG_ERR, "Failed to set session port.");
Packit d14fb6
			return (-1);
Packit d14fb6
		}
Packit d14fb6
		printf("Set session port to %d\n", intf->ssn_params.port);
Packit d14fb6
	}
Packit d14fb6
	else if (strncmp(argv[0], "localaddr", 9) == 0) {
Packit d14fb6
		uint8_t my_addr = 0;
Packit d14fb6
		if (str2uchar(argv[1], &my_addr) != 0) {
Packit d14fb6
			lprintf(LOG_ERR, "Given localaddr '%s' is invalid.",
Packit d14fb6
					argv[1]);
Packit d14fb6
			return (-1);
Packit d14fb6
		}
Packit d14fb6
		intf->my_addr = my_addr;
Packit d14fb6
		printf("Set local IPMB address to 0x%02x\n", intf->my_addr);
Packit d14fb6
	}
Packit d14fb6
	else if (strncmp(argv[0], "targetaddr", 10) == 0) {
Packit d14fb6
		uint8_t target_addr = 0;
Packit d14fb6
		if (str2uchar(argv[1], &target_addr) != 0) {
Packit d14fb6
			lprintf(LOG_ERR, "Given targetaddr '%s' is invalid.",
Packit d14fb6
					argv[1]);
Packit d14fb6
			return (-1);
Packit d14fb6
		}
Packit d14fb6
		intf->target_addr = target_addr;
Packit d14fb6
		printf("Set remote IPMB address to 0x%02x\n", intf->target_addr);
Packit d14fb6
	}
Packit d14fb6
	else {
Packit d14fb6
		ipmi_set_usage();
Packit d14fb6
		return -1;
Packit d14fb6
	}
Packit d14fb6
	return 0;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv)
Packit d14fb6
{
Packit d14fb6
	FILE * fp;
Packit d14fb6
	char buf[EXEC_BUF_SIZE];
Packit d14fb6
	char * ptr, * tok, * ret, * tmp;
Packit d14fb6
	int __argc, i, r;
Packit d14fb6
	char * __argv[EXEC_ARG_SIZE];
Packit d14fb6
	int rc=0;
Packit d14fb6
Packit d14fb6
	if (argc < 1) {
Packit d14fb6
		lprintf(LOG_ERR, "Usage: exec <filename>");
Packit d14fb6
		return -1;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	fp = ipmi_open_file_read(argv[0]);
Packit d14fb6
	if (fp == NULL)
Packit d14fb6
		return -1;
Packit d14fb6
Packit d14fb6
	while (feof(fp) == 0) {
Packit d14fb6
		ret = fgets(buf, EXEC_BUF_SIZE, fp);
Packit d14fb6
		if (ret == NULL)
Packit d14fb6
			continue;
Packit d14fb6
Packit d14fb6
		/* clip off optional comment tail indicated by # */
Packit d14fb6
		ptr = strchr(buf, '#');
Packit d14fb6
		if (ptr)
Packit d14fb6
			*ptr = '\0';
Packit d14fb6
		else
Packit d14fb6
			ptr = buf + strlen(buf);
Packit d14fb6
Packit d14fb6
		/* change "" and '' with spaces in the middle to ~ */
Packit d14fb6
		ptr = buf;
Packit d14fb6
		while (*ptr != '\0') {
Packit d14fb6
			if (*ptr == '"') {
Packit d14fb6
				ptr++;
Packit d14fb6
				while (*ptr != '"' && *ptr != '\0') {
Packit d14fb6
					if (isspace((int)*ptr))
Packit d14fb6
						*ptr = '~';
Packit d14fb6
					ptr++;
Packit d14fb6
				}
Packit d14fb6
			}
Packit d14fb6
			if (*ptr == '\'') {
Packit d14fb6
				ptr++;
Packit d14fb6
				while (*ptr != '\'' && *ptr != '\0') {
Packit d14fb6
					if (isspace((int)*ptr))
Packit d14fb6
						*ptr = '~';
Packit d14fb6
					ptr++;
Packit d14fb6
				}
Packit d14fb6
			}
Packit d14fb6
			ptr++;
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		/* clip off trailing and leading whitespace */
Packit d14fb6
		ptr--;
Packit d14fb6
		while (isspace((int)*ptr) && ptr >= buf)
Packit d14fb6
			*ptr-- = '\0';
Packit d14fb6
		ptr = buf;
Packit d14fb6
		while (isspace((int)*ptr))
Packit d14fb6
			ptr++;
Packit d14fb6
		if (strlen(ptr) == 0)
Packit d14fb6
			continue;
Packit d14fb6
Packit d14fb6
		/* parse it and make argument list */
Packit d14fb6
		__argc = 0;
Packit d14fb6
		for (tok = strtok(ptr, " "); tok != NULL; tok = strtok(NULL, " ")) {
Packit d14fb6
			if (__argc < EXEC_ARG_SIZE) {
Packit d14fb6
				__argv[__argc++] = strdup(tok);
Packit d14fb6
				if (__argv[__argc-1] == NULL) {
Packit d14fb6
					lprintf(LOG_ERR, "ipmitool: malloc failure");
Packit d14fb6
					if (fp) {
Packit d14fb6
						fclose(fp);
Packit d14fb6
						fp = NULL;
Packit d14fb6
					}
Packit d14fb6
					return -1;
Packit d14fb6
				}
Packit d14fb6
				tmp = __argv[__argc-1];
Packit d14fb6
				if (*tmp == '\'') {
Packit d14fb6
					memmove(tmp, tmp+1, strlen(tmp));
Packit d14fb6
					while (*tmp != '\'' && *tmp != '\0') {
Packit d14fb6
						if (*tmp == '~')
Packit d14fb6
							*tmp = ' ';
Packit d14fb6
						tmp++;
Packit d14fb6
					}
Packit d14fb6
					*tmp = '\0';
Packit d14fb6
				}
Packit d14fb6
				if (*tmp == '"') {
Packit d14fb6
					memmove(tmp, tmp+1, strlen(tmp));
Packit d14fb6
					while (*tmp != '"' && *tmp != '\0') {
Packit d14fb6
						if (*tmp == '~')
Packit d14fb6
							*tmp = ' ';
Packit d14fb6
						tmp++;
Packit d14fb6
					}
Packit d14fb6
					*tmp = '\0';
Packit d14fb6
				}
Packit d14fb6
			}
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		/* now run the command, save the result if not successful */
Packit d14fb6
		r = ipmi_cmd_run(intf, __argv[0], __argc-1, &(__argv[1]));
Packit d14fb6
		if (r != 0)
Packit d14fb6
			rc = r;
Packit d14fb6
Packit d14fb6
		/* free argument list */
Packit d14fb6
		for (i=0; i<__argc; i++) {
Packit d14fb6
			if (__argv[i] != NULL) {
Packit d14fb6
				free(__argv[i]);
Packit d14fb6
				__argv[i] = NULL;
Packit d14fb6
			}
Packit d14fb6
		}
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	fclose(fp);
Packit d14fb6
	return rc;
Packit d14fb6
}