New features added.

Maybe it should change version to 0.23
This commit is contained in:
Sergey Dorofeev
2011-12-25 20:15:55 +04:00
parent 463e7a6eaa
commit 08ca6de0a4
16 changed files with 767 additions and 344 deletions
+251 -112
View File
@@ -19,6 +19,13 @@
#include "io.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
/* Unused */
int call_system_modem_init(TIO *old_tio_settings)
@@ -326,6 +333,9 @@ int call_system_modem(void)
const char *p_hangstr = NULL; /* Modem hangup 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
*/
@@ -474,7 +484,7 @@ int call_system_modem(void)
return rc;
}
int call_system_tcpip(void)
int call_system_tcpip(int callwith) // only TCPIP values
{
char abuf[BF_MAXADDRSTR+1];
int rc = BFERR_NOERROR;
@@ -482,8 +492,8 @@ int call_system_tcpip(void)
/*
* Set verbal line name to "tcpip" value
*/
state.linename = xstrcpy("tcpip");
state.linename = xstrcpy("tcpip");
state.inet = TRUE;
/*
@@ -500,34 +510,30 @@ int call_system_tcpip(void)
(void)debug_setfilename(log_getfilename(LOG_FILE_DEBUG));
#endif
if( nodelist_checkflag(state.node.flags, "BINKP") == 0
|| nodelist_checkflag(state.node.flags, "IBN") == 0 )
{
switch( callwith ) {
case CALL_TCPIP_BINKP:
state.tcpmode = TCPMODE_BINKP;
state.session = SESSION_BINKP;
}
else if( nodelist_checkflag(state.node.flags, "TELN") == 0 )
{
break;
case CALL_TCPIP_IFCICO:
state.tcpmode = TCPMODE_RAW;
state.session = SESSION_UNKNOWN;
break;
case CALL_TCPIP_TELNET:
state.tcpmode = TCPMODE_TELNET;
state.session = SESSION_UNKNOWN;
}
else if( nodelist_checkflag(state.node.flags, "IFC") == 0 )
{
state.tcpmode = TCPMODE_RAW;
state.session = SESSION_UNKNOWN;
}
else /* Default is "raw" mode */
{
state.tcpmode = TCPMODE_RAW;
state.session = SESSION_UNKNOWN;
break;
defalt:
log("invalid protocol for TCP/IP module");
return BFERR_FATALERROR;
}
log("calling %s (%s, %s)",
ftn_addrstr(abuf, state.node.addr),
(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) )
{
TTYSTATUS(1);
@@ -544,117 +550,229 @@ int call_system_tcpip(void)
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 runrc = 0;
char abuf[BF_MAXADDRSTR+1];
char *p_lockdir = NULL;
char *errmsg = NULL;
bool inet = FALSE;
int call_mustuse = 0;
int call_mayuse = 0;
init_state(&state);
state.caller = TRUE;
state.valid = TRUE;
state.node.addr = 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) )
{
errmsg = "incorrect hidden line number";
gotoexit(BFERR_PHONE_UNKNOWN);
}
state.listed = state.node.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)
// 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 )
{
call_mayuse = CALL_MODEM | CALL_TCPIP_ANY;
}
else if( opts->runmode == MODE_CALL_STDIO )
{
call_mustuse = CALL_STDIO;
}
else if( opts->runmode == MODE_CALL_MODEM )
{
call_mustuse = CALL_MODEM;
}
else if( opts->runmode == MODE_CALL_IP )
{
if( strcasecmp(opts->ipproto, "binkp") == 0 )
{
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
{
log("Unknown protocol");
return -1;
}
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);
//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);
}
}
/*
* Is now a working time for that node/line
*/
if( !opts->force)
{
time_t unixtime = time(NULL);
struct tm *now = localtime(&unixtime);
bool goodtime = FALSE;
if( timevec_isdefined(&state.override.worktime) )
{
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
goodtime = timevec_isnow(&state.node.worktime, now);
}
if( !goodtime )
{
call_mayuse &= ~CALL_MODEM;
log("bad worktime, excluding modem");
if( call_mustuse & CALL_MODEM )
{
errmsg = "not works now, try later";
gotoexit(BFERR_NOTWORKING);
}
}
}
}
// snprintf(s, 299, "after phone check: may use %d must use %d", call_mayuse, call_mustuse);
// 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));
}
if( opts->iaddr && *opts->iaddr )
// 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) )
{
inet = TRUE;
(void)strnxcpy(state.node.phone,
opts->iaddr, sizeof(state.node.phone));
if( nodelist_checkflag(state.node.flags, "BINKP") != 0 && nodelist_checkflag(state.node.flags, "IBN") != 0 )
{
call_mayuse &= ~CALL_TCPIP_BINKP;
}
}
else if( opts->phone && *opts->phone )
if( !(call_mustuse & CALL_TCPIP_IFCICO) && (call_mayuse & CALL_TCPIP_IFCICO) )
{
(void)strnxcpy(state.node.phone,
opts->phone, sizeof(state.node.phone));
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 )
{
inet = TRUE;
(void)strnxcpy(state.node.phone,
state.override.sIpaddr, sizeof(state.node.phone));
}
else if( state.override.sPhone )
{
(void)strnxcpy(state.node.phone,
state.override.sPhone, sizeof(state.node.phone));
(void)strnxcpy(state.node.host,
state.override.sIpaddr, sizeof(state.node.host));
}
if( !inet )
if( call_mayuse & CALL_TCPIP_ANY && !tcpip_isgood_host(state.node.host) )
{
if( !modem_isgood_phone(state.node.phone) )
errmsg = "don't know phone number";
}
else
{
if( !tcpip_isgood_host(state.node.phone) )
call_mayuse &= ~CALL_TCPIP_ANY;
log("bad host, exclude IP");
if( call_mustuse & CALL_TCPIP_ANY )
{
errmsg = "don't know host name";
}
if( errmsg )
gotoexit(BFERR_PHONE_UNKNOWN);
/*
* Is now a working time for that node/line
*/
if( !inet && !opts->force)
{
time_t unixtime = time(NULL);
struct tm *now = localtime(&unixtime);
bool goodtime;
if( !opts->hiddline )
{
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);
else
{
if( !nodelist_checkflag(state.node.flags, "CM") )
goodtime = TRUE;
else
goodtime = timevec_isnow(&state.node.worktime, now);
}
}
}
else
goodtime = timevec_isnow(&state.override.worktime, now);
if( !goodtime )
{
errmsg = "not works now, try later";
gotoexit(BFERR_NOTWORKING);
gotoexit(BFERR_PHONE_UNKNOWN);
}
}
// snprintf(s, 299, "after IP check: may use %d must use %d", call_mayuse, call_mustuse);
// log(s);
do_session:
//do_session:
/*
* It's easier to ignore than handle! After connect
* new handlers must be installed, don't worry.
@@ -683,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);
}
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 )
p_lockdir = BFORCE_LOCK_DIR;
if( opts->device && *opts->device )
{
if( (state.modemport =
modem_getmatch_port(opts->device)) == NULL )
{
errmsg = "unknown port name";
gotoexit(BFERR_PORTBUSY);
}
state.modemport = modem_getmatch_port(opts->device);
}
else if( (state.modemport =
modem_getfree_port(p_lockdir)) == NULL )
else
{
errmsg = "no free matching ports";
gotoexit(BFERR_PORTBUSY);
state.modemport = modem_getfree_port(p_lockdir);
}
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";
gotoexit(BFERR_PORTBUSY);
}
}
else /* Successfuly locked port */
else
{
rc = call_system_modem();
port_unlock(p_lockdir, state.modemport);
errmsg = "unable to get modem port";
}
}
else
if( rc )
{
rc = call_system_tcpip();
log("no connection effort was successful");
}
exit: