gopher/connection.c

211 lines
4.1 KiB
C
Raw Normal View History

2012-04-15 02:03:26 +00:00
#pragma optimize 79
2012-04-28 01:18:31 +00:00
#pragma noroot
2012-04-15 02:03:26 +00:00
2012-03-11 21:25:17 +00:00
#include "connection.h"
#include <string.h>
2012-04-28 01:18:31 +00:00
#include "s16debug.h"
2012-03-09 02:15:46 +00:00
2012-03-11 21:25:17 +00:00
static char pstring[256];
2012-03-09 02:15:46 +00:00
2012-03-11 21:25:17 +00:00
static Word LoginAndOpen(Connection *buffer)
2012-03-09 02:15:46 +00:00
{
Word ipid;
Word terr;
ipid = TCPIPLogin(
buffer->memID,
buffer->dnr.DNRIPaddress,
buffer->port,
0x0000, 0x0040);
if (_toolErr)
{
2012-03-11 21:25:17 +00:00
buffer->state = kConnectionStateError;
2012-03-09 02:15:46 +00:00
return -1;
}
terr = TCPIPOpenTCP(ipid);
if (_toolErr || terr)
{
TCPIPLogout(ipid);
2012-03-11 21:25:17 +00:00
buffer->state = kConnectionStateError;
2012-03-09 02:15:46 +00:00
buffer->terr = terr;
buffer->ipid = 0;
return -1;
}
buffer->ipid = ipid;
2012-03-11 21:25:17 +00:00
buffer->state = kConnectionStateConnecting;
2012-03-09 02:15:46 +00:00
return 0;
}
2012-03-11 21:25:17 +00:00
Word ConnectionPoll(Connection *buffer)
2012-03-09 02:15:46 +00:00
{
2012-08-26 19:52:43 +00:00
2012-03-09 02:15:46 +00:00
Word state;
if (!buffer) return -1;
state = buffer->state;
if (state == 0) return -1;
2012-03-11 21:25:17 +00:00
if (state == kConnectionStateConnected) return 1;
if (state == kConnectionStateDisconnected) return 1;
if (state == kConnectionStateError) return -1;
2012-03-09 02:15:46 +00:00
TCPIPPoll();
2012-03-11 21:25:17 +00:00
if (state == kConnectionStateDNR)
2012-03-09 02:15:46 +00:00
{
if (buffer->dnr.DNRstatus == DNR_OK)
{
return LoginAndOpen(buffer);
}
else if (buffer->dnr.DNRstatus != DNR_Pending)
{
2012-03-11 21:25:17 +00:00
buffer->state = kConnectionStateError;
2012-03-09 02:15:46 +00:00
return -1;
}
}
2012-03-11 21:25:17 +00:00
if (state == kConnectionStateConnecting || state == kConnectionStateDisconnecting)
2012-03-09 02:15:46 +00:00
{
Word terr;
static srBuff sr;
terr = TCPIPStatusTCP(buffer->ipid, &sr);
2012-03-11 21:25:17 +00:00
if (state == kConnectionStateDisconnecting)
2012-03-09 02:15:46 +00:00
{
// these are not errors.
if (terr == tcperrConClosing || terr == tcperrClosing)
terr = tcperrOK;
}
if (terr || _toolErr)
{
//CloseAndLogout(buffer);
2012-08-26 19:52:43 +00:00
s16_debug_printf("terr = %04x tool error = %04x", terr, _toolErr);
s16_debug_srbuff(&sr);
2012-03-09 02:15:46 +00:00
TCPIPCloseTCP(buffer->ipid);
TCPIPLogout(buffer->ipid);
buffer->ipid = 0;
2012-03-11 21:25:17 +00:00
buffer->state = kConnectionStateError;
2012-03-09 02:15:46 +00:00
buffer->terr = terr;
return -1;
}
2012-03-11 21:25:17 +00:00
if (sr.srState == TCPSESTABLISHED) // && state == kConnectionStateConnecting)
2012-03-09 02:15:46 +00:00
{
2012-03-11 21:25:17 +00:00
buffer->state = kConnectionStateConnected;
2012-03-09 02:15:46 +00:00
return 1;
}
if (sr.srState == TCPSCLOSED || sr.srState == TCPSTIMEWAIT)
{
2012-08-26 19:52:43 +00:00
s16_debug_srbuff(&sr);
2012-03-09 02:15:46 +00:00
TCPIPLogout(buffer->ipid);
buffer->ipid = 0;
2012-03-11 21:25:17 +00:00
buffer->state = kConnectionStateDisconnected;
2012-03-09 02:15:46 +00:00
return 1;
}
}
return 0;
}
2012-03-11 21:25:17 +00:00
Word ConnectionOpenC(Connection *buffer, const char *host, Word port)
{
Word length;
if (!host) return -1;
length = strlen(host);
if (length > 255) return -1;
pstring[0] = length & 0xff;
memcpy(pstring + 1, host, length);
return ConnectionOpen(buffer, pstring, port);
}
Word ConnectionOpenGS(Connection *buffer, const GSString255 *host, Word port)
{
if (!host) return -1;
if (host->length > 255) return -1;
pstring[0] = host->length & 0xff;
memcpy(pstring + 1, host->text, host->length);
return ConnectionOpen(buffer, pstring, port);
}
Word ConnectionOpen(Connection *buffer, const char *host, Word port)
2012-03-09 02:15:46 +00:00
{
buffer->state = 0;
buffer->ipid = 0;
buffer->terr = 0;
buffer->port = port;
2012-03-11 21:25:17 +00:00
if (!buffer || !*buffer) return -1;
2012-03-09 02:15:46 +00:00
// 1. check if we need to do DNR.
if (TCPIPValidateIPString(host))
{
cvtRec cvt;
TCPIPConvertIPToHex(&cvt, host);
buffer->dnr.DNRIPaddress = cvt.cvtIPAddress;
buffer->dnr.DNRstatus = DNR_OK; // fake it.
return LoginAndOpen(buffer);
}
// do dnr.
TCPIPDNRNameToIP(host, &buffer->dnr);
if (_toolErr)
{
2012-03-11 21:25:17 +00:00
buffer->state = kConnectionStateError;
2012-03-09 02:15:46 +00:00
return -1;
}
2012-03-11 21:25:17 +00:00
buffer->state = kConnectionStateDNR;
2012-03-09 02:15:46 +00:00
return 0;
}
2012-03-11 21:25:17 +00:00
void ConnectionInit(Connection *buffer, Word memID)
2012-03-09 02:15:46 +00:00
{
buffer->memID = memID;
buffer->ipid = 0;
buffer->terr = 0;
buffer->state = 0;
buffer->port = 0;
buffer->dnr.DNRstatus = 0;
buffer->dnr.DNRIPaddress = 0;
}
2012-03-11 21:25:17 +00:00
Word ConnectionClose(Connection *buffer)
2012-03-09 02:15:46 +00:00
{
Word state = buffer->state;
// todo -- how do you close if not yet connected?
2012-03-11 21:25:17 +00:00
if (state == kConnectionStateConnected)
2012-03-09 02:15:46 +00:00
{
2012-03-11 21:25:17 +00:00
buffer->state = kConnectionStateDisconnecting;
2012-03-09 02:15:46 +00:00
buffer->terr = TCPIPCloseTCP(buffer->ipid);
return 0;
}
2012-03-11 21:25:17 +00:00
if (state == kConnectionStateDNR)
2012-03-09 02:15:46 +00:00
{
TCPIPCancelDNR(&buffer->dnr);
buffer->state = 0;
return 1;
}
return -1;
}