mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
Mac networking ios still as shafted as ever, but I should probably commit what
I _have_ done. It does manage to open a connection to the correct port on the correct host -- it just then bombs the client with a "CHK error". Pity. [originally from svn r157]
This commit is contained in:
parent
0256bceece
commit
df67c404ae
147
macnet.c
147
macnet.c
@ -1,4 +1,4 @@
|
||||
/* $Id: macnet.c,v 1.1.2.3 1999/04/04 18:23:34 ben Exp $ */
|
||||
/* $Id: macnet.c,v 1.1.2.4 1999/04/06 23:18:49 ben Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1999 Ben Harris
|
||||
* All rights reserved.
|
||||
@ -75,7 +75,9 @@ typedef struct Socket {
|
||||
int port;
|
||||
ProcessSerialNumber psn;
|
||||
Session *s;
|
||||
#if TARGET_CPU_68K && !TARGET_RT_CFM
|
||||
long a5;
|
||||
#endif
|
||||
QHdr sendq; /* Blocks waiting to be sent */
|
||||
} Socket;
|
||||
|
||||
@ -132,11 +134,13 @@ static RoutineDescriptor macnet_completed_close_upp =
|
||||
static RoutineDescriptor macnet_asr_upp =
|
||||
BUILD_ROUTINE_DESCRIPTOR(uppTCPNotifyProcInfo, (ProcPtr)macnet_asr);
|
||||
#else
|
||||
#define macnet_resolved_upp macnet_resolved
|
||||
#define macnet_completed_open_upp macnet_completed_open
|
||||
#define macnet_completed_send_upp macnet_completed_send
|
||||
#define macnet_completed_close_upp macnet_completed_close
|
||||
#define macnet_asr_upp macnet_asr
|
||||
/* These handle A5 switching to thwart the optimiser. */
|
||||
static pascal void macnet_resolved_upp(hostInfo *, char *);
|
||||
static void macnet_completed_open_upp(TCPiopb *);
|
||||
static void macnet_completed_send_upp(TCPiopb *);
|
||||
static void macnet_completed_close_upp(TCPiopb *);
|
||||
static pascal void macnet_asr_upp(StreamPtr, unsigned short, Ptr,
|
||||
unsigned short, ICMPReport *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -155,6 +159,7 @@ static OSErr macnet_init(void) {
|
||||
/*
|
||||
* FIXME: This is hideously broken, in that we're meant to faff
|
||||
* with unit numbers and stuff, and we blatantly don't.
|
||||
* On the other hand, neither does NCSA Telnet. Hmm.
|
||||
*/
|
||||
err = opendriver(".IPP", &mtcp_refnum);
|
||||
if (err != noErr)
|
||||
@ -162,8 +167,7 @@ static OSErr macnet_init(void) {
|
||||
err = OpenResolver(NULL);
|
||||
if (err != noErr)
|
||||
return err;
|
||||
/* Set up the event queues, and fill the free queue with events
|
||||
*/
|
||||
/* Set up the event queues, and fill the free queue with events */
|
||||
macnet_eventq.qFlags = 0;
|
||||
macnet_eventq.qHead = macnet_eventq.qTail = NULL;
|
||||
macnet_freeq.qFlags = 0;
|
||||
@ -192,7 +196,9 @@ Socket *net_open(Session *s, char *host, int port) {
|
||||
/* Make a note of anything we don't want to forget */
|
||||
sock->port = port;
|
||||
GetCurrentProcess(&sock->psn);
|
||||
#if TARGET_CPU_68K && !TARGET_RT_CFM
|
||||
sock->a5 = SetCurrentA5();
|
||||
#endif
|
||||
|
||||
/* Get MacTCP running if it's not already */
|
||||
if (!mtcp_initted)
|
||||
@ -201,6 +207,7 @@ Socket *net_open(Session *s, char *host, int port) {
|
||||
|
||||
/* Get ourselves a TCP stream to play with */
|
||||
sock->iopb.ioCRefNum = mtcp_refnum;
|
||||
sock->iopb.ioCompletion = NULL;
|
||||
sock->iopb.csCode = TCPCreate;
|
||||
sock->iopb.csParam.create.rcvBuff = tcpbuf;
|
||||
sock->iopb.csParam.create.rcvBuffLen = TCPBUF_SIZE;
|
||||
@ -209,24 +216,33 @@ Socket *net_open(Session *s, char *host, int port) {
|
||||
/* This could be done asynchronously, but I doubt it'll take long. */
|
||||
err = PBControlSync((ParmBlkPtr)&sock->iopb);
|
||||
if (err != noErr)
|
||||
fatalbox("TCP stream open failed (%d)", err);
|
||||
fatalbox("TCP stream create failed (%d)", err);
|
||||
|
||||
err = StrToAddr(host, &sock->hostinfo, &macnet_resolved_upp, (char *)sock);
|
||||
if (err != noErr)
|
||||
fatalbox("Host lookup failed (%d)", err);
|
||||
if (sock->hostinfo.rtnCode != cacheFault)
|
||||
/*
|
||||
* A cache fault indicates that the DNR will call us back when
|
||||
* it's found the host for us.
|
||||
*/
|
||||
if (err != cacheFault)
|
||||
macnet_resolved(&sock->hostinfo, (char *)sock);
|
||||
return sock;
|
||||
}
|
||||
|
||||
static pascal void macnet_resolved(hostInfo *hi, char *cookie) {
|
||||
#if TARGET_CPU_68K && !TARGET_RT_CFM
|
||||
static pascal void macnet_resolved_upp(hostInfo *hi, char *cookie) {
|
||||
Socket *sock = (Socket *)cookie;
|
||||
OSErr err;
|
||||
#if !TARGET_RT_CFM
|
||||
long olda5;
|
||||
|
||||
olda5 = SetA5(sock->a5);
|
||||
macnet_resolved(hi, cookie);
|
||||
SetA5(olda5);
|
||||
}
|
||||
#endif
|
||||
|
||||
static pascal void macnet_resolved(hostInfo *hi, char *cookie) {
|
||||
Socket *sock = (Socket *)cookie;
|
||||
OSErr err;
|
||||
|
||||
/*
|
||||
* We've resolved a name, so now we'd like to connect to it (or
|
||||
* report an error).
|
||||
@ -236,19 +252,17 @@ static pascal void macnet_resolved(hostInfo *hi, char *cookie) {
|
||||
/* Open a connection */
|
||||
sock->iopb.ioCompletion = macnet_completed_open_upp;
|
||||
sock->iopb.csCode = TCPActiveOpen;
|
||||
memset(&sock->iopb.csParam, 0, sizeof(sock->iopb.csParam));
|
||||
sock->iopb.csParam.open.validityFlags = typeOfService;
|
||||
sock->iopb.csParam.open.commandTimeoutValue = 0; /* unused */
|
||||
sock->iopb.csParam.open.remoteHost = sock->hostinfo.addr[0]; /*XXX*/
|
||||
sock->iopb.csParam.open.remotePort = sock->port;
|
||||
/* localHost is set by MacTCP. */
|
||||
sock->iopb.csParam.open.localPort = 0;
|
||||
sock->iopb.csParam.open.tosFlags = lowDelay;
|
||||
sock->iopb.csParam.open.dontFrag = 0;
|
||||
sock->iopb.csParam.open.timeToLive = 0; /* default */
|
||||
sock->iopb.csParam.open.security = 0;
|
||||
sock->iopb.csParam.open.optionCnt = 0;
|
||||
sock->iopb.csParam.open.userDataPtr = (char *)sock;
|
||||
err = PBControlSync((ParmBlkPtr)&sock->iopb);
|
||||
err = PBControlAsync((ParmBlkPtr)&sock->iopb);
|
||||
if (err != noErr)
|
||||
macnet_sendevent(sock, NE_NOOPEN);
|
||||
break;
|
||||
@ -256,18 +270,22 @@ static pascal void macnet_resolved(hostInfo *hi, char *cookie) {
|
||||
macnet_sendevent(sock, NE_NOHOST);
|
||||
break;
|
||||
}
|
||||
#if !TARGET_RT_CFM
|
||||
SetA5(olda5);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void macnet_completed_open(TCPiopb *iopb) {
|
||||
#if TARGET_CPU_68K && !TARGET_RT_CFM
|
||||
static void macnet_completed_open_upp(TCPiopb *iopb) {
|
||||
Socket *sock = (Socket *)iopb->csParam.open.userDataPtr;
|
||||
#if !TARGET_RT_CFM
|
||||
long olda5;
|
||||
|
||||
olda5 = SetA5(sock->a5);
|
||||
macnet_completed_open(iopb);
|
||||
SetA5(olda5);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void macnet_completed_open(TCPiopb *iopb) {
|
||||
Socket *sock = (Socket *)iopb->csParam.open.userDataPtr;
|
||||
|
||||
switch (iopb->ioResult) {
|
||||
case noErr:
|
||||
macnet_sendevent(sock, NE_OPEN);
|
||||
@ -276,20 +294,27 @@ static void macnet_completed_open(TCPiopb *iopb) {
|
||||
macnet_sendevent(sock, NE_NOOPEN);
|
||||
break;
|
||||
}
|
||||
#if !TARGET_RT_CFM
|
||||
SetA5(olda5);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if TARGET_CPU_68K && !TARGET_RT_CFM
|
||||
static pascal void macnet_asr_upp(StreamPtr tcpstream,
|
||||
unsigned short eventcode, Ptr cookie,
|
||||
unsigned short terminreason,
|
||||
ICMPReport *icmpmsg) {
|
||||
Socket *sock = (Socket *)cookie;
|
||||
long olda5;
|
||||
|
||||
olda5 = SetA5(sock->a5);
|
||||
macnet_asr(tcpstream, eventcode, cookie, terminreason, icmpmsg);
|
||||
SetA5(olda5);
|
||||
}
|
||||
#endif
|
||||
|
||||
static pascal void macnet_asr(StreamPtr tcpstream, unsigned short eventcode,
|
||||
Ptr cookie, unsigned short terminreason,
|
||||
ICMPReport *icmpmsg) {
|
||||
Socket *sock = (Socket *)cookie;
|
||||
#if !TARGET_RT_CFM
|
||||
long olda5;
|
||||
|
||||
olda5 = SetA5(sock->a5);
|
||||
#endif
|
||||
switch (eventcode) {
|
||||
case TCPClosing:
|
||||
macnet_sendevent(sock, NE_CLOSING);
|
||||
@ -321,9 +346,6 @@ static pascal void macnet_asr(StreamPtr tcpstream, unsigned short eventcode,
|
||||
}
|
||||
break;
|
||||
}
|
||||
#if !TARGET_RT_CFM
|
||||
SetA5(olda5);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -395,7 +417,9 @@ static void macnet_startsend(Socket *sock) {
|
||||
OSErr err;
|
||||
|
||||
buff = (Send_Buffer *)sock->sendq.qHead;
|
||||
sock->iopb.ioCompletion = macnet_completed_send_upp;
|
||||
sock->iopb.csCode = TCPSend;
|
||||
memset(&sock->iopb.csParam, 0, sizeof(sock->iopb.csParam));
|
||||
sock->iopb.csParam.send.validityFlags = 0;
|
||||
sock->iopb.csParam.send.pushFlag = buff->flags & SEND_PUSH ? true : false;
|
||||
sock->iopb.csParam.send.urgentFlag = buff->flags & SEND_URG ? true : false;
|
||||
@ -404,15 +428,45 @@ static void macnet_startsend(Socket *sock) {
|
||||
err = PBControlAsync((ParmBlkPtr)&sock->iopb);
|
||||
}
|
||||
|
||||
#if TARGET_CPU_68K && !TARGET_RT_CFM
|
||||
static void macnet_completed_send_upp(TCPiopb *iopb) {
|
||||
Socket *sock = (Socket *)iopb->csParam.send.userDataPtr;
|
||||
long olda5;
|
||||
|
||||
olda5 = SetA5(sock->a5);
|
||||
macnet_completed_send(iopb);
|
||||
SetA5(olda5);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void macnet_completed_send(TCPiopb *iopb) {
|
||||
Socket *sock = (Socket *)iopb->csParam.send.userDataPtr;
|
||||
|
||||
switch (iopb->ioResult) {
|
||||
case noErr:
|
||||
macnet_sendevent(sock, NE_SENT);
|
||||
break;
|
||||
case connectionClosing:
|
||||
case connectionTerminated:
|
||||
/* We'll get an ASR, so ignore it here. */
|
||||
break;
|
||||
default:
|
||||
macnet_sendevent(sock, NE_DIED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int net_recv(Socket *sock, void *buf, int buflen, int flags) {
|
||||
TCPiopb iopb;
|
||||
OSErr err;
|
||||
int avail, want, got;
|
||||
|
||||
memcpy(&iopb, &sock->iopb, sizeof(TCPiopb));
|
||||
/* Work out if there's anything to recieve (we don't want to block)
|
||||
*/
|
||||
/* Work out if there's anything to recieve (we don't want to block) */
|
||||
iopb.ioCompletion = NULL;
|
||||
iopb.csCode = TCPStatus;
|
||||
memset(&sock->iopb.csParam, 0, sizeof(sock->iopb.csParam));
|
||||
err = PBControlSync((ParmBlkPtr)&iopb);
|
||||
if (err != noErr)
|
||||
return 0; /* macnet_asr should catch it anyway */
|
||||
@ -420,7 +474,9 @@ int net_recv(Socket *sock, void *buf, int buflen, int flags) {
|
||||
if (avail == 0)
|
||||
return 0;
|
||||
want = avail < buflen ? avail : buflen;
|
||||
iopb.ioCompletion = NULL;
|
||||
iopb.csCode = TCPRcv;
|
||||
memset(&sock->iopb.csParam, 0, sizeof(sock->iopb.csParam));
|
||||
iopb.csParam.receive.rcvBuff = buf;
|
||||
iopb.csParam.receive.rcvBuffLen = want;
|
||||
err = PBControlSync((ParmBlkPtr)&iopb);
|
||||
@ -440,6 +496,7 @@ void net_close(Socket *sock) {
|
||||
* free it, which we can't do at interrupt time).
|
||||
*/
|
||||
memcpy(&sock->spareiopb, &sock->iopb, sizeof(TCPiopb));
|
||||
memset(&sock->spareiopb.csParam, 0, sizeof(sock->spareiopb.csParam));
|
||||
sock->spareiopb.ioCompletion = macnet_completed_close_upp;
|
||||
sock->spareiopb.csCode = TCPClose;
|
||||
sock->spareiopb.csParam.close.validityFlags = 0;
|
||||
@ -456,13 +513,20 @@ void net_close(Socket *sock) {
|
||||
}
|
||||
}
|
||||
|
||||
static void macnet_completed_close(TCPiopb* iopb) {
|
||||
#if TARGET_CPU_68K && !TARGET_RT_CFM
|
||||
static void macnet_completed_close_upp(TCPiopb* iopb) {
|
||||
Socket *sock = (Socket *)iopb->csParam.close.userDataPtr;
|
||||
#if !TARGET_RT_CFM
|
||||
long olda5;
|
||||
|
||||
olda5 = SetA5(sock->a5);
|
||||
macnet_completed_close(iopb);
|
||||
SetA5(olda5);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void macnet_completed_close(TCPiopb* iopb) {
|
||||
Socket *sock = (Socket *)iopb->csParam.close.userDataPtr;
|
||||
|
||||
switch (iopb->ioResult) {
|
||||
case noErr:
|
||||
macnet_sendevent(sock, NE_CLOSED);
|
||||
@ -474,9 +538,6 @@ static void macnet_completed_close(TCPiopb* iopb) {
|
||||
macnet_sendevent(sock, NE_DIED);
|
||||
break;
|
||||
}
|
||||
#if !TARGET_RT_CFM
|
||||
SetA5(olda5);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -493,7 +554,9 @@ void net_destroy(Socket *sock) {
|
||||
* synchronous, so we can allocate this one dynamically.
|
||||
*/
|
||||
memcpy(&iopb, &sock->iopb, sizeof(TCPiopb));
|
||||
iopb.ioCompletion = NULL;
|
||||
iopb.csCode = TCPRelease;
|
||||
memset(&iopb.csParam, 0, sizeof(iopb.csParam));
|
||||
err = PBControlSync((ParmBlkPtr)&iopb);
|
||||
sfree(iopb.csParam.create.rcvBuff);
|
||||
sfree(sock);
|
||||
@ -503,7 +566,7 @@ static void macnet_sendevent(Socket *sock, Net_Event_Type type) {
|
||||
NetEvent *ne;
|
||||
|
||||
ne = (NetEvent *)macnet_freeq.qHead;
|
||||
assert (ne != NULL);
|
||||
if (ne == NULL) return; /* It's a disaster, but how do we tell anyone? */
|
||||
Dequeue(&ne->qelem, &macnet_freeq);
|
||||
ne->sock = sock;
|
||||
ne->type = type;
|
||||
|
25
telnet.c
25
telnet.c
@ -9,6 +9,10 @@
|
||||
|
||||
#include "putty.h"
|
||||
|
||||
#ifdef macintosh
|
||||
#pragma segment Telnet
|
||||
#endif
|
||||
|
||||
static SOCKET s = INVALID_SOCKET;
|
||||
/* kludge till we decide where to put telnet state */
|
||||
static Session *sess;
|
||||
@ -479,6 +483,10 @@ static char *telnet_init (Session *this_sess) {
|
||||
sess = this_sess;
|
||||
s = net_open(sess, sess->cfg.host, sess->cfg.port);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void telnet_opened(Session *sess) {
|
||||
/*
|
||||
* Initialise option states.
|
||||
*/
|
||||
@ -496,8 +504,6 @@ static char *telnet_init (Session *this_sess) {
|
||||
*/
|
||||
in_synch = FALSE;
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -512,6 +518,9 @@ static int telnet_msg (Session *sess, SOCKET sock, Net_Event_Type ne) {
|
||||
return -5000;
|
||||
|
||||
switch (ne) {
|
||||
case NE_OPEN:
|
||||
telnet_opened(sess);
|
||||
return 1;
|
||||
case NE_DATA:
|
||||
ret = net_recv(s, buf, sizeof(buf), 0);
|
||||
if (ret < 0) /* any _other_ error */
|
||||
@ -548,6 +557,18 @@ static int telnet_msg (Session *sess, SOCKET sock, Net_Event_Type ne) {
|
||||
case NE_CLOSING:
|
||||
s = INVALID_SOCKET;
|
||||
return 0;
|
||||
case NE_NOHOST:
|
||||
fatalbox("Host not found");
|
||||
case NE_REFUSED:
|
||||
fatalbox("Connection refused");
|
||||
case NE_NOOPEN:
|
||||
fatalbox("Unable to open connection");
|
||||
case NE_TIMEOUT:
|
||||
fatalbox("Connection timed out");
|
||||
case NE_ABORT:
|
||||
fatalbox("Connection reset by peer");
|
||||
case NE_DIED:
|
||||
fatalbox("Connection died");
|
||||
}
|
||||
return 1; /* shouldn't happen, but WTF */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user