660 lines
18 KiB
C
660 lines
18 KiB
C
|
/*****************************************************************************
|
||
|
*
|
||
|
* $Id: yoohoo.c,v 1.25 2007/08/25 18:32:08 mbse Exp $
|
||
|
* Purpose ...............: Fidonet mailer
|
||
|
*
|
||
|
*****************************************************************************
|
||
|
* Copyright (C) 1997-2007
|
||
|
*
|
||
|
* Michiel Broek FIDO: 2:280/2802
|
||
|
* Beekmansbos 10
|
||
|
* 1971 BV IJmuiden
|
||
|
* the Netherlands
|
||
|
*
|
||
|
* This file is part of MBSE BBS.
|
||
|
*
|
||
|
* This BBS 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) any
|
||
|
* later version.
|
||
|
*
|
||
|
* MBSE BBS is distributed in the hope that it will be useful, but
|
||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
* General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with MBSE BBS; see the file COPYING. If not, write to the Free
|
||
|
* Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||
|
*****************************************************************************/
|
||
|
|
||
|
/* Added modifications made on 9 Jun 1996 by P.Saratxaga
|
||
|
* - added "Hello" structure (from FTS-0006) so we can more easily
|
||
|
* parse it.
|
||
|
* - added domain support in hello packet (in Hello.name, reading after
|
||
|
* first \0 there is the domain)
|
||
|
* - added support for 16 bit product code
|
||
|
*/
|
||
|
|
||
|
#include "../config.h"
|
||
|
#include "../lib/mbselib.h"
|
||
|
#include "../lib/nodelist.h"
|
||
|
#include "../lib/users.h"
|
||
|
#include "../lib/mbsedb.h"
|
||
|
#include "statetbl.h"
|
||
|
#include "ttyio.h"
|
||
|
#include "session.h"
|
||
|
#include "config.h"
|
||
|
#include "emsi.h"
|
||
|
#include "hydra.h"
|
||
|
#include "rdoptions.h"
|
||
|
#include "wazoo.h"
|
||
|
#include "dietifna.h"
|
||
|
#include "yoohoo.h"
|
||
|
#include "inbound.h"
|
||
|
#include "callstat.h"
|
||
|
|
||
|
|
||
|
/*------------------------------------------------------------------------*/
|
||
|
/* YOOHOO<tm> CAPABILITY VALUES */
|
||
|
/*------------------------------------------------------------------------*/
|
||
|
#define Y_DIETIFNA 0x0001 /* Can do fast "FTS-0001" 0000 0000 0000 0001 */
|
||
|
#define FTB_USER 0x0002 /* Full-Tilt Boogie 0000 0000 0000 0010 */
|
||
|
#define ZED_ZIPPER 0x0004 /* Does ZModem, 1K blocks 0000 0000 0000 0100 */
|
||
|
#define ZED_ZAPPER 0x0008 /* Can do ZModem variant 0000 0000 0000 1000 */
|
||
|
#define DOES_IANUS 0x0010 /* Can do Janus 0000 0000 0001 0000 */
|
||
|
#define DOES_HYDRA 0x0020 /* Can do Hydra 0000 0000 0010 0000 */
|
||
|
#define Bit_6 0x0040 /* reserved by FTSC 0000 0000 0100 0000 */
|
||
|
#define Bit_7 0x0080 /* reserved by FTSC 0000 0000 1000 0000 */
|
||
|
#define Bit_8 0x0100 /* reserved by FTSC 0000 0001 0000 0000 */
|
||
|
#define Bit_9 0x0200 /* reserved by FTSC 0000 0010 0000 0000 */
|
||
|
#define Bit_a 0x0400 /* reserved by FTSC 0000 0100 0000 0000 */
|
||
|
#define Bit_b 0x0800 /* reserved by FTSC 0000 1000 0000 0000 */
|
||
|
#define Bit_c 0x1000 /* reserved by FTSC 0001 0000 0000 0000 */
|
||
|
#define Bit_d 0x2000 /* reserved by FTSC 0010 0000 0000 0000 */
|
||
|
#define DO_DOMAIN 0x4000 /* Packet contains domain 0100 0000 0000 0000 */
|
||
|
#define WZ_FREQ 0x8000 /* WZ file req. ok 1000 0000 0000 0000 */
|
||
|
|
||
|
#define LOCALCAPS (Y_DIETIFNA|ZED_ZIPPER|ZED_ZAPPER|DOES_HYDRA|DO_DOMAIN)
|
||
|
|
||
|
|
||
|
static int rxyoohoo(void);
|
||
|
static int txyoohoo(void);
|
||
|
static void fillhello(unsigned short,char*);
|
||
|
static int checkhello(void);
|
||
|
|
||
|
static int y_akas;
|
||
|
static int iscaller;
|
||
|
|
||
|
static struct _hello {
|
||
|
unsigned char data[128];
|
||
|
unsigned char crc[2];
|
||
|
} hello;
|
||
|
|
||
|
typedef struct _Hello {
|
||
|
unsigned short signal; /* always 'o' (0x6f) */
|
||
|
unsigned short hello_version; /* currently 1 (0x01) */
|
||
|
unsigned short product; /* product code */
|
||
|
unsigned short product_maj; /* major revision of the product */
|
||
|
unsigned short product_min; /* minor revision of the product */
|
||
|
unsigned char my_name[60]; /* Other end's name, will include domain */
|
||
|
/* if DO_DOMAIN is set in capabilities */
|
||
|
unsigned char sysop[20]; /* sysop's name */
|
||
|
unsigned short my_zone; /* 0== not supported */
|
||
|
unsigned short my_net; /* out primary net number */
|
||
|
unsigned short my_node; /* our primary node number */
|
||
|
unsigned short my_point; /* 0 == not supported */
|
||
|
unsigned char my_password[8]; /* This isn't necessarily null-terminated */
|
||
|
unsigned char reserved2[8]; /* reserved by Opus */
|
||
|
unsigned short capabilities; /* see below */
|
||
|
unsigned char reserved3[12]; /* for non-Opus systems with "approval" */
|
||
|
/* total size 128 bytes */
|
||
|
} Hello;
|
||
|
|
||
|
|
||
|
extern int Loaded;
|
||
|
extern pid_t mypid;
|
||
|
extern int laststat;
|
||
|
extern int session_state;
|
||
|
|
||
|
|
||
|
Hello hello2;
|
||
|
Hello gethello2(unsigned char[]);
|
||
|
|
||
|
|
||
|
|
||
|
int rx_yoohoo(void)
|
||
|
{
|
||
|
int rc, protect = FALSE;
|
||
|
unsigned short capabilities,localcaps;
|
||
|
char *pwd = NULL;
|
||
|
callstat *cst;
|
||
|
|
||
|
pwd = NULL;
|
||
|
y_akas = 0;
|
||
|
localcaps = LOCALCAPS;
|
||
|
if (localoptions & NOZMODEM) localcaps &= ~(ZED_ZAPPER|ZED_ZIPPER);
|
||
|
if (localoptions & NOZEDZAP) localcaps &= ~ZED_ZAPPER;
|
||
|
if (localoptions & NOHYDRA) localcaps &= ~DOES_HYDRA;
|
||
|
emsi_local_opts = 0;
|
||
|
emsi_remote_opts = 0;
|
||
|
iscaller = 0;
|
||
|
|
||
|
if ((rc = rxyoohoo()) == 0) {
|
||
|
Loaded = checkhello();
|
||
|
|
||
|
if (y_akas == 0) {
|
||
|
Syslog('+', "All akas busy, abort");
|
||
|
return MBERR_SESSION_ERROR;
|
||
|
}
|
||
|
|
||
|
capabilities = hello2.capabilities;
|
||
|
if (capabilities & WZ_FREQ)
|
||
|
session_flags |= SESSION_WAZOO;
|
||
|
else
|
||
|
session_flags &= ~SESSION_WAZOO;
|
||
|
localcaps &= capabilities;
|
||
|
if (localcaps & DOES_HYDRA)
|
||
|
localcaps &= DOES_HYDRA;
|
||
|
else if (localcaps & ZED_ZAPPER)
|
||
|
localcaps &= ZED_ZAPPER;
|
||
|
else if (localcaps & ZED_ZIPPER)
|
||
|
localcaps &= ZED_ZIPPER;
|
||
|
else if (localcaps & FTB_USER)
|
||
|
localcaps &= FTB_USER;
|
||
|
else if (localcaps & Y_DIETIFNA)
|
||
|
localcaps &= Y_DIETIFNA;
|
||
|
if ((localoptions & NOFREQS) == 0)
|
||
|
localcaps |= WZ_FREQ;
|
||
|
else
|
||
|
emsi_local_opts |= OPT_NRQ;
|
||
|
|
||
|
if (((nlent=getnlent(remote->addr))) && (nlent->pflag != NL_DUMMY)) {
|
||
|
Syslog('+', "Remote is a listed system");
|
||
|
strncpy(history.location, nlent->location, 35);
|
||
|
UserCity(mypid, nlent->sysop, nlent->location);
|
||
|
}
|
||
|
cst = getstatus(remote->addr);
|
||
|
if (cst->trystat)
|
||
|
laststat = cst->trystat;
|
||
|
Syslog('s', "Last session status %d", laststat);
|
||
|
|
||
|
if (nlent)
|
||
|
rdoptions(Loaded);
|
||
|
|
||
|
if (strlen(nodes.Spasswd)) {
|
||
|
if ((strncasecmp((char*)hello2.my_password, nodes.Spasswd, strlen(nodes.Spasswd)) == 0) &&
|
||
|
(strlen((char*)hello2.my_password) == strlen(nodes.Spasswd))) {
|
||
|
Syslog('+', "Password correct, protected mail session");
|
||
|
protect = TRUE;
|
||
|
pwd = xstrcpy(nodes.Spasswd);
|
||
|
} else {
|
||
|
if (pwd)
|
||
|
free(pwd);
|
||
|
pwd = xstrcpy((char *)"BAD_PASS");
|
||
|
Syslog('?', "Remote password \"%s\", expected \"%s\"", (char*)hello2.my_password, nodes.Spasswd);
|
||
|
localcaps = 0;
|
||
|
}
|
||
|
} else
|
||
|
Syslog('s', "No YooHoo password check");
|
||
|
|
||
|
inbound_open(remote->addr, protect, FALSE);
|
||
|
|
||
|
fillhello(localcaps,pwd);
|
||
|
|
||
|
rc = txyoohoo();
|
||
|
if (pwd)
|
||
|
free(pwd);
|
||
|
}
|
||
|
|
||
|
if ((rc == 0) && ((localcaps & LOCALCAPS) == 0)) {
|
||
|
Syslog('+', "No common protocols or bad password");
|
||
|
return 0;
|
||
|
}
|
||
|
if (rc)
|
||
|
return MBERR_YOOHOO;
|
||
|
|
||
|
IsDoing("Inbound %s", ascfnode(remote->addr, 0x0f));
|
||
|
|
||
|
if (protect)
|
||
|
session_state = STATE_SECURE;
|
||
|
else
|
||
|
session_state = STATE_UNSECURE;
|
||
|
|
||
|
session_flags |= SESSION_WAZOO;
|
||
|
if (localcaps & DOES_HYDRA)
|
||
|
return hydra(0);
|
||
|
else if ((localcaps & ZED_ZAPPER) || (localcaps & ZED_ZIPPER)) {
|
||
|
if (localcaps & ZED_ZAPPER)
|
||
|
emsi_local_protos = PROT_ZAP;
|
||
|
else
|
||
|
emsi_local_protos = PROT_ZMO;
|
||
|
return rxwazoo();
|
||
|
} else if (localcaps & Y_DIETIFNA)
|
||
|
return rxdietifna();
|
||
|
|
||
|
WriteError("YooHoo internal error - no proto for 0x%04xh",localcaps);
|
||
|
return MBERR_YOOHOO;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
int tx_yoohoo(void)
|
||
|
{
|
||
|
int rc;
|
||
|
unsigned short capabilities;
|
||
|
char *pwd;
|
||
|
|
||
|
y_akas = 0;
|
||
|
if (strlen(nodes.Spasswd))
|
||
|
pwd = xstrcpy(nodes.Spasswd);
|
||
|
else
|
||
|
pwd = NULL;
|
||
|
|
||
|
capabilities = LOCALCAPS;
|
||
|
if (localoptions & NOZMODEM)
|
||
|
capabilities &= ~(ZED_ZAPPER|ZED_ZIPPER);
|
||
|
if (localoptions & NOZEDZAP)
|
||
|
capabilities &= ~ZED_ZAPPER;
|
||
|
if (localoptions & NOHYDRA)
|
||
|
capabilities &= ~DOES_HYDRA;
|
||
|
if ((localoptions & NOFREQS) == 0)
|
||
|
capabilities |= WZ_FREQ;
|
||
|
else
|
||
|
emsi_local_opts |= OPT_NRQ;
|
||
|
|
||
|
fillhello(capabilities,pwd);
|
||
|
iscaller=1;
|
||
|
|
||
|
if ((rc = txyoohoo()) == 0) {
|
||
|
rc = rxyoohoo();
|
||
|
checkhello();
|
||
|
capabilities = hello2.capabilities;
|
||
|
if (capabilities & WZ_FREQ)
|
||
|
session_flags |= SESSION_WAZOO;
|
||
|
else
|
||
|
session_flags &= ~SESSION_WAZOO;
|
||
|
}
|
||
|
|
||
|
if (y_akas == 0) {
|
||
|
Syslog('+', "All akas busy, abort");
|
||
|
return MBERR_SESSION_ERROR;
|
||
|
}
|
||
|
if ((rc == 0) && ((capabilities & LOCALCAPS) == 0)) {
|
||
|
Syslog('+', "No common protocols");
|
||
|
return MBERR_SESSION_ERROR;
|
||
|
}
|
||
|
|
||
|
if (rc)
|
||
|
return MBERR_YOOHOO;
|
||
|
|
||
|
IsDoing("Outbound %s", ascfnode(remote->addr, 0x0f));
|
||
|
session_state = STATE_SECURE;
|
||
|
|
||
|
session_flags |= SESSION_WAZOO;
|
||
|
if (capabilities & DOES_HYDRA)
|
||
|
return hydra(1);
|
||
|
else if ((capabilities & ZED_ZAPPER) || (capabilities & ZED_ZIPPER)) {
|
||
|
if (capabilities & ZED_ZAPPER)
|
||
|
emsi_local_protos = PROT_ZAP;
|
||
|
else
|
||
|
emsi_local_protos = PROT_ZMO;
|
||
|
return txwazoo();
|
||
|
} else if (capabilities & Y_DIETIFNA)
|
||
|
return txdietifna();
|
||
|
|
||
|
WriteError("YooHoo internal error - no proto for 0x%04xh",capabilities);
|
||
|
return MBERR_YOOHOO;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
SM_DECL(rxyoohoo,(char *)"rxyoohoo")
|
||
|
SM_STATES
|
||
|
sendenq,
|
||
|
waitchar,
|
||
|
getpacket,
|
||
|
sendnak,
|
||
|
sendack
|
||
|
SM_NAMES
|
||
|
(char *)"sendenq",
|
||
|
(char *)"waitchar",
|
||
|
(char *)"getpacket",
|
||
|
(char *)"sendnak",
|
||
|
(char *)"sendack"
|
||
|
SM_EDECL
|
||
|
|
||
|
int c, count=0;
|
||
|
unsigned short lcrc, rcrc;
|
||
|
|
||
|
SM_START(sendenq)
|
||
|
|
||
|
SM_STATE(sendenq)
|
||
|
|
||
|
if (count++ > 12) {
|
||
|
Syslog('+', "Too many tries to get YooHoo hello packet");
|
||
|
SM_ERROR;
|
||
|
}
|
||
|
PUTCHAR(ENQ);
|
||
|
SM_PROCEED(waitchar)
|
||
|
|
||
|
SM_STATE(waitchar)
|
||
|
|
||
|
c=GETCHAR(10);
|
||
|
if (c == TIMEOUT) {
|
||
|
SM_PROCEED(sendenq);
|
||
|
} else if (c < 0) {
|
||
|
SM_ERROR;
|
||
|
} else switch (c) {
|
||
|
case 0x1f: SM_PROCEED(getpacket);
|
||
|
break;
|
||
|
case YOOHOO: SM_PROCEED(sendenq);
|
||
|
break;
|
||
|
default: SM_PROCEED(waitchar);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
SM_STATE(getpacket)
|
||
|
|
||
|
GET((char*)&hello, sizeof(hello), 30);
|
||
|
if (STATUS) {
|
||
|
SM_ERROR;
|
||
|
}
|
||
|
|
||
|
lcrc = crc16xmodem((char*)hello.data, sizeof(hello.data));
|
||
|
rcrc = (hello.crc[0] << 8) + hello.crc[1];
|
||
|
if (lcrc != rcrc) {
|
||
|
Syslog('+',"crc does not match in YooHoo hello packet: %04xh/%04xh", rcrc,lcrc);
|
||
|
SM_PROCEED(sendnak);
|
||
|
} else {
|
||
|
SM_PROCEED(sendack);
|
||
|
}
|
||
|
|
||
|
SM_STATE(sendnak)
|
||
|
|
||
|
if (count++ > 9) {
|
||
|
Syslog('+', "Too many tries to get YooHoo hello packet");
|
||
|
SM_ERROR;
|
||
|
}
|
||
|
PUTCHAR('?');
|
||
|
SM_PROCEED(waitchar);
|
||
|
|
||
|
SM_STATE(sendack)
|
||
|
|
||
|
PUTCHAR(ACK);
|
||
|
SM_SUCCESS;
|
||
|
|
||
|
SM_END
|
||
|
SM_RETURN
|
||
|
|
||
|
|
||
|
|
||
|
SM_DECL(txyoohoo,(char *)"txyoohoo")
|
||
|
SM_STATES
|
||
|
sendyoohoo,
|
||
|
waitenq,
|
||
|
sendpkt,
|
||
|
waitchar
|
||
|
SM_NAMES
|
||
|
(char *)"sendyoohoo",
|
||
|
(char *)"waitenq",
|
||
|
(char *)"sendpkt",
|
||
|
(char *)"waitchar"
|
||
|
SM_EDECL
|
||
|
|
||
|
int c, count = 0, startstate;
|
||
|
unsigned short lcrc;
|
||
|
|
||
|
if (iscaller)
|
||
|
startstate = sendpkt;
|
||
|
else
|
||
|
startstate = sendyoohoo;
|
||
|
|
||
|
lcrc = crc16xmodem((char*)hello.data, sizeof(hello.data));
|
||
|
hello.crc[0] = lcrc >> 8;
|
||
|
hello.crc[1] = lcrc & 0xff;
|
||
|
|
||
|
SM_START(startstate)
|
||
|
|
||
|
SM_STATE(sendyoohoo)
|
||
|
|
||
|
PUTCHAR(YOOHOO);
|
||
|
SM_PROCEED(waitenq);
|
||
|
|
||
|
SM_STATE(waitenq)
|
||
|
|
||
|
c=GETCHAR(10);
|
||
|
if (c == TIMEOUT) {
|
||
|
if (count++ > 9) {
|
||
|
Syslog('+', "Timeout waiting ENQ");
|
||
|
SM_ERROR;
|
||
|
} else {
|
||
|
SM_PROCEED(sendyoohoo);
|
||
|
}
|
||
|
} else if (c < 0) {
|
||
|
SM_ERROR;
|
||
|
} else switch (c) {
|
||
|
case ENQ: SM_PROCEED(sendpkt);
|
||
|
case YOOHOO: SM_PROCEED(waitenq);
|
||
|
default: Syslog('+',"Got '%s' waiting hello ACK", printablec(c));
|
||
|
SM_PROCEED(waitchar);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
SM_STATE(sendpkt)
|
||
|
|
||
|
if (count++ > 9) {
|
||
|
Syslog('+', "Too many tries to send YooHoo hello packet");
|
||
|
SM_ERROR;
|
||
|
}
|
||
|
|
||
|
PUTCHAR(0x1f);
|
||
|
PUT((char*)&hello, sizeof(hello));
|
||
|
if (STATUS) {
|
||
|
SM_ERROR;
|
||
|
}
|
||
|
SM_PROCEED(waitchar);
|
||
|
|
||
|
SM_STATE(waitchar)
|
||
|
|
||
|
c=GETCHAR(30);
|
||
|
if (c == TIMEOUT) {
|
||
|
Syslog('+', "Timeout waiting hello ACK");
|
||
|
SM_ERROR;
|
||
|
} else if (c < 0) {
|
||
|
SM_ERROR;
|
||
|
} else switch (c) {
|
||
|
case ACK: SM_SUCCESS;
|
||
|
break;
|
||
|
case '?': SM_PROCEED(sendpkt);
|
||
|
break;
|
||
|
case ENQ: SM_PROCEED(sendpkt);
|
||
|
break;
|
||
|
default: SM_PROCEED(waitchar);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
SM_END
|
||
|
SM_RETURN
|
||
|
|
||
|
|
||
|
|
||
|
void fillhello(unsigned short capabilities, char *password)
|
||
|
{
|
||
|
faddr *best;
|
||
|
unsigned short majver, minver;
|
||
|
|
||
|
best = bestaka_s(remote->addr);
|
||
|
sscanf(VERSION,"%hd.%hd", &majver, &minver);
|
||
|
memset(&hello, 0, sizeof(hello));
|
||
|
|
||
|
hello.data[0] = 'o'; /* signal */
|
||
|
hello.data[2] = 1; /* hello-version */
|
||
|
hello.data[4] = (PRODCODE & 0x00ff); /* product code */
|
||
|
hello.data[5] = (PRODCODE & 0xff00) >> 8; /* product code */
|
||
|
hello.data[6] = (VERSION_MAJOR & 0x00ff); /* prod-ver-major */
|
||
|
hello.data[7] = (VERSION_MAJOR & 0xff00) >> 8; /* prod-ver-major */
|
||
|
hello.data[8] = (VERSION_MINOR & 0x00ff); /* prod-ver-minor */
|
||
|
hello.data[9] = (VERSION_MINOR & 0xff00) >> 8; /* prod-ver-minor */
|
||
|
strncpy((char*)hello.data+10, name?name:"Unavailable",59); /* name */
|
||
|
if (name) {
|
||
|
hello.data[10+strlen(name)] = '\0';
|
||
|
strncpy((char*)hello.data+11 + strlen(name),
|
||
|
best->domain, 58-strlen(name)); /* domain */
|
||
|
} else
|
||
|
strncpy((char*)hello.data + 22, best->domain, 47); /* domain */
|
||
|
strncpy((char*)hello.data+70, CFG.sysop_name,19); /* sysop */
|
||
|
hello.data[90] = best->zone&0xff; /* zone */
|
||
|
hello.data[91] = best->zone>>8; /* zone */
|
||
|
hello.data[92] = best->net&0xff; /* net */
|
||
|
hello.data[93] = best->net>>8; /* net */
|
||
|
hello.data[94] = best->node&0xff; /* node */
|
||
|
hello.data[95] = best->node>>8; /* node */
|
||
|
hello.data[96] = best->point&0xff; /* point */
|
||
|
hello.data[97] = best->point>>8; /* point */
|
||
|
|
||
|
if (password)
|
||
|
strncpy((char*)hello.data + 98, password, 8);
|
||
|
|
||
|
hello.data[114] = capabilities & 0xff; /* capabilities */
|
||
|
hello.data[115] = capabilities >> 8; /* capabilities */
|
||
|
tidy_faddr(best);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
int checkhello(void)
|
||
|
{
|
||
|
unsigned short i, majver = 0, minver = 0;
|
||
|
fa_list **tmpl, *tmpa;
|
||
|
faddr remaddr;
|
||
|
char *prodnm, *q;
|
||
|
int loaded = FALSE;
|
||
|
|
||
|
Syslog('s',"check hello \"%s\"",printable((char*)hello.data,128));
|
||
|
hello2 = gethello2(hello.data);
|
||
|
|
||
|
if ((hello2.signal != 0x6f) || (hello2.hello_version != 0x01)) {
|
||
|
Syslog('+', "Got \"%s\" instead of \"o\\000\\001\000\"", printable((char*)hello.data,3));
|
||
|
}
|
||
|
|
||
|
prodnm = xstrcpy((char *)"<unknown program>");
|
||
|
for (i = 0; ftscprod[i].name; i++) {
|
||
|
if (ftscprod[i].code == hello2.product) {
|
||
|
free(prodnm);
|
||
|
prodnm = xstrcpy(ftscprod[i].name);
|
||
|
majver = hello2.product_maj;
|
||
|
minver = hello2.product_min;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
remaddr.zone = hello2.my_zone;
|
||
|
remaddr.net = hello2.my_net;
|
||
|
remaddr.node = hello2.my_node;
|
||
|
remaddr.point = hello2.my_point;
|
||
|
remaddr.name = NULL;
|
||
|
remaddr.domain = NULL;
|
||
|
if (hello2.my_name[0])
|
||
|
remaddr.domain = (char *)hello2.my_name + (strlen((char *)hello2.my_name)) + 1;
|
||
|
if (remaddr.domain[0]) {
|
||
|
if ((q = strchr(remaddr.domain, '.')))
|
||
|
*q = '\0';
|
||
|
} else {
|
||
|
remaddr.domain = NULL;
|
||
|
}
|
||
|
if (remote)
|
||
|
Syslog('s',"Remote known address: %s",ascfnode(remote->addr,0x1f));
|
||
|
|
||
|
for (tmpl = &remote; *tmpl; tmpl = &((*tmpl)->next));
|
||
|
if ((remote == NULL) || (metric(remote->addr, &remaddr) != 0)) {
|
||
|
(*tmpl) = (fa_list*)malloc(sizeof(fa_list));
|
||
|
(*tmpl)->next = NULL;
|
||
|
(*tmpl)->addr = (faddr*)malloc(sizeof(faddr));
|
||
|
(*tmpl)->addr->zone = remaddr.zone;
|
||
|
(*tmpl)->addr->net = remaddr.net;
|
||
|
(*tmpl)->addr->node = remaddr.node;
|
||
|
(*tmpl)->addr->point = remaddr.point;
|
||
|
(*tmpl)->addr->domain = xstrcpy(remaddr.domain);
|
||
|
(*tmpl)->addr->name = NULL; /* Added 15-Dec-1998 */
|
||
|
} else {
|
||
|
tmpl=&remote;
|
||
|
Syslog('s',"Using single remote address");
|
||
|
}
|
||
|
|
||
|
tmpl = &remote;
|
||
|
while (*tmpl) {
|
||
|
if (nodelock((*tmpl)->addr, mypid)) {
|
||
|
Syslog('+', " address: %s is locked, removed from aka list",ascfnode((*tmpl)->addr,0x1f));
|
||
|
tmpa = *tmpl;
|
||
|
*tmpl = (*tmpl)->next;
|
||
|
tidy_faddr(tmpa->addr);
|
||
|
free(tmpa);
|
||
|
} else {
|
||
|
Syslog('+', " address: %s",ascfnode((*tmpl)->addr,0x1f));
|
||
|
y_akas++;
|
||
|
/*
|
||
|
* With the loaded flag we prevent removing the noderecord
|
||
|
* when the remote presents us an address we don't know about.
|
||
|
*/
|
||
|
if (!Loaded) {
|
||
|
if (noderecord((*tmpl)->addr))
|
||
|
Loaded = TRUE;
|
||
|
}
|
||
|
tmpl = &((*tmpl)->next);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (y_akas) { /* Only set if we have aka's left */
|
||
|
history.aka.zone = remote->addr->zone;
|
||
|
history.aka.net = remote->addr->net;
|
||
|
history.aka.node = remote->addr->node;
|
||
|
history.aka.point = remote->addr->point;
|
||
|
}
|
||
|
|
||
|
if (hello2.product < 0x0100)
|
||
|
Syslog('+', " uses: %s [%02X] version %d.%d", prodnm, hello2.product, majver, minver);
|
||
|
else
|
||
|
Syslog('+', " uses: %s [%04X] version %d.%d", prodnm, hello2.product, majver, minver);
|
||
|
Syslog('+', " system: %s",(char*)hello2.my_name);
|
||
|
strncpy(history.system_name, (char *)hello2.my_name, 35);
|
||
|
Syslog('+', " sysop: %s",(char*)hello2.sysop);
|
||
|
strncpy(history.sysop, (char *)hello2.sysop, 35);
|
||
|
snprintf(history.location, 10, "Somewhere");
|
||
|
|
||
|
free(prodnm);
|
||
|
return loaded;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
Hello gethello2(unsigned char Hellop[])
|
||
|
{
|
||
|
int i;
|
||
|
Hello p;
|
||
|
|
||
|
p.signal=Hellop[0]+(Hellop[1]<<8);
|
||
|
p.hello_version=Hellop[2]+(Hellop[3]<<8);
|
||
|
p.product=Hellop[4]+(Hellop[5]<<8);
|
||
|
p.product_maj=Hellop[6]+(Hellop[7]<<8);
|
||
|
p.product_min=Hellop[8]+(Hellop[9]<<8);
|
||
|
for (i=0;i<60;i++)
|
||
|
p.my_name[i]=Hellop[10+i];
|
||
|
for (i=0;i<20;i++)
|
||
|
p.sysop[i]=Hellop[70+i];
|
||
|
p.my_zone=Hellop[90]+(Hellop[91]<<8);
|
||
|
p.my_net=Hellop[92]+(Hellop[93]<<8);
|
||
|
p.my_node=Hellop[94]+(Hellop[95]<<8);
|
||
|
p.my_point=Hellop[96]+(Hellop[97]<<8);
|
||
|
for (i=0;i<8;i++)
|
||
|
p.my_password[i]=Hellop[98+i];
|
||
|
for (i=0;i<8;i++)
|
||
|
p.reserved2[i]=Hellop[106+i];
|
||
|
p.capabilities=Hellop[114]+(Hellop[115]<<8);
|
||
|
for (i=0;i<12;i++)
|
||
|
p.reserved3[i]=Hellop[116+i];
|
||
|
|
||
|
return p;
|
||
|
}
|
||
|
|