1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-25 01:02:24 +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:
Ben Harris 1999-04-06 23:18:50 +00:00
parent 0256bceece
commit df67c404ae
2 changed files with 128 additions and 44 deletions

147
macnet.c
View File

@ -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 * Copyright (c) 1999 Ben Harris
* All rights reserved. * All rights reserved.
@ -75,7 +75,9 @@ typedef struct Socket {
int port; int port;
ProcessSerialNumber psn; ProcessSerialNumber psn;
Session *s; Session *s;
#if TARGET_CPU_68K && !TARGET_RT_CFM
long a5; long a5;
#endif
QHdr sendq; /* Blocks waiting to be sent */ QHdr sendq; /* Blocks waiting to be sent */
} Socket; } Socket;
@ -132,11 +134,13 @@ static RoutineDescriptor macnet_completed_close_upp =
static RoutineDescriptor macnet_asr_upp = static RoutineDescriptor macnet_asr_upp =
BUILD_ROUTINE_DESCRIPTOR(uppTCPNotifyProcInfo, (ProcPtr)macnet_asr); BUILD_ROUTINE_DESCRIPTOR(uppTCPNotifyProcInfo, (ProcPtr)macnet_asr);
#else #else
#define macnet_resolved_upp macnet_resolved /* These handle A5 switching to thwart the optimiser. */
#define macnet_completed_open_upp macnet_completed_open static pascal void macnet_resolved_upp(hostInfo *, char *);
#define macnet_completed_send_upp macnet_completed_send static void macnet_completed_open_upp(TCPiopb *);
#define macnet_completed_close_upp macnet_completed_close static void macnet_completed_send_upp(TCPiopb *);
#define macnet_asr_upp macnet_asr static void macnet_completed_close_upp(TCPiopb *);
static pascal void macnet_asr_upp(StreamPtr, unsigned short, Ptr,
unsigned short, ICMPReport *);
#endif #endif
/* /*
@ -155,6 +159,7 @@ static OSErr macnet_init(void) {
/* /*
* FIXME: This is hideously broken, in that we're meant to faff * FIXME: This is hideously broken, in that we're meant to faff
* with unit numbers and stuff, and we blatantly don't. * with unit numbers and stuff, and we blatantly don't.
* On the other hand, neither does NCSA Telnet. Hmm.
*/ */
err = opendriver(".IPP", &mtcp_refnum); err = opendriver(".IPP", &mtcp_refnum);
if (err != noErr) if (err != noErr)
@ -162,8 +167,7 @@ static OSErr macnet_init(void) {
err = OpenResolver(NULL); err = OpenResolver(NULL);
if (err != noErr) if (err != noErr)
return err; 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.qFlags = 0;
macnet_eventq.qHead = macnet_eventq.qTail = NULL; macnet_eventq.qHead = macnet_eventq.qTail = NULL;
macnet_freeq.qFlags = 0; 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 */ /* Make a note of anything we don't want to forget */
sock->port = port; sock->port = port;
GetCurrentProcess(&sock->psn); GetCurrentProcess(&sock->psn);
#if TARGET_CPU_68K && !TARGET_RT_CFM
sock->a5 = SetCurrentA5(); sock->a5 = SetCurrentA5();
#endif
/* Get MacTCP running if it's not already */ /* Get MacTCP running if it's not already */
if (!mtcp_initted) if (!mtcp_initted)
@ -201,6 +207,7 @@ Socket *net_open(Session *s, char *host, int port) {
/* Get ourselves a TCP stream to play with */ /* Get ourselves a TCP stream to play with */
sock->iopb.ioCRefNum = mtcp_refnum; sock->iopb.ioCRefNum = mtcp_refnum;
sock->iopb.ioCompletion = NULL;
sock->iopb.csCode = TCPCreate; sock->iopb.csCode = TCPCreate;
sock->iopb.csParam.create.rcvBuff = tcpbuf; sock->iopb.csParam.create.rcvBuff = tcpbuf;
sock->iopb.csParam.create.rcvBuffLen = TCPBUF_SIZE; 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. */ /* This could be done asynchronously, but I doubt it'll take long. */
err = PBControlSync((ParmBlkPtr)&sock->iopb); err = PBControlSync((ParmBlkPtr)&sock->iopb);
if (err != noErr) 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); err = StrToAddr(host, &sock->hostinfo, &macnet_resolved_upp, (char *)sock);
if (err != noErr) /*
fatalbox("Host lookup failed (%d)", err); * A cache fault indicates that the DNR will call us back when
if (sock->hostinfo.rtnCode != cacheFault) * it's found the host for us.
*/
if (err != cacheFault)
macnet_resolved(&sock->hostinfo, (char *)sock); macnet_resolved(&sock->hostinfo, (char *)sock);
return 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; Socket *sock = (Socket *)cookie;
OSErr err;
#if !TARGET_RT_CFM
long olda5; long olda5;
olda5 = SetA5(sock->a5); olda5 = SetA5(sock->a5);
macnet_resolved(hi, cookie);
SetA5(olda5);
}
#endif #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 * We've resolved a name, so now we'd like to connect to it (or
* report an error). * report an error).
@ -236,19 +252,17 @@ static pascal void macnet_resolved(hostInfo *hi, char *cookie) {
/* Open a connection */ /* Open a connection */
sock->iopb.ioCompletion = macnet_completed_open_upp; sock->iopb.ioCompletion = macnet_completed_open_upp;
sock->iopb.csCode = TCPActiveOpen; sock->iopb.csCode = TCPActiveOpen;
memset(&sock->iopb.csParam, 0, sizeof(sock->iopb.csParam));
sock->iopb.csParam.open.validityFlags = typeOfService; 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.remoteHost = sock->hostinfo.addr[0]; /*XXX*/
sock->iopb.csParam.open.remotePort = sock->port; 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.tosFlags = lowDelay;
sock->iopb.csParam.open.dontFrag = 0; sock->iopb.csParam.open.dontFrag = 0;
sock->iopb.csParam.open.timeToLive = 0; /* default */ sock->iopb.csParam.open.timeToLive = 0; /* default */
sock->iopb.csParam.open.security = 0; sock->iopb.csParam.open.security = 0;
sock->iopb.csParam.open.optionCnt = 0; sock->iopb.csParam.open.optionCnt = 0;
sock->iopb.csParam.open.userDataPtr = (char *)sock; sock->iopb.csParam.open.userDataPtr = (char *)sock;
err = PBControlSync((ParmBlkPtr)&sock->iopb); err = PBControlAsync((ParmBlkPtr)&sock->iopb);
if (err != noErr) if (err != noErr)
macnet_sendevent(sock, NE_NOOPEN); macnet_sendevent(sock, NE_NOOPEN);
break; break;
@ -256,18 +270,22 @@ static pascal void macnet_resolved(hostInfo *hi, char *cookie) {
macnet_sendevent(sock, NE_NOHOST); macnet_sendevent(sock, NE_NOHOST);
break; 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; Socket *sock = (Socket *)iopb->csParam.open.userDataPtr;
#if !TARGET_RT_CFM
long olda5; long olda5;
olda5 = SetA5(sock->a5); olda5 = SetA5(sock->a5);
macnet_completed_open(iopb);
SetA5(olda5);
}
#endif #endif
static void macnet_completed_open(TCPiopb *iopb) {
Socket *sock = (Socket *)iopb->csParam.open.userDataPtr;
switch (iopb->ioResult) { switch (iopb->ioResult) {
case noErr: case noErr:
macnet_sendevent(sock, NE_OPEN); macnet_sendevent(sock, NE_OPEN);
@ -276,20 +294,27 @@ static void macnet_completed_open(TCPiopb *iopb) {
macnet_sendevent(sock, NE_NOOPEN); macnet_sendevent(sock, NE_NOOPEN);
break; 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, static pascal void macnet_asr(StreamPtr tcpstream, unsigned short eventcode,
Ptr cookie, unsigned short terminreason, Ptr cookie, unsigned short terminreason,
ICMPReport *icmpmsg) { ICMPReport *icmpmsg) {
Socket *sock = (Socket *)cookie; Socket *sock = (Socket *)cookie;
#if !TARGET_RT_CFM
long olda5;
olda5 = SetA5(sock->a5);
#endif
switch (eventcode) { switch (eventcode) {
case TCPClosing: case TCPClosing:
macnet_sendevent(sock, NE_CLOSING); macnet_sendevent(sock, NE_CLOSING);
@ -321,9 +346,6 @@ static pascal void macnet_asr(StreamPtr tcpstream, unsigned short eventcode,
} }
break; break;
} }
#if !TARGET_RT_CFM
SetA5(olda5);
#endif
} }
/* /*
@ -395,7 +417,9 @@ static void macnet_startsend(Socket *sock) {
OSErr err; OSErr err;
buff = (Send_Buffer *)sock->sendq.qHead; buff = (Send_Buffer *)sock->sendq.qHead;
sock->iopb.ioCompletion = macnet_completed_send_upp;
sock->iopb.csCode = TCPSend; sock->iopb.csCode = TCPSend;
memset(&sock->iopb.csParam, 0, sizeof(sock->iopb.csParam));
sock->iopb.csParam.send.validityFlags = 0; sock->iopb.csParam.send.validityFlags = 0;
sock->iopb.csParam.send.pushFlag = buff->flags & SEND_PUSH ? true : false; sock->iopb.csParam.send.pushFlag = buff->flags & SEND_PUSH ? true : false;
sock->iopb.csParam.send.urgentFlag = buff->flags & SEND_URG ? 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); 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) { int net_recv(Socket *sock, void *buf, int buflen, int flags) {
TCPiopb iopb; TCPiopb iopb;
OSErr err; OSErr err;
int avail, want, got; int avail, want, got;
memcpy(&iopb, &sock->iopb, sizeof(TCPiopb)); 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; iopb.csCode = TCPStatus;
memset(&sock->iopb.csParam, 0, sizeof(sock->iopb.csParam));
err = PBControlSync((ParmBlkPtr)&iopb); err = PBControlSync((ParmBlkPtr)&iopb);
if (err != noErr) if (err != noErr)
return 0; /* macnet_asr should catch it anyway */ 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) if (avail == 0)
return 0; return 0;
want = avail < buflen ? avail : buflen; want = avail < buflen ? avail : buflen;
iopb.ioCompletion = NULL;
iopb.csCode = TCPRcv; iopb.csCode = TCPRcv;
memset(&sock->iopb.csParam, 0, sizeof(sock->iopb.csParam));
iopb.csParam.receive.rcvBuff = buf; iopb.csParam.receive.rcvBuff = buf;
iopb.csParam.receive.rcvBuffLen = want; iopb.csParam.receive.rcvBuffLen = want;
err = PBControlSync((ParmBlkPtr)&iopb); err = PBControlSync((ParmBlkPtr)&iopb);
@ -440,6 +496,7 @@ void net_close(Socket *sock) {
* free it, which we can't do at interrupt time). * free it, which we can't do at interrupt time).
*/ */
memcpy(&sock->spareiopb, &sock->iopb, sizeof(TCPiopb)); 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.ioCompletion = macnet_completed_close_upp;
sock->spareiopb.csCode = TCPClose; sock->spareiopb.csCode = TCPClose;
sock->spareiopb.csParam.close.validityFlags = 0; 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; Socket *sock = (Socket *)iopb->csParam.close.userDataPtr;
#if !TARGET_RT_CFM
long olda5; long olda5;
olda5 = SetA5(sock->a5); olda5 = SetA5(sock->a5);
macnet_completed_close(iopb);
SetA5(olda5);
}
#endif #endif
static void macnet_completed_close(TCPiopb* iopb) {
Socket *sock = (Socket *)iopb->csParam.close.userDataPtr;
switch (iopb->ioResult) { switch (iopb->ioResult) {
case noErr: case noErr:
macnet_sendevent(sock, NE_CLOSED); macnet_sendevent(sock, NE_CLOSED);
@ -474,9 +538,6 @@ static void macnet_completed_close(TCPiopb* iopb) {
macnet_sendevent(sock, NE_DIED); macnet_sendevent(sock, NE_DIED);
break; 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. * synchronous, so we can allocate this one dynamically.
*/ */
memcpy(&iopb, &sock->iopb, sizeof(TCPiopb)); memcpy(&iopb, &sock->iopb, sizeof(TCPiopb));
iopb.ioCompletion = NULL;
iopb.csCode = TCPRelease; iopb.csCode = TCPRelease;
memset(&iopb.csParam, 0, sizeof(iopb.csParam));
err = PBControlSync((ParmBlkPtr)&iopb); err = PBControlSync((ParmBlkPtr)&iopb);
sfree(iopb.csParam.create.rcvBuff); sfree(iopb.csParam.create.rcvBuff);
sfree(sock); sfree(sock);
@ -503,7 +566,7 @@ static void macnet_sendevent(Socket *sock, Net_Event_Type type) {
NetEvent *ne; NetEvent *ne;
ne = (NetEvent *)macnet_freeq.qHead; 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); Dequeue(&ne->qelem, &macnet_freeq);
ne->sock = sock; ne->sock = sock;
ne->type = type; ne->type = type;

View File

@ -9,6 +9,10 @@
#include "putty.h" #include "putty.h"
#ifdef macintosh
#pragma segment Telnet
#endif
static SOCKET s = INVALID_SOCKET; static SOCKET s = INVALID_SOCKET;
/* kludge till we decide where to put telnet state */ /* kludge till we decide where to put telnet state */
static Session *sess; static Session *sess;
@ -479,6 +483,10 @@ static char *telnet_init (Session *this_sess) {
sess = this_sess; sess = this_sess;
s = net_open(sess, sess->cfg.host, sess->cfg.port); s = net_open(sess, sess->cfg.host, sess->cfg.port);
return NULL;
}
static void telnet_opened(Session *sess) {
/* /*
* Initialise option states. * Initialise option states.
*/ */
@ -496,8 +504,6 @@ static char *telnet_init (Session *this_sess) {
*/ */
in_synch = FALSE; in_synch = FALSE;
#endif #endif
return NULL;
} }
/* /*
@ -512,6 +518,9 @@ static int telnet_msg (Session *sess, SOCKET sock, Net_Event_Type ne) {
return -5000; return -5000;
switch (ne) { switch (ne) {
case NE_OPEN:
telnet_opened(sess);
return 1;
case NE_DATA: case NE_DATA:
ret = net_recv(s, buf, sizeof(buf), 0); ret = net_recv(s, buf, sizeof(buf), 0);
if (ret < 0) /* any _other_ error */ 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: case NE_CLOSING:
s = INVALID_SOCKET; s = INVALID_SOCKET;
return 0; 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 */ return 1; /* shouldn't happen, but WTF */
} }