From 3a9ee4727a6556b006dd845120587247c6d499a4 Mon Sep 17 00:00:00 2001 From: Alexey Khromov Date: Sun, 20 Apr 2025 21:56:44 +0300 Subject: [PATCH] Fixed nlookup and bfindex for pointlist handling. Added -C config option to utils. Updated man-files --- CHANGES | 2 ++ debian/changelog | 1 + man/bfindex.1 | 2 +- man/bfstat.1 | 2 +- man/nlookup.1 | 2 +- source/bforce/logger.c | 1 + source/bforce/nodelist.c | 71 ++++++++++++++++++++++++++++++++++++--- source/bforce/u_string.c | 3 ++ source/bfutil/bfindex.c | 51 +++++++++++++++++++++++++--- source/bfutil/bfstat.c | 21 ++++++++++-- source/bfutil/nlookup.c | 39 ++++++++++++++++----- source/include/logger.h | 1 + source/include/nodelist.h | 1 + 13 files changed, 174 insertions(+), 23 deletions(-) diff --git a/CHANGES b/CHANGES index 0473730..079538c 100644 --- a/CHANGES +++ b/CHANGES @@ -284,3 +284,5 @@ Alexey Khromov (zx@zxalexis.ru) + Added tests with socat and integrate it with CI + Fixed some minor lint errors by PVS-Studio + Fixed RPM spec-file to make builds for AltLinux + + Added fail2ban filter to contrib + + Fixed node/point-lists indexing and parsing for points listed diff --git a/debian/changelog b/debian/changelog index a1c82a2..497d21a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,7 @@ bforce (0.26.2) UNRELEASED; urgency=medium * Added tests to CI actions + * Fixed nodelist indexing for points handling -- Alexey Khromov Sat, 19 Apr 2025 07:43:54 +0300 diff --git a/man/bfindex.1 b/man/bfindex.1 index d22ff14..ce30f4f 100644 --- a/man/bfindex.1 +++ b/man/bfindex.1 @@ -2,7 +2,7 @@ .SH NAME bfindex \- nodelist compiler for bforce .SH SYNOPSYS -\fBbfindex [-fh]\fR +\fBbfindex [-fh] [-C\fIconfig\fB]\fR .SH DESCRIPTION \fBbfindex\fP is a nodelist compiler for BinkleyForce FTN mailer. diff --git a/man/bfstat.1 b/man/bfstat.1 index 059651b..b1bf26e 100644 --- a/man/bfstat.1 +++ b/man/bfstat.1 @@ -2,7 +2,7 @@ .SH NAME bfstat \- binkley style outbound statistic .SH SYNOPSYS -\fBbfstat [-afhprst] [-n \fInumber\fB]\fR +\fBbfstat [-afhprst] [-n \fInumber\fB] [-C\fIconfig\fB]\fR .SH DESCRIPTION \fBbfstat\fP help you to see your outbound statistic in human readable form. diff --git a/man/nlookup.1 b/man/nlookup.1 index 6e9d0a8..a9b476c 100644 --- a/man/nlookup.1 +++ b/man/nlookup.1 @@ -2,7 +2,7 @@ .SH NAME Bnlookup \- Nodelist search tool for bforce .SH SYNOPSYS -\fBnlookup [-rh]\fR +\fBnlookup [-rh] [-C\fIconfig\fB]\fR .SH DESCRIPTION \fBnlookup\fP is a nodelist search tool for BinkleyForce FTN mailer. diff --git a/source/bforce/logger.c b/source/bforce/logger.c index 1d0c48f..20e4d2b 100644 --- a/source/bforce/logger.c +++ b/source/bforce/logger.c @@ -58,6 +58,7 @@ struct debuglevel { { "Daemon", D_DAEMON }, { "Free", D_FREE }, { "24554", D_24554 }, + { "Index", D_INDEX }, // { "Daemon", D_DAEMON }, { "Full", D_FULL }, { NULL, 0 } diff --git a/source/bforce/nodelist.c b/source/bforce/nodelist.c index 5e857a1..b6e5a93 100644 --- a/source/bforce/nodelist.c +++ b/source/bforce/nodelist.c @@ -198,6 +198,54 @@ int nodelist_parse_Txy(s_node *node, const char *xy) return 0; } +/***************************************************************************** + * Pointlist string parser + * + * Arguments: + * node put here all obtained information + * str pointer to the nodelist string + * + * Return value: + * zero value if string was parsed successfuly, and non-zero if wasn't + */ +int nodelist_parsepoint(s_node *node, char *str) +{ + char *argv[NODELIST_POSFLAGS+1]; + char *p; + int cnt; + + DEB((D_NODELIST,"nodelist: parsepoint %s", str)); + + cnt = string_parse(argv, NODELIST_POSFLAGS+1, str, ','); + if( cnt < NODELIST_POSFLAGS-1 ) + return -1; + DEB((D_NODELIST,"nodelist: parsepoint OK: %d", cnt)); + strnxcpy(node->name, argv[NODELIST_POSNAME], sizeof(node->name)); + DEB((D_NODELIST,"nodelist: parsepoint sys: %s", node->name)); + strnxcpy(node->location, argv[NODELIST_POSLOCATION], sizeof(node->location)); + DEB((D_NODELIST,"nodelist: parsepoint loc: %s", node->location)); + strnxcpy(node->sysop, argv[NODELIST_POSSYSOP], sizeof(node->sysop)); + DEB((D_NODELIST,"nodelist: parsepoint zyz: %s", node->sysop)); + strnxcpy(node->phone, argv[NODELIST_POSPHONE], sizeof(node->phone)); + DEB((D_NODELIST,"nodelist: parsepoint pho: %s", node->phone)); + if (argv[NODELIST_POSFLAGS]) + strnxcpy(node->flags, argv[NODELIST_POSFLAGS], sizeof(node->flags)); + DEB((D_NODELIST,"nodelist: parsepoint fl: %s", node->flags)); + if (argv[NODELIST_POSSPEED]) + node->speed = atoi(argv[NODELIST_POSSPEED]); + DEB((D_NODELIST, "nodelist: Parsed common values SYS: %s, ZYZ: %s, LOC: %s, PHONE: %s", node->name, node->sysop, node->location, node->phone)); + /* + * Replace all '_' by space character + */ + string_replchar(node->name, '_', ' '); + string_replchar(node->location, '_', ' '); + string_replchar(node->sysop, '_', ' '); + node->keyword = KEYWORD_POINT; + + return 0; +} + + /***************************************************************************** * Nodelist string parser * @@ -212,7 +260,7 @@ int nodelist_parsestring(s_node *node, char *str) { char *argv[NODELIST_POSFLAGS+1]; char *p; - + DEB((D_NODELIST,"nodelist: parsestring %s", str)); if( string_parse(argv, NODELIST_POSFLAGS+1, str, ',') != NODELIST_POSFLAGS+1 ) return -1; @@ -671,6 +719,7 @@ int nodelist_lookup_string(char *buffer, size_t buflen, s_faddr addr) */ for( ptrl = conf_first(cf_nodelist); ptrl; ptrl = conf_next(ptrl) ) { + DEB((D_NODELIST,"nl_lookup_string: using %s",ptrl->d.falist.what)); if( ftn_addrcomp_mask(addr, ptrl->d.falist.addr) == 0 ) { if( (nlp = nodelist_open(ndldir, ptrl->d.falist.what, NODELIST_READ)) ) @@ -701,10 +750,24 @@ int nodelist_lookup(s_node *node, s_faddr addr) if( nodelist_lookup_string(buf, sizeof(buf), addr) == 0 ) { node->listed = TRUE; - if( nodelist_parsestring(node, buf) == -1 ) + if (addr.point == 0) { - log("invalid nodelist string for address %s", - ftn_addrstr(abuf, addr)); + if( nodelist_parsestring(node, buf) == -1 ) + { + DEB((D_NODELIST,"invalid nodelist string for address %s", + ftn_addrstr(abuf, addr))); + log("invalid nodelist string for address %s", + ftn_addrstr(abuf, addr)); + } + } else { + if ( nodelist_parsepoint(node, buf) == -1 ) + { + DEB((D_NODELIST,"invalid nodelist string for address %s", + ftn_addrstr(abuf, addr))); + log("invalid nodelist string for address %s", + ftn_addrstr(abuf, addr)); + } + node->addr = addr; } return 0; } diff --git a/source/bforce/u_string.c b/source/bforce/u_string.c index 0dedde9..04538f4 100644 --- a/source/bforce/u_string.c +++ b/source/bforce/u_string.c @@ -598,6 +598,8 @@ int string_parse(char **dest, int items, char *str, int separator) { int count = 0; char *p = str; + //if ( *((unsigned char *)p) == separator ) + // p++; dest[count++] = str; @@ -606,6 +608,7 @@ int string_parse(char **dest, int items, char *str, int separator) if( *((unsigned char *)p) == separator ) { *p++ = '\0'; +// DEB((D_INDEX,"Parsed string: %s", dest[count])); dest[count++] = p; } else ++p; diff --git a/source/bfutil/bfindex.c b/source/bfutil/bfindex.c index b757bd1..5f64042 100644 --- a/source/bfutil/bfindex.c +++ b/source/bfutil/bfindex.c @@ -29,11 +29,12 @@ bool eventexpr(s_expr *expr) static void usage(void) { printf_usage("nodelist compiler", - "usage: bfindex [-fh]\n" + "usage: bfindex [-fh] [-C config]\n" "\n" "options:\n" " -f force nodelist compiling\n" " -h show this help message\n" + " -C config use config\n" "\n" ); } @@ -42,6 +43,7 @@ static int nodelist_makeindex(s_nodelist *nlp, s_faddr addr) { s_bni bni; char buf[1024]; + bool modepoint = FALSE; long countnodes = 0L; long countlines = 0L; enum nodelist_keyword keyword; @@ -52,6 +54,9 @@ static int nodelist_makeindex(s_nodelist *nlp, s_faddr addr) bni.node = addr.node; bni.point = addr.point; + DEB((D_INDEX, "Start create index for addr: %u:%u/%u.%u", bni.zone, + bni.net, bni.node, bni.point)); + if( nodelist_createheader(nlp) == -1 ) { log("cannot create nodelist index header"); @@ -80,13 +85,16 @@ static int nodelist_makeindex(s_nodelist *nlp, s_faddr addr) if( (p = strchr(buf, ',')) ) { + //DEB((D_INDEX, "index: parse comma: %s", p )); *p++ = '\0'; if( (q = strchr(p, ',')) ) *q = '\0'; + } if( p == NULL || *p == '\0' ) { log("incorrect nodelist line %ld: Short line", countlines); + DEB((D_INDEX,"incorrect nodelist line %ld: Short line", countlines)); continue; } @@ -94,20 +102,28 @@ static int nodelist_makeindex(s_nodelist *nlp, s_faddr addr) { log("incorrect nodelist line %d: Bad keyword \"%s\"", countlines, buf); + DEB((D_INDEX,"incorrect nodelist line %d: Bad keyword \"%s\"", + countlines, buf)); continue; } - + //DEB((D_INDEX,"index: keyword=%d", keyword)); if( keyword == KEYWORD_BOSS ) { s_faddr tmpaddr; if( ftn_addrparse(&tmpaddr, p, FALSE) ) { + DEB((D_INDEX,"incorrect nodelist line %ld: Bad boss address \"%s\"", + countlines, p)); log("incorrect nodelist line %ld: Bad boss address \"%s\"", countlines, p); } else { + DEB((D_INDEX,"index: parsing Boss %u:%u/%u.0", + tmpaddr.zone, tmpaddr.net, tmpaddr.node)); + if (addr.point == -1 ) + modepoint = true; bni.zone = tmpaddr.zone; bni.net = tmpaddr.net; bni.node = tmpaddr.node; @@ -131,36 +147,49 @@ static int nodelist_makeindex(s_nodelist *nlp, s_faddr addr) bni.node = 0; bni.point = 0; bni.hub = 0; + modepoint = false; break; case KEYWORD_REGION: bni.net = value; bni.node = 0; bni.point = 0; bni.hub = 0; + modepoint = false; break; case KEYWORD_HOST: bni.net = value; bni.node = 0; bni.point = 0; bni.hub = 0; + modepoint = false; break; case KEYWORD_HUB: bni.node = value; bni.point = 0; bni.hub = value; + modepoint = false; break; case KEYWORD_EMPTY: + if (modepoint) + { + //DEB((D_INDEX,"found empty value=%u",value )); + bni.point = value; + break; + } case KEYWORD_PVT: case KEYWORD_HOLD: case KEYWORD_DOWN: bni.node = value; bni.point = 0; + modepoint = false; break; case KEYWORD_POINT: + DEB((D_INDEX,"index: kw point")); bni.point = value; break; default: ASSERT_MSG(); + DEB((D_INDEX,"index: default assert")); } if( nodelist_putindex(nlp, &bni) == -1 ) @@ -182,10 +211,12 @@ int main(int argc, char *argv[]) { s_cval_entry *cfptr; char *nodelistdir = NULL; + char *confname = NULL; time_t starttime = 0L; bool forcecompile = FALSE; long countnodes = 0L; char c; + int rc = 0; /* Initialise random number generation */ (void)srand((unsigned)time(0)); @@ -193,7 +224,7 @@ int main(int argc, char *argv[]) (void)setlocale(LC_ALL, ""); /* Set our name (for logging only) */ - while( (c = getopt(argc, argv, "hf")) != (char)-1 ) + while( (c = getopt(argc, argv, "hfC:")) != (char)-1 ) { switch( c ) { case 'f': @@ -202,15 +233,25 @@ int main(int argc, char *argv[]) case 'h': usage(); exit(0); + case 'C': + if( confname || !optarg ) { usage(); exit(5); } + confname = (char *)xstrcpy(optarg); + break; default: usage(); exit(5); } } - - if( conf_readconf(conf_getconfname(), 0, false) ) + + if( confname && *confname ) + rc = conf_readconf(confname, 0, false); + else + rc = conf_readconf(conf_getconfname(), 0, false); + + if( rc ) { + log("Can not find config"); exit(1); } diff --git a/source/bfutil/bfstat.c b/source/bfutil/bfstat.c index dc7f1b4..535199a 100644 --- a/source/bfutil/bfstat.c +++ b/source/bfutil/bfstat.c @@ -44,7 +44,7 @@ bool eventexpr(s_expr *expr) static void usage(void) { printf_usage("outbound viewer", - "usage: bfstat [-afhprst] [-n]\n" + "usage: bfstat [-C config] [-afhprst] [-n]\n" "\n" "options:\n" " -a sort by FTN address (default)\n" @@ -56,6 +56,7 @@ static void usage(void) " -r reverse order while sorting\n" " -s sort by total files size\n" " -t disable total sizes printing\n" + " -C config use config file\n" "\n" ); } @@ -248,8 +249,10 @@ int main(int argc, char *argv[]) s_opts opts; s_sysqueue queue; s_outbound_callback_data ocb; + char *confname = NULL; char c; int i; + int rc = 0; bfstat_opts_default(&opts); @@ -288,6 +291,10 @@ int main(int argc, char *argv[]) if( ISDEC(optarg) ) opts.nodeslimit = atoi(optarg); break; + case 'C': + if( confname || !optarg ) { usage(); exit(BFERR_FATALERROR); } + confname = (char *)xstrcpy(optarg); + break; default: usage(); exit(1); @@ -301,8 +308,16 @@ int main(int argc, char *argv[]) /* Initialise current locale */ (void)setlocale(LC_ALL, ""); - if( conf_readconf(conf_getconfname(), 0, false) ) - exit(1); + if( confname && *confname ) + rc = conf_readconf(confname, 0, false); + else + rc = conf_readconf(conf_getconfname(), 0, false); + + if( rc ) + { + log("Can not find config"); + exit(BFERR_FATALERROR); + } memset(&ocb, '\0', sizeof(s_outbound_callback_data)); ocb.callback = out_handle_sysqueue; diff --git a/source/bfutil/nlookup.c b/source/bfutil/nlookup.c index 46be17c..9ac3863 100644 --- a/source/bfutil/nlookup.c +++ b/source/bfutil/nlookup.c @@ -28,12 +28,13 @@ bool eventexpr(s_expr *expr) static void usage(void) { printf_usage("nodelist lookup utility", - "usage: nlookup [-rmh]
\n" + "usage: nlookup [-C config] [-rmh]
\n" "\n" "options:\n" " -r show nodelist string\n" " -m show email address\n" " -h show this help message\n" + " -C config use config file\n" "\n" ); } @@ -82,7 +83,7 @@ void print_nodeinfo(const s_node *node) timevec_check(&node->worktime, now) ? "false" : "true"); } - if( node->sysop && *node->sysop && strcmp(node->sysop, "") ) + if( (node->keyword != KEYWORD_POINT) && node->sysop && *node->sysop && strcmp(node->sysop, "") ) { char username[BNI_MAXSYSOP+1]; @@ -127,6 +128,8 @@ int main(int argc, char *argv[]) s_node node; s_faddr addr; char ch; + int rc = 0; + char *confname = NULL; bool rawstring = FALSE; bool emailaddr = FALSE; @@ -135,7 +138,7 @@ int main(int argc, char *argv[]) /* Initialise current locale */ (void)setlocale(LC_ALL, ""); - while( (ch=getopt(argc, argv, "hrm")) != (char)-1 ) + while( (ch=getopt(argc, argv, "hdrmC:")) != (char)-1 ) { switch( ch ) { case 'h': @@ -147,6 +150,10 @@ int main(int argc, char *argv[]) case 'm': emailaddr = TRUE; break; + case 'C': + if( confname || !optarg ) { usage(); exit(BFERR_FATALERROR); } + confname = (char *)xstrcpy(optarg); + break; default: usage(); exit(BFERR_FATALERROR); @@ -159,8 +166,18 @@ int main(int argc, char *argv[]) exit(BFERR_FATALERROR); } - if( conf_readconf(conf_getconfname(), 0, false) ) + if( confname && *confname ) + rc = conf_readconf(confname, 0, false); + else + rc = conf_readconf(conf_getconfname(), 0, false); + + if( rc ) + { + DEB((D_NODELIST,"nlookup: Can not find config")); exit(BFERR_FATALERROR); + } + + DEB((D_NODELIST,"Starting nlookup")); if( rawstring ) { @@ -171,10 +188,16 @@ int main(int argc, char *argv[]) } else if( nodelist_lookup(&node, addr) == 0 ) { - if( emailaddr ) - print_nodemail(&node); - else - print_nodeinfo(&node); + if (addr.point == 0) { + if( emailaddr ) + print_nodemail(&node); + else + print_nodeinfo(&node); + } + else + { + print_nodeinfo(&node); + } } deinit_conf(); diff --git a/source/include/logger.h b/source/include/logger.h index 7f13b53..a89ce8b 100644 --- a/source/include/logger.h +++ b/source/include/logger.h @@ -48,6 +48,7 @@ enum { LOG_FILE_DAEMON, LOG_FILE_SESSION, LOG_FILE_DEBUG, LOG_FILE_HISTORY }; #define D_DAEMON 0x0001000L #define D_24554 0x0002000L #define D_FREE 0x0004000L + #define D_INDEX 0x0008000L #define D_FULL 0xfffffffL #endif diff --git a/source/include/nodelist.h b/source/include/nodelist.h index e214c50..c7ea3d4 100644 --- a/source/include/nodelist.h +++ b/source/include/nodelist.h @@ -159,6 +159,7 @@ s_node; int nodelist_checkflag(const char *nodeflags, const char *flag); int nodelist_keywordval(const char *keyword); +int nodelist_parsepoint(s_node *node, char *str); int nodelist_parsestring(s_node *node, char *str); s_nodelist *nodelist_open(const char *dir, char *name, int mode); int nodelist_checkheader(s_nodelist *nlp);