From 0d6093a74b5a2fd184d11d94c00f7d79be3da18e Mon Sep 17 00:00:00 2001 From: Lorenzo Cogotti Date: Tue, 3 Aug 2021 23:56:05 +0200 Subject: [PATCH] [tools/peerindex] Add support for -o option --- tools/peerindex/peerindex.1.in | 13 +++++++++-- tools/peerindex/peerindex.c | 37 ++++++++++++++++++++++++++++++- tools/peerindex/peerindex_local.h | 4 ++++ 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/tools/peerindex/peerindex.1.in b/tools/peerindex/peerindex.1.in index 8638295..c01ba83 100644 --- a/tools/peerindex/peerindex.1.in +++ b/tools/peerindex/peerindex.1.in @@ -42,6 +42,14 @@ section below for usage examples. .SH OPTIONS The following options are supported: +.IP "\fB\-o \fI\fP" 10 +Write output to +.BR file . +Instead of using standard output, +.IR @UTILITY@ +shall output PEER INDEX TABLE information to the specified file. If option +occurs multiple times, last specified file is used. + .IP "\fB\-r or \-\-only\-refs\fP" 10 By default .IR @UTILITY@ @@ -67,7 +75,6 @@ may cause some peers inside PEER INDEX TABLES to be discarded (See the .IR OPTIONS section for details). - Each peer is formatted as the following `|' separated fields: .RS 4 .nf @@ -136,7 +143,9 @@ supported compression formats. If the file extension is not recognized, or there is no extension, then it is assumed to be uncompressed. .SH STDOUT -The standard output is used to print a human readable text representation of +Unless redirected explicitly via +.IR OPTIONS , +the standard output is used to print a human readable text representation of PEER INDEX TABLE contents, nothing else shall be written to the standard output. .IR @UTILITY@ may detect and treat as error whenever the standard output is a regular file, diff --git a/tools/peerindex/peerindex.c b/tools/peerindex/peerindex.c index 9c1ffcd..eee55c0 100644 --- a/tools/peerindex/peerindex.c +++ b/tools/peerindex/peerindex.c @@ -32,6 +32,7 @@ typedef enum { ONLY_REFS_FLAG, + OUTPUT_FLAG, NUM_FLAGS } PeerindexOpt; @@ -40,6 +41,9 @@ static Optflag options[] = { [ONLY_REFS_FLAG] = { 'r', "only-refs", NULL, "Only dump peers referenced by RIBs", ARG_NONE }, + [OUTPUT_FLAG] = { + 'o', NULL, "file", "Write output to file", ARG_REQ + }, [NUM_FLAGS] = { '\0' } }; @@ -64,6 +68,21 @@ static void Peerindex_SetupCommandLine(char *argv0) "Any diagnostic message is logged to stderr."; } +static void Peerindex_Fatal(const char *fmt, ...) +{ + va_list va; + + Sys_Print(STDERR, com_progName); + Sys_Print(STDERR, ": ERROR: "); + + va_start(va, fmt); + Sys_VPrintf(STDERR, fmt, va); + va_end(va); + + Sys_Print(STDERR, "\n"); + exit(EXIT_FAILURE); +} + static void Peerindex_Warning(const char *fmt, ...) { va_list va; @@ -180,6 +199,20 @@ static void Peerindex_ApplyProgramOptions(void) S.peerIndexClearVal = 0; else S.peerIndexClearVal = 0xff; // so we always print the full table + + if (options[OUTPUT_FLAG].flagged) { + const char *filename = options[OUTPUT_FLAG].optarg; + + Fildes fd = Sys_Fopen(filename, FM_WRITE, /*hints=*/0); + if (fd == FILDES_BAD) + Peerindex_Fatal("Can't open output file \"%s\"", filename); + + S.outf = STM_FILDES(fd); + S.outfOps = Stm_FildesOps; + } else { + S.outf = STM_CONHN(STDOUT); + S.outfOps = Stm_ConOps; + } } static void Peerindex_Init(void) @@ -267,7 +300,7 @@ static void Peerindex_FlushPeerIndexTable(void) Uint16 idx = 0; - Bufio_Init(&sb, STM_CONHN(STDOUT), Stm_ConOps); + Bufio_Init(&sb, S.outf, S.outfOps); Bgp_StartMrtPeersv2(&it, &S.peerIndex); while ((peer = Bgp_NextMrtPeerv2(&it)) != NULL) { @@ -389,5 +422,7 @@ int main(int argc, char **argv) while (i < argc) Peerindex_ProcessMrtDump(argv[i++]); + if (S.outfOps->Close) S.outfOps->Close(S.outf); + return (S.nerrors > 0) ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/tools/peerindex/peerindex_local.h b/tools/peerindex/peerindex_local.h index 216c0f6..5e698e3 100644 --- a/tools/peerindex/peerindex_local.h +++ b/tools/peerindex/peerindex_local.h @@ -31,6 +31,10 @@ FORCE_INLINE Boolean ISPEERINDEXREF(const PeerRefsTab tab, Uint16 idx) } typedef struct { + // Output stream + void *outf; + const StmOps *outfOps; + // MRT input file stream const char *filename; void *inf;