From c5dc00c084644492f7a5792478fb97bb962e4146 Mon Sep 17 00:00:00 2001 From: Alexey Khromov Date: Tue, 22 Apr 2025 23:30:59 +0300 Subject: [PATCH 01/11] fixed ipv6/ipv4 switchover when ipv6 node is not reachable --- source/bforce/io_tcpip.c | 40 +++++++++++++++++++++++++++------------- tests/mktests.sh | 6 +++--- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/source/bforce/io_tcpip.c b/source/bforce/io_tcpip.c index 06758ae..7d600fc 100644 --- a/source/bforce/io_tcpip.c +++ b/source/bforce/io_tcpip.c @@ -55,14 +55,25 @@ static int tcpip_connect2(struct addrinfo *ai) { DEB((D_INFO, "tcpip_connect2: socket error")); } - else break; - + else + { + DEB((D_INFO, "tcpip_connect2: socket opened - breaking")); + if( connect(fd, rai->ai_addr, rai->ai_addrlen) == -1 ) + { + DEB((D_INFO, "tcpip_connect2: can't connect %s", hbuf)); + logerr("can't connect to %s", hbuf); + close(fd); + } else + break; + } + DEB((D_INFO, "tcpip_connect2: socket not opened - returning")); hbuf[0]='\0'; sbuf[0]='\0'; } DEB((D_INFO, "tcpip_connect2: socket success: %d", fd)); if (fd < 0 ) { + DEB((D_INFO, "tcpip_connect2: can't create socket")); logerr("can't create socket"); return(1); } @@ -73,6 +84,7 @@ static int tcpip_connect2(struct addrinfo *ai) (void)close(0); if( dup(fd) != 0 ) { + DEB((D_INFO, "tcpip_connect2: can't dup socket to stdin")); logerr("cannot dup socket to stdin"); return(1); } @@ -92,7 +104,7 @@ static int tcpip_connect2(struct addrinfo *ai) logerr("cannot dup stdin to stderr"); return(1); } - + DEB((D_INFO, "tcpip_connect2: stdin|out|err are connected")); if( fd > 2 ) (void)close(fd); /* switch off stdio buffering */ @@ -103,22 +115,24 @@ static int tcpip_connect2(struct addrinfo *ai) clearerr(stdin); clearerr(stdout); clearerr(stderr); - - if( connect(0, rai->ai_addr, rai->ai_addrlen) == -1 ) - { - logerr("can't connect to %s", hbuf); - close(0); - close(1); - close(2); - return 1; - } + DEB((D_INFO, "tcpip_connect2: start connecting")); + //if( connect(0, rai->ai_addr, rai->ai_addrlen) == -1 ) + //{ + // DEB((D_INFO, "tcpip_connect2: can't connect %s", hbuf)); + // logerr("can't connect to %s", hbuf); + // + // close(0); + // close(1); + // close(2); + // return 1; + //} if( tcpip_init() ) { tcpip_shutdown(); return 1; } - + DEB((D_INFO, "tcpip_connect2: TCP/IP connect success to %s on service %s", hbuf, sbuf)); (void)log("TCP/IP connect success to %s on service %s", hbuf, sbuf); return(0); diff --git a/tests/mktests.sh b/tests/mktests.sh index c2a2095..533c3a2 100755 --- a/tests/mktests.sh +++ b/tests/mktests.sh @@ -56,17 +56,17 @@ function testcomm() { # Variant 3 works with sockets and pipes - not pty case ${1} in "PSTN") - socat -ly -Wlock EXEC:"${CURDIR}/runbfB.sh ${BFBIN} ${BFCFGB}" EXEC:"${CURDIR}/runbfA.sh ${BFBIN} ${BFCFGA}" + socat -T5 -ly -Wlock EXEC:"${CURDIR}/runbfB.sh ${BFBIN} ${BFCFGB}" EXEC:"${CURDIR}/runbfA.sh ${BFBIN} ${BFCFGA}" sleep 2 ;; "IFC") ${CURDIR}/runbfC.sh ${BFBIN} ${BFCFGA} & - socat -ly -Wlock TCP4-LISTEN:59999 EXEC:"${CURDIR}/runbfD.sh ${BFBIN} ${BFCFGB}" + socat -ly -Wlock TCP4-LISTEN:59999,accept-timeout=3 EXEC:"${CURDIR}/runbfD.sh ${BFBIN} ${BFCFGB}" sleep 2 ;; "BKP") ${CURDIR}/runbfE.sh ${BFBIN} ${BFCFGA} & - socat -ly -Wlock TCP4-LISTEN:59999 EXEC:"${CURDIR}/runbfF.sh ${BFBIN} ${BFCFGB}" + socat -ly -Wlock TCP4-LISTEN:59999,accept-timeout=3 EXEC:"${CURDIR}/runbfF.sh ${BFBIN} ${BFCFGB}" sleep 2 ;; esac -- 2.47.2 From 64cfc794dc62500f628120304f6c094869f61945 Mon Sep 17 00:00:00 2001 From: Alexey Khromov Date: Wed, 23 Apr 2025 12:12:45 +0300 Subject: [PATCH 02/11] Nlookup: new option -o to show configured overrides --- source/bforce/u_misc.c | 2 +- source/bfutil/nlookup.c | 48 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/source/bforce/u_misc.c b/source/bforce/u_misc.c index d2042ec..9163f7c 100644 --- a/source/bforce/u_misc.c +++ b/source/bforce/u_misc.c @@ -329,7 +329,7 @@ void printf_usage(const char *ident, const char *fmt, ...) else printf("Sorry, no usage information available\n\n"); - printf("Mail bug reports to \n"); + printf("Mail bug reports to \n"); fflush(stdout); } diff --git a/source/bfutil/nlookup.c b/source/bfutil/nlookup.c index 9ac3863..23df5e0 100644 --- a/source/bfutil/nlookup.c +++ b/source/bfutil/nlookup.c @@ -28,11 +28,12 @@ bool eventexpr(s_expr *expr) static void usage(void) { printf_usage("nodelist lookup utility", - "usage: nlookup [-C config] [-rmh]
\n" + "usage: nlookup [-C config] [-romh]
\n" "\n" "options:\n" " -r show nodelist string\n" " -m show email address\n" + " -o show overrides\n" " -h show this help message\n" " -C config use config file\n" "\n" @@ -123,22 +124,48 @@ void print_nodeinfo(const s_node *node) fflush(stdout); } +void print_overrides(const s_override *override_info) +{ + s_override *p; + char abuf[BF_MAXADDRSTR+1]; + int lin = 0; + printf("----------- Overrides ------------\n"); + printf("Address : %s\n", ftn_addrstr(abuf, override_info->addr)); + printf("IpAddr : %s\n", override_info->sIpaddr); + printf("Phone : %s\n", override_info->sPhone); + printf("Flags : %s\n", override_info->sFlags); + printf("Run before: %s\n", override_info->run); + p = override_info->hidden; + if (p) { + printf("Hidden lines:\n"); + while( p ) + { + printf(" Hidden IpAddr : %s\n", p->sIpaddr); + printf(" Hidden Phone : %s\n", p->sPhone); + printf(" Hidden Flags : %s\n", p->sFlags); + p = p->hidden; + } + } +} + int main(int argc, char *argv[]) { s_node node; s_faddr addr; + s_override *ovr; char ch; int rc = 0; char *confname = NULL; bool rawstring = FALSE; bool emailaddr = FALSE; + bool overrides = FALSE; /* Initialise random number generation */ (void)srand((unsigned)time(0)); /* Initialise current locale */ (void)setlocale(LC_ALL, ""); - while( (ch=getopt(argc, argv, "hdrmC:")) != (char)-1 ) + while( (ch=getopt(argc, argv, "hdrmoC:")) != (char)-1 ) { switch( ch ) { case 'h': @@ -150,6 +177,9 @@ int main(int argc, char *argv[]) case 'm': emailaddr = TRUE; break; + case 'o': + overrides = TRUE; + break; case 'C': if( confname || !optarg ) { usage(); exit(BFERR_FATALERROR); } confname = (char *)xstrcpy(optarg); @@ -188,6 +218,9 @@ int main(int argc, char *argv[]) } else if( nodelist_lookup(&node, addr) == 0 ) { + // Overrides + ovr = conf_override(cf_override, addr); + if (addr.point == 0) { if( emailaddr ) print_nodemail(&node); @@ -198,6 +231,17 @@ int main(int argc, char *argv[]) { print_nodeinfo(&node); } + if (overrides && ovr) { + print_overrides(ovr); + } + } else { + if (overrides) { + ovr = conf_override(cf_override, addr); + if (ovr) { + printf ("-- No nodelist info, only overrides --"); + print_overrides(ovr); + } + } } deinit_conf(); -- 2.47.2 From 4c796b042c0d09edb9a38745beccc228bd2a998d Mon Sep 17 00:00:00 2001 From: Alexey Khromov Date: Wed, 23 Apr 2025 23:46:24 +0300 Subject: [PATCH 03/11] Fixed many PVS-Studio warnings and suppressed needed overhaul --- source/bforce/daemon.c | 4 ++-- source/bforce/io_unix_lock.c | 2 +- source/bforce/logger.c | 14 +++++++------- source/bforce/nodelist.c | 6 +++--- source/bforce/os_unix.c | 3 --- source/bforce/outb_bsy.c | 2 +- source/bforce/outb_scan.c | 4 ++-- source/bforce/outb_sysqueue.c | 10 +++++----- source/bforce/prot_binkp.c | 6 +++--- source/bforce/prot_common.c | 6 +++--- source/bforce/prot_emsi_api.c | 4 ++-- source/bforce/prot_hydra.c | 28 +++++++++++++++------------- source/bforce/sess_main.c | 2 +- source/bfutil/bfindex.c | 6 ------ source/include/nodelist.h | 13 +++++++++++++ 15 files changed, 58 insertions(+), 52 deletions(-) diff --git a/source/bforce/daemon.c b/source/bforce/daemon.c index b3b86b1..3389012 100644 --- a/source/bforce/daemon.c +++ b/source/bforce/daemon.c @@ -76,8 +76,8 @@ s_daemon_queue daemon_queues[] = { /* * Positions of the certain queues in the 'daemon_queues' array */ -#define MODEM_QUEUE 0 -#define TCPIP_QUEUE 1 +#define MODEM_QUEUE 1 +#define TCPIP_QUEUE 0 static RETSIGTYPE daemon_sighandler_chld(int sig) { diff --git a/source/bforce/io_unix_lock.c b/source/bforce/io_unix_lock.c index 7009157..26a0db8 100644 --- a/source/bforce/io_unix_lock.c +++ b/source/bforce/io_unix_lock.c @@ -116,7 +116,7 @@ static pid_t lock_read_pid(const char *lckname) if( len == sizeof(pid) || sscanf(buf, "%d", &pid) != 1 || pid == 0 ) { /* We found binary lock file? */ - pid = *((u_int *)buf); + pid = *((u_int *)buf); //-V1032 #ifndef LOCK_BINARY log("warning: found binary lock file %s", lckname); #endif diff --git a/source/bforce/logger.c b/source/bforce/logger.c index 20e4d2b..2f1b39f 100644 --- a/source/bforce/logger.c +++ b/source/bforce/logger.c @@ -21,7 +21,7 @@ /* * Local variables for logger */ -static FILE *log_fp = NULL; +static FILE *log_fp = NULL; static char log_name[BF_MAXPATH+1] = BFORCE_LOGFILE; static char log_extension[32] = ""; static char log_ident[32] = ""; @@ -31,7 +31,7 @@ static char log_ttyname[32] = ""; /* * Local variables needed to make debug work */ -static FILE *debug_fp = NULL; +static FILE *debug_fp = NULL; static long debug_current_debuglevel = BFORCE_DEBLEVEL; static char debug_name[BF_MAXPATH+1] = BFORCE_DEBFILE; static bool debug_invalid_name = FALSE; @@ -124,7 +124,7 @@ int log_open(const char *logname, const char *ext, const char *tty) } } - if( log_name ) + if( log_name[0] ) { /* Open previously set log file */ @@ -145,7 +145,7 @@ int log_close(void) ASSERT(log_fp); - if( log_fp != NULL ) + if( log_fp ) //-V0547 { rc = fclose(log_fp); DEB((D_INFO,"Closing log file.")); @@ -162,7 +162,7 @@ int log_reopen(const char *logname, const char *ext, const char *tty) if( log_isopened() ) { if( !strcmp(logname, log_name) - && !strcmp(log_extension ? log_extension : "", ext ? ext : "") ) + && !strcmp(log_extension, ext ? ext : "") ) { return 0; } @@ -464,7 +464,7 @@ int debug_open() ASSERT(debug_fp == NULL); - if( debug_name ) + if( debug_name[0] ) { char log_name[PATH_MAX]; @@ -518,7 +518,7 @@ int debug_close(void) ASSERT(debug_fp != NULL); - if( debug_fp ) + if( debug_fp ) //-V0547 { fprintf(debug_fp, "****************************************************\n"); fprintf(debug_fp, " Closing binkleyforce debug file at %s\n", diff --git a/source/bforce/nodelist.c b/source/bforce/nodelist.c index b6e5a93..898b4e9 100644 --- a/source/bforce/nodelist.c +++ b/source/bforce/nodelist.c @@ -60,7 +60,7 @@ int nodelist_checkflag(const char *nodeflags, const char *flag) if ( nodeflags ) { while( p = strcasestr(searchbase, flag) ) // p - found flag { - if( (p == searchbase) || (p != searchbase && *(p-1) == ',') ) + if (*(p-1) == ',') { if( (q = strchr(p, ',')) == NULL || (q - p) == strlen(flag) ) { DEB((D_NODELIST, "nodelist: found flag %s", flag)); @@ -619,10 +619,10 @@ int nodelist_close(s_nodelist *nlp) ASSERT(nlp && nlp->fp_nodelist && nlp->fp_index); - if( nlp->fp_nodelist && file_close(nlp->fp_nodelist) ) + if( nlp->fp_nodelist && file_close(nlp->fp_nodelist) ) //-V0560 logerr("cannot close nodelist \"%s\"", nlp->name_nodelist); - if( nlp->fp_index && file_close(nlp->fp_index) ) + if( nlp->fp_index && file_close(nlp->fp_index) ) //-V0560 { logerr("cannot close nodelist index \"%s\"", nlp->name_index); rc = 1; diff --git a/source/bforce/os_unix.c b/source/bforce/os_unix.c index aaf46b1..87b6cbf 100644 --- a/source/bforce/os_unix.c +++ b/source/bforce/os_unix.c @@ -362,9 +362,6 @@ int xsystem(const char *command, const char *p_input, const char *p_output) close(fd); exit(-1); } - } - if( p_output ) - { close(2); fd = open(p_output, O_WRONLY|O_APPEND|O_CREAT, 0600); if( fd != 2 ) diff --git a/source/bforce/outb_bsy.c b/source/bforce/outb_bsy.c index 1495e42..56a9fcc 100644 --- a/source/bforce/outb_bsy.c +++ b/source/bforce/outb_bsy.c @@ -369,7 +369,7 @@ static int out_bsy_convert_csy_to_bsy(s_bsylist *ptrl) out_bsy_file_link(lockname, ".csy", lockname, ".bsy") /* Create BSY file in 4D outbound */ - if( !isfailed && ptrl->name_4d ) + if( ptrl->name_4d ) { switch( LINK_CSY_TO_BSY(ptrl->name_4d) ) { case PLOCK_OK: locked_4d = TRUE; break; diff --git a/source/bforce/outb_scan.c b/source/bforce/outb_scan.c index 9f3c607..cec5786 100644 --- a/source/bforce/outb_scan.c +++ b/source/bforce/outb_scan.c @@ -272,7 +272,7 @@ static int out_parse_name_lbox(s_faddr *addr, const char *filename) ASSERT(addr && filename); memset(&tmp, '\0', sizeof(s_faddr)); - if( sscanf(filename, "%d.%d.%d.%d", + if( sscanf(filename, "%u.%u.%u.%u", &tmp.zone, &tmp.net, &tmp.node, &tmp.point) == 4 ) { *addr = tmp; @@ -377,7 +377,7 @@ int out_parse_name_aso(s_faddr *addr, const char *filename) ASSERT(addr && filename); memset(&tmp, '\0', sizeof(s_faddr)); - if( sscanf(filename, "%d.%d.%d.%d.%*s", &tmp.zone, + if( sscanf(filename, "%u.%u.%u.%u.%*s", &tmp.zone, &tmp.net, &tmp.node, &tmp.point) == 4 ) { *addr = tmp; diff --git a/source/bforce/outb_sysqueue.c b/source/bforce/outb_sysqueue.c index fb3ef5a..9d6bf91 100644 --- a/source/bforce/outb_sysqueue.c +++ b/source/bforce/outb_sysqueue.c @@ -186,9 +186,9 @@ int out_handle_sysqueue(s_outbound_callback_data *callback) } /* Try to found existing entry for this address */ - if( (sentry = out_getsysentry((s_sysqueue*)callback->dest, - callback->addr)) == NULL ) - return -1; + sentry = out_getsysentry((s_sysqueue*)callback->dest, + callback->addr); + // if (!sentry) return -1; if( type == TYPE_NETMAIL || type == TYPE_REQUEST || type == TYPE_FILEBOX ) { @@ -283,7 +283,7 @@ void log_sysqueue(const s_sysqueue *q) if( q->systab[i].flavors & FLAVOR_CRASH ) strcat(tmp, "Crash,"); if( q->systab[i].flavors & FLAVOR_NORMAL ) strcat(tmp, "Normal,"); if( q->systab[i].flavors & FLAVOR_HOLD ) strcat(tmp, "Hold,"); - if( tmp[0] ) tmp[strlen(tmp)-1] = '\0'; + if( strlen(tmp)>0 ) tmp[strlen(tmp)-1] = '\0'; DEB((D_OUTBOUND, "log_sysqueue: \tflavors: \"%s\"", tmp)); tmp[0] = '\0'; @@ -294,7 +294,7 @@ void log_sysqueue(const s_sysqueue *q) if( q->systab[i].types & TYPE_FILEECHO ) strcat(tmp, "fileecho,"); if( q->systab[i].types & TYPE_FILEBOX ) strcat(tmp, "filebox,"); if( q->systab[i].types & TYPE_FROMFLO ) strcat(tmp, "fromflo,"); - if( tmp[0] ) tmp[strlen(tmp)-1] = '\0'; + if( strlen(tmp)>0 ) tmp[strlen(tmp)-1] = '\0'; DEB((D_OUTBOUND, "log_sysqueue: \ttypes: \"%s\"", tmp)); } DEB((D_OUTBOUND, "log_sysqueue: END")); diff --git a/source/bforce/prot_binkp.c b/source/bforce/prot_binkp.c index d45a7e1..4e50f7b 100644 --- a/source/bforce/prot_binkp.c +++ b/source/bforce/prot_binkp.c @@ -281,9 +281,9 @@ int binkp_loop(s_binkp_state *bstate) { int binkp_outgoing(s_binkp_sysinfo *local_data, s_binkp_sysinfo *remote_data) { char *p; - init_keys(remote_data->keys_out, local_data->passwd ? local_data->passwd : "-"); + init_keys(remote_data->keys_out, local_data->passwd[0] ? local_data->passwd : "-"); init_keys(remote_data->keys_in, "-"); - for (p=local_data->passwd ? local_data->passwd : "-"; *p; p++) + for (p=local_data->passwd[0] ? local_data->passwd : "-"; *p; p++) update_keys(remote_data->keys_in, (int)*p); s_binkp_state s; s.mode = bmode_outgoing_handshake; @@ -1156,7 +1156,7 @@ case BINKP_BLK_DATA: return 1; } } - PROTO_ERROR("never should be here"); + PROTO_ERROR("never should be here"); //-V0779 default: PROTO_ERROR("impossible block_type"); } diff --git a/source/bforce/prot_common.c b/source/bforce/prot_common.c index be52ea7..a6c22d9 100644 --- a/source/bforce/prot_common.c +++ b/source/bforce/prot_common.c @@ -54,7 +54,7 @@ static int prot_get_next_file(s_filelist **dest, s_protinfo *pi) /* local queue */ for( ptrl = q->fslist; ptrl; ptrl = ptrl->next ) { //DEB((D_OUTBOUND, "scan %s", ptrl->fname)); - if (hint) if (strcmp(hint->fn, ptrl->fname) !=0 || hint->sz != ptrl->size) continue; + if (hint) if (strcmp(hint->fn, ptrl->fname) !=0 || hint->sz != ptrl->size) continue; //-V0547 if( ptrl->status == STATUS_WILLSEND ) { if( pi->reqs_only ) @@ -100,7 +100,7 @@ static int prot_get_next_file(s_filelist **dest, s_protinfo *pi) } for( ptrl = pi->filelist; ptrl; ptrl = ptrl->next ) { - if (hint) if (strcmp(hint->fn, ptrl->fname) !=0 || hint->sz != ptrl->size) continue; + if (hint) if (strcmp(hint->fn, ptrl->fname) !=0 || hint->sz != ptrl->size) continue; //-V0547 if( ptrl->status == STATUS_WILLSEND ) { *dest = ptrl; @@ -112,7 +112,7 @@ static int prot_get_next_file(s_filelist **dest, s_protinfo *pi) /* network queue */ #ifdef NETSPOOL - if (hint) return 1; // cannot choose + if (hint) return 1; //-V0547 cannot choose /*DEB((D_OUTBOUND, log("netspool next file");*/ if(state.netspool.state == NS_NOTINIT) { diff --git a/source/bforce/prot_emsi_api.c b/source/bforce/prot_emsi_api.c index 684dc9e..0bc5397 100644 --- a/source/bforce/prot_emsi_api.c +++ b/source/bforce/prot_emsi_api.c @@ -113,13 +113,13 @@ void emsi_deinit(s_handshake_protocol *THIS) ASSERT(THIS->remote_data); ASSERT(THIS->local_data); - if( THIS->remote_data ) + if( THIS->remote_data ) //-V0547 { memset(THIS->remote_data, '\0', sizeof(s_emsi)); free(THIS->remote_data); } - if( THIS->local_data ) + if( THIS->local_data ) //-V0547 { memset(THIS->local_data, '\0', sizeof(s_emsi)); free(THIS->local_data); diff --git a/source/bforce/prot_hydra.c b/source/bforce/prot_hydra.c index 7d230c2..8952e77 100644 --- a/source/bforce/prot_hydra.c +++ b/source/bforce/prot_hydra.c @@ -286,10 +286,11 @@ static char *hydra_putword(char *buf, int val) static long hydra_getlong(const char *buf) { - return ( (unsigned long) ((unsigned char) buf[0]) ) - | ( (unsigned long) ((unsigned char) buf[1]) << 8 ) - | ( (unsigned long) ((unsigned char) buf[2]) << 16 ) - | ( (unsigned long) ((unsigned char) buf[3]) << 24 ); + //return ( (unsigned long) ((unsigned char) buf[0]) ) + // | ( (unsigned long) ((unsigned char) buf[1]) << 8 ) + // | ( (unsigned long) ((unsigned char) buf[2]) << 16 ) + // | ( (unsigned long) ((unsigned char) buf[3]) << 24 ); + return ( buf[3]<<24 | buf[2]<<16 | buf[1]<<8 | buf[0]); } static int hydra_getword(const char *buf) @@ -480,7 +481,7 @@ static char *hydra_putuueblock(char *buf, char *src, size_t szsrc) *buf++ = HYDRA_UUENC(src[0] >> 2); *buf++ = HYDRA_UUENC(((src[0] << 4) & 0x30) | ((src[1] >> 4) & 0x0f)); *buf++ = HYDRA_UUENC(((src[1] << 2) & 0x3c) | ((src[2] >> 6) & 0x03)); - *buf++ = HYDRA_UUENC(src[2] & 0x3f); + *buf++ = (HYDRA_UUENC(src[2]) & 0x3f); //-V0578 } if( szsrc > 0 ) @@ -1074,8 +1075,8 @@ static int hydra_parse_init(s_hydrainfo *hi, char *pkt, size_t pktlen) sscanf(window, "%08lx%08lx", &txwindow, &rxwindow); - if( txwindow < 0 ) txwindow = 0L; - if( rxwindow < 0 ) rxwindow = 0L; + //if( txwindow < 0 ) txwindow = 0L; + //if( rxwindow < 0 ) rxwindow = 0L; /* * Log other's hydra information only at 1st batch @@ -1594,7 +1595,7 @@ int hydra_batch(s_hydrainfo *hi, s_protinfo *pi) break; case HPKT_START: - if( txstate == HTX_START || txstate == HTX_SWAIT ) + if( txstate == HTX_START || txstate == HTX_SWAIT ) //-V0560 { txtries = 0; txstate = HTX_INIT; @@ -1602,7 +1603,7 @@ int hydra_batch(s_hydrainfo *hi, s_protinfo *pi) break; case HPKT_INIT: - if( rxstate == HRX_INIT ) + if( rxstate == HRX_INIT ) { if( hydra_parse_init(hi, hi->ibuf, hi->isize) ) { @@ -1615,7 +1616,7 @@ int hydra_batch(s_hydrainfo *hi, s_protinfo *pi) break; case HPKT_INITACK: - if( txstate == HTX_INIT || txstate == HTX_INITACK ) + if( txstate == HTX_INIT || txstate == HTX_INITACK ) //-V0560 { txtries = 0; txstate = HTX_RINIT; @@ -1709,7 +1710,7 @@ int hydra_batch(s_hydrainfo *hi, s_protinfo *pi) break; case HPKT_FINFOACK: - if( txstate == HTX_FINFO || txstate == HTX_FINFOACK ) + if( txstate == HTX_FINFO || txstate == HTX_FINFOACK ) //-V0560 { long offs = 0L; @@ -1724,7 +1725,8 @@ int hydra_batch(s_hydrainfo *hi, s_protinfo *pi) { log("Hydra: got invalid FINFOACK packet (ignored)"); } - else if( (offs = hydra_getlong(hi->ibuf)) == 0 ) + offs = hydra_getlong(hi->ibuf); + if( offs == 0 ) { txlastack = 0; txtries = 0; @@ -1992,7 +1994,7 @@ int hydra_batch(s_hydrainfo *hi, s_protinfo *pi) } } } - else if( rxstate == HRX_Skip || rxstate == HRX_SkipAck ) + else if( rxstate == HRX_Skip || rxstate == HRX_SkipAck ) //-V0560 { if( hi->isize < 4 ) { diff --git a/source/bforce/sess_main.c b/source/bforce/sess_main.c index 7759b37..e211483 100644 --- a/source/bforce/sess_main.c +++ b/source/bforce/sess_main.c @@ -612,7 +612,7 @@ void session_traffic_log(bool incoming, s_traffic *traff) strcat(msg, buf); strcat(msg, " files, "); } - if( *msg ) + if( *msg && strlen(msg)>2 ) msg[strlen(msg)-2] = '\0'; } diff --git a/source/bfutil/bfindex.c b/source/bfutil/bfindex.c index 5f64042..ffaefd4 100644 --- a/source/bfutil/bfindex.c +++ b/source/bfutil/bfindex.c @@ -150,12 +150,6 @@ static int nodelist_makeindex(s_nodelist *nlp, s_faddr addr) 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; diff --git a/source/include/nodelist.h b/source/include/nodelist.h index c7ea3d4..7f36188 100644 --- a/source/include/nodelist.h +++ b/source/include/nodelist.h @@ -137,6 +137,18 @@ typedef struct bni } s_bni; +typedef struct pbline +{ + bool inet; + bool prot_binkp; + bool prot_cico; + char *phone; + char *ina; + int port; + struct pbline *nextline; +} +s_pbline; + typedef struct node { s_faddr addr; @@ -154,6 +166,7 @@ typedef struct node bool do_telnet; char host[BNI_MAXHOST+1]; s_timevec worktime; + s_pbline phbook; } s_node; -- 2.47.2 From a2479e18f08d9b2fe8d9991063c7591c53924c83 Mon Sep 17 00:00:00 2001 From: Alexey Khromov Date: Thu, 24 Apr 2025 00:09:49 +0300 Subject: [PATCH 04/11] Revert hydra HXP_DATA transition --- source/bforce/prot_hydra.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/bforce/prot_hydra.c b/source/bforce/prot_hydra.c index 8952e77..0b19261 100644 --- a/source/bforce/prot_hydra.c +++ b/source/bforce/prot_hydra.c @@ -481,7 +481,7 @@ static char *hydra_putuueblock(char *buf, char *src, size_t szsrc) *buf++ = HYDRA_UUENC(src[0] >> 2); *buf++ = HYDRA_UUENC(((src[0] << 4) & 0x30) | ((src[1] >> 4) & 0x0f)); *buf++ = HYDRA_UUENC(((src[1] << 2) & 0x3c) | ((src[2] >> 6) & 0x03)); - *buf++ = (HYDRA_UUENC(src[2]) & 0x3f); //-V0578 + *buf++ = HYDRA_UUENC(src[2] & 0x3f); //-V0578 } if( szsrc > 0 ) @@ -1725,8 +1725,7 @@ int hydra_batch(s_hydrainfo *hi, s_protinfo *pi) { log("Hydra: got invalid FINFOACK packet (ignored)"); } - offs = hydra_getlong(hi->ibuf); - if( offs == 0 ) + else if( (offs = hydra_getlong(hi->ibuf)) == 0 ) //-V0560 do not touch { txlastack = 0; txtries = 0; -- 2.47.2 From 7903fd08afd5a82c488b6991f43387ccca7350e4 Mon Sep 17 00:00:00 2001 From: Alexey Khromov Date: Thu, 24 Apr 2025 06:14:38 +0300 Subject: [PATCH 05/11] Fx nodelist_checkflag --- source/bforce/nodelist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/bforce/nodelist.c b/source/bforce/nodelist.c index 898b4e9..c0252a5 100644 --- a/source/bforce/nodelist.c +++ b/source/bforce/nodelist.c @@ -60,7 +60,7 @@ int nodelist_checkflag(const char *nodeflags, const char *flag) if ( nodeflags ) { while( p = strcasestr(searchbase, flag) ) // p - found flag { - if (*(p-1) == ',') + if ( ((p == searchbase)) || (*(p-1) == ',')) { if( (q = strchr(p, ',')) == NULL || (q - p) == strlen(flag) ) { DEB((D_NODELIST, "nodelist: found flag %s", flag)); -- 2.47.2 From 81b326ca456141ecce67bbe46a6e13ec181e4cff Mon Sep 17 00:00:00 2001 From: Alexey Khromov Date: Sat, 26 Apr 2025 07:56:48 +0300 Subject: [PATCH 06/11] Added calllist option to nlookup, fixed bunch of PVS-Studio lint warnings --- source/bforce/nodelist.c | 71 +++++++++++++++ source/bforce/prot_emsi_misc.c | 2 +- source/bforce/prot_yoohoo.c | 2 +- source/bforce/prot_yoohoo_api.c | 4 +- source/bforce/sess_stat.c | 9 +- source/bforce/u_file.c | 3 +- source/bforce/u_misc.c | 2 +- source/bforce/u_plock.c | 2 +- source/bforce/u_string.c | 8 +- source/bforce/u_time.c | 2 +- source/bfutil/bfindex.c | 4 +- source/bfutil/nlookup.c | 152 ++++++++++++++++++++++++++++++-- source/include/nodelist.h | 2 +- 13 files changed, 235 insertions(+), 28 deletions(-) diff --git a/source/bforce/nodelist.c b/source/bforce/nodelist.c index c0252a5..c499c32 100644 --- a/source/bforce/nodelist.c +++ b/source/bforce/nodelist.c @@ -354,6 +354,77 @@ int nodelist_parsestring(s_node *node, char *str) return 0; } +/***************************************************************************** + * Hidden adresses adder + * + * Arguments: + * node a node for which we add HIDDEN lines with IpAddr + * str pointer to the flags string + * + * Return value: + * -1 if error + * zero value if string had no hidden INA:, pos - num of INA's above + * first + */ + +int nodelist_parsehiddenina(s_node *node,s_override *ov) { + + int rc = 0; + s_override *ovr; + s_override *ovrbase = ov; + + + char *tmp, *p, *q; + const char *searchbase = node->flags; + int flaglen = 3; + + tmp = xmalloc(BNI_MAXHOST+1); + + while( p = strstr(searchbase, "INA") ) + { + if( p == node->flags || *(p-1) == ',' ) // match flag + { + if( *(p+flaglen) == 0 || *(p+flaglen) == ',' ) + { + // empty flag + strncpy(tmp, p,'\0'); + } + else + { + if( *(p+flaglen) == ':' ) { + // flag has data + p += flaglen + 1; // start of data + q = strchrnul(p, ','); // end of data: comma or EOS + strncpy(tmp, p, q-p); + tmp[q-p]='\0'; + + if (!strcmp(tmp, node->host)) { + DEB((D_NODELIST, "nodelist: found host INA %s", tmp)); + + } else { + DEB((D_NODELIST, "nodelist: found hidden INA %s", tmp)); + rc += 1; + // let's find last override to add + while (ovrbase->hidden != NULL) ovrbase = ovrbase->hidden; + // and add new element to hiddens: + ovr = xmalloc(sizeof(s_override)); + memset(ovr,'\0',sizeof(s_override)); + ovr->hidden = NULL; + ovr->sIpaddr = xstrcpy(tmp); + ovr->addr = node->addr; + ovrbase->hidden = ovr; + } + } + } + } + searchbase = p + 1; + } + free(tmp); + return rc; + // +} + + /***************************************************************************** * Open nodelist, nodelist index, do some checks * diff --git a/source/bforce/prot_emsi_misc.c b/source/bforce/prot_emsi_misc.c index c15c185..fbd7b9d 100644 --- a/source/bforce/prot_emsi_misc.c +++ b/source/bforce/prot_emsi_misc.c @@ -439,7 +439,7 @@ char *emsi_createdat(s_emsi *emsi) * Write total length of */ sprintf(buf, "%04hX", (short unsigned)strlen(tmp+14)); - memcpy(tmp+10, buf, 4); + memcpy(tmp+10, buf, 4); //-V1086 return(tmp); } diff --git a/source/bforce/prot_yoohoo.c b/source/bforce/prot_yoohoo.c index 30d75fc..09cbd04 100644 --- a/source/bforce/prot_yoohoo.c +++ b/source/bforce/prot_yoohoo.c @@ -90,7 +90,7 @@ static void yoohoo_put_hello(char *buffer, s_yoohoo_sysinfo *myhello) char *q; if( strlen(myhello->system) + strlen(state.localaddrs[0].addr.domain) > 57 ) { - if( strlen(state.localaddrs[0].addr.domain) < 60 ) //PVS-Suppress V547 + if( strlen(state.localaddrs[0].addr.domain) < 60 ) //-V0547 q = p + (60 - strlen(state.localaddrs[0].addr.domain)); else q = p; diff --git a/source/bforce/prot_yoohoo_api.c b/source/bforce/prot_yoohoo_api.c index 49526b9..45a9474 100644 --- a/source/bforce/prot_yoohoo_api.c +++ b/source/bforce/prot_yoohoo_api.c @@ -81,13 +81,13 @@ void yoohoo_deinit(s_handshake_protocol *THIS) ASSERT(THIS->remote_data); ASSERT(THIS->local_data); - if( THIS->remote_data ) + if( THIS->remote_data ) //-V0547 { memset(THIS->remote_data, '\0', sizeof(s_yoohoo_sysinfo)); free(THIS->remote_data); } - if( THIS->local_data ) + if( THIS->local_data ) //-V0547 { memset(THIS->local_data, '\0', sizeof(s_yoohoo_sysinfo)); free(THIS->local_data); diff --git a/source/bforce/sess_stat.c b/source/bforce/sess_stat.c index 79d75d6..ad487a9 100644 --- a/source/bforce/sess_stat.c +++ b/source/bforce/sess_stat.c @@ -283,15 +283,14 @@ int session_stat_update(s_faddr *addr, s_sess_stat *stat, bool caller, int rc) stat->tries_nodial++; if( BFERR_CANT_CONNECT10 <= rc && rc <= BFERR_CANT_CONNECT19 ) stat->tries_noconn++; - if( rc >= BFERR_CONNECT_TOOLOW ) - stat->tries_sessns++; - - /* Reset some counters */ - if( rc >= BFERR_CONNECT_TOOLOW ) + if( rc >= BFERR_CONNECT_TOOLOW ) { + stat->tries_sessns++; + /* Reset some counters */ stat->tries_noansw = TRIES_RESET; stat->tries_noconn = TRIES_RESET; } + if( rc > BFERR_HANDSHAKE_ERROR ) stat->tries_hshake = TRIES_RESET; } diff --git a/source/bforce/u_file.c b/source/bforce/u_file.c index c00c65d..27dd222 100644 --- a/source/bforce/u_file.c +++ b/source/bforce/u_file.c @@ -178,8 +178,7 @@ char *file_gettmp(void) res = string_concat(tmp, chunk, '\0'); - if( chunk ) - free(chunk); + free(chunk); if( !res ) free(tmp); } diff --git a/source/bforce/u_misc.c b/source/bforce/u_misc.c index 9163f7c..b6f2fec 100644 --- a/source/bforce/u_misc.c +++ b/source/bforce/u_misc.c @@ -176,7 +176,7 @@ int strcasemask(const char *str, const char *mask) } } - return( *s != '\0' || *m != '\0' ); + return( *s != '\0' || *m != '\0' ); //-V0560 It seems more logical } /***************************************************************************** diff --git a/source/bforce/u_plock.c b/source/bforce/u_plock.c index 192185e..acc5f66 100644 --- a/source/bforce/u_plock.c +++ b/source/bforce/u_plock.c @@ -155,7 +155,7 @@ int plock_create(const char *lockname) char *tmpname, *p, *chunk; chunk = xmalloc(7); if (!chunk) { - logerr("can't generate unique file name from \"%s\"", tmpname); + logerr("can't malloc mem for generation of lock name"); DEB((D_FREE, "plock freed")); return PLOCK_ERROR; } diff --git a/source/bforce/u_string.c b/source/bforce/u_string.c index 04538f4..bd87724 100644 --- a/source/bforce/u_string.c +++ b/source/bforce/u_string.c @@ -216,7 +216,7 @@ char *string_chomp(char *str) ASSERT(str != NULL); - if( str && *str ) + if( *str ) { p = str + strlen(str + 1); if( *p == '\n' ) @@ -383,7 +383,7 @@ char *string_trimright(char *str) ASSERT(str != NULL); - if( str && *str ) + if( *str ) { p = str + strlen(str+1); while( p >= str && isspace(*p) ) *p-- = '\0'; @@ -407,7 +407,7 @@ char *string_trimleft(char *str) ASSERT(str != NULL); - if( str && *str ) + if( *str ) { p = str; while( isspace(*p) ) p++; @@ -433,7 +433,7 @@ char *string_trimboth(char *str) ASSERT(str != NULL); - if( str && *str ) + if( *str ) { /* Remove leading spaces */ p = str; diff --git a/source/bforce/u_time.c b/source/bforce/u_time.c index 84aa948..2bdef36 100644 --- a/source/bforce/u_time.c +++ b/source/bforce/u_time.c @@ -469,7 +469,7 @@ int timevec_parse(s_timevec *dest, const char *str) end_day = beg_day; - if( beg_day >= DAY_MONDAY && beg_day <= DAY_SUNDAY ) + if( beg_day <= DAY_SUNDAY ) str += 3; else if( beg_day == DAY_ANY ) str += 3; diff --git a/source/bfutil/bfindex.c b/source/bfutil/bfindex.c index ffaefd4..eec7858 100644 --- a/source/bfutil/bfindex.c +++ b/source/bfutil/bfindex.c @@ -150,14 +150,14 @@ static int nodelist_makeindex(s_nodelist *nlp, s_faddr addr) modepoint = false; break; case KEYWORD_REGION: - case KEYWORD_HOST: + case KEYWORD_HOST: //-V1037 bni.net = value; bni.node = 0; bni.point = 0; bni.hub = 0; modepoint = false; break; - case KEYWORD_HUB: + case KEYWORD_HUB: //-V1037 bni.node = value; bni.point = 0; bni.hub = value; diff --git a/source/bfutil/nlookup.c b/source/bfutil/nlookup.c index 23df5e0..8b3a246 100644 --- a/source/bfutil/nlookup.c +++ b/source/bfutil/nlookup.c @@ -34,6 +34,7 @@ static void usage(void) " -r show nodelist string\n" " -m show email address\n" " -o show overrides\n" + " -t show calltable\n" " -h show this help message\n" " -C config use config file\n" "\n" @@ -44,7 +45,7 @@ void print_nodemail(const s_node *node) { char abuf[BF_MAXADDRSTR+1]; - if( node->sysop && *node->sysop && strcmp(node->sysop, "") ) + if( *node->sysop && strcmp(node->sysop, "") ) { char username[BNI_MAXSYSOP+1]; @@ -84,7 +85,7 @@ void print_nodeinfo(const s_node *node) timevec_check(&node->worktime, now) ? "false" : "true"); } - if( (node->keyword != KEYWORD_POINT) && node->sysop && *node->sysop && strcmp(node->sysop, "") ) + if( (node->keyword != KEYWORD_POINT) && *node->sysop && strcmp(node->sysop, "") ) { char username[BNI_MAXSYSOP+1]; @@ -138,16 +139,141 @@ void print_overrides(const s_override *override_info) p = override_info->hidden; if (p) { printf("Hidden lines:\n"); + while( p ) { - printf(" Hidden IpAddr : %s\n", p->sIpaddr); - printf(" Hidden Phone : %s\n", p->sPhone); - printf(" Hidden Flags : %s\n", p->sFlags); + printf(" %5d: ",++lin); + if (p->sIpaddr) printf("IpAddr: %s, ", p->sIpaddr); + if (p->sPhone) printf("Phone: %s", p->sPhone); + if (p->sFlags) printf("Flags: %s", p->sFlags); + printf("\n"); p = p->hidden; } } } +bool check_phone(const char *str) +{ + if( !str || !str[0] ) + return FALSE; + + if( str[0] == '-' && str[1] == '\0' ) + return FALSE; + + if( string_casestr(str, "unpublished") ) + return FALSE; + + if( string_casestr(str, "unknown") ) + return FALSE; + + if( string_casestr(str, "none") ) + return FALSE; + + if( string_casestr(str, "00-00-000000") ) + return FALSE; + + return TRUE; +} + +void print_calltable(s_faddr addr){ + s_node nnode; + s_override *ovr, *tmpovr; + char *tmphost, *tmpphone; + int rc,ln = 0; + + + if( nodelist_lookup(&nnode, addr) == 0 ) + { + // we got nodelist string + ovr = conf_override(cf_override, addr); + // be aware - ovr may not be, but second INA may + if (ovr) { + ovr->addr = addr; + if (ovr->sIpaddr) strcpy (nnode.host, ovr->sIpaddr); + if (ovr->sPhone) strcpy (nnode.phone, ovr->sPhone); + if (ovr->sFlags) strcpy (nnode.flags, ovr->sFlags); + } else { + ovr = xmalloc(sizeof(s_override)); + memset(ovr,'\0',sizeof(s_override)); + ovr->addr=addr; + ovr->hidden=NULL; + ovr->sIpaddr=NULL; + } + rc = nodelist_parsehiddenina(&nnode, ovr); + + } else { + // we have no nodelist string - only overrides + ovr = conf_override(cf_override, addr); + if (ovr) { + ovr->addr = addr; + if (ovr->sIpaddr) strcpy (nnode.host, ovr->sIpaddr); + if (ovr->sPhone) strcpy (nnode.phone, ovr->sPhone); + if (ovr->sFlags) strcpy (nnode.flags, ovr->sFlags); + } + } + // Let's print this table + // begin with HOST itself + ln = 0; + if (nnode.host) { + tmphost = nnode.host; + } + if (!nodelist_checkflag(nnode.flags, "IBN")) { + ln +=1; + printf ("%5d. %s:binkp\n", ln, tmphost); + } + if (!nodelist_checkflag(nnode.flags, "IFC")) { + ln +=1; + printf ("%5d. %s:ifcico\n", ln, tmphost); + } + if (!nodelist_checkflag(nnode.flags, "ITN")) { + ln +=1; + printf ("%5d. %s:telnet\n", ln, tmphost); + } + if (ovr->hidden) { + tmpovr = ovr; + while (ovr->hidden != NULL) { + ovr = ovr->hidden; + if (ovr->sIpaddr) { + tmphost = ovr->sIpaddr; + if (!nodelist_checkflag(nnode.flags, "IBN")) { + ln +=1; + printf ("%5d. %s:binkp\n", ln, tmphost); + } + if (!nodelist_checkflag(nnode.flags, "IFC")) { + ln +=1; + printf ("%5d. %s:ifcico\n", ln, tmphost); + } + if (!nodelist_checkflag(nnode.flags, "ITN")) { + ln +=1; + printf ("%5d. %s:telnet\n", ln, tmphost); + } + } + } + ovr = tmpovr; + } + + // Calltable for pstn + if (nnode.phone && check_phone(nnode.phone) ) { + tmpphone = nnode.phone; + ln +=1; + printf ("%5d. PSTN %s\n", ln, tmpphone); + if (ovr->hidden) { + tmpovr = ovr; + while (ovr->hidden != NULL) { + ovr = ovr->hidden; + if (ovr->sPhone && check_phone(ovr->sPhone)) { + tmpphone = ovr->sPhone; + ln +=1; + printf ("%5d. PSTN %s\n", ln, tmpphone); + } + } + ovr = tmpovr; + } + } + // free ovr elements +} + + int main(int argc, char *argv[]) { s_node node; @@ -159,13 +285,14 @@ int main(int argc, char *argv[]) bool rawstring = FALSE; bool emailaddr = FALSE; bool overrides = FALSE; + bool calltable = FALSE; /* Initialise random number generation */ (void)srand((unsigned)time(0)); /* Initialise current locale */ (void)setlocale(LC_ALL, ""); - while( (ch=getopt(argc, argv, "hdrmoC:")) != (char)-1 ) + while( (ch=getopt(argc, argv, "hdrtmoC:")) != (char)-1 ) { switch( ch ) { case 'h': @@ -177,6 +304,9 @@ int main(int argc, char *argv[]) case 'm': emailaddr = TRUE; break; + case 't': + calltable = TRUE; + break; case 'o': overrides = TRUE; break; @@ -234,12 +364,20 @@ int main(int argc, char *argv[]) if (overrides && ovr) { print_overrides(ovr); } + if (calltable) { + printf ("----------- Calltable ------------\n"); + print_calltable(addr); + } } else { if (overrides) { ovr = conf_override(cf_override, addr); if (ovr) { - printf ("-- No nodelist info, only overrides --"); + printf ("-------- No nodelist info --------"); print_overrides(ovr); + if (calltable) { + printf ("----- Calltable-on-overrides -----\n"); + print_calltable(addr); + } } } } diff --git a/source/include/nodelist.h b/source/include/nodelist.h index 7f36188..48d7a71 100644 --- a/source/include/nodelist.h +++ b/source/include/nodelist.h @@ -184,7 +184,7 @@ int nodelist_getstr(s_nodelist *nlp, size_t offset, char *buffer, size_t bufle int nodelist_lookup_string(char *buffer, size_t buflen, s_faddr addr); int nodelist_lookup(s_node *node, s_faddr addr); void nodelist_initnode(s_node *node, s_faddr addr); - +int nodelist_parsehiddenina(s_node *node, s_override *ov); #endif /* _NODELIST_H_ */ -- 2.47.2 From 162a22f0a465120371db24ae71fcd0929d27a22d Mon Sep 17 00:00:00 2001 From: Alexey Khromov Date: Sat, 26 Apr 2025 10:21:04 +0300 Subject: [PATCH 07/11] Revert prot_hydra.c getlong function bitshifting --- source/bforce/prot_hydra.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/bforce/prot_hydra.c b/source/bforce/prot_hydra.c index 0b19261..7c7e15c 100644 --- a/source/bforce/prot_hydra.c +++ b/source/bforce/prot_hydra.c @@ -286,11 +286,11 @@ static char *hydra_putword(char *buf, int val) static long hydra_getlong(const char *buf) { - //return ( (unsigned long) ((unsigned char) buf[0]) ) - // | ( (unsigned long) ((unsigned char) buf[1]) << 8 ) - // | ( (unsigned long) ((unsigned char) buf[2]) << 16 ) - // | ( (unsigned long) ((unsigned char) buf[3]) << 24 ); - return ( buf[3]<<24 | buf[2]<<16 | buf[1]<<8 | buf[0]); + return ( (uint32_t) ((uint8_t) buf[0]) ) + | ( (uint32_t) ((uint8_t) buf[1]) << 8 ) + | ( (uint32_t) ((uint8_t) buf[2]) << 16 ) + | ( (uint32_t) ((uint8_t) buf[3]) << 24 ); + //return ( buf[3]<<24 | buf[2]<<16 | buf[1]<<8 | buf[0]); } static int hydra_getword(const char *buf) -- 2.47.2 From 72f46f357da4a4efd5a82a8974aa84b5a6b25ff6 Mon Sep 17 00:00:00 2001 From: Alexey Khromov Date: Sat, 26 Apr 2025 10:34:33 +0300 Subject: [PATCH 08/11] Minor prettyness with types --- source/bforce/prot_hydra.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/bforce/prot_hydra.c b/source/bforce/prot_hydra.c index 7c7e15c..ae416f7 100644 --- a/source/bforce/prot_hydra.c +++ b/source/bforce/prot_hydra.c @@ -286,10 +286,10 @@ static char *hydra_putword(char *buf, int val) static long hydra_getlong(const char *buf) { - return ( (uint32_t) ((uint8_t) buf[0]) ) + return (int32_t)(( (uint32_t) ((uint8_t) buf[0]) ) | ( (uint32_t) ((uint8_t) buf[1]) << 8 ) | ( (uint32_t) ((uint8_t) buf[2]) << 16 ) - | ( (uint32_t) ((uint8_t) buf[3]) << 24 ); + | ( (uint32_t) ((uint8_t) buf[3]) << 24 )); //return ( buf[3]<<24 | buf[2]<<16 | buf[1]<<8 | buf[0]); } -- 2.47.2 From 0999c65b1a088821329aa5eb90b082aef5d502da Mon Sep 17 00:00:00 2001 From: Alexey Khromov Date: Sat, 26 Apr 2025 21:23:31 +0300 Subject: [PATCH 09/11] Added callout hiddenline rotation and multiply INA --- CHANGES | 16 +++ debian/changelog | 14 ++ man/nlookup.1 | 8 +- rpm/bforce.spec | 4 +- source/.version | 2 +- source/bforce/expression.y | 8 +- source/bforce/io_tcpip.c | 27 +++- source/bforce/nodelist.c | 7 +- source/bforce/prot_zmmisc.c | 8 +- source/bforce/prot_zmrecv.c | 4 +- source/bforce/prot_zmsend.c | 10 +- source/bforce/sess_call.c | 252 ++++++++++++++++++++++++++++++------ source/bforce/sess_init.c | 6 +- source/bforce/u_string.c | 58 +++++---- source/bfutil/nlookup.c | 6 +- source/configure.in | 2 +- source/include/nodelist.h | 2 +- 17 files changed, 339 insertions(+), 95 deletions(-) diff --git a/CHANGES b/CHANGES index 079538c..3fe256f 100644 --- a/CHANGES +++ b/CHANGES @@ -286,3 +286,19 @@ Alexey Khromov (zx@zxalexis.ru) + Fixed RPM spec-file to make builds for AltLinux + Added fail2ban filter to contrib + Fixed node/point-lists indexing and parsing for points listed + +0.27 + + Fixed warnings from PVS-Studio analyser + + Fixed getaddrinfo switching through available ip-addresses + + Reduced SYN-SENT timeout to 3 secs to avoid blocking on hosts with services down + + nlookup - new option -o to show configured overrides and hidden lines + + nlookup - new option -t to show calltable + + Added support for multiply INA: addresses of a node + + Added automatic rolling of all available adresses on callout + + Added automatic rolling of all available hidden phone numbers on callout + + Full rework of overrides in config: + * override (not hidden) changes phone,ipaddr and flags (old behaviour - add flags) + * hidden flags temporary rolls instead of original + * INA in hidden flags sets remote address, protoflags change protocols + * ipaddr in hidden flags overwrites original and has max priority + * phone in hidden lines do not affect ip callout in case without flags diff --git a/debian/changelog b/debian/changelog index 497d21a..ca35488 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,17 @@ +bforce (0.27) UNRELEASED; urgency=medium + + * Fixed warnings from PVS-Studio analyser + * Fixed getaddrinfo switching through available ip-addresses + * Reduced SYN-SENT timeout to 3 secs to avoid blocking on hosts with services down + * nlookup - new option -o to show configured overrides and hidden lines + * nlookup - new option -t to show calltable + * Added support for multiply INA: addresses of a node + * Added automatic rolling of all available adresses on callout + * Added automatic rolling of all available hidden phone numbers on callout + * Full rework of overrides in config + + -- Alexey Khromov Sat, 26 Apr 2025 21:19:54 +0300 + bforce (0.26.2) UNRELEASED; urgency=medium * Added tests to CI actions diff --git a/man/nlookup.1 b/man/nlookup.1 index a9b476c..735f32c 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] [-C\fIconfig\fB]\fR +\fBnlookup [-otrh] [-C\fIconfig\fB]\fR .SH DESCRIPTION \fBnlookup\fP is a nodelist search tool for BinkleyForce FTN mailer. @@ -13,6 +13,12 @@ show nodelist string \fB\-m\fR show sysops e-mail (see FSP-1004.001 - p2) .P +\fB\-t\fR +show calltable +.P +\fB\-o\fR +show overrides +.P \fB-h\fR show help message .SH SEE ALSO diff --git a/rpm/bforce.spec b/rpm/bforce.spec index b1b947e..6135e47 100644 --- a/rpm/bforce.spec +++ b/rpm/bforce.spec @@ -1,7 +1,7 @@ Summary: Bforce, Fidonet mailer Name: bforce -Version: 0.26.2 -Release: %{_vendor}.1 +Version: 0.27 +Release: %{_vendor}1 Copyright: GPL Group: Fidonet/mailer Source0: bforce-%{version}.tar.gz diff --git a/source/.version b/source/.version index 894542a..5a9e6bd 100644 --- a/source/.version +++ b/source/.version @@ -1 +1 @@ -0.26.2 +0.27 diff --git a/source/bforce/expression.y b/source/bforce/expression.y index 0c60416..1ee9cbd 100644 --- a/source/bforce/expression.y +++ b/source/bforce/expression.y @@ -137,7 +137,7 @@ elemexp : INCOMING } | FLAG flagstring { - $$ = $2; + $$ = $2; //-V1037 } | CONNSPEED AROP NUMBER { @@ -163,7 +163,7 @@ elemexp : INCOMING } | TIME timestring { - $$ = $2; + $$ = $2; //-V1037 } | EXEC TEXT { @@ -194,7 +194,7 @@ flagstring : TEXT } | TEXT COMMA flagstring { - $$ = expr_check_logic($1, OR, $3); + $$ = expr_check_logic($1, OR, $3); //-V1037 } ; timestring : TEXT @@ -205,7 +205,7 @@ timestring : TEXT } | TEXT COMMA timestring { - $$ = expr_check_logic($1, OR, $3); + $$ = expr_check_logic($1, OR, $3); //-V1037 } ; %% diff --git a/source/bforce/io_tcpip.c b/source/bforce/io_tcpip.c index 7d600fc..176cf8f 100644 --- a/source/bforce/io_tcpip.c +++ b/source/bforce/io_tcpip.c @@ -16,6 +16,7 @@ #include "logger.h" #include "util.h" #include "io.h" +#include #define DEFAULT_PORT 60179 /* Birthday .. mother fucker :) */ @@ -39,10 +40,13 @@ static RETSIGTYPE tcpip_brokenpipe(int sig) static int tcpip_connect2(struct addrinfo *ai) { int fd = -1; + bool connected = FALSE; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; - + int synRetries = 2; // Send a total of 3 SYN packets => Timeout ~7s + int usertimeout = 3000; struct addrinfo *rai; + for (rai = ai; rai != NULL; rai = rai->ai_next) { if (getnameinfo(rai->ai_addr, rai->ai_addrlen, hbuf, sizeof(hbuf), sbuf, @@ -57,23 +61,32 @@ static int tcpip_connect2(struct addrinfo *ai) } else { - DEB((D_INFO, "tcpip_connect2: socket opened - breaking")); + DEB((D_INFO, "tcpip_connect2: socket opened - try to connect")); + setsockopt(fd, IPPROTO_TCP, TCP_SYNCNT, &synRetries, sizeof(synRetries)); + setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &usertimeout, sizeof(usertimeout)); if( connect(fd, rai->ai_addr, rai->ai_addrlen) == -1 ) { DEB((D_INFO, "tcpip_connect2: can't connect %s", hbuf)); logerr("can't connect to %s", hbuf); close(fd); - } else + fd = -1; + } else { + DEB((D_INFO, "tcpip_connect2: connect")); + connected = TRUE; break; + } } - DEB((D_INFO, "tcpip_connect2: socket not opened - returning")); hbuf[0]='\0'; sbuf[0]='\0'; + if (!connected) { + DEB((D_INFO, "tcpip_connect2: socket not opened - returning")); + + } } - DEB((D_INFO, "tcpip_connect2: socket success: %d", fd)); - if (fd < 0 ) + DEB((D_INFO, "tcpip_connect2: socket: %d", fd)); + if ((fd < 0) || !connected) { - DEB((D_INFO, "tcpip_connect2: can't create socket")); + DEB((D_INFO, "tcpip_connect2: can't create socket and connect")); logerr("can't create socket"); return(1); } diff --git a/source/bforce/nodelist.c b/source/bforce/nodelist.c index c499c32..2174e4a 100644 --- a/source/bforce/nodelist.c +++ b/source/bforce/nodelist.c @@ -76,7 +76,7 @@ int nodelist_checkflag(const char *nodeflags, const char *flag) } } - return 1; + return -1; } /***************************************************************************** @@ -387,7 +387,7 @@ int nodelist_parsehiddenina(s_node *node,s_override *ov) { if( *(p+flaglen) == 0 || *(p+flaglen) == ',' ) { // empty flag - strncpy(tmp, p,'\0'); + memset(tmp, '\0', 1); } else { @@ -397,9 +397,10 @@ int nodelist_parsehiddenina(s_node *node,s_override *ov) { q = strchrnul(p, ','); // end of data: comma or EOS strncpy(tmp, p, q-p); tmp[q-p]='\0'; - + DEB((D_NODELIST, "nodelist: host INA is %s", node->host)); if (!strcmp(tmp, node->host)) { DEB((D_NODELIST, "nodelist: found host INA %s", tmp)); + } else { DEB((D_NODELIST, "nodelist: found hidden INA %s", tmp)); diff --git a/source/bforce/prot_zmmisc.c b/source/bforce/prot_zmmisc.c index 1d629b3..71318af 100644 --- a/source/bforce/prot_zmmisc.c +++ b/source/bforce/prot_zmmisc.c @@ -360,12 +360,12 @@ static int noxrd7(void) if( (c = GETCHAR(Z_Rxwait)) < 0 ) return(c); - switch( c &= 0177 ) { + switch( c &= 0x7F ) { // was octal 0177 case XON: case XOFF: continue; default: - if( Z_Ctlesc && !(c & 0140) ) + if( Z_Ctlesc && !(c & 0x60) ) //was octal 0140 b01100000 hex 0x60 continue; case '\r': case '\n': @@ -1056,8 +1056,8 @@ static int zrhhdr(char *hdr) /* There is some characters available.. */ switch( (c = GETCHAR(1)) ) { - case 0215: - case 015: + case 0x8D: //was octal 0215 dec 141 b 10001101 hex 0x8D ZCRC + case 0x0D: //was octal 015 dec 13 b 00001101 hex 0x0D ZCRC /* Throw away possible cr/lf */ if( (c = GETCHAR(1)) < 0 && c != ZTIMER ) return(c); diff --git a/source/bforce/prot_zmrecv.c b/source/bforce/prot_zmrecv.c index fa26258..60b0f64 100644 --- a/source/bforce/prot_zmrecv.c +++ b/source/bforce/prot_zmrecv.c @@ -248,8 +248,8 @@ int rx_zmodem(s_protinfo *pi, bool caller) break; } /* end of switch(rxstate) */ - - if( rxstate != ZRX_INIT && rxstate != ZRX_GOTFILE + // && rxstate != ZRX_GOTFILE - always true, :131 changes it + if( rxstate != ZRX_INIT && rxstate != ZRX_SENDRPOS && rxstate != ZRX_WAITDATA && rxstate != ZRX_SKIP && rxstate != ZRX_REFUSE ) { diff --git a/source/bforce/prot_zmsend.c b/source/bforce/prot_zmsend.c index 794b01a..006d939 100644 --- a/source/bforce/prot_zmsend.c +++ b/source/bforce/prot_zmsend.c @@ -133,6 +133,7 @@ int tx_zmodem(s_protinfo *pi, bool caller) int dtype, n; int ftype; char c, *p; + int ichar = 0; long unsigned crc32; enum ztxstates txstate; time_t deadtimer; @@ -389,8 +390,9 @@ int tx_zmodem(s_protinfo *pi, bool caller) /* Ignore them all */ break; } /* end of switch(txstate) */ - - if( txstate != ZTX_START && txstate != ZTX_RQINIT + + // txstate != ZTX_START always true + if( txstate != ZTX_RQINIT && txstate != ZTX_FINFO && txstate != ZTX_DATA && txstate != ZTX_EOF && txstate != ZTX_FIN ) { @@ -648,8 +650,8 @@ int tx_zmodem(s_protinfo *pi, bool caller) log(" Send file's CRC-32 "); crc32 = 0xFFFFFFFFL; - while( ((c = getc(pi->send->fp)) != EOF) && --Z_Rxpos ) - crc32 = updcrc32(c, crc32); + while( ((ichar = getc(pi->send->fp)) != EOF) && --Z_Rxpos ) + crc32 = updcrc32(ichar, crc32); crc32 = ~crc32; diff --git a/source/bforce/sess_call.c b/source/bforce/sess_call.c index 1a84fc7..2c9175e 100644 --- a/source/bforce/sess_call.c +++ b/source/bforce/sess_call.c @@ -591,7 +591,7 @@ int call_system(s_faddr addr, const s_bforce_opts *opts) log(s); DEB((D_EVENT, s)); // find suitable way of connection and try to make session - + s_override *tmpovr; int rc = 0; int runrc = 0; char abuf[BF_MAXADDRSTR+1]; @@ -599,7 +599,9 @@ int call_system(s_faddr addr, const s_bforce_opts *opts) char *errmsg = NULL; int call_mustuse = 0; int call_mayuse = 0; - + char origphone[BNI_MAXPHONE+1]; + char origflags[BNI_MAXFLAGS+1]; + char orighost[BNI_MAXHOST+1]; init_state(&state); state.caller = TRUE; @@ -611,12 +613,38 @@ int call_system(s_faddr addr, const s_bforce_opts *opts) { errmsg = "incorrect hidden line number"; gotoexit(BFERR_PHONE_UNKNOWN); + } + + // We can do it even if no nodelist string for node + // we got overrides, so apply ALL configs, except tuned by options + // BEFORE we decide how to call + if (state.override.sFlags) { + (void)strnxcpy(state.node.flags, state.override.sFlags, strlen(state.override.sFlags)+1); + state.node.do_binkp = (nodelist_checkflag(state.node.flags, "IBN") == 0); + state.node.do_ifcico = (nodelist_checkflag(state.node.flags, "IFC") == 0); + state.node.do_telnet = (nodelist_checkflag(state.node.flags, "ITN") == 0); + memset(state.node.host,'\0',sizeof(state.node.host)); + nodelist_flagvalue(state.node.flags, "INA",state.node.host); + + DEB((D_EVENT, "sess_call: applied override flags=%s", state.node.flags)); } + if (state.override.sPhone && !(opts->phone)) { + (void)strnxcpy(state.node.phone, state.override.sPhone, strlen(state.override.sPhone)+1); + DEB((D_EVENT, "sess_call: applied override phone=%s", state.node.phone)); + } + if (state.override.sIpaddr && !(opts->iphost)) { + (void)strnxcpy(state.node.host, state.override.sIpaddr, strlen(state.override.sIpaddr)+1); + DEB((D_EVENT, "sess_call: applied override ipaddr=%s", state.node.host)); + } + if (nodelist_parsehiddenina(&state.node, &state.override) > 0) { + DEB((D_EVENT, "sess_call: got hidden INAs")); + } + state.listed = state.node.listed; //DEB((D_EVENT, "Calling init, listed=%d", state.listed)); state.node.addr.domain[0] = '\0'; /* Discard domain for node address */ - + // 1. If call method specified in cmdline, do use it // 2. If not, use nodelist data and overrides and call all available methods // If override contains Phone or IP flags, ignore nodelist connect methods (but save INA if not overrided) @@ -640,7 +668,7 @@ int call_system(s_faddr addr, const s_bforce_opts *opts) } else if( opts->runmode == MODE_CALL_IP ) { - DEB((D_EVENT, "Calling init, MODE_CALL_IP")); + DEB((D_EVENT, "sess_call: MODE_CALL_IP - from cli")); if( !(opts->ipproto) ) // determine from nodelist/override { DEB((D_EVENT, "ipproto not set")); @@ -676,9 +704,9 @@ int call_system(s_faddr addr, const s_bforce_opts *opts) call_mayuse |= call_mustuse; // it simplifies logics: all required is allowed //char s[300]; - //snprintf(s, 299, "initial: may use %d must use %d", call_mayuse, call_mustuse); + snprintf(s, 299, "initial: may use %d must use %d", call_mayuse, call_mustuse); //log(s); - //DEB((D_EVENT, s)); + DEB((D_EVENT, s)); if( (call_mayuse & CALL_MODEM) ) @@ -691,16 +719,17 @@ int call_system(s_faddr addr, const s_bforce_opts *opts) { (void)strnxcpy(state.node.phone, opts->phone, sizeof(state.node.phone)); //log("phone from options"); - } - else if( state.override.sPhone ) - { - (void)strnxcpy(state.node.phone, state.override.sPhone, sizeof(state.node.phone)); - //log("phone from override"); - } + } // Moved to top + //else if( state.override.sPhone ) + //{ + // (void)strnxcpy(state.node.phone, state.override.sPhone, sizeof(state.node.phone)); + // //log("phone from override"); + //} if( !modem_isgood_phone(state.node.phone) ) { log("bad phone, excluding modem"); + DEB((D_EVENT, "sess_call: bad phone, excluding modem" )); call_mayuse &= ~CALL_MODEM; if( !(call_mayuse) ) { @@ -749,14 +778,14 @@ int call_system(s_faddr addr, const s_bforce_opts *opts) //log(s); //DEB((D_EVENT, s)); /* - * Apply overrides to the node information + * Apply overrides to the node information - 2025 moved to start */ - if( state.override.sFlags ) - { - strnxcat(state.node.flags, ",", sizeof(state.node.flags)); - strnxcat(state.node.flags, state.override.sFlags, sizeof(state.node.flags)); - } + //if( state.override.sFlags ) + //{ + // strnxcat(state.node.flags, ",", sizeof(state.node.flags)); + // strnxcat(state.node.flags, state.override.sFlags, sizeof(state.node.flags)); + //} // state.node nodelist // state.override config @@ -764,44 +793,50 @@ int call_system(s_faddr addr, const s_bforce_opts *opts) // filter unavailable protos if not obligated to use it - if( !(call_mustuse & CALL_TCPIP_BINKP) && (call_mayuse & CALL_TCPIP_BINKP) ) + // Decide protos on calling by flags with override + if( (call_mustuse & CALL_TCPIP_BINKP) && (call_mayuse & CALL_TCPIP_BINKP) ) { - //if( nodelist_checkflag(state.node.flags, "BINKP") != 0 && nodelist_checkflag(state.node.flags, "IBN") != 0 ) + //if( nodelist_checkflag(state.node.flags, "IBN") != 0 ) if( state.node.do_binkp == 0 ) { call_mayuse &= ~CALL_TCPIP_BINKP; } } - if( !(call_mustuse & CALL_TCPIP_IFCICO) && (call_mayuse & CALL_TCPIP_IFCICO) ) + if( (call_mustuse & CALL_TCPIP_IFCICO) && (call_mayuse & CALL_TCPIP_IFCICO) ) { - //if( nodelist_checkflag(state.node.flags, "IFC") != 0 && nodelist_checkflag(state.node.flags, "IFC") != 0 ) + //if( nodelist_checkflag(state.node.flags, "IFC") != 0 ) if( state.node.do_ifcico == 0 ) { call_mayuse &= ~CALL_TCPIP_IFCICO; } } - if( !(call_mustuse & CALL_TCPIP_TELNET) && (call_mayuse & CALL_TCPIP_TELNET) ) + if( (call_mustuse & CALL_TCPIP_TELNET) && (call_mayuse & CALL_TCPIP_TELNET) ) { - //if( nodelist_checkflag(state.node.flags, "TELN") != 0 && nodelist_checkflag(state.node.flags, "TLN") != 0 ) + //if( nodelist_checkflag(state.node.flags, "TLN") != 0 ) if( state.node.do_telnet == 0 ) { call_mayuse &= ~CALL_TCPIP_TELNET; } - } - + } + snprintf(s, 299, "after 1 check: may use %d must use %d", call_mayuse, call_mustuse); + log(s); + DEB((D_EVENT, s)); + if( opts->iphost && *opts->iphost ) { + memset(state.node.host,'\0',sizeof(state.node.host)); (void)strnxcpy(state.node.host, opts->iphost, sizeof(state.node.host)); } - else if( state.override.sIpaddr ) - { - (void)strnxcpy(state.node.host, - state.override.sIpaddr, sizeof(state.node.host)); - } + // Moved to start + //else if( state.override.sIpaddr ) + //{ + // (void)strnxcpy(state.node.host, + // state.override.sIpaddr, sizeof(state.node.host)); + //} - //DEB((D_EVENT, "Calling init, IPHOST", state.node.host)); + DEB((D_EVENT, "Calling init, IPHOST %s", state.node.host)); // We have at least one protocol and not valid address - try to // find INA with through Fidonet DNS @@ -871,31 +906,129 @@ int call_system(s_faddr addr, const s_bforce_opts *opts) // try allowed methods and break if rc == 0 rc = -1; + // START CALLING + // ROTATE HIDDEN LINES IF ANY + + //snprintf(s, 299, "before call: may use %d must use %d", call_mayuse, call_mustuse); + //log(s); + //DEB((D_EVENT, s)); + // Hidden lines - if smth is not in place - use orig overriden hard + memcpy(&origphone, &state.node.phone,sizeof(origphone)); + memcpy(&origflags, &state.node.flags,sizeof(origflags)); + memcpy(&orighost, &state.node.host,sizeof(orighost)); + if( call_mayuse & CALL_STDIO ) { - DEB((D_EVENT,"sess_call: calling stdio")); + DEB((D_EVENT,"sess_call: calling stdio, mayuse=%x", call_mayuse)); rc = call_system_quiet(opts->connect, opts->inetd); } + if( rc && (call_mayuse & CALL_TCPIP_BINKP) ) { - DEB((D_EVENT,"sess_call: calling binkp")); + DEB((D_EVENT,"sess_call: calling binkp, mayuse=%x", call_mayuse)); rc = call_system_tcpip(CALL_TCPIP_BINKP); } if( rc && (call_mayuse & CALL_TCPIP_IFCICO) ) { - DEB((D_EVENT,"sess_call: calling ifcico")); + DEB((D_EVENT,"sess_call: calling ifcico, mayuse=%x", call_mayuse)); rc = call_system_tcpip(CALL_TCPIP_IFCICO); } if( rc && (call_mayuse & CALL_TCPIP_TELNET) ) { - DEB((D_EVENT,"sess_call: calling telnet")); + DEB((D_EVENT,"sess_call: calling telnet, mayuse=%x", call_mayuse)); rc = call_system_tcpip(CALL_TCPIP_TELNET); } + tmpovr = &state.override; + while (tmpovr->hidden != NULL && rc) { + DEB((D_EVENT, "sess_call: starting hidden, current is %x", tmpovr->hidden)); + tmpovr = tmpovr->hidden; + + if (tmpovr->sFlags) { + if (nodelist_checkflag(tmpovr->sFlags, "INA") == 0) { + memset(state.node.host,'\0',sizeof(state.node.host)); + nodelist_flagvalue(tmpovr->sFlags, "INA",state.node.host); + } + (void)strnxcpy(state.node.flags, tmpovr->sFlags, strlen(tmpovr->sFlags)+1); + call_mayuse |= call_mustuse; + state.node.do_binkp = nodelist_checkflag(state.node.flags, "IBN") == 0; + state.node.do_ifcico = nodelist_checkflag(state.node.flags, "IFC") == 0; + state.node.do_telnet = nodelist_checkflag(state.node.flags, "ITN") == 0; + DEB((D_EVENT, "sess_call: applied hidden flags=%s", state.node.flags)); + } else { + memcpy(&state.node.flags, &origflags, sizeof(origflags)); + call_mayuse |= call_mustuse; + state.node.do_binkp = nodelist_checkflag(state.node.flags, "IBN") == 0; + state.node.do_ifcico = nodelist_checkflag(state.node.flags, "IFC") == 0; + state.node.do_telnet = nodelist_checkflag(state.node.flags, "ITN") == 0; + DEB((D_EVENT, "sess_call: applied original flags=%s", state.node.flags)); + } + if (tmpovr->sPhone && !(opts->phone)) { + (void)strnxcpy(state.node.phone, tmpovr->sPhone, strlen(tmpovr->sPhone)+1); + DEB((D_EVENT, "sess_call: ?skipping hidden phone=%s", state.node.phone)); + if ( !(tmpovr->sFlags) && !(tmpovr->sIpaddr) ) continue; // skip only telephone + } else { + memcpy(&state.node.phone, &origphone, sizeof(origphone)); + DEB((D_EVENT, "sess_call: applied original phone=%s", state.node.phone)); + } + if (tmpovr->sIpaddr && !(opts->iphost)) { + (void)strnxcpy(state.node.host, tmpovr->sIpaddr, strlen(tmpovr->sIpaddr)+1); + DEB((D_EVENT, "sess_call: applied hidden ipaddr=%s", state.node.host)); + } + + if( (call_mustuse & CALL_TCPIP_BINKP) && (call_mayuse & CALL_TCPIP_BINKP) ) + { + //if( nodelist_checkflag(state.node.flags, "IBN") != 0 ) + if( state.node.do_binkp == 0 ) + { + call_mayuse &= ~CALL_TCPIP_BINKP; + } + } + + if( (call_mustuse & CALL_TCPIP_IFCICO) && (call_mayuse & CALL_TCPIP_IFCICO) ) + { + //if( nodelist_checkflag(state.node.flags, "IFC") != 0 ) + if( state.node.do_ifcico == 0 ) + { + call_mayuse &= ~CALL_TCPIP_IFCICO; + } + } + + if( (call_mustuse & CALL_TCPIP_TELNET) && (call_mayuse & CALL_TCPIP_TELNET) ) + { + //if( nodelist_checkflag(state.node.flags, "TLN") != 0 ) + if( state.node.do_telnet == 0 ) + { + call_mayuse &= ~CALL_TCPIP_TELNET; + } + } + + if( rc && (call_mayuse & CALL_TCPIP_BINKP) ) + { + DEB((D_EVENT,"sess_call: calling binkp")); + rc = call_system_tcpip(CALL_TCPIP_BINKP); + } + + if( rc && (call_mayuse & CALL_TCPIP_IFCICO) ) + { + DEB((D_EVENT,"sess_call: calling ifcico")); + rc = call_system_tcpip(CALL_TCPIP_IFCICO); + } + + if( rc && (call_mayuse & CALL_TCPIP_TELNET) ) + { + DEB((D_EVENT,"sess_call: calling telnet")); + rc = call_system_tcpip(CALL_TCPIP_TELNET); + } + DEB((D_EVENT, "sess_call: finished hidden, next is %x", tmpovr->hidden)); + } + + + // DIALING_ if( rc && (call_mayuse & CALL_MODEM) ) { DEB((D_EVENT,"sess_call: calling MODEM")); @@ -932,7 +1065,54 @@ int call_system(s_faddr addr, const s_bforce_opts *opts) { errmsg = "unable to get modem port"; } + + tmpovr = &state.override; + while (tmpovr->hidden != NULL && rc) { + DEB((D_EVENT, "sess_call: starting hidden, current is %x", tmpovr->hidden)); + tmpovr = tmpovr->hidden; + + // As for now - no effect in phone calls + if (tmpovr->sFlags) { + (void)strnxcpy(state.node.flags, tmpovr->sFlags, strlen(tmpovr->sFlags)+1); + DEB((D_EVENT, "sess_call: applied hidden flags=%s", state.node.flags)); + } else { + memcpy(&state.node.flags, &origflags, sizeof(origflags)); + DEB((D_EVENT, "sess_call: applied original flags=%s", state.node.flags)); + } + if (tmpovr->sPhone && !(opts->phone)) { + (void)strnxcpy(state.node.phone, tmpovr->sPhone, strlen(tmpovr->sPhone)+1); + DEB((D_EVENT, "sess_call: applied hidden phone=%s", state.node.phone)); + } else { + DEB((D_EVENT, "sess_call: no hidden phone - skipping")); + continue; + } + + if( state.modemport ) + { + + if( port_lock(p_lockdir, state.modemport) == 0 ) /* Successfuly locked port */ + { + DEB((D_EVENT,"sess_call: hidden call_system_modem running")); + rc = call_system_modem(); + port_unlock(p_lockdir, state.modemport); + } + else + { + errmsg = "cannot lock modem port"; + } + } + else + { + errmsg = "unable to get modem port"; + } + + + } + + // END_DIALING } + + // END CALLING if( rc ) { diff --git a/source/bforce/sess_init.c b/source/bforce/sess_init.c index 531af9d..e2ffba5 100644 --- a/source/bforce/sess_init.c +++ b/source/bforce/sess_init.c @@ -223,7 +223,8 @@ int session_init_outgoing() } else if( c == ENQ ) { - if( enq_need && ++enqcount >= enq_need && canyoohoo ) + if ( ++enqcount >= enq_need && canyoohoo ) + //if( enq_need && ++enqcount >= enq_need && canyoohoo ) { DEB((D_HSHAKE, "tx_init: exit with YooHoo")); state.session = SESSION_YOOHOO; @@ -232,7 +233,8 @@ int session_init_outgoing() } else if( c == TSYNC ) { - if( nak_need && ++nakcount > nak_need && canftsc ) + if( ++nakcount > nak_need && canftsc ) + //if( nak_need && ++nakcount > nak_need && canftsc ) { DEB((D_HSHAKE, "tx_init: exit with FTS-1")); state.session = SESSION_FTSC; diff --git a/source/bforce/u_string.c b/source/bforce/u_string.c index bd87724..4dd55f2 100644 --- a/source/bforce/u_string.c +++ b/source/bforce/u_string.c @@ -60,7 +60,11 @@ char *xstrcpy(const char *src) return NULL; tmp = xmalloc(strlen(src)+1); - strcpy(tmp, src); + if (!tmp) + return NULL; + else + strcpy(tmp, src); + return tmp; } @@ -85,15 +89,16 @@ char *xstrcat(char *src, const char *add) size = (src ? strlen(src) : 0) + strlen(add); tmp = (char*)xmalloc(size+1); - - if( src ) - { - strcpy(tmp, src); - free(src); - } else - *tmp = '\0'; - - strcat(tmp, add); + if (tmp) { + if( src ) + { + strcpy(tmp, src); + free(src); + } else + *tmp = '\0'; + + strcat(tmp, add); + } return tmp; } @@ -676,7 +681,7 @@ char *string_translate(const char *str, const char *find, const char *repl) size_t sz_find = strlen(find); size_t sz_repl = strlen(repl); size_t sz_dest = strlen(str); - char *dest, *p; + char *tmp, *dest, *p; p = dest = xstrcpy(str); @@ -689,9 +694,13 @@ char *string_translate(const char *str, const char *find, const char *repl) size_t offset = p - dest; size_t newsize = sz_dest + (sz_repl - sz_find); - if( newsize > sz_dest ) - dest = xrealloc(dest, newsize+1); - + if( newsize > sz_dest ) { + tmp = xrealloc(dest, newsize+1); + if (!tmp) { + free(dest); + return NULL; + } else dest = tmp; + } if( sz_repl > sz_find ) memmove(dest + offset + (sz_repl - sz_find), dest + offset, sz_dest - offset + 1); else if( sz_repl < sz_find ) @@ -842,18 +851,19 @@ char *string_concat(const char *str, ...) va_end(args); yield = xmalloc(yield_len + 1); - strncpy(yield, str, yield_len); - yield[yield_len] = '\0'; - yield_ptr = yield + strlen(yield); + if (yield) { + strncpy(yield, str, yield_len); + yield[yield_len] = '\0'; + yield_ptr = yield + strlen(yield); - va_start(args, str); - while( (p = va_arg(args, char *)) ) - { - strcpy(yield_ptr, p); - yield_ptr += strlen(p); + va_start(args, str); + while( (p = va_arg(args, char *)) ) + { + strcpy(yield_ptr, p); + yield_ptr += strlen(p); + } + va_end(args); } - va_end(args); - return yield; } diff --git a/source/bfutil/nlookup.c b/source/bfutil/nlookup.c index 8b3a246..c671380 100644 --- a/source/bfutil/nlookup.c +++ b/source/bfutil/nlookup.c @@ -70,7 +70,7 @@ void print_nodeinfo(const s_node *node) printf("Phone : %s\n", node->phone); printf("Sysop : %s\n", node->sysop); printf("Location : %s\n", node->location); - printf("Speed : %lu\n", node->speed); + printf("Speed : %ld\n", node->speed); printf("Flags : %s\n", node->flags); if( node->worktime.num ) @@ -214,7 +214,7 @@ void print_calltable(s_faddr addr){ // Let's print this table // begin with HOST itself ln = 0; - if (nnode.host) { + if (nnode.host[0]) { tmphost = nnode.host; } if (!nodelist_checkflag(nnode.flags, "IBN")) { @@ -253,7 +253,7 @@ void print_calltable(s_faddr addr){ } // Calltable for pstn - if (nnode.phone && check_phone(nnode.phone) ) { + if (nnode.phone[0] && check_phone(nnode.phone) ) { tmpphone = nnode.phone; ln +=1; printf ("%5d. PSTN %s\n", ln, tmpphone); diff --git a/source/configure.in b/source/configure.in index 5efe9be..992492b 100644 --- a/source/configure.in +++ b/source/configure.in @@ -3,7 +3,7 @@ dnl dnl $Id$ dnl #AC_INIT(bforce/bforce.c) -AC_INIT([bforce],[0.26.2],[zx@zxalexis.ru]) +AC_INIT([bforce],[0.27],[zx@zxalexis.ru]) AC_CONFIG_HEADER(include/config.h) AC_CANONICAL_SYSTEM dnl # Minimum Autoconf version required. diff --git a/source/include/nodelist.h b/source/include/nodelist.h index 48d7a71..2fcef0a 100644 --- a/source/include/nodelist.h +++ b/source/include/nodelist.h @@ -185,6 +185,6 @@ int nodelist_lookup_string(char *buffer, size_t buflen, s_faddr addr); int nodelist_lookup(s_node *node, s_faddr addr); void nodelist_initnode(s_node *node, s_faddr addr); int nodelist_parsehiddenina(s_node *node, s_override *ov); - +int nodelist_flagvalue(const char *nodeflags, const char *flag, char *res); #endif /* _NODELIST_H_ */ -- 2.47.2 From 6bcd460e155cfe25b3fcea3676026fd035c95172 Mon Sep 17 00:00:00 2001 From: Alexey Khromov Date: Sat, 26 Apr 2025 21:49:44 +0300 Subject: [PATCH 10/11] Fx Readme.md --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d2296bd..1fa8fab 100644 --- a/README.md +++ b/README.md @@ -32,9 +32,12 @@ any later version. See the COPYING file for further information. Known Bugs ---------- - - BinkleyForce has no support (yet) for multiple INA: addresses - - Can not rotate hidden lines - - Can not rotate supported IP protocols in case of failure + +~~BinkleyForce has no support (yet) for multiple INA: addresses~~ +~~Can not rotate hidden lines~~ +~~Can not rotate supported IP protocols in case of failure~~ + + - Can not (yet) apply flags to hidden phone lines. Bug Reports ----------- -- 2.47.2 From e94fcfc054c7fda4d6536f80e439e1c4ca35356e Mon Sep 17 00:00:00 2001 From: Alexey Khromov Date: Sun, 27 Apr 2025 22:25:40 +0300 Subject: [PATCH 11/11] Added override example to FAQ --- FAQ | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/FAQ b/FAQ index da9e172..a079ef1 100644 --- a/FAQ +++ b/FAQ @@ -1,7 +1,7 @@ - BinkleyForce FAQ. + BinkleyForce FAQ. -v. 1.15 от 26 марта 2002. + 27 апреля 2025 Q: А как для многолинейки сделать разные строки инициализации? A: /DR/ @@ -103,17 +103,44 @@ A: /AB/ Hу что-нибудь вроде: override 2:5020/??? phone none ipaddr f???.n5020.z2.fidonet.net Еще можно добавить флаги: BINKP - дл BinkP или IFC - для EMSI/.. +A: /AK/ + Формат override-строки такой: + override <фидоадрес> [hidden] [Phone <тлф>] [Ipaddr ] [Flags <флаги>] + ip-адрес/днс-имя сервера можно подменить как через Ipaddr, так и через + флаги, поставив INA:адрес + Пример override: + [флаги нодлиста: CM,IBN,INA:coolbbs.spb.ru,INA:cool2.spb.ru,BEER:lager + override 2:5030/xxx Phone Unpublished Flags IFC,INA:reservbbs.dyndns.org \ + hidden Ipaddr 188.34.34.22 \ + hidden Ipaddr 234.43.44.23 Flags IFC,CM + + Порядок дозвона (до первого успешного установления сессии): + 1. coolbbs.spb.ru:binkp + 2. reservbbs.dyndns.org:ifcico + 3. 188.34.34.22:binkp + 4. 234.43.44.23:ifcico + 5. cool2.spb.ru:binkp + Проверить настроенные override-s и порядок дозвона можно с помощью + программы nlookup: опция -o показывает override, опция -t - порядок + дозвона (IP+PSTN) Q: Демон забивает на указание ip...и звонит по нодлистовому телефону. Вот как это пофиксить? A: /AB/ Это бага така. Для этого и прописываетс "phone none". +A: /AK/ + Приоритеты c версии 0.26.x за ip-дозвоном, демон для ip-узлов не + производит дозвон, для PSTN-only - не ищет ip-адрес. При ручном дозвоне + используются все способы соединения из нодлиста, сначала IP, потом модем Q: Я не понял, почему aftersession запускается, когда еще есть bsy?! Весь нужный эффект теряется (bforce 0.22.3). A: /AB/ Почему теряется? Он же в отдельной сессии запускаться может и бфорсу не обязательно ждать его завершения. +A: /AK/ + aftersession запускается, когда уже есть принятый пакет в inbound. + процесс получает значения переменных окружения от демона Q: subst'ы было бы неплохо расширить т.к. очень не хватает AT~S91=7~DP :-( A: /SNP/ @@ -124,7 +151,7 @@ Q: A: /SNP/ inbound_directory (Protected) /var/spool/fido/inb-protected inbound_directory /var/spool/fido/inb -Прим.: начина с 0.22.3 пример конфига имеет аналогичный порядок. +Прим.: начиная с 0.22.3 пример конфига имеет аналогичный порядок. Q: Статистику после сессии собрать так и не смог. Пишет: "can't get modem statistic: Modem not response". Модем IDC-2814BXL/VR+. @@ -142,7 +169,7 @@ A: /AB/ fido stream tcp nowait root /usr/bin/bforce bforce -i auto Q: А как бы сделать так, чтобы можно было прописать другую директорию для - локов? У мен, например, они в /var/spool/lock лежат... + локов? У меня, например, они в /var/spool/lock лежат... A: /AB/ Либо поправить autoconf (configure.in), либо ручками в config.h прописать. /EK/ @@ -161,6 +188,8 @@ A: /AB/ Q: Пример конфига 'override 2:5029/9 Phone Unpublished' не работает :-( A: /VS/ override 2:5029/9 Phone None +A: /AK/ + Уже работает Q: У меня прописано несколько hidden'ов, но bforce упорно звонит только по одному из них. @@ -169,6 +198,8 @@ A: /PVC/ UUE. Также доступен для фреков на 2:5020/2091 как bforce-0.22.4-0.22.4pl2.diff.bz2. Время для фреков c 1:00 до 5:20, c 7:40-9:00. +A: /AK/ + Исправлено в 0.27 Q: Подскажите, пожалyйста, как запpетить непаpольные соединения. A: /AB/ @@ -210,6 +241,9 @@ A: /AS/ | /var/src/cvs/bforce/ > grep -r 'BFCONFIG' ./ | ./source/bforce/conf_read.c: const char *name = getenv("BFCONFIG"); `---- +A: /AK/ + Опция -с для всех программ комплекта + === Thanx to: -- 2.47.2