diff --git a/CHANGES b/CHANGES index b3c3fc0..fc46fa0 100644 --- a/CHANGES +++ b/CHANGES @@ -257,3 +257,16 @@ Alexey Khromov (zx@zxalexis.ru) 0.25.2 + Adopted for outgoing IPv6 communication +0.25.3 + + Fixed IPv6 address logging in inetd connections + + Fixed outgoing proto detection and order - as Direct, BinkP, Ifcico, + Telnet, Modem first allowed to connect. You may change this order + individually by override flags. + + Daemon mode now tries to make outgoing tcp calls prior to modem + + Daemon mode - fixed working time for tcp nodes (CM) + + Fixed some x64 errors in comparisons to integers + + Added systemd and xinetd service files to contrib folder + + Fixed flag files creation + + Added flags for TIC files (inctic_flag) and files (incfile_flag) + + Fixed nodelist index creation + + Added support for TCP port description in IBN/IFC/ITN flags diff --git a/README.md b/README.md index 8365b06..b639c34 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,26 @@ BinkleyForce FTN mailer ----------------------- -BinkleyForce is a simple ifcico like FTN mailer. It can works via +BinkleyForce is a simple ifcico like FTN mailer. It can work via TCP/IP as well as on modem links. Look sample configs for more information. +Supported Features +------------------ + + - PSTN dial-out with EMSI-II/EMSI/YooHoo handshake + - PSTN protocols: Hydra, ZedZap, ZModem + - PSTN dial-in through mgetty + - TCP/IP dial-out through IPv4 and IPv6 networks + - TCP/IP protocols - ifcico / BinkP 1.1 + - TCP/IP dial-in through xinetd/inetd + - Daemon mode for outbound queue managing + + Linux 2.4.11+, FreeBSD (6+ AFAIR) compatible. + +Licence +------- + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) @@ -12,8 +28,9 @@ any later version. See the COPYING file for further information. Known Bugs ---------- - - BinkD use and expect local file time at BinkP sessions, but - BinkleyForce always use UTC time (?) + - BinkleyForce has no support (yet) for multiple INA: addresses + - Can not rotate hidden lines + - Can not rotate supported IP protocols in case of failure Bug Reports ----------- diff --git a/contrib/mkpoll.sh b/contrib/mkpoll.sh new file mode 100755 index 0000000..8f3e73a --- /dev/null +++ b/contrib/mkpoll.sh @@ -0,0 +1,92 @@ +#!/bin/sh + +# Directories and static values +DEFZONE=2 +# Default outbound +# OUTBOUND="." +# Our AKA +# AKA="2:5030/723@fidonet" +# FLO Extension +FLOEXT="dlo" +# BFCONFIG=/opt/fidonms/etc/bforce.conf + +if [ "${BFCONFIG}" == "" ]; then + BFCONF="/etc/bforce/bforce.conf" +else + BFCONF=${BFCONFIG} +fi + +if [ "$1" == "" ]; then + echo "No FTN provided. Usage: mkpoll
" + exit 1 +fi + +# Address to create poll +FTNA=$1 + +# Outbound address +OUTB="" +if [ -f "${BFCONF}" ]; then + # We have config! + OUTB=$(grep -E "^outbound_directory" ${BFCONF} | awk '{print $2}') +else + OUTB=${OUTBOUND} +fi + +#echo "FTNA: ${FTNA} OUTB: ${OUTB}" + +FZONE=$(echo -n ${FTNA}| awk -F':' '{print $1}') +FNET=$(echo -n ${FTNA} | awk -F':' '{print $2}' | awk -F'/' '{ print $1 }') +FNODE=$(echo -n ${FTNA}| awk -F'/' '{print $2}' | awk -F'@' '{ print $1 }'| awk -F'.' '{ print $1 }') +FPNT=$(echo -n ${FTNA} | awk -F'/' '{print $2}' | awk -F'@' '{ print $1 }'| awk -F'.' '{ print $2 }') +FDOM=$(echo -n ${FTNA} | awk -F'@' '{print $2}') + +# echo "Dest ZONE: ${FZONE}, NET: ${FNET}, NODE: ${FNODE}, PNT: ${FPNT} DOM: ${FDOM}" + +# Our AKA +FAKA="" +if [ -f "${BFCONF}" ]; then + # We have config! + FAKA=$(grep -E "^address" ${BFCONF} | awk '{print $2}') +else + FAKA=${AKA} +fi + +AZONE=$(echo -n ${FAKA}| awk -F':' '{print $1}') +ANET=$(echo -n ${FAKA} | awk -F':' '{print $2}' | awk -F'/' '{ print $1 }') +ANODE=$(echo -n ${FAKA}| awk -F'/' '{print $2}' | awk -F'@' '{ print $1 }'| awk -F'.' '{ print $1 }') +APNT=$(echo -n ${FAKA} | awk -F'/' '{print $2}' | awk -F'@' '{ print $1 }'| awk -F'.' '{ print $2 }') +ADOM=$(echo -n ${FAKA} | awk -F'@' '{print $2}') + +# echo "Our ZONE: ${AZONE}, NET: ${ANET}, NODE: ${ANODE}, PNT: ${APNT} DOM: ${ADOM}" + + +FTNB=$( printf "%04x%04x" ${FNET} ${FNODE} ) + +if [ "${FPNT}" == "" ]; then + FPNT="0" +fi + +FFLO="" +if [ "${AZONE}" == "${FZONE}" ] && [ "${FNET}" == "${ANET}" ] && [ "${FNODE}" == "${ANODE}" ] && [ ! "${FPNT}" == "0" ]; then + # echo "Point operations!" + FLOFIL=$( printf "%08x.${FLOEXT}" ${FPNT} ) + PNTDIR=$( echo -n "${OUTB}/${FTNB}.pnt") + FFLO=$( echo -n "${PNTDIR}/${FLOFIL}" ) +elif [ ! "${DEFZONE}" == "${FZONE}" ]; then + # Interzonal poll + FLOFIL=$( echo -n "${FTNB}.${FLOEXT}" ) + FDIR=$( printf "%03x" ${FZONE} ) + FFLO=$( echo -n "${OUTB}.${FDIR}/${FLOFIL}" ) +else + # Normal in-zone poll + FLOFIL=$( echo -n "${FTNB}.${FLOEXT}" ) + FFLO=$( echo -n "${OUTB}/${FLOFIL}" ) +fi + +# echo "FloFile: ${FFLO}" + +if [ ! -f "${FFLO}" ]; then + touch "${FFLO}" +fi + diff --git a/contrib/systemd/bforce.service b/contrib/systemd/bforce.service new file mode 100644 index 0000000..9b2463a --- /dev/null +++ b/contrib/systemd/bforce.service @@ -0,0 +1,13 @@ +[Unit] +Description=Binkleyforce Outbound server + +[Service] +Type=forking +PIDFile=/tmp/bforce.pid +User=fido +Group=fido +ExecStart=/usr/bin/bforce -d -C /opt/fidonms/etc/bforce.conf +ExecStop=/usr/bin/bforce -q + +[Install] +WantedBy=multi-user.target diff --git a/contrib/xinetd.d/bforce-binkp b/contrib/xinetd.d/bforce-binkp new file mode 100644 index 0000000..fcddb5f --- /dev/null +++ b/contrib/xinetd.d/bforce-binkp @@ -0,0 +1,13 @@ +#binkleyforce ifc (port 60179) EMSI-over-ip +service binkp +{ + disable = no + socket_type = stream +# flags = IPv4 + protocol = tcp + port = 24554 + wait = no + user = fido + server = /usr/bin/bforce + server_args = -C /opt/fidonms/etc/bforce.conf -i binkp +} diff --git a/contrib/xinetd.d/bforce-ifcico b/contrib/xinetd.d/bforce-ifcico new file mode 100644 index 0000000..2d47a70 --- /dev/null +++ b/contrib/xinetd.d/bforce-ifcico @@ -0,0 +1,13 @@ +#binkleyforce ifc (port 60179) EMSI-over-ip +service ifc +{ + disable = no + socket_type = stream +# flags = IPv4 + protocol = tcp + port = 60179 + wait = no + user = fido + server = /usr/bin/bforce + server_args = -C /opt/fidonms/etc/bforce.conf -i auto +} \ No newline at end of file diff --git a/examples/bforce.conf b/examples/bforce.conf index c613b43..6c54a58 100644 --- a/examples/bforce.conf +++ b/examples/bforce.conf @@ -103,6 +103,11 @@ nodial_flag /etc/nodial #incnet_flag /var/spool/fido/flags/mail # Arcmail: #incarc_flag /var/spool/fido/flags/echo +# FileEcho TIC +#inctic_flag /var/spool/fido/flags/tick +# Regular file recieve +#incfile_flag /var/spool/fido/flags/alert + # # Inbound directories diff --git a/source/.version b/source/.version index 166c9e2..3d9dcb1 100644 --- a/source/.version +++ b/source/.version @@ -1 +1 @@ -0.25.2 +0.25.3 diff --git a/source/bforce/conf_proc.c b/source/bforce/conf_proc.c index 1d7d02a..fc85dbf 100644 --- a/source/bforce/conf_proc.c +++ b/source/bforce/conf_proc.c @@ -100,6 +100,8 @@ s_conf_entry bforce_config[BFORCE_NUMBER_OF_KEYWORDS+1] = { CONF_KEY(freq_srif_command, CT_STRING), CONF_KEY(incnet_flag, CT_STRING), CONF_KEY(incarc_flag, CT_STRING), + CONF_KEY(inctic_flag, CT_STRING), + CONF_KEY(incfile_flag, CT_STRING), CONF_KEY(hide_our_aka, CT_ADDRESS), CONF_KEY(history_file, CT_STRING), CONF_KEY(hydra_options, CT_OPTIONS), diff --git a/source/bforce/daemon.c b/source/bforce/daemon.c index d50a839..dfd706e 100644 --- a/source/bforce/daemon.c +++ b/source/bforce/daemon.c @@ -178,7 +178,7 @@ static int daemon_sysentry_deinit(s_sysentry *sysent) return 0; } -static bool daemon_node_cancall_line(const s_node *node, const s_override *ovrd) +static int daemon_node_cancall_line(const s_node *node, const s_override *ovrd) { bool good_phone = FALSE; bool good_host = FALSE; @@ -208,6 +208,11 @@ static bool daemon_node_cancall_line(const s_node *node, const s_override *ovrd) if( tcpip_isgood_host(ovrd->sIpaddr) ) good_host = TRUE; } + else if ( node && *node->host ) + { + if( tcpip_isgood_host(node->host) ) + good_host = TRUE; + } /* * Check work time @@ -231,6 +236,16 @@ static bool daemon_node_cancall_line(const s_node *node, const s_override *ovrd) good_time = TRUE; } + + // Must be more complicated, i.e. call to IP even if modem is not good time + if ( good_host ) + { + good_time = TRUE; + } + + DEB((D_DAEMON, "daemon: node_cancall_line good_phone: %d, good_time:%d, good_host:%d", + good_phone, good_time, good_host)); + if( good_time ) { if( good_host ) @@ -323,9 +338,23 @@ static bool daemon_node_cancall(s_sysentry *syst, bool ign_wtime, bool tcpip) return FALSE; } + /* Make check for tcpip out */ + if ( tcpip ) + { + rc = daemon_node_cancall_line(&syst->node, NULL); + DEB((D_DAEMON, "daemon tcpip: node_cancall rc=%d", rc)); + if ( rc == 2 ) + { + syst->tcpip = TRUE; + return TRUE; + } + } + + /* Make checks for all lines */ if( syst->overrides ) { + DEB((D_DAEMON, "daemon: node_cancall OVR-IN")); if( syst->lineptr && syst->lineptr->hidden ) { line = syst->line + 1; @@ -363,11 +392,18 @@ static bool daemon_node_cancall(s_sysentry *syst, bool ign_wtime, bool tcpip) } line++; } + } else /* Node without overriden parameters */ { syst->line = line = 0; - return daemon_node_cancall_line(&syst->node, NULL); + rc = daemon_node_cancall_line(&syst->node, NULL); + DEB((D_DAEMON, "daemon: node_cancall rc=%d", rc)); + if ( rc ) + { + syst->tcpip = (rc == 2) ? TRUE : FALSE; + return TRUE; + } } return FALSE; @@ -687,6 +723,8 @@ int daemon_rescan_sysqueue(s_sysqueue *q, s_daemon_queue dqs[]) #ifdef DEBUG log_sysqueue(q); + DEB((D_DAEMON, "daemon rescan_sysqueue daemon queue: MODEM: %d, %d; TCPIP: %d, %d", + dqs[MODEM_QUEUE].circle, dqs[MODEM_QUEUE].current, dqs[TCPIP_QUEUE].circle, dqs[TCPIP_QUEUE].current)); #endif return 0; @@ -1010,10 +1048,17 @@ int daemon_run(const char *confname, const char *incname, bool quit) timer_set(&timer_alive, DAEMON_ALIVE_TIMER); } + if( max_tcpip > 0 ) + { + DEB((D_DAEMON,"daemon: daemon_tcpip_queue")); + daemon_queue_do(&daemon_queues[TCPIP_QUEUE]); + } + if( max_modem > 0 ) + { + DEB((D_DAEMON,"daemon: daemon_modem_queue")); daemon_queue_do(&daemon_queues[MODEM_QUEUE]); - if( max_tcpip > 0 ) - daemon_queue_do(&daemon_queues[TCPIP_QUEUE]); + } (void)sleep(DAEMON_IDLE_SLEEP); break; diff --git a/source/bforce/daemon_call.c b/source/bforce/daemon_call.c index 4bf2ec6..1139379 100644 --- a/source/bforce/daemon_call.c +++ b/source/bforce/daemon_call.c @@ -54,15 +54,20 @@ static int daemon_call_branch(s_sysentry *syst, const char *lockdir, s_modemport s_bforce_opts opts; // TODO: add hiddenline round-robin - opts.hiddline=0; - opts.runmode = MODE_CALL_DEFAULT; + memset(&opts, '\0', sizeof(s_bforce_opts)); + + opts.hiddline = 0; + if ( syst->tcpip ) + opts.runmode = MODE_CALL_IP; + else + opts.runmode = MODE_CALL_DEFAULT; opts.ipproto = NULL; opts.phone = NULL; opts.force = 0; opts.inetd = 0; opts.connect = NULL; opts.device = NULL; - + DEB((D_DAEMON, "daemon_call: calling call_system from branch")); // log("doing call_system"); return call_system(syst->node.addr, &opts); } @@ -87,8 +92,11 @@ int daemon_call(s_sysentry *syst) /* * Check whether this node is allready locked */ - if( out_bsy_check(syst->node.addr) ) + if( out_bsy_check(syst->node.addr) ) + { + DEB((D_DAEMON, "daemon_call: node locked by .bsy file")); return 0; + } /* * Set state structure to make expressions works properly now @@ -101,6 +109,7 @@ int daemon_call(s_sysentry *syst) if( syst->tcpip == FALSE ) { + DEB((D_DAEMON, "daemon_call: tcpip false - prep modem line")); if( (p_lockdir = conf_string(cf_uucp_lock_directory)) == NULL ) p_lockdir = BFORCE_LOCK_DIR; @@ -110,7 +119,10 @@ int daemon_call(s_sysentry *syst) return 1; } } - + DEB((D_DAEMON, "call %s line %d via %s", + ftn_addrstr(abuf, syst->node.addr), syst->line, + syst->tcpip ? "TCP/IP" : modemport->name)); + log("call %s line %d via %s", ftn_addrstr(abuf, syst->node.addr), syst->line, syst->tcpip ? "TCP/IP" : modemport->name); @@ -138,7 +150,7 @@ int daemon_call(s_sysentry *syst) } /* Now we are in child process */ - + DEB((D_DAEMON, "daemon_call: fork success - calling...")); exit(daemon_call_branch(syst, p_lockdir, modemport)); } diff --git a/source/bforce/io_tcpip.c b/source/bforce/io_tcpip.c index e4f38f7..38f3145 100644 --- a/source/bforce/io_tcpip.c +++ b/source/bforce/io_tcpip.c @@ -54,7 +54,6 @@ static int tcpip_connect2(struct addrinfo *ai) if ( fd == -1 ) { DEB((D_INFO, "tcpip_connect2: socket error")); - continue; } else break; diff --git a/source/bforce/io_unix_tio.c b/source/bforce/io_unix_tio.c index 91b4281..5f37c1f 100644 --- a/source/bforce/io_unix_tio.c +++ b/source/bforce/io_unix_tio.c @@ -118,6 +118,9 @@ int tio_get(int fd, TIO *tio) { #ifdef HAVE_TERMIOS_H return tcgetattr(fd, tio); +#else + DEB(("io_unix_tio: TERMIOS not supported!")); + return -1; #endif } @@ -127,6 +130,9 @@ int tio_set(int fd, TIO *tio) { #ifdef HAVE_TERMIOS_H return tcsetattr(fd, TCSANOW, tio); +#else + DEB(("io_unix_tio: TERMIOS not supported!")); + return -1; #endif } @@ -177,7 +183,7 @@ int tio_get_speed(TIO *tio) return speedtab[i].nspeed; } - return-1; + return -1; } int tio_set_flow_control(int fd, TIO *tio, int flow) diff --git a/source/bforce/logger.c b/source/bforce/logger.c index f3599cf..d62d35b 100644 --- a/source/bforce/logger.c +++ b/source/bforce/logger.c @@ -106,11 +106,15 @@ int log_open(const char *logname, const char *ext, const char *tty) if( logname ) { + DEB((D_INFO,"log_open: Opening log file %s", logname)); + strnxcpy(log_name, logname, sizeof(log_name)); + // May be NULL, so check both if( tty && *tty ) strnxcpy(log_ttyname, tty, sizeof(log_ttyname)); + // May be NULL, so check both if( ext && *ext ) { strnxcpy(log_extension, ext, sizeof(log_extension)); @@ -142,7 +146,9 @@ int log_close(void) if( log_fp ) { - rc = fclose(log_fp); log_fp = NULL; + rc = fclose(log_fp); + DEB((D_INFO,"Closing log file.")); + log_fp = NULL; } return rc; diff --git a/source/bforce/nodelist.c b/source/bforce/nodelist.c index 8357dad..e686a1c 100644 --- a/source/bforce/nodelist.c +++ b/source/bforce/nodelist.c @@ -243,7 +243,7 @@ int nodelist_parsestring(s_node *node, char *str) strnxcpy(node->phone, argv[NODELIST_POSPHONE], sizeof(node->phone)); strnxcpy(node->flags, argv[NODELIST_POSFLAGS], sizeof(node->flags)); 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 */ @@ -291,8 +291,11 @@ int nodelist_parsestring(s_node *node, char *str) node->do_ifcico = nodelist_checkflag(node->flags, "IFC") == 0; node->do_telnet = nodelist_checkflag(node->flags, "ITN") == 0; + //TODO: Add more INA flags to array nodelist_flagvalue(node->flags, "INA", node->host); + DEB((D_NODELIST, "nodelist: Parsed inet values IBN: %d, IFC: %d, ITN: %d, INA: %s", node->do_binkp, node->do_ifcico, node->do_telnet, node->host)); + return 0; } diff --git a/source/bforce/outb_fsqueue.c b/source/bforce/outb_fsqueue.c index ddf0e9f..7e8a9fb 100644 --- a/source/bforce/outb_fsqueue.c +++ b/source/bforce/outb_fsqueue.c @@ -31,6 +31,7 @@ int out_filetype(const char *fname) else p_nam = fname; + DEB((D_EVENT, "outb_fsqueue: getting type of file %s", p_nam)); /* * Get file name extension */ @@ -39,12 +40,19 @@ int out_filetype(const char *fname) for( i = 0; outtab[i].ext; i++ ) if( strcasemask(p_ext, outtab[i].ext) == 0 ) + { + DEB((D_EVENT, "outb_fsqueue: got type %d from outtab ext %s", outtab[i].type, p_ext )); return outtab[i].type; + } for( i = 0; exttab[i].ext; i++ ) if( strcasemask(p_ext, exttab[i].ext) == 0 ) + { + DEB((D_EVENT, "outb_fsqueue: got type %d from exttab ext %s", exttab[i].type, p_ext )); return exttab[i].type; + } + DEB((D_EVENT, "outb_fsqueue: got type UNKNOWN", exttab[i].type, p_ext )); return TYPE_UNKNOWN; } diff --git a/source/bforce/prot_binkp.c b/source/bforce/prot_binkp.c index 3c3d051..53731db 100644 --- a/source/bforce/prot_binkp.c +++ b/source/bforce/prot_binkp.c @@ -740,7 +740,7 @@ case BPMSG_PWD: /* Session password */ /* Do authorization */ if( binkp_auth_incoming(bstate->remote_data) ) { log("error: invalid password"); - if( bstate->extracmd[0] !=-1 ) return 0; // suspend if extra is occupied + if( bstate->extracmd[0] != (char)-1 ) return 0; // suspend if extra is occupied bstate->extracmd[0] = BPMSG_ERR; strcpy(bstate->extracmd+1, "Security violation"); bstate->extraislast = true; @@ -749,7 +749,7 @@ case BPMSG_PWD: /* Session password */ // lock addresses if( session_addrs_lock(state.remoteaddrs, state.n_remoteaddr) ) { log("error locking addresses of the remote"); - if( bstate->extracmd[0] !=-1 ) return 0; // suspend if extra is occupied + if( bstate->extracmd[0] != (char)-1 ) return 0; // suspend if extra is occupied bstate->extracmd[0] = BPMSG_BSY; strcpy(bstate->extracmd+1, "All addresses are busy"); bstate->extraislast = true; @@ -770,6 +770,7 @@ case BPMSG_FILE: /* File information */ s_bpfinfo recvfi; if( binkp_parsfinfo(buf+1, &recvfi, true) ) { log ("M_FILE parse error: %s", buf + 1); + DEB((D_24554, "M_FILE parse error: %s", buf + 1 )); PROTO_ERROR("invalid M_FILE"); } bstate->batch_recv_count += 1; @@ -786,9 +787,9 @@ case BPMSG_FILE: /* File information */ return 1; } DEB((D_24554, "no, skipping; TODO: accept it")); - if( bstate->extracmd[0] != -1 ) return 0; + if( bstate->extracmd[0] != (char)-1 ) return 0; bstate->extracmd[0] = BPMSG_SKIP; - sprintf(bstate->extracmd+1, "%s %ld %ld %ld", recvfi.fn, recvfi.sz, recvfi.tm); + sprintf(bstate->extracmd+1, "%s %ld %ld %ld", recvfi.fn, recvfi.sz, recvfi.tm, recvfi.offs); bstate->extraislast = false; return 1; } @@ -798,7 +799,7 @@ case BPMSG_FILE: /* File information */ PROTO_ERROR("invalid mode for M_FILE"); } - if( bstate->extracmd[0] != -1 ) return 0; + if( bstate->extracmd[0] != (char)-1 ) return 0; switch(p_rx_fopen(bstate->pi, recvfi.fn, recvfi.sz, recvfi.tm, 0)) { case 0: if (bstate->pi->recv->bytes_skipped == recvfi.offs) { @@ -1051,7 +1052,7 @@ case BINKP_BLK_DATA: if( n < 0 ) { log("error writing local file"); - if( n == -2 ) { + if( n == (long int)-2 ) { bstate->extracmd[0] = BPMSG_GOT; sprintf(bstate->extracmd+1, "%s %ld %ld", bstate->pi->recv->net_name, (long)bstate->pi->recv->bytes_total, (long)bstate->pi->recv->mod_time); @@ -1080,28 +1081,33 @@ case BINKP_BLK_DATA: p_rx_fclose(bstate->pi); PROTO_ERROR("extra data for file") } - else if( bstate->pi->recv->bytes_received == bstate->pi->recv->bytes_total ) { - DEB((D_24554, "receive completed")); - bstate->frs = frs_nothing; - bstate->pi->recv->status = FSTAT_SUCCESS; - if( !p_rx_fclose(bstate->pi) ) { - bstate->extracmd[0] = BPMSG_GOT; - sprintf(bstate->extracmd+1, "%s %ld %ld", - bstate->pi->recv->net_name, (long)bstate->pi->recv->bytes_total, - (long)bstate->pi->recv->mod_time); - bstate->extraislast = false; - return 1; - } - else { - DEB((D_24554, "some error committing file")); - bstate->extracmd[0] = BPMSG_SKIP; - sprintf(bstate->extracmd+1, "%s %ld %ld", - bstate->pi->recv->net_name, (long)bstate->pi->recv->bytes_total, - (long)bstate->pi->recv->mod_time); - bstate->extraislast = false; - return 1; - } - } else { + else if( bstate->pi->recv->bytes_received == bstate->pi->recv->bytes_total ) + { + DEB((D_24554, "receive completed")); + bstate->frs = frs_nothing; + bstate->pi->recv->status = FSTAT_SUCCESS; + if( !p_rx_fclose(bstate->pi) ) + { + bstate->extracmd[0] = BPMSG_GOT; + sprintf(bstate->extracmd+1, "%s %ld %ld", + bstate->pi->recv->net_name, (long)bstate->pi->recv->bytes_total, + (long)bstate->pi->recv->mod_time); + bstate->extraislast = false; + return 1; + } + else + { + DEB((D_24554, "some error committing file")); + bstate->extracmd[0] = BPMSG_SKIP; + sprintf(bstate->extracmd+1, "%s %ld %ld", + bstate->pi->recv->net_name, (long)bstate->pi->recv->bytes_total, + (long)bstate->pi->recv->mod_time); + bstate->extraislast = false; + return 1; + } + } + else + { DEB((D_24554, "data block accepted")); return 1; } diff --git a/source/bforce/prot_common.c b/source/bforce/prot_common.c index 4fd536f..afd6e9d 100644 --- a/source/bforce/prot_common.c +++ b/source/bforce/prot_common.c @@ -415,6 +415,7 @@ int p_tx_rewind(s_protinfo *pi, size_t pos) void prot_traffic_update(s_traffic *traf, size_t size, int xtime, int type) { + DEB((D_EVENT, "prot_common: Adding type %d with size %ld to stats", type, size)); if( type & TYPE_REQANSW ) { traf->freqed_size += size; @@ -433,6 +434,10 @@ void prot_traffic_update(s_traffic *traf, size_t size, int xtime, int type) traf->arcmail_time += xtime; traf->arcmail_num++; } + else if( type & TYPE_TICFILE ) + { + traf->ticfile_num++; + } else { traf->files_size += size; diff --git a/source/bforce/sess_answ.c b/source/bforce/sess_answ.c index ddb0642..4d24efe 100644 --- a/source/bforce/sess_answ.c +++ b/source/bforce/sess_answ.c @@ -22,8 +22,16 @@ int answ_system(e_session type, char *connstr, int inetd) { TIO oldtio; - struct sockaddr_in client; + union { + struct sockaddr a; + struct sockaddr_in in; + struct sockaddr_in6 in6; + } client; + //struct sockaddr_storage client; int clientlen = sizeof(client); + char clienthost[NI_MAXHOST]; + char clientport[NI_MAXSERV]; + int clientres = 0; int rc = 0; char *p; @@ -74,18 +82,20 @@ int answ_system(e_session type, char *connstr, int inetd) log("Answering TCPIP call..."); if( connstr && *connstr ) state.connstr = (char*)xstrcpy(connstr); - else if( getpeername(0, (struct sockaddr*)&client, &clientlen) == -1 ) - logerr("can't get client address"); - else + else { -#ifdef IPV6 - >char addr_str[INET6_ADDRSTRLEN+1]; - state.peername = (char*)xstrcpy(inet_ntop(AF_INET6, client.sin6_addr, addr_str, INET6_ADDRSTRLEN)); - state.peerport = (long)ntohs(client.sin6_port); -#else - state.peername = (char*)xstrcpy(inet_ntoa(client.sin_addr)); - state.peerport = (long)ntohs(client.sin_port); -#endif + if(getpeername(0, &client.a, &clientlen)) + log("sess_answ: can't detrmine socket client"); + clientres = getnameinfo( &client.a, clientlen, + clienthost, sizeof(clienthost), clientport, + sizeof(clientport), NI_NUMERICHOST | NI_NUMERICSERV); + if ( clientres == 0 ) + { + state.peername = (char*)xstrcpy(clienthost); + state.peerport = (long)atol(clientport); + } + else + log("sess_answ: can't get client address: ", gai_strerror(clientres)); } } diff --git a/source/bforce/sess_call.c b/source/bforce/sess_call.c index b2e897f..268a805 100644 --- a/source/bforce/sess_call.c +++ b/source/bforce/sess_call.c @@ -480,10 +480,15 @@ int call_system_tcpip(int callwith) // only TCPIP values { char abuf[BF_MAXADDRSTR+1]; int rc = BFERR_NOERROR; - + char * pbuf; + char * target; + int resflg; /* * Set verbal line name to "tcpip" value */ + memset(abuf, '\0', BF_MAXADDRSTR+1); + target = xmalloc(1024); + memset(target, '\0', 1024); state.linename = xstrcpy("tcpip"); state.inet = TRUE; @@ -502,14 +507,17 @@ int call_system_tcpip(int callwith) // only TCPIP values case CALL_TCPIP_BINKP: state.tcpmode = TCPMODE_BINKP; state.session = SESSION_BINKP; + target = xstrcpy("IBN"); break; case CALL_TCPIP_IFCICO: state.tcpmode = TCPMODE_RAW; state.session = SESSION_UNKNOWN; + target = xstrcpy("IFC"); break; case CALL_TCPIP_TELNET: state.tcpmode = TCPMODE_TELNET; state.session = SESSION_UNKNOWN; + target = xstrcpy("ITN"); break; defalt: log("invalid protocol for TCP/IP module"); @@ -520,8 +528,45 @@ defalt: ftn_addrstr(abuf, state.node.addr), (state.node.name && *state.node.name ) ? state.node.name : "