1/*	$NetBSD: named-journalprint.c,v 1.8 2024/02/21 22:51:41 christos Exp $	*/
2
3/*
4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5 *
6 * SPDX-License-Identifier: MPL-2.0
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11 *
12 * See the COPYRIGHT file distributed with this work for additional
13 * information regarding copyright ownership.
14 */
15
16/*! \file */
17
18#include <stdlib.h>
19
20#include <isc/commandline.h>
21#include <isc/log.h>
22#include <isc/mem.h>
23#include <isc/print.h>
24#include <isc/result.h>
25#include <isc/util.h>
26
27#include <dns/journal.h>
28#include <dns/log.h>
29#include <dns/types.h>
30
31const char *progname = NULL;
32
33static void
34usage(void) {
35	fprintf(stderr, "Usage: %s [-dux] journal\n", progname);
36	exit(1);
37}
38
39/*
40 * Setup logging to use stderr.
41 */
42static isc_result_t
43setup_logging(isc_mem_t *mctx, FILE *errout, isc_log_t **logp) {
44	isc_logdestination_t destination;
45	isc_logconfig_t *logconfig = NULL;
46	isc_log_t *log = NULL;
47
48	isc_log_create(mctx, &log, &logconfig);
49	isc_log_setcontext(log);
50	dns_log_init(log);
51	dns_log_setcontext(log);
52
53	destination.file.stream = errout;
54	destination.file.name = NULL;
55	destination.file.versions = ISC_LOG_ROLLNEVER;
56	destination.file.maximum_size = 0;
57	isc_log_createchannel(logconfig, "stderr", ISC_LOG_TOFILEDESC,
58			      ISC_LOG_DYNAMIC, &destination, 0);
59
60	RUNTIME_CHECK(isc_log_usechannel(logconfig, "stderr", NULL, NULL) ==
61		      ISC_R_SUCCESS);
62
63	*logp = log;
64	return (ISC_R_SUCCESS);
65}
66
67int
68main(int argc, char **argv) {
69	char *file;
70	isc_mem_t *mctx = NULL;
71	isc_result_t result;
72	isc_log_t *lctx = NULL;
73	uint32_t flags = 0U;
74	int ch;
75	bool compact = false;
76	bool downgrade = false;
77	bool upgrade = false;
78	unsigned int serial = 0;
79	char *endp = NULL;
80
81	progname = argv[0];
82	while ((ch = isc_commandline_parse(argc, argv, "c:dux")) != -1) {
83		switch (ch) {
84		case 'c':
85			compact = true;
86			serial = strtoul(isc_commandline_argument, &endp, 0);
87			if (endp == isc_commandline_argument || *endp != 0) {
88				fprintf(stderr, "invalid serial: %s\n",
89					isc_commandline_argument);
90				exit(1);
91			}
92			break;
93		case 'd':
94			downgrade = true;
95			break;
96		case 'u':
97			upgrade = true;
98			break;
99		case 'x':
100			flags |= DNS_JOURNAL_PRINTXHDR;
101			break;
102		default:
103			usage();
104		}
105	}
106
107	argc -= isc_commandline_index;
108	argv += isc_commandline_index;
109
110	if (argc != 1) {
111		usage();
112	}
113	file = argv[0];
114
115	isc_mem_create(&mctx);
116	RUNTIME_CHECK(setup_logging(mctx, stderr, &lctx) == ISC_R_SUCCESS);
117
118	if (upgrade) {
119		flags = DNS_JOURNAL_COMPACTALL;
120		result = dns_journal_compact(mctx, file, 0, flags, 0);
121	} else if (downgrade) {
122		flags = DNS_JOURNAL_COMPACTALL | DNS_JOURNAL_VERSION1;
123		result = dns_journal_compact(mctx, file, 0, flags, 0);
124	} else if (compact) {
125		flags = 0;
126		result = dns_journal_compact(mctx, file, serial, flags, 0);
127	} else {
128		result = dns_journal_print(mctx, flags, file, stdout);
129		if (result == DNS_R_NOJOURNAL) {
130			fprintf(stderr, "%s\n", isc_result_totext(result));
131		}
132	}
133	isc_log_destroy(&lctx);
134	isc_mem_detach(&mctx);
135	return (result != ISC_R_SUCCESS ? 1 : 0);
136}
137