1 /*****************************************************************************\
2  *  $Id: bmc-watchdog-argp.c,v 1.25 2010-06-30 21:56:36 chu11 Exp $
3  *****************************************************************************
4  *  Copyright (C) 2007-2015 Lawrence Livermore National Security, LLC.
5  *  Copyright (C) 2004-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-155913
9  *
10  *  This file is part of Bmc-watchdog, a base management controller
11  *  (BMC) watchdog timer management tool. For details, see
12  *  http://www.llnl.gov/linux/.
13  *
14  *  Bmc-Watchdog is free software; you can redistribute it and/or modify
15  *  it under the terms of the GNU General Public License as published by the
16  *  Free Software Foundation; either version 3 of the License, or (at your
17  *  option) any later version.
18  *
19  *  Bmc-Watchdog is distributed in the hope that it will be useful, but
20  *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21  *  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
22  *  for more details.
23  *
24  *  You should have received a copy of the GNU General Public License along
25  *  with Bmc-Watchdog.  If not, see <http://www.gnu.org/licenses/>.
26 \*****************************************************************************/
27 
28 #if HAVE_CONFIG_H
29 #include "config.h"
30 #endif /* HAVE_CONFIG_H */
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #if STDC_HEADERS
35 #include <string.h>
36 #endif /* STDC_HEADERS */
37 #if HAVE_ARGP_H
38 #include <argp.h>
39 #else /* !HAVE_ARGP_H */
40 #include "freeipmi-argp.h"
41 #endif /* !HAVE_ARGP_H */
42 #include <assert.h>
43 #include <errno.h>
44 
45 #include "bmc-watchdog.h"
46 #include "bmc-watchdog-argp.h"
47 
48 #include "freeipmi-portability.h"
49 #include "tool-cmdline-common.h"
50 #include "tool-config-file-common.h"
51 
52 const char *argp_program_version =
53   "bmc-watchdog - " PACKAGE_VERSION "\n"
54   "Copyright (C) 2003-2015 FreeIPMI Core Team\n"
55   "This program is free software; you may redistribute it under the terms of\n"
56   "the GNU General Public License.  This program has absolutely no warranty.";
57 
58 const char *argp_program_bug_address =
59   "<" PACKAGE_BUGREPORT ">";
60 
61 static char cmdline_doc[] =
62   "bmc-watchdog - BMC watchdog timer daemon and control utility";
63 
64 static char cmdline_args_doc[] = "";
65 
66 static struct argp_option cmdline_options[] =
67   {
68     ARGP_COMMON_OPTIONS_DRIVER,
69     ARGP_COMMON_OPTIONS_INBAND,
70     ARGP_COMMON_OPTIONS_CONFIG_FILE,
71     ARGP_COMMON_OPTIONS_WORKAROUND_FLAGS,
72     ARGP_COMMON_OPTIONS_DEBUG,
73     { "set", SET_KEY, NULL, 0,
74       "Set BMC Watchdog Config.", 40},
75     { "get", GET_KEY, NULL, 0,
76       "Get BMC Watchdog Config.", 41},
77     { "reset", RESET_KEY, NULL, 0,
78       "Reset BMC Watchdog Timer.", 42},
79     { "start", START_KEY, NULL, 0,
80       "Start BMC Watchdog Timer.", 43},
81     { "stop", STOP_KEY, NULL, 0,
82       "Stop BMC Watchdog Timer.", 44},
83     { "clear", CLEAR_KEY, NULL, 0,
84       "Clear BMC Watchdog Config.", 45},
85     { "daemon", DAEMON_KEY, NULL, 0,
86       "Run in daemon mode.", 46},
87     { "logfile", LOGFILE_KEY, "FILE", OPTION_HIDDEN,
88       "Specify an alternate logfile.", 47},
89     { "verbose-logging", VERBOSE_LOGGING_KEY, 0, 0,
90       "Increase verbosity in logging.", 48},
91     { "no-logging", NO_LOGGING_KEY, NULL, 0,
92       "Turn off all syslogging.", 49},
93     { "timer-use", TIMER_USE_KEY, "INT", 0,
94       "Set timer use.", 50},
95     { "stop-timer", STOP_TIMER_KEY, "INT", 0,
96       "Set Stop Timer Flag.", 51},
97     { "log", LOG_KEY, "INT", 0,
98       "Set Log Flag.", 52},
99     { "timeout-action", TIMEOUT_ACTION_KEY, "INT", 0,
100       "Set timeout action.", 53},
101     { "pre-timeout-interrupt", PRE_TIMEOUT_INTERRUPT_KEY, "INT", 0,
102       "Set pre-timeout interrupt.", 54},
103     { "pre-timeout-interval", PRE_TIMEOUT_INTERVAL_KEY, "SECONDS", 0,
104       "Set pre-timeout interval in seconds.", 55},
105     { "clear-bios-frb2", CLEAR_BIOS_FRB2_KEY, NULL, 0,
106       "Clear BIOS FRB2 Timer Use Flag.", 56},
107     { "clear-bios-post", CLEAR_BIOS_POST_KEY, NULL, 0,
108       "Clear BIOS POST Timer Use Flag.", 57},
109     { "clear-os-load", CLEAR_OS_LOAD_KEY, NULL, 0,
110       "Clear OS Load Timer Use Flag.", 58},
111     { "clear-sms-os", CLEAR_SMS_OS_KEY, NULL, 0,
112       "Clear SMS/OS Timer Use Flag.", 59},
113     { "clear-oem", CLEAR_OEM_KEY, NULL, 0,
114       "Clear OEM Timer Use Flag.", 60},
115     { "initial-countdown", INITIAL_COUNTDOWN_KEY, "SECONDS", 0,
116       "Set initial countdown in seconds.", 61},
117     { "start-after-set", START_AFTER_SET_KEY, NULL, 0,
118       "Start timer after set if timer is stopped.", 62},
119     { "reset-after-set", RESET_AFTER_SET_KEY, NULL, 0,
120       "Reset timer after set if timer is running.", 63},
121     { "start-if-stopped", START_IF_STOPPED_KEY, NULL, 0,
122       "Don't set if timer is stopped, just start.", 64},
123     { "reset-if-running", RESET_IF_RUNNING_KEY, NULL, 0,
124       "Don't set if timer is running, just reset.", 65},
125     { "gratuitous-arp", GRATUITOUS_ARP_KEY, "INT", 0,
126       "Set Gratuitous ARPs Flag.", 66},
127     { "arp-response", ARP_RESPONSE_KEY, "INT", 0,
128       "Set ARP Responses Flag.", 67},
129     { "reset-period", RESET_PERIOD_KEY, "SECONDS", 0,
130       "Specify time interval before resetting timer.", 68},
131     { "help", HELP_KEY, NULL, 0,
132       "Output help.", 69},
133     { "help", HELP_KEY, NULL, 0,
134       "Output help.", 70},
135     { "version", VERSION_KEY, NULL, 0,
136       "Output version.", 71},
137     { NULL, 0, NULL, 0, NULL, 0}
138   };
139 
140 static error_t cmdline_parse (int key, char *arg, struct argp_state *state);
141 
142 static struct argp cmdline_argp = { cmdline_options,
143                                     cmdline_parse,
144                                     cmdline_args_doc,
145                                     cmdline_doc };
146 
147 static struct argp cmdline_config_file_argp = { cmdline_options,
148                                                 cmdline_config_file_parse,
149                                                 cmdline_args_doc,
150                                                 cmdline_doc };
151 
152 static char *
_cmd_string(struct bmc_watchdog_arguments * cmd_args)153 _cmd_string (struct bmc_watchdog_arguments *cmd_args)
154 {
155   if (cmd_args->get)
156     return "--get";
157   else if (cmd_args->set)
158     return "--set";
159   else if (cmd_args->reset)
160     return "--reset";
161   else if (cmd_args->start)
162     return "--start";
163   else if (cmd_args->stop)
164     return "--stop";
165   else if (cmd_args->clear)
166     return "--clear";
167   else if (cmd_args->daemon)
168     return "--daemon";
169   else
170     return (NULL);
171 }
172 
173 static void
_usage(struct bmc_watchdog_arguments * cmd_args)174 _usage (struct bmc_watchdog_arguments *cmd_args)
175 {
176   char *cmdstr;
177 
178   cmdstr = _cmd_string (cmd_args);
179   if (!cmdstr)
180     {
181       fprintf (stderr,
182                "Usage: bmc-watchdog <COMMAND> [OPTIONS]... [COMMAND_OPTIONS]...\n\n");
183       fprintf (stderr,
184                "COMMANDS:\n"
185                "  -s         --set                            Set BMC Watchdog Config.\n"
186                "  -g         --get                            Get BMC Watchdog Config.\n"
187                "  -r         --reset                          Reset BMC Watchdog Timer.\n"
188                "  -t         --start                          Start BMC Watchdog Timer.\n"
189                "  -y         --stop                           Stop BMC Watchdog Timer.\n"
190                "  -c         --clear                          Clear BMC Watchdog Config.\n"
191                "  -d         --daemon                         Run in Daemon Mode.\n\n");
192     }
193   else
194     fprintf (stderr,
195              "Usage: bmc-watchdog %s [OPTIONS]... \n\n", cmdstr);
196 
197   fprintf (stderr,
198            "OPTIONS:\n"
199            "  -D IPMIDRIVER  --driver-type=IPMIDRIVER             Specify IPMI driver type.\n"
200            "                 --disable-auto-probe                 Do not probe driver for default settings.\n"
201            "                 --driver-address=DRIVER-ADDRESS      Specify driver address.\n"
202            "                 --driver-device=DEVICE               Specify driver device path.\n"
203            "                 --register-spacing=REGISTER-SPACING  Specify driver register spacing.\n"
204            "                 --config-file=FILE                   Specify an alternate config file\n"
205            "  -v             --verbose-logging                    Turn on verbose logging\n"
206            "  -n             --no-logging                         Turn off all logging\n"
207            "  -?             --help                               Output help menu.\n"
208            "  -V             --version                            Output version.\n");
209 
210   fprintf (stderr,
211            "                 --debug                              Turn on debugging.\n");
212 
213   fprintf (stderr, "\n");
214   if (cmd_args->set || cmd_args->start || cmd_args->daemon)
215     fprintf (stderr,
216              "COMMAND SPECIFIC OPTIONS:\n");
217 
218   if (cmd_args->set || cmd_args->daemon)
219     fprintf (stderr,
220              "  -u INT     --timer-use=INT              Set timer use.\n"
221              "             %d = BIOS FRB2\n"
222              "             %d = BIOS POST\n"
223              "             %d = OS_LOAD\n"
224              "             %d = SMS OS\n"
225              "             %d = OEM\n"
226              "  -m INT     --stop-timer=INT             Set Stop Timer Flag.\n"
227              "             %d = Stop Timer\n"
228              "             %d = Don't Stop timer\n"
229              "  -l INT     --log=INT                    Set Log Flag.\n"
230              "             %d = Enable Log\n"
231              "             %d = Disable Log\n"
232              "  -a INT     --timeout-action=INT         Set timeout action.\n"
233              "             %d = No action\n"
234              "             %d = Hard Reset\n"
235              "             %d = Power Down\n"
236              "             %d = Power Cycle\n"
237              "  -p INT     --pre-timeout-interrupt=INT  Set pre-timeout interrupt.\n"
238              "             %d = None\n"
239              "             %d = SMI\n"
240              "             %d = NMI\n"
241              "             %d = Messaging Interrupt\n"
242              "  -z SECS    --pre-timeout-interval=SECS  Set pre-timeout interval in seconds.\n"
243              "  -F         --clear-bios-frb2            Clear BIOS FRB2 Timer Use Flag.\n"
244              "  -P         --clear-bios-post            Clear BIOS POST Timer Use Flag.\n"
245              "  -L         --clear-os-load              Clear OS Load Timer Use Flag.\n"
246              "  -S         --clear-sms-os               Clear SMS/OS Timer Use Flag.\n"
247              "  -O         --clear-oem                  Clear OEM Timer Use Flag.\n"
248              "  -i SECS    --initial-countdown=SECS     Set initial countdown in seconds.\n",
249              IPMI_BMC_WATCHDOG_TIMER_TIMER_USE_BIOS_FRB2,
250              IPMI_BMC_WATCHDOG_TIMER_TIMER_USE_BIOS_POST,
251              IPMI_BMC_WATCHDOG_TIMER_TIMER_USE_OS_LOAD,
252              IPMI_BMC_WATCHDOG_TIMER_TIMER_USE_SMS_OS,
253              IPMI_BMC_WATCHDOG_TIMER_TIMER_USE_OEM,
254              IPMI_BMC_WATCHDOG_TIMER_STOP_TIMER_ENABLE,
255              IPMI_BMC_WATCHDOG_TIMER_STOP_TIMER_DISABLE,
256              IPMI_BMC_WATCHDOG_TIMER_LOG_ENABLE,
257              IPMI_BMC_WATCHDOG_TIMER_LOG_DISABLE,
258              IPMI_BMC_WATCHDOG_TIMER_TIMEOUT_ACTION_NO_ACTION,
259              IPMI_BMC_WATCHDOG_TIMER_TIMEOUT_ACTION_HARD_RESET,
260              IPMI_BMC_WATCHDOG_TIMER_TIMEOUT_ACTION_POWER_DOWN,
261              IPMI_BMC_WATCHDOG_TIMER_TIMEOUT_ACTION_POWER_CYCLE,
262              IPMI_BMC_WATCHDOG_TIMER_PRE_TIMEOUT_INTERRUPT_NONE,
263              IPMI_BMC_WATCHDOG_TIMER_PRE_TIMEOUT_INTERRUPT_SMI,
264              IPMI_BMC_WATCHDOG_TIMER_PRE_TIMEOUT_INTERRUPT_NMI,
265              IPMI_BMC_WATCHDOG_TIMER_PRE_TIMEOUT_INTERRUPT_MESSAGING_INTERRUPT);
266 
267   if (cmd_args->set)
268     fprintf (stderr,
269              "  -w         --start-after-set            Start timer after set if timer is stopped.\n"
270              "  -x         --reset-after-set            Reset timer after set if timer is running.\n"
271              "  -j         --start-if-stopped           Don't set if timer is stopped, just start.\n"
272              "  -k         --reset-if-running           Don't set if timer is running, just reset.\n");
273 
274   if (cmd_args->start || cmd_args->daemon)
275     fprintf (stderr,
276              "  -G INT     --gratuitous-arp=INT         Set Gratuitous ARPs Flag.\n"
277              "             %d = Suspend Gratuitous ARPs\n"
278              "             %d = Do Not Suspend Gratuitous ARPs\n"
279              "  -A INT     --arp-response=INT           Set ARP Responses Flag.\n"
280              "             %d = Suspend ARP Responses\n"
281              "             %d = Do Not Suspend ARP Responses\n",
282              IPMI_BMC_GENERATED_GRATUITOUS_ARP_SUSPEND,
283              IPMI_BMC_GENERATED_GRATUITOUS_ARP_DO_NOT_SUSPEND,
284              IPMI_BMC_GENERATED_ARP_RESPONSE_SUSPEND,
285              IPMI_BMC_GENERATED_ARP_RESPONSE_DO_NOT_SUSPEND);
286   if (cmd_args->daemon)
287     fprintf (stderr,
288              "  -e SECS    --reset-period=SECS          Specify time interval before resetting timer.\n");
289 
290   if (cmd_args->set || cmd_args->start || cmd_args->daemon)
291     fprintf (stderr, "\n");
292 
293   exit (EXIT_FAILURE);
294 }
295 
296 static error_t
cmdline_parse(int key,char * arg,struct argp_state * state)297 cmdline_parse (int key, char *arg, struct argp_state *state)
298 {
299   struct bmc_watchdog_arguments *cmd_args;
300   char *endptr;
301   int tmp;
302 
303   assert (state);
304 
305   cmd_args = state->input;
306 
307   switch (key)
308     {
309     case SET_KEY:
310       cmd_args->set++;
311       break;
312     case GET_KEY:
313       cmd_args->get++;
314       break;
315     case RESET_KEY:
316       cmd_args->reset++;
317       break;
318     case START_KEY:
319       cmd_args->start++;
320       break;
321     case STOP_KEY:
322       cmd_args->stop++;
323       break;
324     case CLEAR_KEY:
325       cmd_args->clear++;
326       break;
327     case DAEMON_KEY:
328       cmd_args->daemon++;
329       break;
330     case LOGFILE_KEY:
331       /* deprecated */
332       break;
333     case VERBOSE_LOGGING_KEY:
334       cmd_args->verbose_logging++;
335       break;
336     case NO_LOGGING_KEY:
337       cmd_args->no_logging++;
338       break;
339     case TIMER_USE_KEY:
340       cmd_args->timer_use++;
341       errno = 0;
342       tmp = strtol (arg, &endptr, 10);
343       if (errno
344           || endptr[0] != '\0'
345           || !IPMI_BMC_WATCHDOG_TIMER_TIMER_USE_VALID (tmp))
346         {
347           fprintf (stderr, "invalid timer use\n");
348           exit (EXIT_FAILURE);
349         }
350       cmd_args->timer_use_arg = tmp;
351       break;
352     case STOP_TIMER_KEY:
353       cmd_args->stop_timer++;
354       errno = 0;
355       tmp = strtol (arg, &endptr, 10);
356       if (errno
357           || endptr[0] != '\0'
358           || !IPMI_BMC_WATCHDOG_TIMER_STOP_TIMER_VALID (tmp))
359         {
360           fprintf (stderr, "invalid stop timer value\n");
361           exit (EXIT_FAILURE);
362         }
363       cmd_args->stop_timer_arg = tmp;
364       break;
365     case LOG_KEY:
366       cmd_args->log++;
367       errno = 0;
368       tmp = strtol (arg, &endptr, 10);
369       if (errno
370           || endptr[0] != '\0'
371           || !IPMI_BMC_WATCHDOG_TIMER_LOG_VALID (tmp))
372         {
373           fprintf (stderr, "invalid log value\n");
374           exit (EXIT_FAILURE);
375         }
376       cmd_args->log_arg = tmp;
377       break;
378     case TIMEOUT_ACTION_KEY:
379       cmd_args->timeout_action++;
380       errno = 0;
381       tmp = strtol (arg, &endptr, 10);
382       if (errno
383           || endptr[0] != '\0'
384           || !IPMI_BMC_WATCHDOG_TIMER_TIMEOUT_ACTION_VALID (tmp))
385         {
386           fprintf (stderr, "invalid timeout action value\n");
387           exit (EXIT_FAILURE);
388         }
389       cmd_args->timeout_action_arg = tmp;
390       break;
391     case PRE_TIMEOUT_INTERRUPT_KEY:
392       cmd_args->pre_timeout_interrupt++;
393       errno = 0;
394       tmp = strtol (arg, &endptr, 10);
395       if (errno
396           || endptr[0] != '\0'
397           || !IPMI_BMC_WATCHDOG_TIMER_PRE_TIMEOUT_INTERRUPT_VALID (tmp))
398         {
399           fprintf (stderr, "invalid pre timeout interrupt value\n");
400           exit (EXIT_FAILURE);
401         }
402       cmd_args->pre_timeout_interrupt_arg = tmp;
403       break;
404     case PRE_TIMEOUT_INTERVAL_KEY:
405       cmd_args->pre_timeout_interval++;
406       errno = 0;
407       tmp = strtol (arg, &endptr, 10);
408       if (errno
409           || endptr[0] != '\0')
410         {
411           fprintf (stderr, "invalid pre timeout interval\n");
412           exit (EXIT_FAILURE);
413         }
414       if (tmp < IPMI_BMC_WATCHDOG_TIMER_PRE_TIMEOUT_INTERVAL_MIN
415           || tmp > IPMI_BMC_WATCHDOG_TIMER_PRE_TIMEOUT_INTERVAL_MAX)
416         {
417           fprintf (stderr, "pre timeout interval out of range\n");
418           exit (EXIT_FAILURE);
419         }
420       cmd_args->pre_timeout_interval_arg = tmp;
421       break;
422     case CLEAR_BIOS_FRB2_KEY:
423       cmd_args->clear_bios_frb2++;
424       break;
425     case CLEAR_BIOS_POST_KEY:
426       cmd_args->clear_bios_post++;
427       break;
428     case CLEAR_OS_LOAD_KEY:
429       cmd_args->clear_os_load++;
430       break;
431     case CLEAR_SMS_OS_KEY:
432       cmd_args->clear_sms_os++;
433       break;
434     case CLEAR_OEM_KEY:
435       cmd_args->clear_oem++;
436       break;
437     case INITIAL_COUNTDOWN_KEY:
438       cmd_args->initial_countdown_seconds++;
439       errno = 0;
440       tmp = strtol (arg, &endptr, 10);
441       if (errno
442           || endptr[0] != '\0')
443         {
444           fprintf (stderr, "invalid initial countdown\n");
445           exit (EXIT_FAILURE);
446         }
447       if (tmp < IPMI_BMC_WATCHDOG_TIMER_INITIAL_COUNTDOWN_MIN_SECONDS
448           || tmp > IPMI_BMC_WATCHDOG_TIMER_INITIAL_COUNTDOWN_MAX_SECONDS)
449         {
450           fprintf (stderr, "initial countdown out of range\n");
451           exit (EXIT_FAILURE);
452         }
453       cmd_args->initial_countdown_seconds_arg = tmp;
454       break;
455     case START_AFTER_SET_KEY:
456       cmd_args->start_after_set++;
457       break;
458     case RESET_AFTER_SET_KEY:
459       cmd_args->reset_after_set++;
460       break;
461     case START_IF_STOPPED_KEY:
462       cmd_args->start_if_stopped++;
463       break;
464     case RESET_IF_RUNNING_KEY:
465       cmd_args->reset_if_running++;
466       break;
467     case GRATUITOUS_ARP_KEY:
468       cmd_args->gratuitous_arp++;
469       errno = 0;
470       tmp = strtol (arg, &endptr, 10);
471       if (errno
472           || endptr[0] != '\0'
473           || !IPMI_BMC_GENERATED_GRATUITOUS_ARP_VALID (tmp))
474         {
475           fprintf (stderr, "invalid gratuitous arp value\n");
476           exit (EXIT_FAILURE);
477         }
478       cmd_args->gratuitous_arp_arg = tmp;
479       break;
480     case ARP_RESPONSE_KEY:
481       cmd_args->arp_response++;
482       errno = 0;
483       tmp = strtol (arg, &endptr, 10);
484       if (errno
485           || endptr[0] != '\0'
486           || !IPMI_BMC_GENERATED_ARP_RESPONSE_VALID (tmp))
487         {
488           fprintf (stderr, "invalid arp response value\n");
489           exit (EXIT_FAILURE);
490         }
491       cmd_args->arp_response_arg = tmp;
492       break;
493     case RESET_PERIOD_KEY:
494       cmd_args->reset_period++;
495       errno = 0;
496       tmp = strtol (arg, &endptr, 10);
497       if (errno
498           || endptr[0] != '\0')
499         {
500           fprintf (stderr, "invalid reset period\n");
501           exit (EXIT_FAILURE);
502         }
503       if (tmp < IPMI_BMC_WATCHDOG_TIMER_INITIAL_COUNTDOWN_MIN_SECONDS
504           || tmp > IPMI_BMC_WATCHDOG_TIMER_INITIAL_COUNTDOWN_MAX_SECONDS)
505         {
506           fprintf (stderr, "reset period out of range\n");
507           exit (EXIT_FAILURE);
508         }
509       cmd_args->reset_period_arg = tmp;
510       break;
511       /* do not output default argp help, do internal help */
512     case HELP_KEY:
513       cmd_args->help++;
514       break;
515     case VERSION_KEY:
516       cmd_args->version++;
517       break;
518     case ARGP_KEY_ARG:
519       /* Too many arguments. */
520       argp_usage (state);
521       break;
522     case ARGP_KEY_END:
523       break;
524     default:
525       return (common_parse_opt (key, arg, &(cmd_args->common_args)));
526     }
527 
528   return (0);
529 }
530 
531 static void
_bmc_watchdog_config_file_parse(struct bmc_watchdog_arguments * cmd_args)532 _bmc_watchdog_config_file_parse (struct bmc_watchdog_arguments *cmd_args)
533 {
534   struct config_file_data_bmc_watchdog config_file_data;
535 
536   memset (&config_file_data,
537           '\0',
538           sizeof (struct config_file_data_bmc_watchdog));
539 
540   if (config_file_parse (cmd_args->common_args.config_file,
541                          0,
542                          &(cmd_args->common_args),
543                          CONFIG_FILE_INBAND,
544                          CONFIG_FILE_TOOL_BMC_WATCHDOG,
545                          &config_file_data) < 0)
546 
547     {
548       fprintf (stderr, "config_file_parse: %s\n", strerror (errno));
549       exit (EXIT_FAILURE);
550     }
551 
552   if (config_file_data.verbose_logging_count)
553     cmd_args->verbose_logging = config_file_data.verbose_logging;
554   if (config_file_data.no_logging_count)
555     cmd_args->no_logging = config_file_data.no_logging;
556 }
557 
558 static void
_bmc_watchdog_args_validate(struct bmc_watchdog_arguments * cmd_args)559 _bmc_watchdog_args_validate (struct bmc_watchdog_arguments *cmd_args)
560 {
561   int count;
562 
563   assert (cmd_args);
564 
565   if (cmd_args->help)
566     _usage (cmd_args);
567 
568   if (cmd_args->version)
569     {
570       fprintf (stderr, "%s\n", argp_program_version);
571       exit (EXIT_FAILURE);
572     }
573 
574   count = cmd_args->set + cmd_args->get + cmd_args->reset +
575     cmd_args->start + cmd_args->stop + cmd_args->clear + cmd_args->daemon;
576   if (!count)
577     _usage (cmd_args);
578   if (count > 1)
579     {
580       fprintf (stderr, "Only one command can be specified\n");
581       exit (EXIT_FAILURE);
582     }
583 
584   if (((cmd_args->get
585         || cmd_args->reset
586         || cmd_args->start
587         || cmd_args->stop
588         || cmd_args->clear)
589        && (cmd_args->timer_use
590            || cmd_args->stop_timer
591            || cmd_args->log
592            || cmd_args->timeout_action
593            || cmd_args->pre_timeout_interrupt
594            || cmd_args->pre_timeout_interval
595            || cmd_args->clear_bios_frb2
596            || cmd_args->clear_bios_post
597            || cmd_args->clear_sms_os
598            || cmd_args->clear_oem
599            || cmd_args->initial_countdown_seconds
600            || cmd_args->start_after_set
601            || cmd_args->reset_after_set
602            || cmd_args->reset_if_running
603            || cmd_args->reset_period))
604       || (cmd_args->set
605           && cmd_args->reset_period)
606       || (cmd_args->daemon
607           && (cmd_args->stop_timer
608               || cmd_args->start_after_set
609               || cmd_args->reset_after_set
610               || cmd_args->reset_if_running))
611       || ((cmd_args->set
612            || cmd_args->get
613            || cmd_args->reset
614            || cmd_args->stop
615            || cmd_args->clear)
616           && (cmd_args->gratuitous_arp
617               || cmd_args->arp_response)))
618     {
619       char *cmdstr;
620 
621       cmdstr = _cmd_string (cmd_args);
622       fprintf (stderr, "Invalid command option specified for '%s' command\n", cmdstr);
623       exit (EXIT_FAILURE);
624     }
625 }
626 
627 void
bmc_watchdog_argp_parse(int argc,char ** argv,struct bmc_watchdog_arguments * cmd_args)628 bmc_watchdog_argp_parse (int argc, char **argv, struct bmc_watchdog_arguments *cmd_args)
629 {
630   assert (argc >= 0);
631   assert (argv);
632   assert (cmd_args);
633 
634   init_common_cmd_args_user (&(cmd_args->common_args));
635 
636   cmd_args->set = 0;
637   cmd_args->get = 0;
638   cmd_args->reset = 0;
639   cmd_args->start = 0;
640   cmd_args->stop = 0;
641   cmd_args->clear = 0;
642   cmd_args->daemon = 0;
643   cmd_args->verbose_logging = 0;
644   cmd_args->no_logging = 0;
645   cmd_args->timer_use = 0;
646   cmd_args->timer_use_arg = 0;
647   cmd_args->stop_timer = 0;
648   cmd_args->stop_timer_arg = 0;
649   cmd_args->log = 0;
650   cmd_args->log_arg = 0;
651   cmd_args->timeout_action = 0;
652   cmd_args->timeout_action_arg = 0;
653   cmd_args->pre_timeout_interrupt = 0;
654   cmd_args->pre_timeout_interrupt_arg = 0;
655   cmd_args->pre_timeout_interval = 0;
656   cmd_args->pre_timeout_interval_arg = 0;
657   cmd_args->clear_bios_frb2 = 0;
658   cmd_args->clear_bios_post = 0;
659   cmd_args->clear_os_load = 0;
660   cmd_args->clear_sms_os = 0;
661   cmd_args->clear_oem = 0;
662   cmd_args->initial_countdown_seconds = 0;
663   cmd_args->initial_countdown_seconds_arg = 0;
664   cmd_args->start_after_set = 0;
665   cmd_args->reset_after_set = 0;
666   cmd_args->start_if_stopped = 0;
667   cmd_args->reset_if_running = 0;
668   cmd_args->gratuitous_arp = 0;
669   cmd_args->gratuitous_arp_arg = 0;
670   cmd_args->arp_response = 0;
671   cmd_args->arp_response_arg = 0;
672   cmd_args->reset_period = 0;
673   cmd_args->reset_period_arg = 0;
674   cmd_args->help = 0;
675   cmd_args->version = 0;
676 
677   argp_parse (&cmdline_config_file_argp,
678               argc,
679               argv,
680               ARGP_IN_ORDER | ARGP_NO_HELP,
681               NULL,
682               &(cmd_args->common_args));
683 
684   _bmc_watchdog_config_file_parse (cmd_args);
685 
686   argp_parse (&cmdline_argp,
687               argc,
688               argv,
689               ARGP_IN_ORDER | ARGP_NO_HELP,
690               NULL,
691               cmd_args);
692 
693   verify_common_cmd_args (&(cmd_args->common_args));
694   _bmc_watchdog_args_validate (cmd_args);
695 }
696