1 /*****************************************************************************\
2  *  $Id: ipmipower_prompt.c,v 1.121 2010-08-06 18:38:37 chu11 Exp $
3  *****************************************************************************
4  *  Copyright (C) 2007-2015 Lawrence Livermore National Security, LLC.
5  *  Copyright (C) 2003-2007 The Regents of the University of California.
6  *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
7  *  Written by Albert Chu <chu11@llnl.gov>
8  *  UCRL-CODE-155698
9  *
10  *  This file is part of Ipmipower, a remote power control utility.
11  *  For details, see http://www.llnl.gov/linux/.
12  *
13  *  Ipmipower is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU General Public License as published by the
15  *  Free Software Foundation; either version 3 of the License, or (at your
16  *  option) any later version.
17  *
18  *  Ipmipower is distributed in the hope that it will be useful, but
19  *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20  *  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21  *  for more details.
22  *
23  *  You should have received a copy of the GNU General Public License along
24  *  with Ipmipower.  If not, see <http://www.gnu.org/licenses/>.
25 \*****************************************************************************/
26 
27 #if HAVE_CONFIG_H
28 #include "config.h"
29 #endif /* HAVE_CONFIG_H */
30 
31 #include <stdio.h>
32 #include <stdlib.h>
33 #if STDC_HEADERS
34 #include <string.h>
35 #endif /* STDC_HEADERS */
36 #include <stdint.h>
37 #include <sys/stat.h>
38 #if HAVE_FCNTL_H
39 #include <fcntl.h>
40 #endif /* HAVE_FCNTL_H */
41 #include <assert.h>
42 #if HAVE_UNISTD_H
43 #include <unistd.h>
44 #endif /* HAVE_UNISTD_H */
45 #include <errno.h>
46 
47 #include "ipmipower_prompt.h"
48 #include "ipmipower_error.h"
49 #include "ipmipower_connection.h"
50 #include "ipmipower_oem.h"
51 #include "ipmipower_ping.h"
52 #include "ipmipower_powercmd.h"
53 #include "ipmipower_output.h"
54 #include "ipmipower_util.h"
55 
56 #include "argv.h"
57 
58 #include "freeipmi-portability.h"
59 #include "cbuf.h"
60 #include "fi_hostlist.h"
61 #include "pstdout.h"
62 #include "tool-cmdline-common.h"
63 #include "tool-util-common.h"
64 
65 extern cbuf_t ttyout;
66 extern cbuf_t ttyin;
67 
68 extern struct ipmipower_arguments cmd_args;
69 extern struct ipmipower_connection *ics;
70 
71 extern unsigned int ics_len;
72 
73 extern struct oem_power_type_data *oem_power_type_data;
74 
75 extern unsigned int output_counts[IPMIPOWER_MSG_TYPE_NUM_ENTRIES];
76 
77 /* eliminate
78  *
79  * Note: only for non-interactive mode on the command line.  Won't be
80  * anywhere in this file.
81  */
82 
83 static void
_cmd_driver_type(char ** argv)84 _cmd_driver_type (char **argv)
85 {
86   assert (argv);
87 
88   if (argv[1])
89     {
90       int tmp;
91 
92       if ((tmp = parse_outofband_driver_type (argv[1])) < 0)
93         ipmipower_cbuf_printf (ttyout,
94                                "invalid driver type '%s' specified\n",
95                                argv[1]);
96       else
97         {
98           cmd_args.common_args.driver_type = tmp;
99           ipmipower_cbuf_printf (ttyout,
100                                  "driver type is now %s\n",
101                                  argv[1]);
102         }
103     }
104   else
105     ipmipower_cbuf_printf (ttyout,
106                            "driver_type must be specified: %s, %s\n",
107                            IPMI_PARSE_DEVICE_LAN_STR,
108                            IPMI_PARSE_DEVICE_LAN_2_0_STR);
109 }
110 
111 static void
_cmd_hostname_clear(void)112 _cmd_hostname_clear (void)
113 {
114   free (cmd_args.common_args.hostname);
115   cmd_args.common_args.hostname = NULL;
116 
117   ipmipower_connection_array_destroy (ics, ics_len);
118   ics = NULL;
119   ics_len = 0;
120 }
121 
122 static void
_cmd_hostname(char ** argv)123 _cmd_hostname (char **argv)
124 {
125   assert (argv);
126 
127   if (!argv[1])
128     {
129       _cmd_hostname_clear ();
130       ipmipower_cbuf_printf (ttyout, "hostname(s) unconfigured\n");
131     }
132   else
133     {
134       struct ipmipower_connection *icsPtr;
135       unsigned int len = 0;
136 
137       if (!(icsPtr = ipmipower_connection_array_create (argv[1], &len)))
138         {
139           /* dump error outputs here, most notably invalid hostname output */
140           if (cbuf_read_to_fd (ttyout, STDOUT_FILENO, -1) > 0)
141             return;
142           else
143             ipmipower_cbuf_printf (ttyout,
144                                    "ipmipower_connection_array_create: %s\n",
145                                    strerror (errno));
146           return;
147         }
148 
149       _cmd_hostname_clear ();
150 
151       ics = icsPtr;
152       ics_len = len;
153 
154       if (!(cmd_args.common_args.hostname = strdup (argv[1])))
155         {
156           IPMIPOWER_ERROR (("strdup: %s", strerror(errno)));
157           exit (EXIT_FAILURE);
158         }
159 
160       ipmipower_ping_force_discovery_sweep ();
161 
162       ipmipower_cbuf_printf (ttyout,
163                              "hostname: %s\n",
164                              cmd_args.common_args.hostname);
165     }
166 }
167 
168 static void
_cmd_username(char ** argv)169 _cmd_username (char **argv)
170 {
171   assert (argv);
172 
173   if (!argv[1]
174       || (argv[1] && strlen (argv[1]) <= IPMI_MAX_USER_NAME_LENGTH))
175     {
176       free (cmd_args.common_args.username);
177       cmd_args.common_args.username = NULL;
178 
179       if (argv[1])
180         {
181           if (!(cmd_args.common_args.username = strdup (argv[1])))
182             {
183               IPMIPOWER_ERROR (("strdup: %s", strerror(errno)));
184               exit (EXIT_FAILURE);
185             }
186         }
187 
188       ipmipower_cbuf_printf (ttyout,
189                              "username: %s\n",
190                              (cmd_args.common_args.username) ? cmd_args.common_args.username : "NULL");
191     }
192   else
193     ipmipower_cbuf_printf (ttyout, "username invalid length\n");
194 }
195 
196 static void
_cmd_password(char ** argv)197 _cmd_password (char **argv)
198 {
199   assert (argv);
200 
201   if (argv[1] && cmd_args.common_args.authentication_type == IPMI_AUTHENTICATION_TYPE_NONE)
202     ipmipower_cbuf_printf (ttyout,
203                            "password cannot be set for authentication_type '%s'\n",
204                            IPMI_PARSE_AUTHENTICATION_TYPE_NONE_STR);
205   else if (!argv[1]
206            || (argv[1]
207                && ((cmd_args.common_args.driver_type == IPMI_DEVICE_LAN_2_0
208                     && strlen (argv[1]) <= IPMI_2_0_MAX_PASSWORD_LENGTH)
209                    || (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN
210                        && strlen (argv[1]) <= IPMI_1_5_MAX_PASSWORD_LENGTH))))
211     {
212       free (cmd_args.common_args.password);
213       cmd_args.common_args.password = NULL;
214 
215       if (argv[1])
216         {
217           if (!(cmd_args.common_args.password = strdup (argv[1])))
218             {
219               IPMIPOWER_ERROR (("strdup: %s", strerror(errno)));
220               exit (EXIT_FAILURE);
221             }
222         }
223 
224 #ifdef NDEBUG
225       ipmipower_cbuf_printf (ttyout, "password changed\n");
226 #else  /* !NDEBUG */
227       ipmipower_cbuf_printf (ttyout,
228                              "password: %s\n",
229                              (cmd_args.common_args.password) ? cmd_args.common_args.password : "NULL");
230 #endif /* !NDEBUG */
231     }
232   else
233     ipmipower_cbuf_printf (ttyout, "password invalid length\n");
234 }
235 
236 static void
_cmd_k_g(char ** argv)237 _cmd_k_g (char **argv)
238 {
239   int rv = 0;
240 #ifndef NDEBUG
241   char buf[IPMI_MAX_K_G_LENGTH*2+3];
242 #endif /* !NDEBUG */
243 
244   assert (argv);
245 
246   if (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN)
247     ipmipower_cbuf_printf (ttyout, "k_g is only used for IPMI 2.0");
248   else
249     {
250       memset (cmd_args.common_args.k_g, '\0', IPMI_MAX_K_G_LENGTH + 1);
251 
252       if (argv[1])
253         rv = parse_kg (cmd_args.common_args.k_g, IPMI_MAX_K_G_LENGTH, argv[1]);
254 
255       if (rv < 0)
256         ipmipower_cbuf_printf (ttyout, "k_g invalid\n");
257       else
258         {
259           cmd_args.common_args.k_g_len = rv;
260 #ifdef NDEBUG
261           ipmipower_cbuf_printf (ttyout, "k_g changed\n");
262 #else  /* !NDEBUG */
263           ipmipower_cbuf_printf (ttyout,
264 "k_g: %s\n",
265                                  (cmd_args.common_args.k_g_len) ? format_kg (buf,
266                                                                              IPMI_MAX_K_G_LENGTH*2+3,
267                                                                              cmd_args.common_args.k_g) : "NULL");
268 #endif /* !NDEBUG */
269         }
270     }
271 }
272 
273 static void
_cmd_authentication_type(char ** argv)274 _cmd_authentication_type (char **argv)
275 {
276   assert (argv);
277 
278   if (argv[1])
279     {
280       int tmp;
281 
282       if ((tmp = parse_authentication_type (argv[1])) < 0)
283         ipmipower_cbuf_printf (ttyout,
284                                "%s invalid authentication_type\n",
285                                argv[1]);
286       else
287         {
288           cmd_args.common_args.authentication_type = tmp;
289           ipmipower_cbuf_printf (ttyout,
290                                  "authentication type is now %s\n",
291                                  argv[1]);
292         }
293     }
294   else
295     ipmipower_cbuf_printf (ttyout,
296                            "authentication_type must be specified: %s, %s, %s, %s\n",
297                            IPMI_PARSE_AUTHENTICATION_TYPE_NONE_STR,
298                            IPMI_PARSE_AUTHENTICATION_TYPE_STRAIGHT_PASSWORD_KEY_STR,
299                            IPMI_PARSE_AUTHENTICATION_TYPE_MD2_STR,
300                            IPMI_PARSE_AUTHENTICATION_TYPE_MD5_STR);
301 }
302 
303 static void
_cmd_cipher_suite_id(char ** argv)304 _cmd_cipher_suite_id (char **argv)
305 {
306   assert (argv);
307 
308   if (argv[1])
309     {
310       char *endptr;
311       int tmp;
312 
313       errno = 0;
314       tmp = strtol (argv[1], &endptr, 10);
315       if (errno
316           || endptr[0] != '\0'
317           || tmp < IPMI_CIPHER_SUITE_ID_MIN
318           || tmp > IPMI_CIPHER_SUITE_ID_MAX)
319         ipmipower_cbuf_printf (ttyout,
320                                "%s invalid cipher suite id\n",
321                                argv[1]);
322       else if (!IPMI_CIPHER_SUITE_ID_SUPPORTED (tmp))
323         ipmipower_cbuf_printf (ttyout,
324                                "%s unsupported cipher suite id\n",
325                                argv[1]);
326       else
327         {
328           cmd_args.common_args.cipher_suite_id = tmp;
329           ipmipower_cbuf_printf (ttyout,
330                                  "cipher suite id is now %s\n",
331                                  argv[1]);
332         }
333     }
334   else
335     ipmipower_cbuf_printf (ttyout,
336                            "cipher_suite_id must be specified: 0, 1, 2, 3, 6, 7, 8, 11, 12\n");
337 }
338 
339 static void
_cmd_privilege_level(char ** argv)340 _cmd_privilege_level (char **argv)
341 {
342   assert (argv);
343 
344   if (argv[1])
345     {
346       int tmp;
347 
348       if ((tmp = parse_privilege_level (argv[1])) < 0)
349         ipmipower_cbuf_printf (ttyout,
350                                "%s invalid privilege_level\n",
351                                argv[1]);
352       else
353         {
354           cmd_args.common_args.authentication_type = tmp;
355           ipmipower_cbuf_printf (ttyout,
356                                  "privilege_level type is now %s\n",
357                                  argv[1]);
358         }
359     }
360   else
361     ipmipower_cbuf_printf (ttyout,
362                            "privilege must be specified: %s, %s, %s\n",
363                            IPMI_PARSE_PRIVILEGE_LEVEL_USER_STR,
364                            IPMI_PARSE_PRIVILEGE_LEVEL_OPERATOR_STR,
365                            IPMI_PARSE_PRIVILEGE_LEVEL_ADMIN_STR);
366 }
367 
368 static void
_cmd_workaround_flags(char ** argv)369 _cmd_workaround_flags (char **argv)
370 {
371   assert (argv);
372 
373   if (argv[1])
374     {
375       unsigned int outofband_flags, outofband_2_0_flags;
376 
377       if (parse_workaround_flags_tool (argv[1],
378                                        &outofband_flags,
379                                        &outofband_2_0_flags,
380                                        NULL,
381                                        NULL,
382                                        NULL) < 0)
383         ipmipower_cbuf_printf (ttyout,
384                                "%s invalid workaround flags specified\n",
385                                argv[1]);
386       else
387         {
388           cmd_args.common_args.workaround_flags_outofband = outofband_flags;
389           cmd_args.common_args.workaround_flags_outofband_2_0 = outofband_2_0_flags;
390           ipmipower_cbuf_printf (ttyout,
391                                  "workaround flags are now %s\n",
392                                  argv[1]);
393         }
394     }
395   else
396     ipmipower_cbuf_printf (ttyout,
397                            "workaround_flags must be specified: %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n",
398                            IPMI_PARSE_WORKAROUND_FLAGS_NONE_STR,
399                            IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_AUTHENTICATION_CAPABILITIES_STR,
400                            IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_NO_CHECKSUM_CHECK_STR,
401                            IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_ACCEPT_SESSION_ID_ZERO_STR,
402                            IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_FORCE_PERMSG_AUTHENTICATION_STR,
403                            IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_CHECK_UNEXPECTED_AUTHCODE_STR,
404                            IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_BIG_ENDIAN_SEQUENCE_NUMBER_STR,
405                            IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_NO_AUTH_CODE_CHECK_STR,
406                            IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_INTEL_2_0_SESSION_STR,
407                            IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_SUPERMICRO_2_0_SESSION_STR,
408                            IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_SUN_2_0_SESSION_STR,
409                            IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_OPEN_SESSION_PRIVILEGE_STR,
410                            IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_NON_EMPTY_INTEGRITY_CHECK_VALUE_STR,
411                            IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IPMIPING_STR);
412 }
413 
414 static void
_cmd_power_all_nodes(ipmipower_power_cmd_t cmd)415 _cmd_power_all_nodes (ipmipower_power_cmd_t cmd)
416 {
417   struct ipmipower_connection_extra_arg *eanode;
418   unsigned int nodes_queued = 0;
419   int i;
420 
421   assert (IPMIPOWER_POWER_CMD_VALID (cmd));
422 
423   memset (output_counts, '\0', sizeof (output_counts));
424 
425   for (i = 0; i < ics_len; i++)
426     {
427       if (cmd_args.ping_interval
428           && ics[i].discover_state == IPMIPOWER_DISCOVER_STATE_UNDISCOVERED)
429         ipmipower_output (IPMIPOWER_MSG_TYPE_NOTDISCOVERED, ics[i].hostname, NULL);
430       else if (cmd_args.ping_interval
431                && cmd_args.ping_packet_count
432                && cmd_args.ping_percent
433                && ics[i].discover_state == IPMIPOWER_DISCOVER_STATE_BADCONNECTION)
434         ipmipower_output (IPMIPOWER_MSG_TYPE_BADCONNECTION, ics[i].hostname, NULL);
435       else
436         {
437           if (cmd_args.oem_power_type != IPMIPOWER_OEM_POWER_TYPE_NONE)
438             {
439               eanode = ics[i].extra_args;
440               while (eanode)
441                 {
442                   if (ipmipower_oem_power_cmd_check_extra_arg (eanode->extra_arg,
443                                                                NULL,
444                                                                0) <= 0)
445                     ipmipower_output (IPMIPOWER_MSG_TYPE_INVALID_ARGUMENT_FOR_OEM_EXTENSION,
446                                       ics[i].hostname,
447                                       eanode->extra_arg);
448                   else
449                     {
450                       ipmipower_connection_clear (&ics[i]);
451                       ipmipower_powercmd_queue (cmd, &ics[i], eanode->extra_arg);
452                       nodes_queued++;
453                     }
454                   eanode = eanode->next;
455                 }
456             }
457           else
458             {
459               ipmipower_connection_clear (&ics[i]);
460               ipmipower_powercmd_queue (cmd, &ics[i], NULL);
461               nodes_queued++;
462             }
463         }
464     }
465 
466   /* Special corner case when no nodes are discovered */
467   if (!nodes_queued)
468     ipmipower_output_finish ();
469 }
470 
471 static void
_cmd_power_specific_nodes(char ** argv,ipmipower_power_cmd_t cmd)472 _cmd_power_specific_nodes (char **argv, ipmipower_power_cmd_t cmd)
473 {
474   fi_hostlist_t h = NULL;
475   fi_hostlist_iterator_t hitr = NULL;
476   fi_hostlist_t h2 = NULL;
477   fi_hostlist_iterator_t h2itr = NULL;
478   char *hstr = NULL;
479   char *h2str = NULL;
480 
481   assert (argv);
482   assert (IPMIPOWER_POWER_CMD_VALID (cmd));
483   assert (IPMIPOWER_OEM_POWER_TYPE_VALID (cmd_args.oem_power_type));
484 
485   if (!(h = fi_hostlist_create (argv[1])))
486     {
487       ipmipower_cbuf_printf (ttyout, "invalid hostname(s) specified\n");
488       goto cleanup;
489     }
490 
491   if (!(hitr = fi_hostlist_iterator_create (h)))
492     {
493       IPMIPOWER_ERROR (("fi_hostlist_iterator_create: %s", strerror (errno)));
494       exit (EXIT_FAILURE);
495     }
496 
497   memset (output_counts, '\0', sizeof (output_counts));
498 
499   while ((hstr = fi_hostlist_next (hitr)))
500     {
501       /* achu: The double fi_hostlist_create is to handle the corner case
502        * of someone inputting.
503        *
504        * foohost[1-3]+[1-3]
505        *
506        * We need to double fi_hostlist to get all the hosts and extra
507        * args.
508        *
509        * Under most scenarios, this is just inefficient code.  But we
510        * feel the performance hit isn't egregious.  In addition, the
511        * code logic is simpler to do it this way then have a whole
512        * bunch of wacky if-check scenarios to make it more efficient.
513        * We'll revisit as necessary in the future.
514        */
515 
516       if (!(h2 = fi_hostlist_create (hstr)))
517         {
518           ipmipower_cbuf_printf (ttyout, "invalid hostname(s) specified\n");
519           goto cleanup;
520         }
521 
522       fi_hostlist_uniq (h2);
523 
524       if (!(h2itr = fi_hostlist_iterator_create (h2)))
525         {
526           IPMIPOWER_ERROR (("fi_hostlist_iterator_create: %s", strerror (errno)));
527           exit (EXIT_FAILURE);
528         }
529 
530       while ((h2str = fi_hostlist_next (h2itr)))
531         {
532           char *h2str_extra_arg = NULL;
533           int i;
534 
535           if (cmd_args.oem_power_type != IPMIPOWER_OEM_POWER_TYPE_NONE)
536             {
537               char *ptr;
538 
539               if ((ptr = strchr (h2str, '+')))
540                 {
541                   *ptr = '\0';
542                   ptr++;
543 
544                   if (!(h2str_extra_arg = strdup (ptr)))
545                     {
546                       IPMIPOWER_ERROR (("strdup: %s", strerror(errno)));
547                       exit (EXIT_FAILURE);
548                     }
549                 }
550             }
551 
552           i = ipmipower_connection_hostname_index (ics, ics_len, h2str);
553 
554           if (i < 0)
555             ipmipower_output (IPMIPOWER_MSG_TYPE_UNCONFIGURED_HOSTNAME, h2str, NULL);
556           else if (cmd_args.ping_interval
557                    && ics[i].discover_state == IPMIPOWER_DISCOVER_STATE_UNDISCOVERED)
558             ipmipower_output (IPMIPOWER_MSG_TYPE_NOTDISCOVERED, ics[i].hostname, NULL);
559           else if (cmd_args.ping_interval
560                    && cmd_args.ping_packet_count
561                    && cmd_args.ping_percent
562                    && ics[i].discover_state == IPMIPOWER_DISCOVER_STATE_BADCONNECTION)
563             ipmipower_output (IPMIPOWER_MSG_TYPE_BADCONNECTION, ics[i].hostname, NULL);
564           else
565             {
566               if (cmd_args.oem_power_type != IPMIPOWER_OEM_POWER_TYPE_NONE)
567                 {
568                   if (ipmipower_oem_power_cmd_check_extra_arg (h2str_extra_arg,
569                                                                NULL,
570                                                                0) <= 0)
571                     {
572                       ipmipower_output (IPMIPOWER_MSG_TYPE_INVALID_ARGUMENT_FOR_OEM_EXTENSION,
573                                         ics[i].hostname,
574                                         h2str_extra_arg);
575                       goto end_inner_loop;
576                     }
577                   ipmipower_connection_clear (&ics[i]);
578                   ipmipower_powercmd_queue (cmd, &ics[i], h2str_extra_arg);
579                 }
580               else
581                 {
582                   ipmipower_connection_clear (&ics[i]);
583                   ipmipower_powercmd_queue (cmd, &ics[i], NULL);
584                 }
585             }
586 
587         end_inner_loop:
588           free (h2str_extra_arg);
589           free (h2str);
590           h2str = NULL;
591         }
592 
593       fi_hostlist_iterator_destroy (h2itr);
594       fi_hostlist_destroy (h2);
595       h2itr = NULL;
596       h2 = NULL;
597     }
598 
599  cleanup:
600   fi_hostlist_iterator_destroy (h2itr);
601   fi_hostlist_destroy (h2);
602   fi_hostlist_iterator_destroy (hitr);
603   fi_hostlist_destroy (h);
604   free (hstr);
605   free (h2str);
606 }
607 
608 static void
_cmd_power(char ** argv,ipmipower_power_cmd_t cmd)609 _cmd_power (char **argv, ipmipower_power_cmd_t cmd)
610 {
611   char errbuf[IPMIPOWER_OUTPUT_BUFLEN + 1];
612 
613   assert (argv);
614   assert (IPMIPOWER_POWER_CMD_VALID (cmd));
615   assert (IPMIPOWER_OEM_POWER_TYPE_VALID (cmd_args.oem_power_type));
616 
617   if (!cmd_args.common_args.hostname)
618     {
619       ipmipower_cbuf_printf (ttyout, "no hostname(s) configured\n");
620       return;
621     }
622 
623   memset (errbuf, '\0', IPMIPOWER_OUTPUT_BUFLEN + 1);
624   if (cmd_args.oem_power_type == IPMIPOWER_OEM_POWER_TYPE_NONE)
625     {
626       if (ipmipower_power_cmd_check_privilege (cmd,
627                                                errbuf,
628                                                IPMIPOWER_OUTPUT_BUFLEN) <= 0)
629         {
630           ipmipower_cbuf_printf (ttyout, "%s\n", errbuf);
631           return;
632         }
633     }
634   else
635     {
636       if (ipmipower_oem_power_cmd_check_support_and_privilege (cmd,
637                                                                errbuf,
638                                                                IPMIPOWER_OUTPUT_BUFLEN) <= 0)
639         {
640           ipmipower_cbuf_printf (ttyout, "%s\n", errbuf);
641           return;
642         }
643     }
644 
645   /* all nodes */
646   if (!argv[1])
647     _cmd_power_all_nodes (cmd);
648   else
649     _cmd_power_specific_nodes (argv, cmd);
650 }
651 
652 static void
_cmd_help(void)653 _cmd_help (void)
654 {
655   ipmipower_cbuf_printf (ttyout,
656                          "driver-type IPMIDRIVER                   - Specify the ipmi driver to use.\n"
657                          "hostname [IPMIHOST]                      - Specify a new set of hosts.  No input to unconfigure all hosts.\n"
658                          "username [USERNAME]                      - Specify a new username.  No input for null username.\n"
659                          "password [PASSWORD]                      - Specify a new password.  No input for null password.\n"
660                          "k_g [K_G]                                - Specify a new K_g BMC Key.  No input for null key.\n"
661                          "session-timeout MILLISECONDS             - Specify a new session timeout length.\n"
662                          "retransmission-timeout MILLISECONDS      - Specify a new retransmission timeout length.\n"
663                          "authentication-type AUTHENTICATION-TYPE  - Specify the authentication type to use.\n"
664                          "cipher-suite-id CIPHER-SUITE-ID          - Specify the cipher suite id to use.\n"
665                          "privilege-level PRIVILEGE-LEVEL          - Specify the privilege level to use.\n"
666                          "workaround-flags WORKAROUNDS             - Specify workaround flags.\n"
667                          "debug [on|off]                           - Toggle debug to stderr.\n");
668 #ifndef NDEBUG
669   ipmipower_cbuf_printf (ttyout,
670                          "rmcpdump [on|off]                        - Toggle RMCP dump output.\n");
671 #endif /* NDEBUG */
672   ipmipower_cbuf_printf (ttyout,
673                          "on [IPMIHOST(s)]                         - Turn on all configured hosts or specified hosts.\n"
674                          "off [IPMIHOST(s)]                        - Turn off all configured hosts or specified hosts.\n"
675                          "cycle [IPMIHOST(s)]                      - Power cycle all configured hosts or specified hosts.\n"
676                          "reset [IPMIHOST(s)]                      - Reset all configured hosts or specified hosts.\n"
677                          "stat [IPMIHOST(s)]                       - Query power status for all configured hosts or specified hosts.\n"
678                          "pulse [IPMIHOST(s)]                      - Pulse diagnostic interrupt all configured hosts or specified hosts.\n"
679                          "soft [IPMIHOST(s)]                       - Initiate a soft-shutdown for all configured hosts or specified hosts.\n"
680                          "identify-on [IPMIHOST(s)]                - Turn on physical system identification.\n"
681                          "identify-off [IPMIHOST(s)]               - Turn off physical system identification.\n"
682                          "identify-status [IPMIHOST(s)]            - Query physical system identification status.\n"
683                          "on-if-off [on|off]                       - Toggle on-if-off functionality.\n"
684                          "wait-until-on [on|off]                   - Toggle wait-until-on functionality.\n"
685                          "wait-until-off [on|off]                  - Toggle wait-until-off functionality.\n"
686                          "retransmission-wait-timeout MILLISECONDS - Specify a new retransmission timeout length.\n"
687                          "retransmission-backoff-count COUNT       - Specify a new retransmission backoff count.\n"
688                          "ping-interval MILLISECONDS               - Specify a new ping interval length.\n"
689                          "ping-timeout MILLISECONDS                - Specify a new ping timeout length.\n"
690                          "ping-packet-count COUNT                  - Specify a new ping packet count.\n"
691                          "ping-percent COUNT                       - Specify a new ping percent number.\n"
692                          "ping-consec-count COUNT                  - Specify a new ping consec count.\n"
693                          "buffer-output [on|off]                   - Toggle buffer-output functionality.\n"
694                          "consolidate-output [on|off]              - Toggle consolidate-output functionality.\n"
695                          "fanout COUNT                             - Specify a fanout.\n"
696                          "always-prefix [on|off]                   - Toggle always-prefix functionality.\n"
697                          "help                                     - Output help menu.\n"
698                          "version                                  - Output version.\n"
699                          "config                                   - Output current configuration.\n"
700                          "quit                                     - Quit program.\n");
701 }
702 
703 static void
_cmd_version(void)704 _cmd_version (void)
705 {
706   ipmipower_cbuf_printf (ttyout, "ipmipower %s\n", VERSION);
707 }
708 
709 static void
_workarounds_strcat(char * strbuf,unsigned int bitmask,unsigned int mask,const char * str,int * is_first)710 _workarounds_strcat (char *strbuf,
711                      unsigned int bitmask,
712                      unsigned int mask,
713                      const char *str,
714                      int *is_first)
715 {
716   assert (strbuf && str && is_first);
717 
718   if (bitmask & mask)
719     {
720       if ((*is_first))
721         strcat (strbuf, ",");
722       strcat (strbuf, str);
723       (*is_first)++;
724     }
725 }
726 
727 static void
_cmd_debug(char ** argv)728 _cmd_debug (char **argv)
729 {
730   assert (argv);
731 
732   if (!argv[1])
733     cmd_args.common_args.debug = !cmd_args.common_args.debug;
734   else
735     {
736       if (!strcasecmp (argv[1], "on"))
737         cmd_args.common_args.debug = 1;
738       else if (!strcasecmp (argv[1], "off"))
739         cmd_args.common_args.debug = 0;
740       else
741         {
742           ipmipower_cbuf_printf (ttyout, "invalid parameter\n");
743           return;
744         }
745     }
746   ipmipower_cbuf_printf (ttyout,
747                          "debugging is now %s\n", (cmd_args.common_args.debug) ? "on" : "off");
748 }
749 
750 static void
_cmd_config(void)751 _cmd_config (void)
752 {
753 #ifndef NDEBUG
754   char kgbuf[IPMI_MAX_K_G_LENGTH*2+3];
755 #endif /* NDEBUG */
756   char strbuf[IPMIPOWER_OUTPUT_BUFLEN];
757   char *str;
758   int is_first = 0;
759 
760   str = "";
761   if (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN)
762     str = IPMI_PARSE_DEVICE_LAN_STR;
763   else if (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN_2_0)
764     str = IPMI_PARSE_DEVICE_LAN_2_0_STR;
765 
766   ipmipower_cbuf_printf (ttyout,
767                          "Driver_Type:                  %s\n",
768                          str);
769 
770   if (cmd_args.common_args.hostname)
771     {
772 #ifndef NDEBUG
773       int i;
774       fi_hostlist_t discovered = NULL;
775       fi_hostlist_t undiscovered = NULL;
776       fi_hostlist_t badconnection = NULL;
777       char buf[IPMIPOWER_OUTPUT_BUFLEN];
778       int rv;
779 #endif /* NDEBUG */
780 
781       ipmipower_cbuf_printf (ttyout,
782                              "Hostname:                     %s\n",
783                              cmd_args.common_args.hostname);
784 
785 #ifndef NDEBUG
786       if (!(discovered = fi_hostlist_create (NULL)))
787         goto cleanup;
788       if (!(undiscovered = fi_hostlist_create (NULL)))
789         goto cleanup;
790       if (!(badconnection = fi_hostlist_create (NULL)))
791         goto cleanup;
792 
793       for (i = 0; i < ics_len; i++)
794         {
795           if (ics[i].discover_state == IPMIPOWER_DISCOVER_STATE_DISCOVERED)
796             rv = fi_hostlist_push_host (discovered, ics[i].hostname);
797           else if (ics[i].discover_state == IPMIPOWER_DISCOVER_STATE_UNDISCOVERED)
798             rv = fi_hostlist_push_host (undiscovered, ics[i].hostname);
799           else
800             rv = fi_hostlist_push_host (badconnection, ics[i].hostname);
801 
802           if (!rv)
803             goto cleanup;
804         }
805 
806       fi_hostlist_sort (discovered);
807       fi_hostlist_sort (undiscovered);
808       fi_hostlist_sort (badconnection);
809 
810       if ((rv = fi_hostlist_ranged_string (discovered, IPMIPOWER_OUTPUT_BUFLEN, buf)) < 0)
811         {
812           IPMIPOWER_ERROR (("fi_hostlist_ranged_string: %s", strerror (errno)));
813           exit (EXIT_FAILURE);
814         }
815 
816       if (rv > 0)
817         ipmipower_cbuf_printf (ttyout,
818                                "Discovered:                   %s\n",
819                                buf);
820 
821       if ((rv = fi_hostlist_ranged_string (undiscovered, IPMIPOWER_OUTPUT_BUFLEN, buf)) < 0)
822         {
823           IPMIPOWER_ERROR (("fi_hostlist_ranged_string: %s", strerror (errno)));
824           exit (EXIT_FAILURE);
825         }
826 
827       if (rv > 0)
828         ipmipower_cbuf_printf (ttyout,
829                                "Undiscovered:                 %s\n",
830                                buf);
831 
832       if ((rv = fi_hostlist_ranged_string (badconnection, IPMIPOWER_OUTPUT_BUFLEN, buf)) < 0)
833         {
834           IPMIPOWER_ERROR (("fi_hostlist_ranged_string: %s", strerror (errno)));
835           exit (EXIT_FAILURE);
836         }
837 
838       if (rv > 0)
839         ipmipower_cbuf_printf (ttyout,
840                                "BadConnection:                %s\n",
841                                buf);
842 
843     cleanup:
844       fi_hostlist_destroy (discovered);
845       fi_hostlist_destroy (undiscovered);
846       fi_hostlist_destroy (badconnection);
847 #endif /* NDEBUG */
848     }
849   else
850     ipmipower_cbuf_printf (ttyout,
851                            "Hostname:                     NONE\n");
852 
853   ipmipower_cbuf_printf (ttyout,
854                          "Username:                     %s\n",
855                          (cmd_args.common_args.username) ? cmd_args.common_args.username : "NULL");
856 
857 #ifndef NDEBUG
858   ipmipower_cbuf_printf (ttyout,
859                          "Password:                     %s\n",
860                          (cmd_args.common_args.password) ? cmd_args.common_args.password : "NULL");
861   ipmipower_cbuf_printf (ttyout,
862                          "K_g:                          %s\n",
863                          (cmd_args.common_args.k_g_len) ?
864                          format_kg (kgbuf, IPMI_MAX_K_G_LENGTH*2+3, cmd_args.common_args.k_g) : "NULL");
865 #else  /* !NDEBUG */
866   ipmipower_cbuf_printf (ttyout,
867                          "Password:                     *****\n");
868   ipmipower_cbuf_printf (ttyout,
869                          "K_g:                          *****\n");
870 #endif /* !NDEBUG */
871 
872   ipmipower_cbuf_printf (ttyout,
873                          "Session Timeout:              %u ms\n",
874                          cmd_args.common_args.session_timeout);
875   ipmipower_cbuf_printf (ttyout,
876                          "Retransmission Timeout:       %u ms\n",
877                          cmd_args.common_args.retransmission_timeout);
878 
879   str = "";
880   if (cmd_args.common_args.authentication_type == IPMI_AUTHENTICATION_TYPE_NONE)
881     str = IPMI_PARSE_AUTHENTICATION_TYPE_NONE_STR;
882   else if (cmd_args.common_args.authentication_type == IPMI_AUTHENTICATION_TYPE_MD2)
883     str = IPMI_PARSE_AUTHENTICATION_TYPE_MD2_STR;
884   else if (cmd_args.common_args.authentication_type == IPMI_AUTHENTICATION_TYPE_MD5)
885     str = IPMI_PARSE_AUTHENTICATION_TYPE_MD5_STR;
886   else if (cmd_args.common_args.authentication_type == IPMI_AUTHENTICATION_TYPE_STRAIGHT_PASSWORD_KEY)
887     str = IPMI_PARSE_AUTHENTICATION_TYPE_STRAIGHT_PASSWORD_KEY_STR;
888 
889   ipmipower_cbuf_printf (ttyout,
890                          "Authentication_Type:          %s\n",
891                          str);
892 
893   str = "";
894   if (cmd_args.common_args.cipher_suite_id == 0)
895     str = "0";
896   else if (cmd_args.common_args.cipher_suite_id == 1)
897     str = "1";
898   else if (cmd_args.common_args.cipher_suite_id == 2)
899     str = "2";
900   else if (cmd_args.common_args.cipher_suite_id == 3)
901     str = "3";
902   else if (cmd_args.common_args.cipher_suite_id == 6)
903     str = "6";
904   else if (cmd_args.common_args.cipher_suite_id == 7)
905     str = "7";
906   else if (cmd_args.common_args.cipher_suite_id == 8)
907     str = "8";
908   else if (cmd_args.common_args.cipher_suite_id == 11)
909     str = "11";
910   else if (cmd_args.common_args.cipher_suite_id == 12)
911     str = "12";
912 
913   ipmipower_cbuf_printf (ttyout,
914                          "Cipher Suite Id:              %s\n",
915                          str);
916 
917   str = "";
918   if (cmd_args.common_args.privilege_level == IPMI_PRIVILEGE_LEVEL_USER)
919     str = IPMI_PARSE_PRIVILEGE_LEVEL_USER_STR;
920   else if (cmd_args.common_args.privilege_level == IPMI_PRIVILEGE_LEVEL_OPERATOR)
921     str = IPMI_PARSE_PRIVILEGE_LEVEL_OPERATOR_STR;
922   else if (cmd_args.common_args.privilege_level == IPMI_PRIVILEGE_LEVEL_ADMIN)
923     str = IPMI_PARSE_PRIVILEGE_LEVEL_ADMIN_STR;
924 
925   ipmipower_cbuf_printf (ttyout,
926                          "Privilege_Level:              %s\n",
927                          str);
928 
929   memset (strbuf, '\0', IPMIPOWER_OUTPUT_BUFLEN);
930   is_first = 0;
931   _workarounds_strcat (strbuf,
932                        cmd_args.common_args.workaround_flags_outofband,
933                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_AUTHENTICATION_CAPABILITIES,
934                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_AUTHENTICATION_CAPABILITIES_STR,
935                        &is_first);
936   _workarounds_strcat (strbuf,
937                        cmd_args.common_args.workaround_flags_outofband,
938                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_ACCEPT_SESSION_ID_ZERO,
939                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_ACCEPT_SESSION_ID_ZERO_STR,
940                        &is_first);
941   _workarounds_strcat (strbuf,
942                        cmd_args.common_args.workaround_flags_outofband,
943                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_FORCE_PERMSG_AUTHENTICATION,
944                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_FORCE_PERMSG_AUTHENTICATION_STR,
945                        &is_first);
946   _workarounds_strcat (strbuf,
947                        cmd_args.common_args.workaround_flags_outofband,
948                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_CHECK_UNEXPECTED_AUTHCODE,
949                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_CHECK_UNEXPECTED_AUTHCODE_STR,
950                        &is_first);
951   _workarounds_strcat (strbuf,
952                        cmd_args.common_args.workaround_flags_outofband,
953                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_BIG_ENDIAN_SEQUENCE_NUMBER,
954                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_BIG_ENDIAN_SEQUENCE_NUMBER_STR,
955                        &is_first);
956   _workarounds_strcat (strbuf,
957                        cmd_args.common_args.workaround_flags_outofband,
958                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_NO_AUTH_CODE_CHECK,
959                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_NO_AUTH_CODE_CHECK_STR,
960                        &is_first);
961   _workarounds_strcat (strbuf,
962                        cmd_args.common_args.workaround_flags_outofband,
963                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_NO_CHECKSUM_CHECK,
964                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_NO_CHECKSUM_CHECK_STR,
965                        &is_first);
966   /* This is a duplicate of the IPMI 1.5 version */
967 #if 0
968   _workarounds_strcat (strbuf,
969                        cmd_args.common_args.workaround_flags_outofband_2_0,
970                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_AUTHENTICATION_CAPABILITIES,
971                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_AUTHENTICATION_CAPABILITIES_STR,
972                        &is_first);
973 #endif
974   _workarounds_strcat (strbuf,
975                        cmd_args.common_args.workaround_flags_outofband_2_0,
976                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_INTEL_2_0_SESSION,
977                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_INTEL_2_0_SESSION_STR,
978                        &is_first);
979   _workarounds_strcat (strbuf,
980                        cmd_args.common_args.workaround_flags_outofband_2_0,
981                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_SUPERMICRO_2_0_SESSION,
982                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_SUPERMICRO_2_0_SESSION_STR,
983                        &is_first);
984   _workarounds_strcat (strbuf,
985                        cmd_args.common_args.workaround_flags_outofband_2_0,
986                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_SUN_2_0_SESSION,
987                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_SUN_2_0_SESSION_STR,
988                        &is_first);
989   _workarounds_strcat (strbuf,
990                        cmd_args.common_args.workaround_flags_outofband_2_0,
991                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_OPEN_SESSION_PRIVILEGE,
992                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_OPEN_SESSION_PRIVILEGE_STR,
993                        &is_first);
994   _workarounds_strcat (strbuf,
995                        cmd_args.common_args.workaround_flags_outofband_2_0,
996                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_NON_EMPTY_INTEGRITY_CHECK_VALUE,
997                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_NON_EMPTY_INTEGRITY_CHECK_VALUE_STR,
998                        &is_first);
999   /* This is a duplicate of the IPMI 1.5 version */
1000 #if 0
1001   _workarounds_strcat (strbuf,
1002                        cmd_args.common_args.workaround_flags_outofband_2_0,
1003                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_NO_CHECKSUM_CHECK,
1004                        IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_NO_CHECKSUM_CHECK_STR,
1005                        &is_first);
1006 #endif
1007   _workarounds_strcat (strbuf,
1008                        cmd_args.common_args.workaround_flags_outofband_2_0,
1009                        IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IPMIPING,
1010                        IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IPMIPING_STR,
1011                        &is_first);
1012 
1013   ipmipower_cbuf_printf (ttyout,
1014                          "WorkaroundFlags:              %s\n",
1015                          strbuf);
1016 
1017   ipmipower_cbuf_printf (ttyout,
1018                          "Debug:                        %s\n",
1019                          cmd_args.common_args.debug ? "on" : "off");
1020 
1021 #ifndef NDEBUG
1022   ipmipower_cbuf_printf (ttyout,
1023                          "Rmcpdump:                     %s\n",
1024                          (cmd_args.rmcpdump) ? "on" : "off");
1025 #endif /* NDEBUG */
1026 
1027   ipmipower_cbuf_printf (ttyout,
1028                          "On-If-Off:                    %s\n",
1029                          (cmd_args.on_if_off) ? "enabled" : "disabled");
1030   ipmipower_cbuf_printf (ttyout,
1031                          "Wait-Until-On:                %s\n",
1032                          (cmd_args.wait_until_on) ? "enabled" : "disabled");
1033   ipmipower_cbuf_printf (ttyout,
1034                          "Wait-Until-Off:               %s\n",
1035                          (cmd_args.wait_until_off) ? "enabled" : "disabled");
1036   ipmipower_cbuf_printf (ttyout,
1037                          "Retransmission Wait Timeout:  %u ms\n",
1038                          cmd_args.retransmission_wait_timeout);
1039   ipmipower_cbuf_printf (ttyout,
1040                          "Retransmission Backoff Count: %u\n",
1041                          cmd_args.retransmission_backoff_count);
1042   ipmipower_cbuf_printf (ttyout,
1043                          "Ping Interval:                %u ms\n",
1044                          cmd_args.ping_interval);
1045   ipmipower_cbuf_printf (ttyout,
1046                          "Ping Timeout:                 %u ms\n",
1047                          cmd_args.ping_timeout);
1048   ipmipower_cbuf_printf (ttyout,
1049                          "Ping Packet Count:            %u\n",
1050                          cmd_args.ping_packet_count);
1051   ipmipower_cbuf_printf (ttyout,
1052                          "Ping Percent:                 %u percent\n",
1053                          cmd_args.ping_percent);
1054   ipmipower_cbuf_printf (ttyout,
1055                          "Ping Consec Count:            %u\n",
1056                          cmd_args.ping_consec_count);
1057 
1058   ipmipower_cbuf_printf (ttyout,
1059                          "Buffer-Output:                %s\n",
1060                          (cmd_args.common_args.buffer_output) ? "enabled" : "disabled");
1061   ipmipower_cbuf_printf (ttyout,
1062                          "Consolidate-Output:           %s\n",
1063                          (cmd_args.common_args.consolidate_output) ? "enabled" : "disabled");
1064   ipmipower_cbuf_printf (ttyout,
1065                          "Fanout:                       %u\n",
1066                          cmd_args.common_args.fanout);
1067   ipmipower_cbuf_printf (ttyout,
1068                          "Always-Prefix:                %s\n",
1069                          (cmd_args.common_args.always_prefix) ? "enabled" : "disabled");
1070 }
1071 
1072 static void
_cmd_set_unsigned_int(char ** argv,unsigned int * value,const char * str,int allow_zero)1073 _cmd_set_unsigned_int (char **argv,
1074                        unsigned int *value,
1075                        const char *str,
1076                        int allow_zero)
1077 {
1078   assert (argv && value && str);
1079 
1080   if (!argv[1])
1081     ipmipower_cbuf_printf (ttyout,
1082                            "%s not specified\n",
1083                            str);
1084   else
1085     {
1086       char *endptr;
1087       unsigned int temp;
1088 
1089       errno = 0;
1090       temp = strtoul (argv[1], &endptr, 10);
1091       if (errno
1092           || endptr[0] != '\0')
1093         ipmipower_cbuf_printf (ttyout,
1094                                "invalid %s input\n",
1095                                str);
1096       else if (allow_zero && !temp)
1097         {
1098           *value = temp;
1099           ipmipower_cbuf_printf (ttyout,
1100                                  "%s is now %d\n",
1101                                  str,
1102                                  *value);
1103         }
1104       else
1105         ipmipower_cbuf_printf (ttyout,
1106                                "invalid %s input\n",
1107                                str);
1108     }
1109 }
1110 
1111 static void
_cmd_set_unsigned_int_ranged(char ** argv,unsigned int * value,const char * str,int allow_zero,int min,int max)1112 _cmd_set_unsigned_int_ranged (char **argv,
1113                               unsigned int *value,
1114                               const char *str,
1115                               int allow_zero,
1116                               int min,
1117                               int max)
1118 {
1119   assert (argv && value && str);
1120 
1121   if (!argv[1])
1122     ipmipower_cbuf_printf (ttyout,
1123                            "%s not specified\n",
1124                            str);
1125   else
1126     {
1127       char *endptr;
1128       int temp;
1129 
1130       errno = 0;
1131       temp = strtol (argv[1], &endptr, 10);
1132       if (errno
1133           || endptr[0] != '\0')
1134         ipmipower_cbuf_printf (ttyout,
1135                                "invalid %s input\n",
1136                                str);
1137       else if ((allow_zero
1138                 && !temp)
1139                || (temp <= max
1140                    && temp >= min))
1141         {
1142           *value = temp;
1143           ipmipower_cbuf_printf (ttyout,
1144                                  "%s is now %d\n",
1145                                  str,
1146                                  *value);
1147         }
1148       else
1149         ipmipower_cbuf_printf (ttyout,
1150                                "invalid %s input, range is %d <=> %d\n",
1151                                str,
1152                                min,
1153                                max);
1154     }
1155 }
1156 
1157 static void
_cmd_set_flag(char ** argv,int * flag,const char * str)1158 _cmd_set_flag (char **argv, int *flag, const char *str)
1159 {
1160   assert (argv && flag && str);
1161 
1162   if (!argv[1])
1163     *flag = !(*flag);
1164   else
1165     {
1166       if (!strcasecmp (argv[1], "on"))
1167         *flag = 1;
1168       else if (!strcasecmp (argv[1], "off"))
1169         *flag = 0;
1170       else
1171         {
1172           ipmipower_cbuf_printf (ttyout, "invalid parameter\n");
1173           return;
1174         }
1175     }
1176   ipmipower_cbuf_printf (ttyout,
1177                          "%s is now %s\n",
1178                          str,
1179                          (*flag) ? "on" : "off");
1180 }
1181 
1182 /* _readcmd
1183  * - Read a command line from the tty and return it in buf.
1184  *   If no commands are available, return a null-terminated empty string.
1185  */
1186 static void
_readcmd(char * buf,int buflen)1187 _readcmd (char *buf, int buflen)
1188 {
1189   int dropped, bytes_peeked, len = 0;
1190 
1191   buf[0] = '\0';
1192   if ((bytes_peeked = cbuf_peek (ttyin, buf, buflen)) < 0)
1193     {
1194       IPMIPOWER_ERROR (("cbuf_peek: %s", strerror (errno)));
1195       exit (EXIT_FAILURE);
1196     }
1197 
1198   if (!bytes_peeked)
1199     return;
1200 
1201   for (len = 0; len < bytes_peeked; len++)
1202     {
1203       if (buf[len] == '\n')
1204         {
1205           buf[len+1] = '\0';
1206           break;
1207         }
1208     }
1209 
1210   if (len == bytes_peeked)
1211     return;
1212 
1213   len++;
1214 
1215   if ((dropped = cbuf_drop (ttyin, len)) != len)
1216     IPMIPOWER_DEBUG (("cbuf_drop returned %d != %d)", dropped, len));
1217 }
1218 
1219 int
ipmipower_prompt_process_cmdline(void)1220 ipmipower_prompt_process_cmdline (void)
1221 {
1222   static int need_prompt = 1;
1223   char *buf;
1224   int quit = 0;
1225 
1226   if (!(buf = (char *)malloc (IPMIPOWER_MAX_TTY_BUF)))
1227     {
1228       IPMIPOWER_ERROR (("malloc: %s", strerror(errno)));
1229       exit (EXIT_FAILURE);
1230     }
1231 
1232   do
1233     {
1234       if (ipmipower_powercmd_pending ())
1235         break;
1236       if (need_prompt)
1237         {
1238           ipmipower_cbuf_printf (ttyout, "ipmipower> ");
1239           need_prompt = 0;
1240         }
1241       buf[0] = '\0';
1242       _readcmd (buf, IPMIPOWER_MAX_TTY_BUF);
1243       if (strlen (buf) > 0)
1244         {
1245           char **argv = argv_create (buf, "");
1246           int i;
1247 
1248           if (argv[0])
1249             {
1250               /* support "ipmi_version" and "ipmi-version" for backwards compatability */
1251               if (!strcmp (argv[0], "driver-type")
1252                   || !strcmp (argv[0], "ipmi_version")
1253                   || !strcmp (argv[0], "ipmi-version"))
1254                 _cmd_driver_type (argv);
1255               /* support hostnames (plural) for backwards compatability */
1256               else if (!strcmp (argv[0], "hostnames")
1257                        || !strcmp (argv[0], "hostname"))
1258                 _cmd_hostname (argv);
1259               else if (!strcmp (argv[0], "username"))
1260                 _cmd_username (argv);
1261               else if (!strcmp (argv[0], "password"))
1262                 _cmd_password (argv);
1263               else if (!strcmp (argv[0], "k_g"))
1264                 _cmd_k_g (argv);
1265               /* support "timeout" for backwards compatability */
1266               else if (!strcmp (argv[0], "timeout")
1267                        || !strcmp (argv[0], "session-timeout"))
1268                 _cmd_set_unsigned_int (argv,
1269                                        &cmd_args.common_args.session_timeout,
1270                                        "timeout",
1271                                        0);
1272               /* support "retry-timeout" for backwards compatability */
1273               else if (!strcmp (argv[0], "retry-timeout")
1274                        || !strcmp (argv[0], "retransmission-timeout"))
1275                 _cmd_set_unsigned_int_ranged (argv,
1276                                               &cmd_args.common_args.retransmission_timeout,
1277                                               "retransmission-timeout",
1278                                               0,
1279                                               1,
1280                                               cmd_args.common_args.session_timeout);
1281               /* support underscored version for backwards compatability */
1282               else if (!strcmp (argv[0], "authentication_type")
1283                        || !strcmp (argv[0], "authentication-type"))
1284                 _cmd_authentication_type (argv);
1285               /* support underscored version for backwards compatability */
1286               else if (!strcmp (argv[0], "cipher_suite_id")
1287                        || !strcmp (argv[0], "cipher-suite-id"))
1288                 _cmd_cipher_suite_id (argv);
1289               /* support "privilege" command for backwards compatability */
1290               else if (!strcmp (argv[0], "privilege")
1291                        || !strcmp (argv[0], "privilege-level"))
1292                 _cmd_privilege_level (argv);
1293               else if (!strcmp (argv[0], "workaround-flags"))
1294                 _cmd_workaround_flags (argv);
1295               else if (!strcmp (argv[0], "debug"))
1296                 _cmd_debug (argv);
1297 #ifndef NDEBUG
1298               else if (!strcmp (argv[0], "rmcpdump"))
1299                 _cmd_set_flag (argv,
1300                                &cmd_args.rmcpdump,
1301                                "rmcp dump");
1302 #endif /* NDEBUG */
1303               else if (!strcmp (argv[0], "happyeaster"))
1304                 ipmipower_cbuf_printf (ttyout, "by Albert Chu <chu11@llnl.gov>\n");
1305               else if (!strcmp (argv[0], "on"))
1306                 _cmd_power (argv, IPMIPOWER_POWER_CMD_POWER_ON);
1307               else if (!strcmp (argv[0], "off"))
1308                 _cmd_power (argv, IPMIPOWER_POWER_CMD_POWER_OFF);
1309               else if (!strcmp (argv[0], "cycle"))
1310                 _cmd_power (argv, IPMIPOWER_POWER_CMD_POWER_CYCLE);
1311               else if (!strcmp (argv[0], "reset"))
1312                 _cmd_power (argv, IPMIPOWER_POWER_CMD_POWER_RESET);
1313               else if (!strcmp (argv[0], "stat"))
1314                 _cmd_power (argv, IPMIPOWER_POWER_CMD_POWER_STATUS);
1315               else if (!strcmp (argv[0], "pulse"))
1316                 _cmd_power (argv, IPMIPOWER_POWER_CMD_PULSE_DIAGNOSTIC_INTERRUPT);
1317               else if (!strcmp (argv[0], "soft"))
1318                 _cmd_power (argv, IPMIPOWER_POWER_CMD_SOFT_SHUTDOWN_OS);
1319               else if (!strcmp (argv[0], "identify-on"))
1320                 _cmd_power (argv, IPMIPOWER_POWER_CMD_IDENTIFY_ON);
1321               else if (!strcmp (argv[0], "identify-off"))
1322                 _cmd_power (argv, IPMIPOWER_POWER_CMD_IDENTIFY_OFF);
1323               else if (!strcmp (argv[0], "identify-status"))
1324                 _cmd_power (argv, IPMIPOWER_POWER_CMD_IDENTIFY_STATUS);
1325               else if (!strcmp (argv[0], "on-if-off"))
1326                 _cmd_set_flag (argv,
1327                                &cmd_args.on_if_off,
1328                                "on-if-off");
1329               else if (!strcmp (argv[0], "wait-until-on"))
1330                 _cmd_set_flag (argv,
1331                                &cmd_args.wait_until_on,
1332                                "wait-until-on");
1333               else if (!strcmp (argv[0], "wait-until-off"))
1334                 _cmd_set_flag (argv,
1335                                &cmd_args.wait_until_off,
1336                                "wait-until-off");
1337               /* support "retry-wait-timeout" for backwards compatability */
1338               else if (!strcmp (argv[0], "retry-wait-timeout")
1339                        || !strcmp (argv[0], "retransmission-wait-timeout"))
1340                 _cmd_set_unsigned_int_ranged (argv,
1341                                               &cmd_args.retransmission_wait_timeout,
1342                                               "retransmission-wait-timeout",
1343                                               0,
1344                                               1,
1345                                               cmd_args.common_args.session_timeout);
1346               /* support "retry-backoff-count" for backwards compatability */
1347               else if (!strcmp (argv[0], "retry-backoff-count")
1348                        || !strcmp (argv[0], "retransmission-backoff-count"))
1349                 _cmd_set_unsigned_int (argv,
1350                                        &cmd_args.retransmission_backoff_count,
1351                                        "retransmission-backoff-count",
1352                                        0);
1353               else if (!strcmp (argv[0], "ping-interval"))
1354                 _cmd_set_unsigned_int_ranged (argv,
1355                                               &cmd_args.ping_interval,
1356                                               "ping-interval",
1357                                               1,
1358                                               0,
1359                                               cmd_args.ping_timeout);
1360               else if (!strcmp (argv[0], "ping-timeout"))
1361                 _cmd_set_unsigned_int (argv,
1362                                        &cmd_args.ping_timeout,
1363                                        "ping-timeout",
1364                                        1);
1365               else if (!strcmp (argv[0], "ping-packet-count"))
1366                 _cmd_set_unsigned_int (argv,
1367                                        &cmd_args.ping_packet_count,
1368                                        "ping-packet-count",
1369                                        1);
1370               else if (!strcmp (argv[0], "ping-percent"))
1371                 _cmd_set_unsigned_int (argv,
1372                                        &cmd_args.ping_percent,
1373                                        "ping-percent",
1374                                        1);
1375               else if (!strcmp (argv[0], "ping-consec-count"))
1376                 _cmd_set_unsigned_int_ranged (argv,
1377                                               &cmd_args.ping_consec_count,
1378                                               "ping-consec-count",
1379                                               1,
1380                                               0,
1381                                               cmd_args.ping_packet_count);
1382               else if (!strcmp (argv[0], "buffer-output"))
1383                 _cmd_set_flag (argv,
1384                                &cmd_args.common_args.buffer_output,
1385                                "buffer-output");
1386               else if (!strcmp (argv[0], "consolidate-output"))
1387                 _cmd_set_flag (argv,
1388                                &cmd_args.common_args.consolidate_output,
1389                                "consolidate-output");
1390               else if (!strcmp (argv[0], "always-prefix"))
1391                 _cmd_set_flag (argv,
1392                                &cmd_args.common_args.always_prefix,
1393                                "always-prefix");
1394               else if (!strcmp (argv[0], "fanout"))
1395                 _cmd_set_unsigned_int_ranged (argv,
1396                                               &cmd_args.common_args.fanout,
1397                                               "fanout",
1398                                               1,
1399                                               PSTDOUT_FANOUT_MIN,
1400                                               PSTDOUT_FANOUT_MAX);
1401               else if (!strcmp (argv[0], "help")
1402                        || !strcmp (argv[0], "?")
1403                        || !strcmp (argv[0], "advanced") /* legacy */
1404                        || !strcmp (argv[0], "network")) /* legacy */
1405                 _cmd_help ();
1406               else if (!strcmp (argv[0], "version"))
1407                 _cmd_version ();
1408               else if (!strcmp (argv[0], "config"))
1409                 _cmd_config ();
1410               else if (!strcmp (argv[0], "quit"))
1411                 quit = 1;
1412               else
1413                 ipmipower_cbuf_printf (ttyout, "unknown command - type \"help\"\n");
1414             }
1415           need_prompt = 1;
1416 
1417           /* Clear out argv data for generic security purposes since
1418            * usernames or passwords could be stored here.  argv_create
1419            * guarantees a null terminated pointer, so this loop is
1420            * safe
1421            */
1422           i = 0;
1423           while (argv[i])
1424             {
1425               memset (argv[i], '\0', strlen (argv[i]));
1426               i++;
1427             }
1428 
1429           argv_destroy (argv);
1430         }
1431     } while (!quit && strlen (buf) > 0);
1432   free (buf);
1433 
1434   return (!quit);
1435 }
1436