You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
481 lines
10 KiB
C
481 lines
10 KiB
C
/*
|
|
* binkleyforce -- unix FTN mailer project
|
|
*
|
|
* Copyright (c) 1998-2000 Alexander Belkin, 2:5020/1398.11
|
|
*
|
|
* 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 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* $Id$
|
|
*/
|
|
|
|
#include "includes.h"
|
|
#include "confread.h"
|
|
#include "version.h"
|
|
#include "logger.h"
|
|
#include "util.h"
|
|
#include "nodelist.h"
|
|
#include "session.h"
|
|
#include "prot_emsi.h"
|
|
|
|
void emsi_init(s_handshake_protocol *THIS);
|
|
void emsi_deinit(s_handshake_protocol *THIS);
|
|
int emsi_incoming(s_handshake_protocol *THIS);
|
|
int emsi_outgoing(s_handshake_protocol *THIS);
|
|
s_faddr *emsi_remote_address(s_handshake_protocol *THIS);
|
|
char *emsi_remote_password(s_handshake_protocol *THIS);
|
|
char *emsi_remote_sysop_name(s_handshake_protocol *THIS);
|
|
char *emsi_remote_system_name(s_handshake_protocol *THIS);
|
|
char *emsi_remote_location(s_handshake_protocol *THIS);
|
|
char *emsi_remote_phone(s_handshake_protocol *THIS);
|
|
char *emsi_remote_flags(s_handshake_protocol *THIS);
|
|
char *emsi_remote_mailer(s_handshake_protocol *THIS);
|
|
int emsi_remote_traffic(s_handshake_protocol *THIS, s_traffic *dest);
|
|
s_faddr *emsi_local_address(s_handshake_protocol *THIS);
|
|
char *emsi_local_password(s_handshake_protocol *THIS);
|
|
|
|
s_handshake_protocol handshake_protocol_emsi = {
|
|
/* Section 1 */
|
|
"EMSI",
|
|
"Joaquim H. Homrighausen",
|
|
"FSC-0056,0088",
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
emsi_init,
|
|
emsi_deinit,
|
|
emsi_incoming,
|
|
emsi_outgoing,
|
|
/* Section 2 */
|
|
emsi_remote_address,
|
|
emsi_remote_password,
|
|
emsi_remote_sysop_name,
|
|
emsi_remote_system_name,
|
|
emsi_remote_location,
|
|
emsi_remote_phone,
|
|
emsi_remote_flags,
|
|
emsi_remote_mailer,
|
|
emsi_remote_traffic,
|
|
/* Section 3 */
|
|
emsi_local_address,
|
|
emsi_local_password
|
|
};
|
|
|
|
static void emsi_set_send_options(s_emsi *remote_emsi)
|
|
{
|
|
session_set_send_options();
|
|
|
|
if( remote_emsi->linkcodes.FNC )
|
|
state.sopts.fnc = 1;
|
|
|
|
if( remote_emsi->linkcodes.RH1 )
|
|
state.sopts.hydraRH1 = 1;
|
|
|
|
if( state.caller )
|
|
{
|
|
if( remote_emsi->linkcodes.HRQ
|
|
|| remote_emsi->compcodes.NRQ )
|
|
state.sopts.holdreq = 1;
|
|
if( remote_emsi->linkcodes.HAT )
|
|
state.sopts.holdall = 1;
|
|
if( remote_emsi->linkcodes.HXT )
|
|
state.sopts.holdxt = 1;
|
|
}
|
|
else
|
|
{
|
|
if( remote_emsi->linkcodes.NPU )
|
|
state.sopts.holdall = 1;
|
|
if( remote_emsi->linkcodes.PMO )
|
|
state.sopts.holdfiles = 1;
|
|
if( remote_emsi->linkcodes.NRQ )
|
|
state.sopts.holdreq = 1;
|
|
}
|
|
}
|
|
|
|
void emsi_init(s_handshake_protocol *THIS)
|
|
{
|
|
ASSERT(THIS);
|
|
ASSERT(THIS->remote_data == NULL);
|
|
ASSERT(THIS->local_data == NULL);
|
|
|
|
THIS->remote_data = (char *)xmalloc(sizeof(s_emsi));
|
|
THIS->local_data = (char *)xmalloc(sizeof(s_emsi));
|
|
|
|
memset(THIS->remote_data, '\0', sizeof(s_emsi));
|
|
memset(THIS->local_data, '\0', sizeof(s_emsi));
|
|
}
|
|
|
|
void emsi_deinit(s_handshake_protocol *THIS)
|
|
{
|
|
ASSERT(THIS);
|
|
ASSERT(THIS->remote_data);
|
|
ASSERT(THIS->local_data);
|
|
|
|
if( THIS->remote_data )
|
|
{
|
|
memset(THIS->remote_data, '\0', sizeof(s_emsi));
|
|
free(THIS->remote_data);
|
|
}
|
|
|
|
if( THIS->local_data )
|
|
{
|
|
memset(THIS->local_data, '\0', sizeof(s_emsi));
|
|
free(THIS->local_data);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Do incoming emsi session
|
|
*/
|
|
int emsi_incoming(s_handshake_protocol *THIS)
|
|
{
|
|
int rc = HRC_OK;
|
|
s_emsi *remote_emsi = NULL;
|
|
s_emsi *local_emsi = NULL;
|
|
|
|
ASSERT(THIS);
|
|
ASSERT(THIS->remote_data);
|
|
ASSERT(THIS->local_data);
|
|
|
|
remote_emsi = (s_emsi *)THIS->remote_data;
|
|
local_emsi = (s_emsi *)THIS->local_data;
|
|
|
|
/*
|
|
* Receive EMSI_DAT packet
|
|
*/
|
|
if( emsi_recv_emsidat(remote_emsi) )
|
|
return HRC_OTHER_ERR;
|
|
|
|
/*
|
|
* Check password(s)
|
|
*/
|
|
if( session_addrs_check(remote_emsi->addrs, remote_emsi->anum,
|
|
remote_emsi->passwd, NULL, 0) )
|
|
{
|
|
rc = HRC_BAD_PASSWD;
|
|
/* Don't return. Send EMSI_DAT with
|
|
* invalid password messages */
|
|
}
|
|
else
|
|
{
|
|
/* Lock (create BSY) remote addresses */
|
|
if( session_addrs_lock(remote_emsi->addrs, remote_emsi->anum) )
|
|
{
|
|
log("all remote addresses are busy");
|
|
rc = HRC_BUSY;
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* We know caller's address so we can process
|
|
* more expressions and fill state.node structure..
|
|
*/
|
|
session_remote_lookup(remote_emsi->addrs, remote_emsi->anum);
|
|
|
|
if( session_check_speed() )
|
|
rc = HRC_LOW_SPEED;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Put EMSI information to log
|
|
*/
|
|
(void)emsi_logdat(remote_emsi);
|
|
|
|
session_remote_log_status();
|
|
|
|
if( rc == HRC_OK )
|
|
{
|
|
const long options = conf_options(cf_options);
|
|
|
|
/*
|
|
* Set inbound directories, ignore errors,
|
|
* because we want send mail in any case.
|
|
*/
|
|
(void)session_set_inbound();
|
|
|
|
/*
|
|
* Set protocol that we will use
|
|
*/
|
|
if( remote_emsi->compcodes.HYD && !(options & OPTIONS_NO_HYDRA) )
|
|
THIS->protocol = PROT_HYDRA;
|
|
else if( remote_emsi->compcodes.ZAP && !(options & OPTIONS_NO_ZEDZAP) )
|
|
THIS->protocol = PROT_ZEDZAP;
|
|
else if( remote_emsi->compcodes.ZMO && !(options & OPTIONS_NO_ZMODEM) )
|
|
THIS->protocol = PROT_ZMODEM;
|
|
else /* NCP */
|
|
{
|
|
THIS->protocol = PROT_NOPROT;
|
|
rc = HRC_NO_PROTOS;
|
|
}
|
|
|
|
/*
|
|
* Check EMSI flags and set corresponding local HOLD flags
|
|
*/
|
|
(void)emsi_set_send_options(remote_emsi);
|
|
|
|
/*
|
|
* Create mail/files queue
|
|
*/
|
|
session_create_files_queue(remote_emsi->addrs,
|
|
remote_emsi->anum);
|
|
|
|
/*
|
|
* Set FREQ processor status
|
|
*/
|
|
if( rc == HRC_OK && THIS->protocol != PROT_NOPROT )
|
|
session_set_freqs_status();
|
|
else
|
|
state.reqstat = REQS_DISABLED;
|
|
}
|
|
|
|
/*
|
|
* Prepare ``local_emsi'' structure
|
|
*/
|
|
(void)emsi_set_sysinfo(local_emsi, remote_emsi, rc, THIS->protocol);
|
|
|
|
/*
|
|
* Send EMSI_DAT packet
|
|
*/
|
|
if( emsi_send_emsidat(local_emsi) )
|
|
return HRC_OTHER_ERR;
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* Do outgoing emsi session
|
|
*/
|
|
int emsi_outgoing(s_handshake_protocol *THIS)
|
|
{
|
|
s_emsi *remote_emsi = NULL;
|
|
s_emsi *local_emsi = NULL;
|
|
|
|
ASSERT(THIS);
|
|
ASSERT(THIS->remote_data);
|
|
ASSERT(THIS->local_data);
|
|
|
|
remote_emsi = (s_emsi *)THIS->remote_data;
|
|
local_emsi = (s_emsi *)THIS->local_data;
|
|
|
|
/*
|
|
* Set FREQ processor status
|
|
*/
|
|
session_set_freqs_status();
|
|
|
|
/*
|
|
* Prepare ``local_emsi'' structure
|
|
*/
|
|
(void)emsi_set_sysinfo(local_emsi, NULL, HRC_OK, THIS->protocol);
|
|
|
|
/*
|
|
* Send EMSI_DAT packet
|
|
*/
|
|
if( emsi_send_emsidat(local_emsi) )
|
|
return HRC_OTHER_ERR;
|
|
|
|
/*
|
|
* Receive EMSI_DAT packet
|
|
*/
|
|
if( emsi_recv_emsidat(remote_emsi) )
|
|
return HRC_OTHER_ERR;
|
|
|
|
/*
|
|
* Put EMSI information to the log
|
|
*/
|
|
(void)emsi_logdat(remote_emsi);
|
|
|
|
/*
|
|
* Make sure expected address was presented
|
|
*/
|
|
if( session_addrs_check_genuine(remote_emsi->addrs,
|
|
remote_emsi->anum, state.node.addr) )
|
|
return HRC_NO_ADDRESS;
|
|
|
|
/*
|
|
* Check password(s)
|
|
*/
|
|
if( session_addrs_check(remote_emsi->addrs, remote_emsi->anum,
|
|
remote_emsi->passwd, NULL, 0) )
|
|
return HRC_BAD_PASSWD;
|
|
|
|
/*
|
|
* Lock (create BSY) remote addresses
|
|
*/
|
|
(void)session_addrs_lock(remote_emsi->addrs, remote_emsi->anum);
|
|
|
|
/*
|
|
* Set protocol we will use ("options" ignored)
|
|
*/
|
|
if( remote_emsi->compcodes.HYD && local_emsi->compcodes.HYD )
|
|
THIS->protocol = PROT_HYDRA;
|
|
else if( remote_emsi->compcodes.JAN && local_emsi->compcodes.JAN )
|
|
THIS->protocol = PROT_JANUS;
|
|
else if( remote_emsi->compcodes.DZA && local_emsi->compcodes.DZA )
|
|
THIS->protocol = PROT_DIRZAP;
|
|
else if( remote_emsi->compcodes.ZAP && local_emsi->compcodes.ZAP )
|
|
THIS->protocol = PROT_ZEDZAP;
|
|
else if( remote_emsi->compcodes.ZMO && local_emsi->compcodes.ZMO )
|
|
THIS->protocol = PROT_ZMODEM;
|
|
else
|
|
return HRC_NO_PROTOS;
|
|
|
|
/*
|
|
* Show remote status (prot/unprot, listed/unlisted)
|
|
*/
|
|
session_remote_log_status();
|
|
|
|
/*
|
|
* Set inbound directories
|
|
*/
|
|
if( session_set_inbound() )
|
|
return HRC_OTHER_ERR;
|
|
|
|
/*
|
|
* Check EMSI flags and set corresponding local HOLD flags
|
|
*/
|
|
(void)emsi_set_send_options(remote_emsi);
|
|
|
|
/*
|
|
* Create mail/files queue
|
|
*/
|
|
session_create_files_queue(remote_emsi->addrs,
|
|
remote_emsi->anum);
|
|
|
|
return HRC_OK;
|
|
}
|
|
|
|
s_faddr *emsi_remote_address(s_handshake_protocol *THIS)
|
|
{
|
|
ASSERT(THIS);
|
|
ASSERT(THIS->remote_data);
|
|
|
|
if( ((s_emsi *)THIS->remote_data)->anum > 0 )
|
|
return &((s_emsi *)THIS->remote_data)->addrs[0].addr;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
char *emsi_remote_password(s_handshake_protocol *THIS)
|
|
{
|
|
ASSERT(THIS);
|
|
ASSERT(THIS->remote_data);
|
|
|
|
if( ((s_emsi *)THIS->remote_data)->passwd[0] )
|
|
return ((s_emsi *)THIS->remote_data)->passwd;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
char *emsi_remote_sysop_name(s_handshake_protocol *THIS)
|
|
{
|
|
ASSERT(THIS);
|
|
ASSERT(THIS->remote_data);
|
|
|
|
if( ((s_emsi *)THIS->remote_data)->sysop[0] )
|
|
return ((s_emsi *)THIS->remote_data)->sysop;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
char *emsi_remote_system_name(s_handshake_protocol *THIS)
|
|
{
|
|
ASSERT(THIS);
|
|
ASSERT(THIS->remote_data);
|
|
|
|
if( ((s_emsi *)THIS->remote_data)->sname[0] )
|
|
return ((s_emsi *)THIS->remote_data)->sname;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
char *emsi_remote_location(s_handshake_protocol *THIS)
|
|
{
|
|
ASSERT(THIS);
|
|
ASSERT(THIS->remote_data);
|
|
|
|
if( ((s_emsi *)THIS->remote_data)->location[0] )
|
|
return ((s_emsi *)THIS->remote_data)->location;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
char *emsi_remote_phone(s_handshake_protocol *THIS)
|
|
{
|
|
ASSERT(THIS);
|
|
ASSERT(THIS->remote_data);
|
|
|
|
if( ((s_emsi *)THIS->remote_data)->phone[0] )
|
|
return ((s_emsi *)THIS->remote_data)->phone;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
char *emsi_remote_flags(s_handshake_protocol *THIS)
|
|
{
|
|
ASSERT(THIS);
|
|
ASSERT(THIS->remote_data);
|
|
|
|
if( ((s_emsi *)THIS->remote_data)->flags[0] )
|
|
return ((s_emsi *)THIS->remote_data)->flags;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
char *emsi_remote_mailer(s_handshake_protocol *THIS)
|
|
{
|
|
ASSERT(THIS);
|
|
ASSERT(THIS->remote_data);
|
|
|
|
if( ((s_emsi *)THIS->remote_data)->m_name[0] )
|
|
return ((s_emsi *)THIS->remote_data)->m_name;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int emsi_remote_traffic(s_handshake_protocol *THIS, s_traffic *dest)
|
|
{
|
|
ASSERT(THIS);
|
|
ASSERT(THIS->remote_data);
|
|
ASSERT(dest);
|
|
|
|
memset(dest, '\0', sizeof(s_traffic));
|
|
|
|
if( ((s_emsi *)THIS->remote_data)->have_traf
|
|
|| ((s_emsi *)THIS->remote_data)->have_moh )
|
|
{
|
|
dest->netmail_size = ((s_emsi *)THIS->remote_data)->netmail_size;
|
|
dest->arcmail_size = ((s_emsi *)THIS->remote_data)->arcmail_size;
|
|
dest->files_size = ((s_emsi *)THIS->remote_data)->files_size;
|
|
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
s_faddr *emsi_local_address(s_handshake_protocol *THIS)
|
|
{
|
|
ASSERT(THIS);
|
|
ASSERT(THIS->local_data);
|
|
|
|
if( ((s_emsi *)THIS->local_data)->anum > 0 )
|
|
return &((s_emsi *)THIS->local_data)->addrs[0].addr;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
char *emsi_local_password(s_handshake_protocol *THIS)
|
|
{
|
|
ASSERT(THIS);
|
|
ASSERT(THIS->local_data);
|
|
|
|
if( ((s_emsi *)THIS->local_data)->passwd[0] )
|
|
return ((s_emsi *)THIS->local_data)->passwd;
|
|
|
|
return NULL;
|
|
}
|
|
|