Merge pull request #1 from fidoman/master

updates
master
Max N. Boyarov 13 years ago
commit 869016ad1a

@ -0,0 +1,19 @@
=== 2011-12-25 ===
Cmdline processing code is partially rewritten.
New key -u for selection proto for IP session.
Added code to get node IP address from nodelist (INA flag).
Some maybe noisy messages in log added.
Some code rearrangements in session_call.
Added feature to try all available connection ways if not specified one
on calls from command line (IP methods then modem).
=== 2011-12-15 ===
Patch io_unix_tio.diff for OpenBSD systems running telnetted serial modem.
=== 2011-12-13 ===
Split inbound feature have added.
Received files from different links are placed in separate folders in inbound.
Use option "split_inbound" to enable this feature.

@ -0,0 +1 @@
To run fido under user not root, do `chmod +x /bin' and manually update group/passwd files (add uucp group and fido user)

@ -106,6 +106,8 @@ nodial_flag /etc/nodial
inbound_directory (Protected) /var/spool/fido/bt/pin inbound_directory (Protected) /var/spool/fido/bt/pin
inbound_directory /var/spool/fido/bt/in inbound_directory /var/spool/fido/bt/in
split_inbound yes
# #
# Path to your 4D outbound (use zone as extension) # Path to your 4D outbound (use zone as extension)
# #

@ -0,0 +1,11 @@
--- /home/sergey/nas/fido/src/bforce-0.22.8orig/source/bforce/io_unix_tio.c 2011-09-19 12:57:52.000000000 +0400
+++ io_unix_tio.c 2011-09-19 13:01:36.000000000 +0400
@@ -233,7 +233,7 @@
tio->c_iflag = TIO_FLOW_SOFT;
tio->c_oflag = 0;
tio->c_lflag = 0;
- tio->c_cc[VMIN] = 128;
+ tio->c_cc[VMIN] = 1;
tio->c_cc[VTIME] = 1;
#endif
}

@ -70,26 +70,39 @@ static void print_compiled_configuration(void)
static void usage(void) static void usage(void)
{ {
printf_usage(NULL, printf_usage(NULL,
"usage: bforce [-fmh] [-I<include>] [-n<phone>] [-l<line_number>]\n" "call:\n"
" [-a<ip_address>] [-S<connect>] [-p<device>] <node>\n" " use nodelist and config overrides\n"
" bforce [-ih] [-I<include>] [-S<connect>]\n" " bforce [-f] [-I<include>] [-p<device>] <node>\n"
" <tsync|yoohoo|emsi|binkp|auto> (this implies slave mode)\n" " use modem\n"
" bforce [-dh] [-C<config>] [-I<include>]\n" " bforce [-f] [-I<include>] -n<phone> [-l<line_number>] \n"
" [-p<device>] <node>\n"
" use TCP/IP\n"
" bforce [-I<include>] [-a<ip_address>] -u proto <node>\n"
" start on stdio\n"
" bforce [-f] [-I<include>] -o <node>\n"
"\n"
"answer:\n"
" bforce [-i] [-I<include>] [-S<connect>]\n"
" <tsync|yoohoo|emsi|binkp|auto>\n"
"\n"
"start daemon:\n"
" bforce -d [-C<config>] [-I<include>]\n"
"\n"
"stop daemon:\n"
" bforce -q [-C<config>] [-I<include>]\n"
"\n" "\n"
"options:\n" "options:\n"
" -d run as daemon\n" " -i run from inetd (for slave mode only)\n"
" -q terminate daemon\n" " -f ignore system's work time\n"
" -i run from inetd (for slave mode only)\n" " -C <config> main config file name (\"%s\")\n"
" -f ignore system's work time\n" " -I <config> additional config file name (one allowed)\n"
" -o starts outgoing session on stdin/stdout\n" " -n <phone> override phone number\n"
" -C <config> main config file name (\"%s\")\n" " -l <line_number> call on this hidden line (default is 0) \n"
" -I <config> additional config file name\n" " -a <ip_address> override internet address\n"
" -n <phone> override phone number\n" " -S <connect_str> connect string (for slave mode only)\n"
" -l <line_number> call on this hidden line (default is 0) \n" " -p <port> override modem port (must be defined in config)\n"
" -a <ip_address> override internet address\n" " -u binkp|ifcico|telnet protocol to use over TCP/IP\n"
" -S <connect_str> connect string (for slave mode only)\n" " -h show this help message\n"
" -p <port> override modem port (must be defined in config)\n"
" -h show this help message\n"
"\n", "\n",
conf_getconfname() conf_getconfname()
); );
@ -194,7 +207,7 @@ static int bforce_master(const s_bforce_opts *opts)
{ {
int callopt = 0; int callopt = 0;
if( opts->iaddr ) callopt |= CALLOPT_INET; if( opts->runmode == MODE_CALL_IP ) callopt |= CALLOPT_INET;
if( opts->force ) callopt |= CALLOPT_FORCE; if( opts->force ) callopt |= CALLOPT_FORCE;
rc = call_system(tmpl->addr, opts); rc = call_system(tmpl->addr, opts);
@ -232,105 +245,88 @@ static int bforce_daemon(const s_bforce_opts *opts)
return daemon_run(opts->confname, opts->incname, opts->quit); return daemon_run(opts->confname, opts->incname, opts->quit);
} }
int main(int argc, char *argv[], char *envp[]) int main(int argc, char *argv[], char *envp[])
{ {
s_bforce_opts opts; s_bforce_opts opts;
int rc = 0; int rc = 0;
int ch = 0; int ch = 0;
int role = 0; opts.runmode = MODE_UNDEFINED;
memset(&opts, '\0', sizeof(s_bforce_opts)); memset(&opts, '\0', sizeof(s_bforce_opts));
while( (ch=getopt(argc, argv, "hodqr:ifC:I:n:l:a:S:p:")) != EOF ) // parsing
while( (ch=getopt(argc, argv, "hfI:p:n:l:a:u:oiC:S:dq")) != EOF )
{ {
switch( ch ) { switch( ch ) {
case 'h': case 'h':
usage(); usage();
exit(BFERR_NOERROR); exit(BFERR_NOERROR);
case 'd':
if( opts.inetd || opts.force || opts.phone
|| opts.hiddline || opts.iaddr || opts.connect
|| opts.device || opts.quit )
{ usage(); exit(BFERR_FATALERROR); }
else
{ opts.daemon = 1; }
break;
case 'q':
if( opts.inetd || opts.force || opts.phone
|| opts.hiddline || opts.iaddr || opts.connect
|| opts.device || opts.daemon )
{ usage(); exit(BFERR_FATALERROR); }
else
{ opts.daemon = 1; opts.quit = 1; }
break;
case 'i':
if( opts.daemon )
{ usage(); exit(BFERR_FATALERROR); }
else
{ opts.inetd = 1; }
break;
case 'f': case 'f':
if( opts.daemon ) if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_CALL_MODEM;
{ usage(); exit(BFERR_FATALERROR); } if( opts.runmode != MODE_CALL_MODEM || opts.force ) { usage(); exit(BFERR_FATALERROR); }
else opts.force = 1;
{ opts.force = 1; }
break;
case 'o':
if( opts.dontcall )
{ usage(); exit(BFERR_FATALERROR); }
else
{ opts.dontcall = TRUE; }
break;
case 'C':
if( opts.confname ) free(opts.confname);
if( optarg ) opts.confname = (char *)xstrcpy(optarg);
break; break;
case 'I': case 'I':
if( opts.incname ) free(opts.incname); if( opts.incname || !optarg ) { usage(); exit(BFERR_FATALERROR); } //free(opts.incname);
if( optarg ) opts.incname = (char *)xstrcpy(optarg); opts.incname = (char *)xstrcpy(optarg);
break;
case 'p':
if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_CALL_MODEM;
if( opts.runmode != MODE_CALL_MODEM || opts.device || !optarg ) { usage(); exit(BFERR_FATALERROR); }
opts.device = (char *)xstrcpy(optarg);
break; break;
case 'n': case 'n':
if( opts.daemon ) if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_CALL_MODEM;
{ usage(); exit(BFERR_FATALERROR); } if( opts.runmode != MODE_CALL_MODEM || opts.phone || !optarg ) { usage(); exit(BFERR_FATALERROR); }
else //if( opts.phone ) free(opts.phone);
{ opts.phone = (char *)xstrcpy(optarg);
if( opts.phone ) free(opts.phone);
if( optarg ) opts.phone = (char *)xstrcpy(optarg);
}
break; break;
case 'l': case 'l':
if( ISDEC(optarg) && opts.daemon == 0 ) if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_CALL_MODEM;
opts.hiddline = atoi(optarg); if( opts.runmode != MODE_CALL_MODEM || opts.hiddline || !optarg || ISDEC(optarg) ) { usage(); exit(BFERR_FATALERROR); }
else opts.hiddline = atoi(optarg);
{ usage(); exit(BFERR_FATALERROR); }
break; break;
case 'a': case 'a':
if( opts.daemon ) if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_CALL_IP;
{ usage(); exit(BFERR_FATALERROR); } if( opts.runmode != MODE_CALL_IP || opts.iphost || !optarg ) { usage(); exit(BFERR_FATALERROR); }
else opts.iphost = (char *)xstrcpy(optarg);
{ break;
if( opts.iaddr ) free(opts.iaddr); case 'u':
if( optarg ) opts.iaddr = (char *)xstrcpy(optarg); if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_CALL_IP;
} if( opts.runmode != MODE_CALL_IP || opts.ipproto || !optarg ) { usage(); exit(BFERR_FATALERROR); }
opts.ipproto = (char *)xstrcpy(optarg);
break;
case 'o':
if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_CALL_STDIO;
if( opts.runmode != MODE_CALL_STDIO || opts.usestdio ) { usage(); exit(BFERR_FATALERROR); }
opts.usestdio = TRUE;
break;
case 'i':
//if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_ANSWER;
//if( opts.runmode != MODE_ANSWER || opts.inetd ) { usage(); exit(BFERR_FATALERROR); }
opts.inetd = 1;
break;
case 'C':
if( opts.confname || !optarg ) { usage(); exit(BFERR_FATALERROR); }
opts.confname = (char *)xstrcpy(optarg);
break; break;
case 'S': case 'S':
if( opts.daemon ) if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_ANSWER;
{ usage(); exit(BFERR_FATALERROR); } if( opts.runmode != MODE_ANSWER || opts.connect || !optarg ) { usage(); exit(BFERR_FATALERROR); }
else opts.connect = (char *)xstrcpy(optarg);
{
if( opts.connect ) free(opts.connect);
if( optarg ) opts.connect = (char *)xstrcpy(optarg);
}
break; break;
case 'p': case 'd':
if( opts.daemon ) if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_DAEMON;
{ usage(); exit(BFERR_FATALERROR); } if( opts.runmode != MODE_DAEMON || opts.daemon || opts.quit ) { usage(); exit(BFERR_FATALERROR); }
else opts.daemon = 1;
{ break;
if( opts.device ) free(opts.device); case 'q':
if( optarg ) opts.device = (char *)xstrcpy(optarg); if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_DAEMON;
} if( opts.runmode != MODE_DAEMON || opts.quit ) { usage(); exit(BFERR_FATALERROR); }
opts.quit = 1;
opts.daemon = 1;
break; break;
default : default :
usage(); usage();
@ -338,6 +334,12 @@ int main(int argc, char *argv[], char *envp[])
} }
} }
if( opts.inetd && opts.runmode != MODE_ANSWER && opts.runmode != MODE_CALL_STDIO )
{
usage();
exit(BFERR_FATALERROR);
}
/* Expression checker use it, so init first */ /* Expression checker use it, so init first */
init_state(&state); init_state(&state);
@ -368,37 +370,45 @@ int main(int argc, char *argv[], char *envp[])
if( strcasecmp(p, "tsync") == 0 ) if( strcasecmp(p, "tsync") == 0 )
{ {
role = 0; if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_ANSWER;
if( opts.runmode != MODE_ANSWER || opts.stype ) { usage(); exit(BFERR_FATALERROR); }
opts.stype = SESSION_FTSC; opts.stype = SESSION_FTSC;
} }
else if( strcasecmp(p, "yoohoo") == 0 ) else if( strcasecmp(p, "yoohoo") == 0 )
{ {
role = 0; if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_ANSWER;
if( opts.runmode != MODE_ANSWER || opts.stype ) { usage(); exit(BFERR_FATALERROR); }
opts.stype = SESSION_YOOHOO; opts.stype = SESSION_YOOHOO;
} }
else if( strcasecmp(p, "**EMSI_INQC816") == 0 ) else if( strcasecmp(p, "**EMSI_INQC816") == 0 )
{ {
role = 0; if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_ANSWER;
if( opts.runmode != MODE_ANSWER || opts.stype ) { usage(); exit(BFERR_FATALERROR); }
opts.stype = SESSION_EMSI; opts.stype = SESSION_EMSI;
} }
else if( strncasecmp(p, "emsi", 4) == 0 ) else if( strncasecmp(p, "emsi", 4) == 0 )
{ {
role = 0; if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_ANSWER;
if( opts.runmode != MODE_ANSWER || opts.stype ) { usage(); exit(BFERR_FATALERROR); }
opts.stype = SESSION_EMSI; opts.stype = SESSION_EMSI;
} }
else if( strcasecmp(p, "binkp") == 0 ) else if( strcasecmp(p, "binkp") == 0 )
{ {
role = 0; if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_ANSWER;
if( opts.runmode != MODE_ANSWER || opts.stype ) { usage(); exit(BFERR_FATALERROR); }
opts.stype = SESSION_BINKP; opts.stype = SESSION_BINKP;
} }
else if( strcasecmp(p, "auto") == 0 ) else if( strcasecmp(p, "auto") == 0 )
{ {
role = 0; if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_ANSWER;
if( opts.runmode != MODE_ANSWER || opts.stype ) { usage(); exit(BFERR_FATALERROR); }
opts.stype = SESSION_UNKNOWN; opts.stype = SESSION_UNKNOWN;
} }
else if( ftn_addrparse(&addr, p, FALSE) == 0 ) else if( ftn_addrparse(&addr, p, FALSE) == 0 )
{ {
role = 1; if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_CALL_DEFAULT;
if( opts.runmode != MODE_CALL_DEFAULT && opts.runmode != MODE_CALL_IP &&
opts.runmode != MODE_CALL_MODEM && opts.runmode != MODE_CALL_STDIO ) { usage(); exit(BFERR_FATALERROR); }
(*alist) = (s_falist*)xmalloc(sizeof(s_falist)); (*alist) = (s_falist*)xmalloc(sizeof(s_falist));
memset(*alist, '\0', sizeof(s_falist)); memset(*alist, '\0', sizeof(s_falist));
(*alist)->addr = addr; (*alist)->addr = addr;
@ -411,12 +421,6 @@ int main(int argc, char *argv[], char *envp[])
exit(BFERR_FATALERROR); exit(BFERR_FATALERROR);
} }
} }
if( opts.dontcall && role == 0 )
{
usage();
exit(BFERR_FATALERROR);
}
} }
/* if( (rc = log_open(log_getfilename(LOG_FILE_SESSION), NULL, NULL)) ) /* if( (rc = log_open(log_getfilename(LOG_FILE_SESSION), NULL, NULL)) )
@ -449,13 +453,31 @@ int main(int argc, char *argv[], char *envp[])
(void)debug_setfilename(log_getfilename(LOG_FILE_DEBUG)); (void)debug_setfilename(log_getfilename(LOG_FILE_DEBUG));
#endif #endif
if( opts.daemon ) //char runmode_str[21];
//snprintf(runmode_str, 20, "Run mode: %d", opts.runmode);
//log(runmode_str);
switch( opts.runmode )
{
case MODE_DAEMON:
log("Daemon mode");
rc = bforce_daemon(&opts); rc = bforce_daemon(&opts);
else if( role ) break;
case MODE_CALL_DEFAULT:
case MODE_CALL_IP:
case MODE_CALL_MODEM:
case MODE_CALL_STDIO:
log("Outgoing call");
rc = bforce_master(&opts); rc = bforce_master(&opts);
else break;
case MODE_ANSWER:
log("Start answer");
rc = bforce_slave(&opts); rc = bforce_slave(&opts);
break;
default:
log("Could not determine run mode");
}
exit: exit:
deinit_conf(); deinit_conf();
@ -475,7 +497,8 @@ static void deinit_opts(s_bforce_opts *opts)
if( opts->confname ) free(opts->confname); if( opts->confname ) free(opts->confname);
if( opts->incname ) free(opts->incname); if( opts->incname ) free(opts->incname);
if( opts->phone ) free(opts->phone); if( opts->phone ) free(opts->phone);
if( opts->iaddr ) free(opts->iaddr); if( opts->iphost ) free(opts->iphost);
if( opts->ipproto ) free(opts->ipproto);
if( opts->connect ) free(opts->connect); if( opts->connect ) free(opts->connect);
if( opts->device ) free(opts->device); if( opts->device ) free(opts->device);
if( opts->addrlist ) deinit_falist(opts->addrlist); if( opts->addrlist ) deinit_falist(opts->addrlist);

@ -175,6 +175,7 @@ s_conf_entry bforce_config[BFORCE_NUMBER_OF_KEYWORDS+1] = {
CONF_KEY(debug_file, CT_STRING), CONF_KEY(debug_file, CT_STRING),
CONF_KEY(debug_level, CT_DEBLEVEL), CONF_KEY(debug_level, CT_DEBLEVEL),
#endif #endif
CONF_KEY(split_inbound, CT_BOOLEAN),
CONF_END() CONF_END()
}; };

@ -52,78 +52,19 @@ static int daemon_call_branch(s_sysentry *syst, const char *lockdir, s_modemport
signal(SIGUSR1, SIG_DFL); signal(SIGUSR1, SIG_DFL);
signal(SIGUSR2, SIG_DFL); signal(SIGUSR2, SIG_DFL);
/* s_bforce_opts opts;
* Initialise ``state'' information structure // TODO: add hiddenline round-robin
*/ opts.hiddline=0;
init_state(&state); opts.runmode = MODE_CALL_DEFAULT;
state.caller = TRUE; opts.ipproto = NULL;
state.valid = TRUE; opts.phone = NULL;
state.node = syst->node; opts.force = 0;
state.listed = syst->node.listed; opts.inetd = 0;
state.modemport = (!syst->tcpip) ? port : NULL; opts.connect = NULL;
if( syst->lineptr ) opts.device = NULL;
state.override = *syst->lineptr;
if( *state.node.addr.domain )
*state.node.addr.domain = '\0';
/*
* Apply overrides to the node information
*/
if( state.override.sFlags )
{
strnxcat(state.node.flags, ",", sizeof(state.node.flags));
strnxcat(state.node.flags, state.override.sFlags, sizeof(state.node.flags));
}
if( !syst->tcpip && state.override.sPhone )
(void)strnxcpy(state.node.phone, state.override.sPhone, sizeof(state.node.phone));
else if( syst->tcpip && state.override.sIpaddr )
(void)strnxcpy(state.node.phone, state.override.sIpaddr, sizeof(state.node.phone));
/*
* Try to lock address of system we are going to call
*/
#ifdef BFORCE_USE_CSY
if( out_bsy_lock(state.node.addr, TRUE) )
#else
if( out_bsy_lock(state.node.addr) )
#endif
gotoexit(BFERR_SYSTEM_LOCKED);
setproctitle("bforce calling %s, %s",
ftn_addrstr(abuf, state.node.addr), state.node.phone);
/* if( ( syst->tcpip ) || (strcmp(state.node.phone,NO_PSTN_PHONE)== 0) ) */
if( syst->tcpip )
{
rc = call_system_tcpip();
}
else /* via Modem */
{
state.modemport = port;
if( port_lock(lockdir, state.modemport) )
{
log("cannot lock modem port");
rc = BFERR_PORTBUSY;
}
else /* Locked port */
{
rc = call_system_modem();
port_unlock(lockdir, state.modemport);
}
}
exit:
out_bsy_unlockall();
log("session rc = %d (\"%s\")", rc, BFERR_NAME(rc)); // log("doing call_system");
return call_system(syst->node.addr, &opts);
(void)session_stat_update(&state.node.addr,
&state.sess_stat, TRUE, rc);
deinit_state(&state);
return rc;
} }
int daemon_call(s_sysentry *syst) int daemon_call(s_sysentry *syst)

@ -59,6 +59,9 @@ bool modem_isgood_phone(const char *str)
if( string_casestr(str, "none") ) if( string_casestr(str, "none") )
return FALSE; return FALSE;
if( string_casestr(str, "00-00-000000") )
return FALSE;
return TRUE; return TRUE;
} }

@ -11,6 +11,9 @@
* $Id$ * $Id$
*/ */
#define _GNU_SOURCE
#include <string.h>
#include "includes.h" #include "includes.h"
#include "confread.h" #include "confread.h"
#include "logger.h" #include "logger.h"
@ -49,20 +52,73 @@ struct keyword {
*/ */
int nodelist_checkflag(const char *nodeflags, const char *flag) int nodelist_checkflag(const char *nodeflags, const char *flag)
{ {
char *p, *q; char *p;
const char *searchbase = nodeflags;
char *q;
if( (p = strstr(nodeflags, flag)) ) while( p = strstr(searchbase, flag) )
{ {
if( p == nodeflags || *(p-1) == ',' ) if( p == searchbase || *(p-1) == ',' )
{ {
if( (q = strchr(p, ',')) == NULL || (q - p) == strlen(flag) ) if( (q = strchr(p, ',')) == NULL || (q - p) == strlen(flag) )
return 0; return 0;
if( (strchrnul(p, ':') - p) == strlen(flag) )
return 0;
} }
searchbase = p + 1; // avoid finding again the same
} }
return 1; return 1;
} }
/*****************************************************************************
* Get value from flag (e.g. INA:host.domain.ru)
*
* Arguments:
* nodeflags pointer to the node's nodelist flags string
* flag pointer to the flag that we want to check
* value pointer to string buffer for result. please allocate
* max possible value of strlen(nodeflags) bytes
*
* Return value:
* zero value if flag is presented in flags, and non-zero if not
* res is zero lengh string if no flag or flag is empty
*/
int nodelist_flagvalue(const char *nodeflags, const char *flag, char *res)
{
char *p, *q;
const char *searchbase = nodeflags;
int flaglen = strlen(flag);
while( p = strstr(searchbase, flag) )
{
if( p == nodeflags || *(p-1) == ',' ) // match flag
{
if( *(p+flaglen) == 0 || *(p+flaglen) == ',' )
{
// empty flag
res[0]=0;
return 0;
}
else
{
if( *(p+flaglen) == ':' ) {
// flag has data
p += flaglen + 1; // start of data
q = strchrnul(p, ','); // end of data: comma or EOS
strncpy(res, p, q-p);
return 0;
}
}
}
searchbase = p + 1;
}
res[0] = 0;
return 1;
}
/***************************************************************************** /*****************************************************************************
* Get nodelist keyword (e.g. Host, Hub, Point, etc.) value * Get nodelist keyword (e.g. Host, Hub, Point, etc.) value
* (e.g. KEYWORD_HOST, KEYWORD_HUB, etc.) * (e.g. KEYWORD_HOST, KEYWORD_HUB, etc.)
@ -231,6 +287,12 @@ int nodelist_parsestring(s_node *node, char *str)
} }
} }
node->do_binkp = nodelist_checkflag(node->flags, "IBN") == 0;
node->do_ifcico = nodelist_checkflag(node->flags, "IFC") == 0;
node->do_telnet = nodelist_checkflag(node->flags, "ITN") == 0;
nodelist_flagvalue(node->flags, "INA", node->host);
return 0; return 0;
} }

@ -425,7 +425,9 @@ int binkp_transfer(s_protinfo *pi) {
BPT_EOB BPT_EOB
} binkp_send_state = BPT_Start_Send_File; } binkp_send_state = BPT_Start_Send_File;
remote = (s_binkp_sysinfo *) state.handshake->remote_data; remote = (s_binkp_sysinfo *) state.handshake->remote_data;
binkp_init_bpinfo(&bpi); binkp_init_bpinfo(&bpi);
while (1) { while (1) {
if (binkp_send_state == BPT_Start_Send_File) { if (binkp_send_state == BPT_Start_Send_File) {
if (p_tx_fopen (pi)) { if (p_tx_fopen (pi)) {
@ -699,10 +701,12 @@ int binkp_transfer(s_protinfo *pi) {
} }
} /* end of while( !sent_EOB || !rcvd_EOB ) */ } /* end of while( !sent_EOB || !rcvd_EOB ) */
FinishSession: FinishSession:
if( binkp_flush_queue(&bpi, bpi.timeout) && rc == PRC_NOERROR ) if( binkp_flush_queue(&bpi, bpi.timeout) && rc == PRC_NOERROR )
rc = PRC_ERROR; rc = PRC_ERROR;
exit: exit:
if( pi->send && pi->send->fp ) p_tx_fclose(pi); if( pi->send && pi->send->fp ) p_tx_fclose(pi);
if( pi->recv && pi->recv->fp ) p_rx_fclose(pi); if( pi->recv && pi->recv->fp ) p_rx_fclose(pi);

@ -1453,11 +1453,13 @@ void init_protinfo(s_protinfo *pi, bool caller)
{ {
long tmp; long tmp;
long sesslimit; long sesslimit;
memset(pi, '\0', sizeof(s_protinfo)); memset(pi, '\0', sizeof(s_protinfo));
pi->start_time = time(NULL); pi->start_time = time(NULL);
if( (pi->buflen = conf_number(cf_recv_buffer_size)) > 0 ) if( (pi->buflen = conf_number(cf_recv_buffer_size)) > 0 )
pi->buflen = (pi->buflen / 2048) * 2048; pi->buflen = (pi->buflen / 2048) * 2048;
else else
@ -1471,6 +1473,7 @@ void init_protinfo(s_protinfo *pi, bool caller)
else else
pi->min_cps_time = 60; pi->min_cps_time = 60;
/* /*
* Set abort time if session limit was specified * Set abort time if session limit was specified
*/ */

@ -81,8 +81,14 @@ int answ_system(e_session type, char *connstr, int inetd)
logerr("can't get client address"); 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.peername = (char*)xstrcpy(inet_ntoa(client.sin_addr));
state.peerport = (long)ntohs(client.sin_port); state.peerport = (long)ntohs(client.sin_port);
#endif
} }
} }

@ -19,6 +19,13 @@
#include "io.h" #include "io.h"
#include "session.h" #include "session.h"
#define CALL_STDIO (1)
#define CALL_MODEM (2)
#define CALL_TCPIP_BINKP (4)
#define CALL_TCPIP_IFCICO (8)
#define CALL_TCPIP_TELNET (16)
#define CALL_TCPIP_ANY (CALL_TCPIP_BINKP | CALL_TCPIP_IFCICO | CALL_TCPIP_TELNET)
#ifdef XXXX #ifdef XXXX
/* Unused */ /* Unused */
int call_system_modem_init(TIO *old_tio_settings) int call_system_modem_init(TIO *old_tio_settings)
@ -254,8 +261,14 @@ int call_system_quiet(const char *connstr, bool inet)
logerr("can't get client address"); 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.peername = (char*)xstrcpy(inet_ntoa(client.sin_addr));
state.peerport = (long)ntohs(client.sin_port); state.peerport = (long)ntohs(client.sin_port);
#endif
} }
} }
@ -320,6 +333,9 @@ int call_system_modem(void)
const char *p_hangstr = NULL; /* Modem hangup string */ const char *p_hangstr = NULL; /* Modem hangup string */
const char *p_statstr = NULL; /* Modem statistic string */ const char *p_statstr = NULL; /* Modem statistic string */
// automatically determine session type
state.session = SESSION_UNKNOWN;
/* /*
* Set verbal line name to the modem device name * Set verbal line name to the modem device name
*/ */
@ -468,7 +484,7 @@ int call_system_modem(void)
return rc; return rc;
} }
int call_system_tcpip(void) int call_system_tcpip(int callwith) // only TCPIP values
{ {
char abuf[BF_MAXADDRSTR+1]; char abuf[BF_MAXADDRSTR+1];
int rc = BFERR_NOERROR; int rc = BFERR_NOERROR;
@ -476,8 +492,8 @@ int call_system_tcpip(void)
/* /*
* Set verbal line name to "tcpip" value * Set verbal line name to "tcpip" value
*/ */
state.linename = xstrcpy("tcpip");
state.linename = xstrcpy("tcpip");
state.inet = TRUE; state.inet = TRUE;
/* /*
@ -494,34 +510,30 @@ int call_system_tcpip(void)
(void)debug_setfilename(log_getfilename(LOG_FILE_DEBUG)); (void)debug_setfilename(log_getfilename(LOG_FILE_DEBUG));
#endif #endif
if( nodelist_checkflag(state.node.flags, "BINKP") == 0 switch( callwith ) {
|| nodelist_checkflag(state.node.flags, "IBN") == 0 ) case CALL_TCPIP_BINKP:
{
state.tcpmode = TCPMODE_BINKP; state.tcpmode = TCPMODE_BINKP;
state.session = SESSION_BINKP; state.session = SESSION_BINKP;
} break;
else if( nodelist_checkflag(state.node.flags, "TELN") == 0 ) case CALL_TCPIP_IFCICO:
{
state.tcpmode = TCPMODE_TELNET;
state.session = SESSION_UNKNOWN;
}
else if( nodelist_checkflag(state.node.flags, "IFC") == 0 )
{
state.tcpmode = TCPMODE_RAW; state.tcpmode = TCPMODE_RAW;
state.session = SESSION_UNKNOWN; state.session = SESSION_UNKNOWN;
} break;
else /* Default is "raw" mode */ case CALL_TCPIP_TELNET:
{ state.tcpmode = TCPMODE_TELNET;
state.tcpmode = TCPMODE_RAW;
state.session = SESSION_UNKNOWN; state.session = SESSION_UNKNOWN;
break;
defalt:
log("invalid protocol for TCP/IP module");
return BFERR_FATALERROR;
} }
log("calling %s (%s, %s)", log("calling %s (%s, %s)",
ftn_addrstr(abuf, state.node.addr), ftn_addrstr(abuf, state.node.addr),
(state.node.name && *state.node.name ) ? state.node.name : "<none>", (state.node.name && *state.node.name ) ? state.node.name : "<none>",
(state.node.phone && *state.node.phone) ? state.node.phone : "<none>"); (state.node.host && *state.node.host) ? state.node.host : "<none>");
if( (rc = tcpip_connect(state.node.phone, state.tcpmode)) == 0 if( (rc = tcpip_connect(state.node.host, state.tcpmode)) == 0
&& (rc = tcpip_init() == 0) ) && (rc = tcpip_init() == 0) )
{ {
TTYSTATUS(1); TTYSTATUS(1);
@ -538,117 +550,229 @@ int call_system_tcpip(void)
int call_system(s_faddr addr, const s_bforce_opts *opts) int call_system(s_faddr addr, const s_bforce_opts *opts)
{ {
// if added new opts check daemon_call
char s[300];
snprintf(s, 299, "bforce calling system %d:%d/%d.%d", addr.zone, addr.net, addr.node, addr.point );
log(s);
// find suitable way of connection and try to make session
int rc = 0; int rc = 0;
int runrc = 0; int runrc = 0;
char abuf[BF_MAXADDRSTR+1]; char abuf[BF_MAXADDRSTR+1];
char *p_lockdir = NULL; char *p_lockdir = NULL;
char *errmsg = NULL; char *errmsg = NULL;
bool inet = FALSE; int call_mustuse = 0;
int call_mayuse = 0;
init_state(&state); init_state(&state);
state.caller = TRUE; state.caller = TRUE;
state.valid = TRUE; state.valid = TRUE;
state.node.addr = addr; state.node.addr = addr;
nodelist_lookup(&state.node, addr); nodelist_lookup(&state.node, addr);
state.listed = state.node.listed;
state.node.addr.domain[0] = '\0'; /* Discard domain for node address */
if( opts->dontcall )
goto do_session;
/*
* Get node overrides
*/
if( override_get(&state.override, state.node.addr, opts->hiddline) ) if( override_get(&state.override, state.node.addr, opts->hiddline) )
{ {
errmsg = "incorrect hidden line number"; errmsg = "incorrect hidden line number";
gotoexit(BFERR_PHONE_UNKNOWN); gotoexit(BFERR_PHONE_UNKNOWN);
} }
/*
* Apply overrides to the node information
*/
if( state.override.sFlags )
{
strnxcat(state.node.flags, ",", sizeof(state.node.flags));
strnxcat(state.node.flags, state.override.sFlags, sizeof(state.node.flags));
}
if( opts->iaddr && *opts->iaddr ) state.listed = state.node.listed;
{ state.node.addr.domain[0] = '\0'; /* Discard domain for node address */
inet = TRUE;
(void)strnxcpy(state.node.phone, // 1. If call method specified in cmdline, do use it
opts->iaddr, sizeof(state.node.phone)); // 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)
else if( opts->phone && *opts->phone )
// 1st - get all allowed call ways
// 2nd - gather information reqired to call and remove unavailable ways (no info, node does not support)
call_mayuse = 0;
if( opts->runmode == MODE_CALL_DEFAULT )
{ {
(void)strnxcpy(state.node.phone, call_mayuse = CALL_MODEM | CALL_TCPIP_ANY;
opts->phone, sizeof(state.node.phone));
} }
else if( state.override.sIpaddr ) else if( opts->runmode == MODE_CALL_STDIO )
{ {
inet = TRUE; call_mustuse = CALL_STDIO;
(void)strnxcpy(state.node.phone,
state.override.sIpaddr, sizeof(state.node.phone));
} }
else if( state.override.sPhone ) else if( opts->runmode == MODE_CALL_MODEM )
{ {
(void)strnxcpy(state.node.phone, call_mustuse = CALL_MODEM;
state.override.sPhone, sizeof(state.node.phone));
} }
else if( opts->runmode == MODE_CALL_IP )
if( !inet )
{ {
if( !modem_isgood_phone(state.node.phone) ) if( strcasecmp(opts->ipproto, "binkp") == 0 )
errmsg = "don't know phone number"; {
call_mustuse = CALL_TCPIP_BINKP;
}
else if ( strcasecmp(opts->ipproto, "ifcico") == 0 )
{
call_mustuse = CALL_TCPIP_IFCICO;
}
else if( strcasecmp(opts->ipproto, "telnet") == 0 )
{
call_mustuse = CALL_TCPIP_TELNET;
}
else if( opts->ipproto == NULL ) // determine from nodelist/override
{
call_mayuse = CALL_TCPIP_ANY;
call_mustuse = 0;
}
else
{
log("Unknown protocol");
return -1;
}
} }
else else
{ {
if( !tcpip_isgood_host(state.node.phone) ) log("Unknown protocol");
errmsg = "don't know host name"; return -1;
} }
if( errmsg ) call_mayuse |= call_mustuse; // it simplifies logics: all required is allowed
gotoexit(BFERR_PHONE_UNKNOWN);
//char s[300];
//snprintf(s, 299, "initial: may use %d must use %d", call_mayuse, call_mustuse);
//log(s);
if( call_mayuse & CALL_MODEM )
{
// 1. use phone from opts
// 2. use overrides
// 3. use nodelist
if( opts->phone && *opts->phone )
{
(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");
}
if( !modem_isgood_phone(state.node.phone) )
{
log("bad phone, excluding modem");
call_mayuse &= ~CALL_MODEM;
if( call_mustuse & CALL_MODEM )
{
errmsg = "don't know phone number";
gotoexit(BFERR_PHONE_UNKNOWN);
}
} else
if( !opts->force)
{
/* /*
* Is now a working time for that node/line * Is now a working time for that node/line
*/ */
if( !inet && !opts->force) time_t unixtime = time(NULL);
{ struct tm *now = localtime(&unixtime);
time_t unixtime = time(NULL); bool goodtime = FALSE;
struct tm *now = localtime(&unixtime);
bool goodtime;
if( !opts->hiddline ) if( timevec_isdefined(&state.override.worktime) )
{
if( state.override.sFlags && !nodelist_checkflag(state.override.sFlags, "CM") )
goodtime = TRUE;
else
{ {
if( timevec_isdefined(&state.override.worktime) ) goodtime = timevec_isnow(&state.override.worktime, now);
goodtime = timevec_isnow(&state.override.worktime, now); }
else if( state.override.sFlags )
{
goodtime = !nodelist_checkflag(state.override.sFlags, "CM");
}
else if( !opts->hiddline )
{
if( !nodelist_checkflag(state.node.flags, "CM") )
goodtime = TRUE;
else else
goodtime = timevec_isnow(&state.node.worktime, now);
}
if( !goodtime )
{
call_mayuse &= ~CALL_MODEM;
log("bad worktime, excluding modem");
if( call_mustuse & CALL_MODEM )
{ {
if( !nodelist_checkflag(state.node.flags, "CM") ) errmsg = "not works now, try later";
goodtime = TRUE; gotoexit(BFERR_NOTWORKING);
else
goodtime = timevec_isnow(&state.node.worktime, now);
} }
} }
} }
else }
goodtime = timevec_isnow(&state.override.worktime, now);
// snprintf(s, 299, "after phone check: may use %d must use %d", call_mayuse, call_mustuse);
if( !goodtime ) // log(s);
/*
* Apply overrides to the node information
*/
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
// opts cmdline
// filter unavailable protos if not obligated to use it
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 )
{ {
errmsg = "not works now, try later"; call_mayuse &= ~CALL_TCPIP_BINKP;
gotoexit(BFERR_NOTWORKING);
} }
} }
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 )
{
call_mayuse &= ~CALL_TCPIP_IFCICO;
}
}
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 )
{
call_mayuse &= ~CALL_TCPIP_TELNET;
}
}
if( opts->iphost && *opts->iphost )
{
(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));
}
do_session: if( call_mayuse & CALL_TCPIP_ANY && !tcpip_isgood_host(state.node.host) )
{
call_mayuse &= ~CALL_TCPIP_ANY;
log("bad host, exclude IP");
if( call_mustuse & CALL_TCPIP_ANY )
{
errmsg = "don't know host name";
gotoexit(BFERR_PHONE_UNKNOWN);
}
}
// snprintf(s, 299, "after IP check: may use %d must use %d", call_mayuse, call_mustuse);
// log(s);
//do_session:
/* /*
* It's easier to ignore than handle! After connect * It's easier to ignore than handle! After connect
* new handlers must be installed, don't worry. * new handlers must be installed, don't worry.
@ -677,48 +801,69 @@ do_session:
} }
} }
setproctitle("bforce calling %.32s, %.32s",
ftn_addrstr(abuf, state.node.addr), state.node.phone);
if( opts->dontcall ) // try allowed methods and break if rc == 0
rc = -1;
if( rc && call_mayuse & CALL_STDIO )
{ {
rc = call_system_quiet(opts->connect, opts->inetd); rc = call_system_quiet(opts->connect, opts->inetd);
} }
else if( !inet )
if( rc && call_mayuse & CALL_TCPIP_BINKP )
{
rc = call_system_tcpip(CALL_TCPIP_BINKP);
}
if( rc && call_mayuse & CALL_TCPIP_IFCICO )
{
rc = call_system_tcpip(CALL_TCPIP_IFCICO);
}
if( rc && call_mayuse & CALL_TCPIP_TELNET )
{
rc = call_system_tcpip(CALL_TCPIP_TELNET);
}
if( rc && call_mayuse & CALL_MODEM )
{ {
setproctitle("bforce calling %.32s, %.32s",
ftn_addrstr(abuf, state.node.addr), state.node.phone);
rc = -1;
if( (p_lockdir = conf_string(cf_uucp_lock_directory)) == NULL ) if( (p_lockdir = conf_string(cf_uucp_lock_directory)) == NULL )
p_lockdir = BFORCE_LOCK_DIR; p_lockdir = BFORCE_LOCK_DIR;
if( opts->device && *opts->device ) if( opts->device && *opts->device )
{ {
if( (state.modemport = state.modemport = modem_getmatch_port(opts->device);
modem_getmatch_port(opts->device)) == NULL )
{
errmsg = "unknown port name";
gotoexit(BFERR_PORTBUSY);
}
} }
else if( (state.modemport = else
modem_getfree_port(p_lockdir)) == NULL )
{ {
errmsg = "no free matching ports"; state.modemport = modem_getfree_port(p_lockdir);
gotoexit(BFERR_PORTBUSY);
} }
if( port_lock(p_lockdir, state.modemport) ) if( state.modemport )
{ {
if( port_lock(p_lockdir, state.modemport) == 0 ) /* Successfuly locked port */
{
rc = call_system_modem();
port_unlock(p_lockdir, state.modemport);
}
else
{
errmsg = "cannot lock modem port"; errmsg = "cannot lock modem port";
gotoexit(BFERR_PORTBUSY); }
} }
else /* Successfuly locked port */ else
{ {
rc = call_system_modem(); errmsg = "unable to get modem port";
port_unlock(p_lockdir, state.modemport);
} }
} }
else
if( rc )
{ {
rc = call_system_tcpip(); log("no connection effort was successful");
} }
exit: exit:

@ -36,7 +36,8 @@
* $INBOUND * $INBOUND
* $CONNECT, * $CONNECT,
* $CALLERID, * $CALLERID,
* $RC * $RC,
* $PEERNAME
*/ */
int session_run_command(const char *execstr) int session_run_command(const char *execstr)
{ {
@ -111,6 +112,10 @@ int session_run_command(const char *execstr)
if( state.cidstr && *state.cidstr ) if( state.cidstr && *state.cidstr )
exec_env_add(&eopts, "CALLERID", state.cidstr); exec_env_add(&eopts, "CALLERID", state.cidstr);
if( state.peername && *state.peername )
exec_env_add(&eopts, "PEERNAME", state.peername);
if( state.session_rc >= 0 ) if( state.session_rc >= 0 )
{ {

@ -31,7 +31,7 @@
/* On success: zero (state.session is handshake type) */ /* On success: zero (state.session is handshake type) */
/* On error: non-zero (state.session set to UNKNOWN) */ /* On error: non-zero (state.session set to UNKNOWN) */
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
int session_init_outgoing(void) int session_init_outgoing()
{ {
int c = 0; int c = 0;
int tries = 0; int tries = 0;
@ -72,8 +72,10 @@ int session_init_outgoing(void)
/* /*
* Put CR until any character received * Put CR until any character received
*/ */
if( PUTCHAR('\r') < 0 || FLUSHOUT() < 0 ) if( PUTCHAR('\r') < 0 || FLUSHOUT() < 0 ) {
log("error: output");
return 1; return 1;
}
while( !CHARWAIT(1) ) while( !CHARWAIT(1) )
{ {
@ -83,8 +85,10 @@ int session_init_outgoing(void)
return 1; return 1;
} }
if( PUTCHAR('\r') < 0 || FLUSHOUT() < 0 ) if( PUTCHAR('\r') < 0 || FLUSHOUT() < 0 ) {
log("error: output");
return 1; return 1;
}
} }
#ifdef DEBUG #ifdef DEBUG
@ -122,17 +126,27 @@ int session_init_outgoing(void)
{ {
DEB((D_HSHAKE, "tx_sendsync: resyncing")); DEB((D_HSHAKE, "tx_sendsync: resyncing"));
if( canemsi && PUTSTR("**EMSI_INQC816**EMSI_INQC816") < 0 ) if( canemsi && PUTSTR("**EMSI_INQC816**EMSI_INQC816") < 0 ) {
log("error: output");
return 1; return 1;
if( canyoohoo && PUTCHAR(YOOHOO) < 0 ) }
if( canyoohoo && PUTCHAR(YOOHOO) < 0 ) {
log("error: output");
return 1; return 1;
if( canftsc && PUTCHAR(TSYNC) < 0 ) }
if( canftsc && PUTCHAR(TSYNC) < 0 ) {
log("error: output");
return 1; return 1;
if( canemsi && PUTCHAR('\r') < 0 ) }
if( canemsi && PUTCHAR('\r') < 0 ) {
log("error: output");
return 1; return 1;
}
if( FLUSHOUT() < 0 ) if( FLUSHOUT() < 0 ) {
log("error: flush");
return 1; return 1;
}
timer_set(&sync_timer, OUTGOING_SYNC_TIMER); timer_set(&sync_timer, OUTGOING_SYNC_TIMER);
} }
@ -260,10 +274,14 @@ int session_init_outgoing(void)
state.session = SESSION_EMSI; state.session = SESSION_EMSI;
if( PUTSTR("**EMSI_INQC816\r") < 0 if( PUTSTR("**EMSI_INQC816\r") < 0
|| PUTSTR("**EMSI_INQC816\r") < 0 ) || PUTSTR("**EMSI_INQC816\r") < 0 ) {
log("error: output");
return 1; return 1;
if( FLUSHOUT() < 0 ) }
if( FLUSHOUT() < 0 ) {
log("error: output");
return 1; return 1;
}
return 0; return 0;
} }
@ -281,15 +299,19 @@ int session_init_outgoing(void)
sleep(3); sleep(3);
if( PUTSTR("**EMSI_INQC816\r") < 0 if( PUTSTR("**EMSI_INQC816\r") < 0
|| FLUSHOUT() < 0 ) || FLUSHOUT() < 0 ) {
log("error: flush");
return 1; return 1;
}
/* Wait for a password prompt */ /* Wait for a password prompt */
sleep(2); sleep(2);
if( PUTSTR("**EMSI_INQC816\r") < 0 if( PUTSTR("**EMSI_INQC816\r") < 0
|| FLUSHOUT() < 0 ) || FLUSHOUT() < 0 ) {
log("error: output");
return 1; return 1;
}
timer_set(&sync_timer, OUTGOING_SYNC_TIMER); timer_set(&sync_timer, OUTGOING_SYNC_TIMER);
} }
@ -314,6 +336,7 @@ int session_init_outgoing(void)
c, string_printable(buf_emsi))); c, string_printable(buf_emsi)));
} }
} }
//log("session_init_outgoing: end loop");
return 1; return 1;
} }
@ -325,7 +348,7 @@ int session_init_outgoing(void)
/* */ /* */
/* TODO: It is not working yet, it only reports about EMSI requests.. (1) */ /* TODO: It is not working yet, it only reports about EMSI requests.. (1) */
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
int session_init_incoming(void) int session_init_incoming()
{ {
int c = 0; int c = 0;
int pos = 0; int pos = 0;
@ -345,42 +368,64 @@ int session_init_incoming(void)
state.session = SESSION_UNKNOWN; state.session = SESSION_UNKNOWN;
if( (options & OPTIONS_NO_EMSI) != OPTIONS_NO_EMSI ) //log("init");
if( (options & OPTIONS_NO_EMSI) != OPTIONS_NO_EMSI ) {
//log("can emsi");
canemsi = TRUE; canemsi = TRUE;
if( (options & OPTIONS_NO_YOOHOO) != OPTIONS_NO_YOOHOO ) }
if( (options & OPTIONS_NO_YOOHOO) != OPTIONS_NO_YOOHOO ) {
//log("can yahoo");
canyoohoo = TRUE; canyoohoo = TRUE;
if( (options & OPTIONS_NO_FTS1) != OPTIONS_NO_FTS1 ) }
if( (options & OPTIONS_NO_FTS1) != OPTIONS_NO_FTS1 ) {
//log("can ftsc");
canftsc = TRUE; canftsc = TRUE;
}
yoohoo_need = canemsi ? 2 : 1; yoohoo_need = canemsi ? 2 : 1;
tsync_need = (canemsi || canyoohoo) ? 2 : 1; tsync_need = (canemsi || canyoohoo) ? 2 : 1;
if( PUTCHAR('\r') < 0 ) if( PUTCHAR('\r') < 0 ) {
log("error: cannot put char");
return 1; return 1;
}
/* /*
* Output banner * Output banner
*/ */
if( canemsi && PUTSTR("**EMSI_REQA77E\r") < 0 ) if( canemsi && PUTSTR("**EMSI_REQA77E\r") < 0 ) {
log("error: cannot put banner");
return 1; return 1;
}
if( state.connstr ) if( state.connstr )
{ {
/* Show connect string */ /* Show connect string */
if( PUTCHAR('[') < 0 ) if( PUTCHAR('[') < 0 ) {
log("error: cannot put ']'");
return 1; return 1;
if( PUTSTR(state.connstr) < 0 ) }
if( PUTSTR(state.connstr) < 0 ) {
log("error: cannot put connstr");
return 1; return 1;
if( PUTSTR("]\n") < 0 ) }
if( PUTSTR("]\n") < 0 ) {
log("error: cannot put ']'");
return 1; return 1;
}
} }
if( PUTSTR(BF_BANNERVER) < 0 || PUTCHAR(' ') < 0 if( PUTSTR(BF_BANNERVER) < 0 || PUTCHAR(' ') < 0
|| PUTSTR(BF_COPYRIGHT) < 0 || PUTCHAR('\n') < 0 ) || PUTSTR(BF_COPYRIGHT) < 0 || PUTCHAR('\n') < 0 ) {
log("session_init_incoming error: output");
return 1; return 1;
}
if( FLUSHOUT() < 0 ) if( FLUSHOUT() < 0 ) {
log("session_init_incoming error: flush");
return 1; return 1;
}
/* Start timers */ /* Start timers */
timer_set(&mast_timer, INCOMING_MAST_TIMER); timer_set(&mast_timer, INCOMING_MAST_TIMER);
@ -390,6 +435,8 @@ int session_init_incoming(void)
* Determine supported handshakes on called system * Determine supported handshakes on called system
* (support for FTS-1, YooHoo, EMSI) * (support for FTS-1, YooHoo, EMSI)
*/ */
//log("begin loop");
while(1) while(1)
{ {
if( timer_expired(mast_timer) ) if( timer_expired(mast_timer) )
@ -404,11 +451,15 @@ int session_init_incoming(void)
{ {
DEB((D_HSHAKE, "rx_init: resyncing")); DEB((D_HSHAKE, "rx_init: resyncing"));
if( canemsi && PUTSTR("**EMSI_REQA77E\r") < 0 ) if( canemsi && PUTSTR("**EMSI_REQA77E\r") < 0 ) {
log("session_init_incoming error: output");
return 1; return 1;
}
if( FLUSHOUT() < 0 ) if( FLUSHOUT() < 0 ) {
log("session_init_incoming error: flush");
return 1; return 1;
}
timer_set(&sync_timer, INCOMING_SYNC_TIMER); timer_set(&sync_timer, INCOMING_SYNC_TIMER);
} }

@ -311,14 +311,41 @@ int session_set_inbound(void)
struct stat st; struct stat st;
char *p_inb; char *p_inb;
if( (p_inb = conf_string(cf_inbound_directory)) ) p_inb = conf_string(cf_inbound_directory);
if( !p_inb ) {
log("no inbound specified, assume current directory");
p_inb = "./";
}
if( conf_boolean(cf_split_inbound) )
{ {
state.inbound = (char*)xstrcpy(p_inb); char buf[PATH_MAX+31];
//if( state.node.addr.point ) {
// snprintf( buf, PATH_MAX, "%s%d:%d/%d.%d/%s-in/",
snprintf( buf, PATH_MAX, "%s%d.%d.%d.%d/%s-in/",
p_inb,
state.node.addr.zone,
state.node.addr.net,
state.node.addr.node,
state.node.addr.point,
state.protected? "pwd": "unchecked" );
/*} else {
// snprintf( buf, PATH_MAX, "%s%d:%d/%d/%s-in/",
snprintf( buf, PATH_MAX, "%s%d.%d.%d/%s-in/",
p_inb,
state.node.addr.zone,
state.node.addr.net,
state.node.addr.node,
state.protected? "pwd": "unchecked" );
} */
log("inbound: %s", buf);
state.inbound = (char*)xstrcpy(buf);
snprintf( buf, PATH_MAX+30, "/bin/mkdir -p %s -m 700", state.inbound ); /* 30 additional chars allowed */
system( buf );
} }
else else
{ {
log("no inbound specified, assume \"./\""); state.inbound = (char*)xstrcpy(p_inb);
state.inbound = (char*)xstrcpy("./");
} }
state.tinbound = (char*)xstrcpy(state.inbound); state.tinbound = (char*)xstrcpy(state.inbound);
@ -779,6 +806,7 @@ int session(void)
/* /*
* Log expected traffic * Log expected traffic
*/ */
session_traffic(); session_traffic();
init_protinfo(&pi, state.caller); init_protinfo(&pi, state.caller);
@ -829,6 +857,7 @@ int session(void)
/* /*
* Do session clenup (remove temp. files, etc.) * Do session clenup (remove temp. files, etc.)
*/ */
(void)p_session_cleanup(&pi, (rc == BFERR_NOERROR)); (void)p_session_cleanup(&pi, (rc == BFERR_NOERROR));
if( rc == BFERR_NOERROR ) if( rc == BFERR_NOERROR )
@ -873,9 +902,11 @@ int session(void)
*/ */
if( (p = conf_string(cf_run_after_session)) ) if( (p = conf_string(cf_run_after_session)) )
session_run_command(p); session_run_command(p);
} }
exit: exit:
state.session_rc = rc; state.session_rc = rc;
session_update_history(&traff_send, &traff_recv, rc); session_update_history(&traff_send, &traff_recv, rc);

1568
source/config.guess vendored

File diff suppressed because it is too large Load Diff

1031
source/config.sub vendored

File diff suppressed because it is too large Load Diff

@ -170,20 +170,31 @@ typedef signed char SINT8;
typedef struct { typedef struct {
bool daemon; /* Run as daemon? */ bool daemon; /* Run as daemon? */
bool quit; /* Quit from daemon */ bool quit; /* Quit from daemon */
bool dontcall; /* -m key */ bool usestdio; /* Session on stdin and stdout */
int inetd; /* Called from inetd? */ int inetd; /* Called from inetd? */
int force; /* Force call? */ int force; /* Force call? */
int hiddline; /* Hidden line number (0,1..) */ int hiddline; /* Hidden line number (0,1..) */
char *confname; /* Use this config instead def. */ char *confname; /* Use this config instead def. */
char *incname; /* Include this config */ char *incname; /* Include this config */
char *phone; /* Forced phone number */ char *phone; /* Forced phone number */
char *iaddr; /* Forced IP address */
char *connect; /* Connect string */ char *connect; /* Connect string */
char *device; /* Forced device name */ char *device; /* Forced device name */
int stype; /* Handshake type in slave mode */ char *iphost; /* Forced IP address */
char *ipproto; /* proto to use over TCP/IP */
int stype; /* Handshake type in slave (answer) mode */
int runmode; /* concluded runmode */
s_falist *addrlist; s_falist *addrlist;
} s_bforce_opts; } s_bforce_opts;
#define MODE_UNDEFINED (0)
#define MODE_CALL_DEFAULT (1)
#define MODE_CALL_MODEM (2)
#define MODE_CALL_IP (3)
#define MODE_CALL_STDIO (4)
#define MODE_ANSWER (5)
#define MODE_DAEMON (6)
/* /*
* Global variables * Global variables
*/ */

@ -270,6 +270,7 @@ typedef enum {
cf_debug_file, cf_debug_file,
cf_debug_level, cf_debug_level,
#endif #endif
cf_split_inbound,
BFORCE_NUMBER_OF_KEYWORDS BFORCE_NUMBER_OF_KEYWORDS
} bforce_config_keyword; } bforce_config_keyword;

@ -82,7 +82,8 @@ enum nodelist_limit
BNI_MAXLOCATION = 48, BNI_MAXLOCATION = 48,
BNI_MAXSYSOP = 48, BNI_MAXSYSOP = 48,
BNI_MAXPHONE = 48, BNI_MAXPHONE = 48,
BNI_MAXFLAGS = 120 BNI_MAXHOST = 200,
BNI_MAXFLAGS = 200
}; };
/* /*
@ -148,6 +149,10 @@ typedef struct node
char phone[BNI_MAXPHONE+1]; char phone[BNI_MAXPHONE+1];
long speed; long speed;
char flags[BNI_MAXFLAGS+1]; char flags[BNI_MAXFLAGS+1];
bool do_binkp;
bool do_ifcico;
bool do_telnet;
char host[BNI_MAXHOST+1];
s_timevec worktime; s_timevec worktime;
} }
s_node; s_node;

@ -176,8 +176,8 @@ void init_state(s_state *pstate);
void deinit_state(s_state *pstate); void deinit_state(s_state *pstate);
/* s_init.c */ /* s_init.c */
int session_init_outgoing(void); int session_init_outgoing();
int session_init_incoming(void); int session_init_incoming();
/* s_main.c */ /* s_main.c */
extern s_state state; extern s_state state;
@ -209,7 +209,7 @@ int session(void);
/* sess_call.c */ /* sess_call.c */
int call_system(s_faddr addr, const s_bforce_opts *opts); int call_system(s_faddr addr, const s_bforce_opts *opts);
int call_system_modem(void); int call_system_modem(void);
int call_system_tcpip(void); int call_system_tcpip(int callwith);
/* sess_answ.c */ /* sess_answ.c */
int answ_system(e_session type, char *connstr, int inetd); int answ_system(e_session type, char *connstr, int inetd);

@ -0,0 +1,14 @@
#!/bin/sh
TOOLCHAIN=$HOME/OpenWRT/OpenWrt-Toolchain-ar71xx-for-mips_r2-gcc-4.3.3+cs_uClibc-0.9.30.1/toolchain-mips_r2_gcc-4.3.3+cs_uClibc-0.9.30.1
PATH=$PATH:$TOOLCHAIN/usr/bin
PREFIX=mips-openwrt-linux
CPP=$PREFIX-cpp
CC=$PREFIX-gcc
#CFLAGS=
export PATH CC CPP
#./configure --prefix=/opt/bforce --host=mips-openwrt-linux --disable-syslog
Loading…
Cancel
Save