From 8c241675de8bfdb5a97350894f791b65912ddd60 Mon Sep 17 00:00:00 2001
From: Alexander Zubkov <green@qrator.net>
Date: Mon, 3 Jan 2022 13:48:29 +0100
Subject: [PATCH 3/3] CLI: add "keep" option to "configure" command

Parse "configure" command parameters like permutable options and add
"keep" option to set RECONFIG_KEEP flag for reconfiguration.

diff --git a/sysdep/unix/config.Y b/sysdep/unix/config.Y
index f8d6b036..67efd75f 100644
--- a/sysdep/unix/config.Y
+++ b/sysdep/unix/config.Y
@@ -14,14 +14,15 @@ CF_HDR
 CF_DEFINES
 
 static struct log_config *this_log;
+static struct reconfig_config *this_rc;
 
 CF_DECLS
 
 CF_KEYWORDS(LOG, SYSLOG, ALL, DEBUG, TRACE, INFO, REMOTE, WARNING, ERROR, AUTH, FATAL, BUG, STDERR, SOFT)
 CF_KEYWORDS(NAME, CONFIRM, UNDO, CHECK, TIMEOUT, DEBUG, LATENCY, LIMIT, WATCHDOG, WARNING, STATUS)
-CF_KEYWORDS(GRACEFUL, RESTART)
+CF_KEYWORDS(GRACEFUL, RESTART, KEEP)
 
-%type <i> log_mask log_mask_list log_cat cfg_timeout
+%type <i> log_mask log_mask_list log_cat
 %type <t> cfg_name
 %type <tf> timeformat_which
 %type <t> syslog_name
@@ -115,16 +116,22 @@ debug_unix:
 
 CF_CLI_HELP(CONFIGURE, ..., [[Reload configuration]])
 
-CF_CLI(CONFIGURE, cfg_name cfg_timeout, [\"<file>\"] [timeout [<sec>]], [[Reload configuration]])
-{ cmd_reconfig($2, RECONFIG_DO_HARD, $3); } ;
+CF_CLI(CONFIGURE, cfg_opts, [soft] [keep] [\"<file>\"] [timeout [<sec>]], [[Reload configuration]])
+{ cmd_reconfig(this_rc->name, this_rc->type|RECONFIG_DO, this_rc->timeout); } ;
 
-CF_CLI(CONFIGURE SOFT, cfg_name cfg_timeout, [\"<file>\"] [timeout [<sec>]], [[Reload configuration and ignore changes in filters]])
-{ cmd_reconfig($3, RECONFIG_DO_SOFT, $4); } ;
-
-/* Hack to get input completion for 'timeout' */
+/* Hack to get input completion */
+CF_CLI_CMD(CONFIGURE SOFT,, [[Reload configuration and ignore changes in filters]])
+CF_CLI_CMD(CONFIGURE KEEP,, [[Reload configuration and keep runtime states]])
 CF_CLI_CMD(CONFIGURE TIMEOUT, [<sec>], [[Reload configuration with undo timeout]])
+
+CF_CLI_CMD(CONFIGURE KEEP SOFT,,,)
+CF_CLI_CMD(CONFIGURE SOFT KEEP,,,)
+CF_CLI_CMD(CONFIGURE KEEP TIMEOUT, [<sec>], [[Reload configuration with undo timeout]])
 CF_CLI_CMD(CONFIGURE SOFT TIMEOUT, [<sec>], [[Reload configuration with undo timeout]])
+CF_CLI_CMD(CONFIGURE KEEP SOFT TIMEOUT, [<sec>], [[Reload configuration with undo timeout]])
+CF_CLI_CMD(CONFIGURE SOFT KEEP TIMEOUT, [<sec>], [[Reload configuration with undo timeout]])
 
+/* Other configure commands */
 CF_CLI(CONFIGURE CONFIRM,,, [[Confirm last configuration change - deactivate undo timeout]])
 { cmd_reconfig_confirm(); } ;
 
@@ -145,18 +152,42 @@ CF_CLI_HELP(GRACEFUL, restart, [[Shut the daemon down for graceful restart]])
 CF_CLI(GRACEFUL RESTART,,, [[Shut the daemon down for graceful restart]])
 { cmd_graceful_restart(); } ;
 
+cfg_opts:
+   /* empty */ {
+     this_rc = cfg_allocz(sizeof(struct reconfig_config));
+   }
+ | cfg_opts SOFT {
+     if (this_rc->type & RECONFIG_SOFT)
+       cf_error("Only one soft flag expected");
+     this_rc->type |= RECONFIG_SOFT;
+   }
+ | cfg_opts KEEP {
+     if (this_rc->type & RECONFIG_KEEP)
+       cf_error("Only one soft keep expected");
+     this_rc->type |= RECONFIG_KEEP;
+   }
+ | cfg_opts TEXT {
+     if (this_rc->name)
+       cf_error("Only one config file expected");
+     this_rc->name = $2;
+   }
+ | cfg_opts TIMEOUT {
+     if (this_rc->timeout)
+       cf_error("Only one timeout expected");
+     this_rc->timeout = UNIX_DEFAULT_CONFIGURE_TIMEOUT;
+   }
+ | cfg_opts TIMEOUT expr {
+     if (this_rc->timeout)
+       cf_error("Only one timeout expected");
+     this_rc->timeout = $3;
+   }
+ ;
 
 cfg_name:
    /* empty */ { $$ = NULL; }
  | TEXT
  ;
 
-cfg_timeout:
-   /* empty */ { $$ = 0; }
- | TIMEOUT { $$ = UNIX_DEFAULT_CONFIGURE_TIMEOUT; }
- | TIMEOUT expr { $$ = $2; }
- ;
-
 CF_CODE
 
 CF_END
diff --git a/sysdep/unix/unix.h b/sysdep/unix/unix.h
index ad85d1ea..3af3ff52 100644
--- a/sysdep/unix/unix.h
+++ b/sysdep/unix/unix.h
@@ -38,6 +38,12 @@ void cmd_graceful_restart(void);
 #define UNIX_DEFAULT_LATENCY_LIMIT	(1 S_)
 #define UNIX_DEFAULT_WATCHDOG_WARNING	(5 S_)
 
+struct reconfig_config {
+  uint timeout;		/* Reconfig timeout */
+  int type;		/* Reconfig type (RECONFIG_SOFT,RECONFIG_KEEP,...) */
+  const char *name;	/* Config file name */
+};
+
 /* io.c */
 
 #define ERR(c) do { s->err = c; return -1; } while (0)
-- 
2.34.0

