From 4fd0e18d0b7213d8523cc4a06863fbab71ef9c1c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20H=C3=A1k?= <jan.hak@nic.cz>
Date: Fri, 10 Jun 2022 14:59:32 +0200
Subject: [PATCH] kcatalogprint: add parameters for filtering catalog or member
 zone

---
 doc/man/kcatalogprint.8in      |  6 +++++
 doc/man_kcatalogprint.rst      |  6 +++++
 src/utils/kcatalogprint/main.c | 49 +++++++++++++++++++++++++++-------
 3 files changed, 51 insertions(+), 10 deletions(-)

diff --git a/doc/man/kcatalogprint.8in b/doc/man/kcatalogprint.8in
index 09c0ae91d7..0bdcaeccd2 100644
--- a/doc/man/kcatalogprint.8in
+++ b/doc/man/kcatalogprint.8in
@@ -53,6 +53,12 @@ Use specified catalog database path and default configuration.
 .SS Options
 .INDENT 0.0
 .TP
+\fB\-a\fP, \fB\-\-catalog\fP
+Filter the output by catalog zone name.
+.TP
+\fB\-m\fP, \fB\-\-member\fP
+Filter the output by member zone name.
+.TP
 \fB\-h\fP, \fB\-\-help\fP
 Print the program help.
 .TP
diff --git a/doc/man_kcatalogprint.rst b/doc/man_kcatalogprint.rst
index 963f13b538..0fb50883b8 100644
--- a/doc/man_kcatalogprint.rst
+++ b/doc/man_kcatalogprint.rst
@@ -30,6 +30,12 @@ Config options
 Options
 .......
 
+**-a**, **--catalog**
+  Filter the output by catalog zone name.
+
+**-m**, **--member**
+  Filter the output by member zone name.
+
 **-h**, **--help**
   Print the program help.
 
diff --git a/src/utils/kcatalogprint/main.c b/src/utils/kcatalogprint/main.c
index 33be9e9ada..23ae772c42 100644
--- a/src/utils/kcatalogprint/main.c
+++ b/src/utils/kcatalogprint/main.c
@@ -1,4 +1,4 @@
-/*  Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/*  Copyright (C) 2022 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
 
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -25,18 +25,24 @@
 
 #define PROGRAM_NAME	"kcatalogprint"
 
+static knot_dname_t *filter_member = NULL;
+static knot_dname_t *filter_catalog = NULL;
+
 static void print_help(void)
 {
 	printf("Usage: %s [-c | -C | -D <path>] [parameters]\n"
 	       "\n"
 	       "Parameters:\n"
-	       " -c, --config <file> Path to a textual configuration file.\n"
-	       "                      (default %s)\n"
-	       " -C, --confdb <dir>  Path to a configuration database directory.\n"
-	       "                      (default %s)\n"
-	       " -D, --dir <path>    Path to a catalog database directory, use default configuration.\n"
-	       " -h, --help          Print the program help.\n"
-	       " -V, --version       Print the program version.\n",
+	       " -c, --config <file>   Path to a textual configuration file.\n"
+	       "                        (default %s)\n"
+	       " -C, --confdb <dir>    Path to a configuration database directory.\n"
+	       "                        (default %s)\n"
+	       " -D, --dir <path>      Path to a catalog database directory, use default\n"
+	       "                       configuration.\n"
+	       " -a, --catalog <name>  Filter the output by catalog zone name.\n"
+	       " -m, --member <name>   Filter the output by member zone name.\n"
+	       " -h, --help            Print the program help.\n"
+	       " -V, --version         Print the program version.\n",
 	       PROGRAM_NAME, CONF_DEFAULT_FILE, CONF_DEFAULT_DBDIR);
 }
 
@@ -50,6 +56,9 @@ static void print_dname(const knot_dname_t *d)
 static int catalog_print_cb(const knot_dname_t *mem, const knot_dname_t *ow,
                             const knot_dname_t *cz, const char *group, void *ctx)
 {
+	if (filter_catalog != NULL && !knot_dname_is_equal(filter_catalog, cz)) {
+		return KNOT_EOK;
+	}
 	print_dname(mem);
 	print_dname(ow);
 	print_dname(cz);
@@ -67,7 +76,7 @@ static void catalog_print(catalog_t *cat)
 	if (cat != NULL) {
 		int ret = catalog_open(cat);
 		if (ret == KNOT_EOK) {
-			ret = catalog_apply(cat, NULL, catalog_print_cb, &total, false);
+			ret = catalog_apply(cat, filter_member, catalog_print_cb, &total, false);
 		}
 		if (ret != KNOT_EOK) {
 			ERR2("failed to print catalog (%s)\n", knot_strerror(ret));
@@ -78,19 +87,27 @@ static void catalog_print(catalog_t *cat)
 	printf("Total records: %zd\n", total);
 }
 
+static void params_cleanup(void)
+{
+	free(filter_member);
+	free(filter_catalog);
+}
+
 int main(int argc, char *argv[])
 {
 	struct option opts[] = {
 		{ "config",  required_argument, NULL, 'c' },
 		{ "confdb",  required_argument, NULL, 'C' },
 		{ "dir",     required_argument, NULL, 'D' },
+		{ "catalog", required_argument, NULL, 'a' },
+		{ "member",  required_argument, NULL, 'm' },
 		{ "help",    no_argument,       NULL, 'h' },
 		{ "version", no_argument,       NULL, 'V' },
 		{ NULL }
 	};
 
 	int opt = 0;
-	while ((opt = getopt_long(argc, argv, "c:C:D:hV", opts, NULL)) != -1) {
+	while ((opt = getopt_long(argc, argv, "c:C:D:a:m:hV", opts, NULL)) != -1) {
 		switch (opt) {
 		case 'c':
 			if (util_conf_init_file(optarg) != KNOT_EOK) {
@@ -107,6 +124,16 @@ int main(int argc, char *argv[])
 				goto failure;
 			}
 			break;
+		case 'a':
+			free(filter_catalog);
+			filter_catalog = knot_dname_from_str_alloc(optarg);
+			knot_dname_to_lower(filter_catalog);
+			break;
+		case 'm':
+			free(filter_member);
+			filter_member = knot_dname_from_str_alloc(optarg);
+			knot_dname_to_lower(filter_member);
+			break;
 		case 'h':
 			print_help();
 			goto success;
@@ -141,9 +168,11 @@ int main(int argc, char *argv[])
 	catalog_deinit(&c);
 
 success:
+	params_cleanup();
 	util_conf_deinit();
 	return EXIT_SUCCESS;
 failure:
+	params_cleanup();
 	util_conf_deinit();
 	return EXIT_FAILURE;
 }
-- 
GitLab