xref: /openbmc/ipmitool/src/ipmishell.c (revision 2d79e69f)
1c18ec02fSPetter Reinholdtsen /*
2c18ec02fSPetter Reinholdtsen  * Copyright (c) 2003, 2004 Sun Microsystems, Inc.  All Rights Reserved.
3c18ec02fSPetter Reinholdtsen  *
4c18ec02fSPetter Reinholdtsen  * Redistribution and use in source and binary forms, with or without
5c18ec02fSPetter Reinholdtsen  * modification, are permitted provided that the following conditions
6c18ec02fSPetter Reinholdtsen  * are met:
7c18ec02fSPetter Reinholdtsen  *
8c18ec02fSPetter Reinholdtsen  * Redistribution of source code must retain the above copyright
9c18ec02fSPetter Reinholdtsen  * notice, this list of conditions and the following disclaimer.
10c18ec02fSPetter Reinholdtsen  *
11c18ec02fSPetter Reinholdtsen  * Redistribution in binary form must reproduce the above copyright
12c18ec02fSPetter Reinholdtsen  * notice, this list of conditions and the following disclaimer in the
13c18ec02fSPetter Reinholdtsen  * documentation and/or other materials provided with the distribution.
14c18ec02fSPetter Reinholdtsen  *
15c18ec02fSPetter Reinholdtsen  * Neither the name of Sun Microsystems, Inc. or the names of
16c18ec02fSPetter Reinholdtsen  * contributors may be used to endorse or promote products derived
17c18ec02fSPetter Reinholdtsen  * from this software without specific prior written permission.
18c18ec02fSPetter Reinholdtsen  *
19c18ec02fSPetter Reinholdtsen  * This software is provided "AS IS," without a warranty of any kind.
20c18ec02fSPetter Reinholdtsen  * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
21c18ec02fSPetter Reinholdtsen  * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
22c18ec02fSPetter Reinholdtsen  * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
23c18ec02fSPetter Reinholdtsen  * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
24c18ec02fSPetter Reinholdtsen  * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
25c18ec02fSPetter Reinholdtsen  * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL
26c18ec02fSPetter Reinholdtsen  * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
27c18ec02fSPetter Reinholdtsen  * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
28c18ec02fSPetter Reinholdtsen  * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
29c18ec02fSPetter Reinholdtsen  * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
30c18ec02fSPetter Reinholdtsen  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31c18ec02fSPetter Reinholdtsen  */
32c18ec02fSPetter Reinholdtsen 
33c18ec02fSPetter Reinholdtsen #include <stdio.h>
34c18ec02fSPetter Reinholdtsen #include <unistd.h>
35c18ec02fSPetter Reinholdtsen #include <errno.h>
36c18ec02fSPetter Reinholdtsen #include <stdlib.h>
37c18ec02fSPetter Reinholdtsen #include <string.h>
38c18ec02fSPetter Reinholdtsen #include <ctype.h>
39c18ec02fSPetter Reinholdtsen 
40c18ec02fSPetter Reinholdtsen #include <ipmitool/helper.h>
41c18ec02fSPetter Reinholdtsen #include <ipmitool/log.h>
42c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi.h>
43c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_intf.h>
44c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_session.h>
45c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_main.h>
46c18ec02fSPetter Reinholdtsen 
47c18ec02fSPetter Reinholdtsen #ifdef HAVE_CONFIG_H
48c18ec02fSPetter Reinholdtsen # include <config.h>
49c18ec02fSPetter Reinholdtsen #endif
50c18ec02fSPetter Reinholdtsen 
51c18ec02fSPetter Reinholdtsen #define EXEC_BUF_SIZE	2048
52c18ec02fSPetter Reinholdtsen #define EXEC_ARG_SIZE	64
53c18ec02fSPetter Reinholdtsen #define MAX_PORT	65535
54c18ec02fSPetter Reinholdtsen 
55c18ec02fSPetter Reinholdtsen extern const struct valstr ipmi_privlvl_vals[];
56c18ec02fSPetter Reinholdtsen extern const struct valstr ipmi_authtype_session_vals[];
57c18ec02fSPetter Reinholdtsen 
58c18ec02fSPetter Reinholdtsen #ifdef HAVE_READLINE
59c18ec02fSPetter Reinholdtsen 
60c18ec02fSPetter Reinholdtsen /* avoid warnings errors due to non-ANSI type declarations in readline.h */
61c18ec02fSPetter Reinholdtsen #define _FUNCTION_DEF
62c18ec02fSPetter Reinholdtsen #define USE_VARARGS
63c18ec02fSPetter Reinholdtsen #define PREFER_STDARG
64c18ec02fSPetter Reinholdtsen 
65c18ec02fSPetter Reinholdtsen #include <readline/readline.h>
66c18ec02fSPetter Reinholdtsen #include <readline/history.h>
67c18ec02fSPetter Reinholdtsen #define RL_PROMPT		"ipmitool> "
68c18ec02fSPetter Reinholdtsen #define RL_TIMEOUT		30
69c18ec02fSPetter Reinholdtsen 
70c18ec02fSPetter Reinholdtsen static struct ipmi_intf * shell_intf;
71c18ec02fSPetter Reinholdtsen 
72c18ec02fSPetter Reinholdtsen /* This function attempts to keep lan sessions active
73c18ec02fSPetter Reinholdtsen  * so they do not time out waiting for user input.  The
74c18ec02fSPetter Reinholdtsen  * readline timeout is set to 1 second but lan session
75c18ec02fSPetter Reinholdtsen  * timeout is ~60 seconds.
76c18ec02fSPetter Reinholdtsen  */
rl_event_keepalive(void)77c18ec02fSPetter Reinholdtsen static int rl_event_keepalive(void)
78c18ec02fSPetter Reinholdtsen {
79c18ec02fSPetter Reinholdtsen 	static int internal_timer = 0;
80c18ec02fSPetter Reinholdtsen 
81c18ec02fSPetter Reinholdtsen 	if (shell_intf == NULL)
82c18ec02fSPetter Reinholdtsen 		return -1;
83c18ec02fSPetter Reinholdtsen 	if (shell_intf->keepalive == NULL)
84c18ec02fSPetter Reinholdtsen 		return 0;
85c18ec02fSPetter Reinholdtsen #if defined (RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0402
86c18ec02fSPetter Reinholdtsen 	if (internal_timer++ < RL_TIMEOUT)
87c18ec02fSPetter Reinholdtsen #else
88c18ec02fSPetter Reinholdtsen 	/* In readline < 4.2 keyboard timeout hardcoded to 0.1 second */
89c18ec02fSPetter Reinholdtsen 	if (internal_timer++ < RL_TIMEOUT * 10)
90c18ec02fSPetter Reinholdtsen #endif
91c18ec02fSPetter Reinholdtsen 		return 0;
92c18ec02fSPetter Reinholdtsen 
93c18ec02fSPetter Reinholdtsen 	internal_timer = 0;
94c18ec02fSPetter Reinholdtsen 	shell_intf->keepalive(shell_intf);
95c18ec02fSPetter Reinholdtsen 
96c18ec02fSPetter Reinholdtsen 	return 0;
97c18ec02fSPetter Reinholdtsen }
98c18ec02fSPetter Reinholdtsen 
ipmi_shell_main(struct ipmi_intf * intf,int argc,char ** argv)99c18ec02fSPetter Reinholdtsen int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
100c18ec02fSPetter Reinholdtsen {
101c18ec02fSPetter Reinholdtsen 	char *ptr, *pbuf, **ap, *__argv[EXEC_ARG_SIZE];
102c18ec02fSPetter Reinholdtsen 	int __argc, rc=0;
103c18ec02fSPetter Reinholdtsen 
104c18ec02fSPetter Reinholdtsen 	rl_readline_name = "ipmitool";
105c18ec02fSPetter Reinholdtsen 
106c18ec02fSPetter Reinholdtsen 	/* this essentially disables command completion
107c18ec02fSPetter Reinholdtsen 	 * until its implemented right, otherwise we get
108c18ec02fSPetter Reinholdtsen 	 * the current directory contents... */
109c18ec02fSPetter Reinholdtsen 	rl_bind_key('\t', rl_insert);
110c18ec02fSPetter Reinholdtsen 
111c18ec02fSPetter Reinholdtsen 	if (intf->keepalive) {
112c18ec02fSPetter Reinholdtsen 		/* hook to keep lan sessions active */
113c18ec02fSPetter Reinholdtsen 		shell_intf = intf;
114c18ec02fSPetter Reinholdtsen 		rl_event_hook = rl_event_keepalive;
115c18ec02fSPetter Reinholdtsen #if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0402
116c18ec02fSPetter Reinholdtsen 		/* There is a bug in readline 4.2 and later (at least on FreeBSD and NetBSD):
117c18ec02fSPetter Reinholdtsen 		 * timeout equal or greater than 1 second causes an infinite loop. */
118c18ec02fSPetter Reinholdtsen 		rl_set_keyboard_input_timeout(1000 * 1000 - 1);
119c18ec02fSPetter Reinholdtsen #endif
120c18ec02fSPetter Reinholdtsen 	}
121c18ec02fSPetter Reinholdtsen 
122c18ec02fSPetter Reinholdtsen 	while ((pbuf = (char *)readline(RL_PROMPT)) != NULL) {
123c18ec02fSPetter Reinholdtsen 		if (strlen(pbuf) == 0) {
124c18ec02fSPetter Reinholdtsen 			free(pbuf);
125c18ec02fSPetter Reinholdtsen 			pbuf = NULL;
126c18ec02fSPetter Reinholdtsen 			continue;
127c18ec02fSPetter Reinholdtsen 		}
128c18ec02fSPetter Reinholdtsen 		if (strncmp(pbuf, "quit", 4) == 0 ||
129c18ec02fSPetter Reinholdtsen 		    strncmp(pbuf, "exit", 4) == 0) {
130c18ec02fSPetter Reinholdtsen 			free(pbuf);
131c18ec02fSPetter Reinholdtsen 			pbuf = NULL;
132c18ec02fSPetter Reinholdtsen 			return 0;
133c18ec02fSPetter Reinholdtsen 		}
134c18ec02fSPetter Reinholdtsen 		if (strncmp(pbuf, "help", 4) == 0 ||
135c18ec02fSPetter Reinholdtsen 		    strncmp(pbuf, "?", 1) == 0) {
136c18ec02fSPetter Reinholdtsen 			ipmi_cmd_print(intf->cmdlist);
137c18ec02fSPetter Reinholdtsen 			free(pbuf);
138c18ec02fSPetter Reinholdtsen 			pbuf = NULL;
139c18ec02fSPetter Reinholdtsen 			continue;
140c18ec02fSPetter Reinholdtsen 		}
141c18ec02fSPetter Reinholdtsen 
142c18ec02fSPetter Reinholdtsen 		/* for the all-important up arrow :) */
143c18ec02fSPetter Reinholdtsen 		add_history(pbuf);
144c18ec02fSPetter Reinholdtsen 
145c18ec02fSPetter Reinholdtsen 		/* change "" and '' with spaces in the middle to ~ */
146c18ec02fSPetter Reinholdtsen 		ptr = pbuf;
147c18ec02fSPetter Reinholdtsen 		while (*ptr != '\0') {
148c18ec02fSPetter Reinholdtsen 			if (*ptr == '"') {
149c18ec02fSPetter Reinholdtsen 				ptr++;
150c18ec02fSPetter Reinholdtsen 				while (*ptr != '"' && *ptr != '\0') {
151c18ec02fSPetter Reinholdtsen 					if (isspace((int)*ptr))
152c18ec02fSPetter Reinholdtsen 						*ptr = '~';
153c18ec02fSPetter Reinholdtsen 					ptr++;
154c18ec02fSPetter Reinholdtsen 				}
155c18ec02fSPetter Reinholdtsen 			}
156c18ec02fSPetter Reinholdtsen 			if (*ptr == '\'') {
157c18ec02fSPetter Reinholdtsen 				ptr++;
158c18ec02fSPetter Reinholdtsen 				while (*ptr != '\'' && *ptr != '\0') {
159c18ec02fSPetter Reinholdtsen 					if (isspace((int)*ptr))
160c18ec02fSPetter Reinholdtsen 						*ptr = '~';
161c18ec02fSPetter Reinholdtsen 					ptr++;
162c18ec02fSPetter Reinholdtsen 				}
163c18ec02fSPetter Reinholdtsen 			}
164c18ec02fSPetter Reinholdtsen 			ptr++;
165c18ec02fSPetter Reinholdtsen 		}
166c18ec02fSPetter Reinholdtsen 
167c18ec02fSPetter Reinholdtsen 		__argc = 0;
168c18ec02fSPetter Reinholdtsen 		ap = __argv;
169c18ec02fSPetter Reinholdtsen 
170c18ec02fSPetter Reinholdtsen 		for (*ap = strtok(pbuf, " \t");
171c18ec02fSPetter Reinholdtsen 		     *ap != NULL;
172c18ec02fSPetter Reinholdtsen 		     *ap = strtok(NULL, " \t")) {
173c18ec02fSPetter Reinholdtsen 			__argc++;
174c18ec02fSPetter Reinholdtsen 
175c18ec02fSPetter Reinholdtsen 			ptr = *ap;
176c18ec02fSPetter Reinholdtsen 			if (*ptr == '\'') {
177c18ec02fSPetter Reinholdtsen 				memmove(ptr, ptr+1, strlen(ptr));
178c18ec02fSPetter Reinholdtsen 				while (*ptr != '\'' && *ptr != '\0') {
179c18ec02fSPetter Reinholdtsen 					if (*ptr == '~')
180c18ec02fSPetter Reinholdtsen 						*ptr = ' ';
181c18ec02fSPetter Reinholdtsen 					ptr++;
182c18ec02fSPetter Reinholdtsen 				}
183c18ec02fSPetter Reinholdtsen 				*ptr = '\0';
184c18ec02fSPetter Reinholdtsen 			}
185c18ec02fSPetter Reinholdtsen 			if (*ptr == '"') {
186c18ec02fSPetter Reinholdtsen 				memmove(ptr, ptr+1, strlen(ptr));
187c18ec02fSPetter Reinholdtsen 				while (*ptr != '"' && *ptr != '\0') {
188c18ec02fSPetter Reinholdtsen 					if (*ptr == '~')
189c18ec02fSPetter Reinholdtsen 						*ptr = ' ';
190c18ec02fSPetter Reinholdtsen 					ptr++;
191c18ec02fSPetter Reinholdtsen 				}
192c18ec02fSPetter Reinholdtsen 				*ptr = '\0';
193c18ec02fSPetter Reinholdtsen 			}
194c18ec02fSPetter Reinholdtsen 
195c18ec02fSPetter Reinholdtsen 			if (**ap != '\0') {
196c18ec02fSPetter Reinholdtsen 				if (++ap >= &__argv[EXEC_ARG_SIZE])
197c18ec02fSPetter Reinholdtsen 					break;
198c18ec02fSPetter Reinholdtsen 			}
199c18ec02fSPetter Reinholdtsen 		}
200c18ec02fSPetter Reinholdtsen 
201c18ec02fSPetter Reinholdtsen 		if (__argc && __argv[0])
202c18ec02fSPetter Reinholdtsen 			rc = ipmi_cmd_run(intf,
203c18ec02fSPetter Reinholdtsen 					  __argv[0],
204c18ec02fSPetter Reinholdtsen 					  __argc-1,
205c18ec02fSPetter Reinholdtsen 					  &(__argv[1]));
206c18ec02fSPetter Reinholdtsen 
207c18ec02fSPetter Reinholdtsen 		free(pbuf);
208c18ec02fSPetter Reinholdtsen 		pbuf = NULL;
209c18ec02fSPetter Reinholdtsen 	}
210c18ec02fSPetter Reinholdtsen 	printf("\n");
211c18ec02fSPetter Reinholdtsen 	return rc;
212c18ec02fSPetter Reinholdtsen }
213c18ec02fSPetter Reinholdtsen 
214c18ec02fSPetter Reinholdtsen #else  /* HAVE_READLINE */
215c18ec02fSPetter Reinholdtsen 
216c18ec02fSPetter Reinholdtsen int
ipmi_shell_main(struct ipmi_intf * intf,int argc,char ** argv)217c18ec02fSPetter Reinholdtsen ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
218c18ec02fSPetter Reinholdtsen {
219c18ec02fSPetter Reinholdtsen 	lprintf(LOG_ERR, "Compiled without readline, shell is disabled");
220c18ec02fSPetter Reinholdtsen 	return -1;
221c18ec02fSPetter Reinholdtsen }
222c18ec02fSPetter Reinholdtsen 
223c18ec02fSPetter Reinholdtsen #endif /* HAVE_READLINE */
224c18ec02fSPetter Reinholdtsen 
ipmi_echo_main(struct ipmi_intf * intf,int argc,char ** argv)225c18ec02fSPetter Reinholdtsen int ipmi_echo_main(struct ipmi_intf * intf, int argc, char ** argv)
226c18ec02fSPetter Reinholdtsen {
227c18ec02fSPetter Reinholdtsen 	int i;
228c18ec02fSPetter Reinholdtsen 
229c18ec02fSPetter Reinholdtsen 	for (i=0; i<argc; i++) {
230c18ec02fSPetter Reinholdtsen 		printf("%s ", argv[i]);
231c18ec02fSPetter Reinholdtsen 	}
232c18ec02fSPetter Reinholdtsen 	printf("\n");
233c18ec02fSPetter Reinholdtsen 
234c18ec02fSPetter Reinholdtsen 	return 0;
235c18ec02fSPetter Reinholdtsen }
236c18ec02fSPetter Reinholdtsen 
237c18ec02fSPetter Reinholdtsen static void
ipmi_set_usage(void)238c18ec02fSPetter Reinholdtsen ipmi_set_usage(void)
239c18ec02fSPetter Reinholdtsen {
240c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "Usage: set <option> <value>\n");
241c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "Options are:");
242c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "    hostname <host>        Session hostname");
243c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "    username <user>        Session username");
244c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "    password <pass>        Session password");
245c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "    privlvl <level>        Session privilege level force");
246c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "    authtype <type>        Authentication type force");
247c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "    localaddr <addr>       Local IPMB address");
248c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "    targetaddr <addr>      Remote target IPMB address");
249c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "    port <port>            Remote RMCP port");
250c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "    csv [level]            enable output in comma separated format");
251c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "    verbose [level]        Verbose level");
252c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "");
253c18ec02fSPetter Reinholdtsen }
254c18ec02fSPetter Reinholdtsen 
ipmi_set_main(struct ipmi_intf * intf,int argc,char ** argv)255c18ec02fSPetter Reinholdtsen int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv)
256c18ec02fSPetter Reinholdtsen {
257c18ec02fSPetter Reinholdtsen 	if (argc == 0 || strncmp(argv[0], "help", 4) == 0) {
258c18ec02fSPetter Reinholdtsen 		ipmi_set_usage();
259c18ec02fSPetter Reinholdtsen 		return -1;
260c18ec02fSPetter Reinholdtsen 	}
261c18ec02fSPetter Reinholdtsen 
262c18ec02fSPetter Reinholdtsen 	/* these options can have no arguments */
263c18ec02fSPetter Reinholdtsen 	if (strncmp(argv[0], "verbose", 7) == 0) {
264c18ec02fSPetter Reinholdtsen 		if (argc > 1) {
265c18ec02fSPetter Reinholdtsen 			if (str2int(argv[1], &verbose) != 0) {
266c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR,
267c18ec02fSPetter Reinholdtsen 						"Given verbose '%s' argument is invalid.",
268c18ec02fSPetter Reinholdtsen 						argv[1]);
269c18ec02fSPetter Reinholdtsen 				return (-1);
270c18ec02fSPetter Reinholdtsen 			}
271c18ec02fSPetter Reinholdtsen 		} else {
272c18ec02fSPetter Reinholdtsen 			verbose = verbose + 1;
273c18ec02fSPetter Reinholdtsen 		}
274c18ec02fSPetter Reinholdtsen 		return 0;
275c18ec02fSPetter Reinholdtsen 	}
276c18ec02fSPetter Reinholdtsen 	if (strncmp(argv[0], "csv", 3) == 0) {
277c18ec02fSPetter Reinholdtsen 		if (argc > 1) {
278c18ec02fSPetter Reinholdtsen 			if (str2int(argv[1], &csv_output) != 0) {
279c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR,
280c18ec02fSPetter Reinholdtsen 						"Given csv '%s' argument is invalid.",
281c18ec02fSPetter Reinholdtsen 						argv[1]);
282c18ec02fSPetter Reinholdtsen 				return (-1);
283c18ec02fSPetter Reinholdtsen 			}
284c18ec02fSPetter Reinholdtsen 		} else {
285c18ec02fSPetter Reinholdtsen 			csv_output = 1;
286c18ec02fSPetter Reinholdtsen 		}
287c18ec02fSPetter Reinholdtsen 		return 0;
288c18ec02fSPetter Reinholdtsen 	}
289c18ec02fSPetter Reinholdtsen 
290c18ec02fSPetter Reinholdtsen 	/* the rest need an argument */
291c18ec02fSPetter Reinholdtsen 	if (argc == 1) {
292c18ec02fSPetter Reinholdtsen 		ipmi_set_usage();
293c18ec02fSPetter Reinholdtsen 		return -1;
294c18ec02fSPetter Reinholdtsen 	}
295c18ec02fSPetter Reinholdtsen 
296c18ec02fSPetter Reinholdtsen 	if (strncmp(argv[0], "host", 4) == 0 ||
297c18ec02fSPetter Reinholdtsen 	    strncmp(argv[0], "hostname", 8) == 0) {
298c18ec02fSPetter Reinholdtsen 		ipmi_intf_session_set_hostname(intf, argv[1]);
299c18ec02fSPetter Reinholdtsen 		if (intf->session == NULL) {
300c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Failed to set session hostname.");
301c18ec02fSPetter Reinholdtsen 			return (-1);
302c18ec02fSPetter Reinholdtsen 		}
303c18ec02fSPetter Reinholdtsen 		printf("Set session hostname to %s\n",
304*eb541367SZdenek Styblik 				intf->ssn_params.hostname);
305c18ec02fSPetter Reinholdtsen 	}
306c18ec02fSPetter Reinholdtsen 	else if (strncmp(argv[0], "user", 4) == 0 ||
307c18ec02fSPetter Reinholdtsen 		 strncmp(argv[0], "username", 8) == 0) {
308c18ec02fSPetter Reinholdtsen 		ipmi_intf_session_set_username(intf, argv[1]);
309c18ec02fSPetter Reinholdtsen 		if (intf->session == NULL) {
310c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Failed to set session username.");
311c18ec02fSPetter Reinholdtsen 			return (-1);
312c18ec02fSPetter Reinholdtsen 		}
313c18ec02fSPetter Reinholdtsen 		printf("Set session username to %s\n",
314*eb541367SZdenek Styblik 				intf->ssn_params.username);
315c18ec02fSPetter Reinholdtsen 	}
316c18ec02fSPetter Reinholdtsen 	else if (strncmp(argv[0], "pass", 4) == 0 ||
317c18ec02fSPetter Reinholdtsen 		 strncmp(argv[0], "password", 8) == 0) {
318c18ec02fSPetter Reinholdtsen 		ipmi_intf_session_set_password(intf, argv[1]);
319c18ec02fSPetter Reinholdtsen 		if (intf->session == NULL) {
320c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Failed to set session password.");
321c18ec02fSPetter Reinholdtsen 			return (-1);
322c18ec02fSPetter Reinholdtsen 		}
323c18ec02fSPetter Reinholdtsen 		printf("Set session password\n");
324c18ec02fSPetter Reinholdtsen 	}
325c18ec02fSPetter Reinholdtsen 	else if (strncmp(argv[0], "authtype", 8) == 0) {
326c18ec02fSPetter Reinholdtsen 		int authtype;
327c18ec02fSPetter Reinholdtsen 		authtype = str2val(argv[1], ipmi_authtype_session_vals);
328c18ec02fSPetter Reinholdtsen 		if (authtype == 0xFF) {
329c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Invalid authtype: %s",
330c18ec02fSPetter Reinholdtsen 					argv[1]);
331c18ec02fSPetter Reinholdtsen 			return (-1);
332c18ec02fSPetter Reinholdtsen 		}
333c18ec02fSPetter Reinholdtsen 		ipmi_intf_session_set_authtype(intf, authtype);
334c18ec02fSPetter Reinholdtsen 		if (intf->session == NULL) {
335c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Failed to set session authtype.");
336c18ec02fSPetter Reinholdtsen 			return (-1);
337c18ec02fSPetter Reinholdtsen 		}
338c18ec02fSPetter Reinholdtsen 		printf("Set session authtype to %s\n",
339*eb541367SZdenek Styblik 		       val2str(intf->ssn_params.authtype_set,
340c18ec02fSPetter Reinholdtsen 				   ipmi_authtype_session_vals));
341c18ec02fSPetter Reinholdtsen 	}
342c18ec02fSPetter Reinholdtsen 	else if (strncmp(argv[0], "privlvl", 7) == 0) {
343c18ec02fSPetter Reinholdtsen 		int privlvl;
344c18ec02fSPetter Reinholdtsen 		privlvl = str2val(argv[1], ipmi_privlvl_vals);
345c18ec02fSPetter Reinholdtsen 		if (privlvl == 0xFF) {
346c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Invalid privilege level: %s",
347c18ec02fSPetter Reinholdtsen 					argv[1]);
348c18ec02fSPetter Reinholdtsen 			return (-1);
349c18ec02fSPetter Reinholdtsen 		}
350c18ec02fSPetter Reinholdtsen 		ipmi_intf_session_set_privlvl(intf, privlvl);
351c18ec02fSPetter Reinholdtsen 		if (intf->session == NULL) {
352c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR,
353c18ec02fSPetter Reinholdtsen 					"Failed to set session privilege level.");
354c18ec02fSPetter Reinholdtsen 			return (-1);
355c18ec02fSPetter Reinholdtsen 		}
356c18ec02fSPetter Reinholdtsen 		printf("Set session privilege level to %s\n",
357*eb541367SZdenek Styblik 		       val2str(intf->ssn_params.privlvl,
358c18ec02fSPetter Reinholdtsen 				   ipmi_privlvl_vals));
359c18ec02fSPetter Reinholdtsen 	}
360c18ec02fSPetter Reinholdtsen 	else if (strncmp(argv[0], "port", 4) == 0) {
361c18ec02fSPetter Reinholdtsen 		int port = 0;
362c18ec02fSPetter Reinholdtsen 		if (str2int(argv[1], &port) != 0 || port > MAX_PORT) {
363c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Given port '%s' is invalid.",
364c18ec02fSPetter Reinholdtsen 					argv[1]);
365c18ec02fSPetter Reinholdtsen 			return (-1);
366c18ec02fSPetter Reinholdtsen 		}
367c18ec02fSPetter Reinholdtsen 		ipmi_intf_session_set_port(intf, port);
368c18ec02fSPetter Reinholdtsen 		if (intf->session == NULL) {
369c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Failed to set session port.");
370c18ec02fSPetter Reinholdtsen 			return (-1);
371c18ec02fSPetter Reinholdtsen 		}
372*eb541367SZdenek Styblik 		printf("Set session port to %d\n", intf->ssn_params.port);
373c18ec02fSPetter Reinholdtsen 	}
374c18ec02fSPetter Reinholdtsen 	else if (strncmp(argv[0], "localaddr", 9) == 0) {
375c18ec02fSPetter Reinholdtsen 		uint8_t my_addr = 0;
376c18ec02fSPetter Reinholdtsen 		if (str2uchar(argv[1], &my_addr) != 0) {
377c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Given localaddr '%s' is invalid.",
378c18ec02fSPetter Reinholdtsen 					argv[1]);
379c18ec02fSPetter Reinholdtsen 			return (-1);
380c18ec02fSPetter Reinholdtsen 		}
381c18ec02fSPetter Reinholdtsen 		intf->my_addr = my_addr;
382c18ec02fSPetter Reinholdtsen 		printf("Set local IPMB address to 0x%02x\n", intf->my_addr);
383c18ec02fSPetter Reinholdtsen 	}
384c18ec02fSPetter Reinholdtsen 	else if (strncmp(argv[0], "targetaddr", 10) == 0) {
385c18ec02fSPetter Reinholdtsen 		uint8_t target_addr = 0;
386c18ec02fSPetter Reinholdtsen 		if (str2uchar(argv[1], &target_addr) != 0) {
387c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Given targetaddr '%s' is invalid.",
388c18ec02fSPetter Reinholdtsen 					argv[1]);
389c18ec02fSPetter Reinholdtsen 			return (-1);
390c18ec02fSPetter Reinholdtsen 		}
391c18ec02fSPetter Reinholdtsen 		intf->target_addr = target_addr;
392c18ec02fSPetter Reinholdtsen 		printf("Set remote IPMB address to 0x%02x\n", intf->target_addr);
393c18ec02fSPetter Reinholdtsen 	}
394c18ec02fSPetter Reinholdtsen 	else {
395c18ec02fSPetter Reinholdtsen 		ipmi_set_usage();
396c18ec02fSPetter Reinholdtsen 		return -1;
397c18ec02fSPetter Reinholdtsen 	}
398c18ec02fSPetter Reinholdtsen 	return 0;
399c18ec02fSPetter Reinholdtsen }
400c18ec02fSPetter Reinholdtsen 
ipmi_exec_main(struct ipmi_intf * intf,int argc,char ** argv)401c18ec02fSPetter Reinholdtsen int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv)
402c18ec02fSPetter Reinholdtsen {
403c18ec02fSPetter Reinholdtsen 	FILE * fp;
404c18ec02fSPetter Reinholdtsen 	char buf[EXEC_BUF_SIZE];
405c18ec02fSPetter Reinholdtsen 	char * ptr, * tok, * ret, * tmp;
406c18ec02fSPetter Reinholdtsen 	int __argc, i, r;
407c18ec02fSPetter Reinholdtsen 	char * __argv[EXEC_ARG_SIZE];
408c18ec02fSPetter Reinholdtsen 	int rc=0;
409c18ec02fSPetter Reinholdtsen 
410c18ec02fSPetter Reinholdtsen 	if (argc < 1) {
411c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Usage: exec <filename>");
412c18ec02fSPetter Reinholdtsen 		return -1;
413c18ec02fSPetter Reinholdtsen 	}
414c18ec02fSPetter Reinholdtsen 
415c18ec02fSPetter Reinholdtsen 	fp = ipmi_open_file_read(argv[0]);
416c18ec02fSPetter Reinholdtsen 	if (fp == NULL)
417c18ec02fSPetter Reinholdtsen 		return -1;
418c18ec02fSPetter Reinholdtsen 
419c18ec02fSPetter Reinholdtsen 	while (feof(fp) == 0) {
420c18ec02fSPetter Reinholdtsen 		ret = fgets(buf, EXEC_BUF_SIZE, fp);
421c18ec02fSPetter Reinholdtsen 		if (ret == NULL)
422c18ec02fSPetter Reinholdtsen 			continue;
423c18ec02fSPetter Reinholdtsen 
424c18ec02fSPetter Reinholdtsen 		/* clip off optional comment tail indicated by # */
425c18ec02fSPetter Reinholdtsen 		ptr = strchr(buf, '#');
426c18ec02fSPetter Reinholdtsen 		if (ptr)
427c18ec02fSPetter Reinholdtsen 			*ptr = '\0';
428c18ec02fSPetter Reinholdtsen 		else
429c18ec02fSPetter Reinholdtsen 			ptr = buf + strlen(buf);
430c18ec02fSPetter Reinholdtsen 
431c18ec02fSPetter Reinholdtsen 		/* change "" and '' with spaces in the middle to ~ */
432c18ec02fSPetter Reinholdtsen 		ptr = buf;
433c18ec02fSPetter Reinholdtsen 		while (*ptr != '\0') {
434c18ec02fSPetter Reinholdtsen 			if (*ptr == '"') {
435c18ec02fSPetter Reinholdtsen 				ptr++;
436c18ec02fSPetter Reinholdtsen 				while (*ptr != '"' && *ptr != '\0') {
437c18ec02fSPetter Reinholdtsen 					if (isspace((int)*ptr))
438c18ec02fSPetter Reinholdtsen 						*ptr = '~';
439c18ec02fSPetter Reinholdtsen 					ptr++;
440c18ec02fSPetter Reinholdtsen 				}
441c18ec02fSPetter Reinholdtsen 			}
442c18ec02fSPetter Reinholdtsen 			if (*ptr == '\'') {
443c18ec02fSPetter Reinholdtsen 				ptr++;
444c18ec02fSPetter Reinholdtsen 				while (*ptr != '\'' && *ptr != '\0') {
445c18ec02fSPetter Reinholdtsen 					if (isspace((int)*ptr))
446c18ec02fSPetter Reinholdtsen 						*ptr = '~';
447c18ec02fSPetter Reinholdtsen 					ptr++;
448c18ec02fSPetter Reinholdtsen 				}
449c18ec02fSPetter Reinholdtsen 			}
450c18ec02fSPetter Reinholdtsen 			ptr++;
451c18ec02fSPetter Reinholdtsen 		}
452c18ec02fSPetter Reinholdtsen 
453c18ec02fSPetter Reinholdtsen 		/* clip off trailing and leading whitespace */
454c18ec02fSPetter Reinholdtsen 		ptr--;
455c18ec02fSPetter Reinholdtsen 		while (isspace((int)*ptr) && ptr >= buf)
456c18ec02fSPetter Reinholdtsen 			*ptr-- = '\0';
457c18ec02fSPetter Reinholdtsen 		ptr = buf;
458c18ec02fSPetter Reinholdtsen 		while (isspace((int)*ptr))
459c18ec02fSPetter Reinholdtsen 			ptr++;
460c18ec02fSPetter Reinholdtsen 		if (strlen(ptr) == 0)
461c18ec02fSPetter Reinholdtsen 			continue;
462c18ec02fSPetter Reinholdtsen 
463c18ec02fSPetter Reinholdtsen 		/* parse it and make argument list */
464c18ec02fSPetter Reinholdtsen 		__argc = 0;
465c18ec02fSPetter Reinholdtsen 		for (tok = strtok(ptr, " "); tok != NULL; tok = strtok(NULL, " ")) {
466c18ec02fSPetter Reinholdtsen 			if (__argc < EXEC_ARG_SIZE) {
467c18ec02fSPetter Reinholdtsen 				__argv[__argc++] = strdup(tok);
468c18ec02fSPetter Reinholdtsen 				if (__argv[__argc-1] == NULL) {
469c18ec02fSPetter Reinholdtsen 					lprintf(LOG_ERR, "ipmitool: malloc failure");
470c076fde0SZdenek Styblik 					if (fp) {
471c076fde0SZdenek Styblik 						fclose(fp);
472c076fde0SZdenek Styblik 						fp = NULL;
473c076fde0SZdenek Styblik 					}
474c18ec02fSPetter Reinholdtsen 					return -1;
475c18ec02fSPetter Reinholdtsen 				}
476c18ec02fSPetter Reinholdtsen 				tmp = __argv[__argc-1];
477c18ec02fSPetter Reinholdtsen 				if (*tmp == '\'') {
478c18ec02fSPetter Reinholdtsen 					memmove(tmp, tmp+1, strlen(tmp));
479c18ec02fSPetter Reinholdtsen 					while (*tmp != '\'' && *tmp != '\0') {
480c18ec02fSPetter Reinholdtsen 						if (*tmp == '~')
481c18ec02fSPetter Reinholdtsen 							*tmp = ' ';
482c18ec02fSPetter Reinholdtsen 						tmp++;
483c18ec02fSPetter Reinholdtsen 					}
484c18ec02fSPetter Reinholdtsen 					*tmp = '\0';
485c18ec02fSPetter Reinholdtsen 				}
486c18ec02fSPetter Reinholdtsen 				if (*tmp == '"') {
487c18ec02fSPetter Reinholdtsen 					memmove(tmp, tmp+1, strlen(tmp));
488c18ec02fSPetter Reinholdtsen 					while (*tmp != '"' && *tmp != '\0') {
489c18ec02fSPetter Reinholdtsen 						if (*tmp == '~')
490c18ec02fSPetter Reinholdtsen 							*tmp = ' ';
491c18ec02fSPetter Reinholdtsen 						tmp++;
492c18ec02fSPetter Reinholdtsen 					}
493c18ec02fSPetter Reinholdtsen 					*tmp = '\0';
494c18ec02fSPetter Reinholdtsen 				}
495c18ec02fSPetter Reinholdtsen 			}
496c18ec02fSPetter Reinholdtsen 		}
497c18ec02fSPetter Reinholdtsen 
498c18ec02fSPetter Reinholdtsen 		/* now run the command, save the result if not successful */
499c18ec02fSPetter Reinholdtsen 		r = ipmi_cmd_run(intf, __argv[0], __argc-1, &(__argv[1]));
500c18ec02fSPetter Reinholdtsen 		if (r != 0)
501c18ec02fSPetter Reinholdtsen 			rc = r;
502c18ec02fSPetter Reinholdtsen 
503c18ec02fSPetter Reinholdtsen 		/* free argument list */
504c18ec02fSPetter Reinholdtsen 		for (i=0; i<__argc; i++) {
505c18ec02fSPetter Reinholdtsen 			if (__argv[i] != NULL) {
506c18ec02fSPetter Reinholdtsen 				free(__argv[i]);
507c18ec02fSPetter Reinholdtsen 				__argv[i] = NULL;
508c18ec02fSPetter Reinholdtsen 			}
509c18ec02fSPetter Reinholdtsen 		}
510c18ec02fSPetter Reinholdtsen 	}
511c18ec02fSPetter Reinholdtsen 
512c18ec02fSPetter Reinholdtsen 	fclose(fp);
513c18ec02fSPetter Reinholdtsen 	return rc;
514c18ec02fSPetter Reinholdtsen }
515