From d25f9823be478b4b8eab34f016f85122525b2bed Mon Sep 17 00:00:00 2001 From: ben Date: Sun, 5 Jan 2003 12:53:38 +0000 Subject: [PATCH] Add reception support for MacTCP. Now I can log in over TELNET, just about. There are still lots of things to fix, like urgent data or the fact that everything seems to happen one keypress too late, but this is an important milestone. git-svn-id: svn://svn.tartarus.org/sgt/putty@2458 cda61777-01e9-0310-a592-d414129be87e --- mac/README.mac | 3 +- mac/mac.c | 3 +- mac/mac.h | 1 + mac/mtcpnet.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 87 insertions(+), 10 deletions(-) diff --git a/mac/README.mac b/mac/README.mac index a0c57ccc..7a305c67 100644 --- a/mac/README.mac +++ b/mac/README.mac @@ -1,4 +1,4 @@ -$Id: README.mac,v 1.7 2003/01/02 18:09:21 ben Exp $ +$Id: README.mac,v 1.8 2003/01/05 12:53:38 ben Exp $ Information about PuTTY for the Mac OS -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= @@ -54,6 +54,7 @@ Known bugs: Features we need (and aren't entirely obvious): + * TCP urgent data. * Scroll-conflation -- scroll_display should change the in-memory display and remember the scroll, then do_scroll should be called only when scroll_display gets called for a different rectangle or diff --git a/mac/mac.c b/mac/mac.c index 8aac2ad3..9c1abdf8 100644 --- a/mac/mac.c +++ b/mac/mac.c @@ -1,4 +1,4 @@ -/* $Id: mac.c,v 1.18 2003/01/05 10:52:56 ben Exp $ */ +/* $Id: mac.c,v 1.19 2003/01/05 12:53:38 ben Exp $ */ /* * Copyright (c) 1999 Ben Harris * All rights reserved. @@ -213,6 +213,7 @@ static void mac_eventloop(void) { mac_adjustcursor(cursrgn); if (gotevent) mac_event(&event); + mactcp_poll(); } DisposeRgn(cursrgn); } diff --git a/mac/mac.h b/mac/mac.h index a784a284..19e42dd6 100644 --- a/mac/mac.h +++ b/mac/mac.h @@ -88,6 +88,7 @@ extern void init_ucs(void); /* from mtcpnet.c */ extern OSErr mactcp_init(void); extern void mactcp_shutdown(void); +extern void mactcp_poll(void); #endif diff --git a/mac/mtcpnet.c b/mac/mtcpnet.c index cf38417e..d057dc4f 100644 --- a/mac/mtcpnet.c +++ b/mac/mtcpnet.c @@ -37,6 +37,7 @@ #include +#define DEFINE_PLUG_METHOD_MACROS #include "putty.h" #include "network.h" #include "mac.h" @@ -161,6 +162,8 @@ struct Socket_tag { int oobinline; int pending_error; /* in case send() returns error */ int listener; + struct Socket_tag *next; + struct Socket_tag **prev; }; /* @@ -184,6 +187,7 @@ static struct { Handle dnr_handle; int initialised; short refnum; + Actual_Socket socklist; } mactcp; static pascal void mactcp_lookupdone(struct hostInfo *hi, char *cookie); @@ -197,6 +201,8 @@ static void *mactcp_get_private_ptr(Socket); static char *mactcp_socket_error(Socket); static void mactcp_set_frozen(Socket, int); +static void mactcp_recv(Actual_Socket s, size_t len); + /* * Initialise MacTCP. * This should be called once before any TCP connection is opened. @@ -287,11 +293,16 @@ void sk_getaddr(SockAddr addr, char *buf, int buflen) char mybuf[16]; OSErr err; - /* XXX only return first address */ - err = AddrToStr(addr->hostinfo.addr[0], mybuf); - buf[0] = '\0'; - if (err != noErr) - strncat(buf, mybuf, buflen - 1); + if (addr->resolved) { + /* XXX only return first address */ + err = AddrToStr(addr->hostinfo.addr[0], mybuf); + buf[0] = '\0'; + if (err != noErr) + strncat(buf, mybuf, buflen - 1); + } else { + buf[0] = '\0'; + strncat(buf, addr->hostname, buflen - 1); + } } /* I think "local" here really means "loopback" */ @@ -387,6 +398,7 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline, ret->frozen_readable = 0; ret->localhost_only = 0; /* unused, but best init anyway */ ret->pending_error = 0; + ret->oobinline = oobinline; ret->oobpending = FALSE; ret->listener = 0; @@ -451,6 +463,11 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline, ret->connected = TRUE; ret->writable = TRUE; + /* Add this to the list of all sockets */ + ret->next = mactcp.socklist; + ret->prev = &mactcp.socklist; + mactcp.socklist = ret; + fprintf(stderr, "Socket connected\n"); return (Socket)ret; } @@ -488,6 +505,12 @@ static void mactcp_close(Socket sock) s->err = PBControlSync((ParmBlkPtr)&pb); if (s->err == noErr) sfree(pb.csParam.create.rcvBuff); + + /* Unhitch from list of sockets */ + *s->prev = s->next; + if (s->next != NULL) + s->next->prev = s->prev; + sfree(s); } @@ -497,8 +520,6 @@ static int mactcp_write(Socket sock, char *buf, int len) wdsEntry wds[2]; TCPiopb pb; - fprintf(stderr, "Write data, %d bytes\n", len); - wds[0].length = len; wds[0].ptr = buf; wds[1].length = 0; @@ -522,6 +543,56 @@ static int mactcp_write_oob(Socket sock, char *buf, int len) } /* + * Called from our event loop if there's work to do. + */ +void mactcp_poll(void) +{ + Actual_Socket s; + TCPiopb pb; + + for (s = mactcp.socklist; s != NULL; s = s->next) { + /* XXX above can't handle sockets being deleted. */ + pb.ioCRefNum = mactcp.refnum; + pb.csCode = TCPStatus; + pb.tcpStream = s->s; + pb.csParam.status.userDataPtr = (Ptr)s; + s->err = PBControlSync((ParmBlkPtr)&pb); + if (s->err != noErr) + continue; + if (pb.csParam.status.amtUnreadData > 0) + mactcp_recv(s, pb.csParam.status.amtUnreadData); + /* Should check connectionState in case remote has closed */ + } +} + +static void mactcp_recv(Actual_Socket s, size_t len) +{ + rdsEntry rds[2]; + TCPiopb pb; + + if (s->frozen) return; + + while (len > 0) { + pb.ioCRefNum = mactcp.refnum; + pb.csCode = TCPNoCopyRcv; + pb.tcpStream = s->s; + pb.csParam.receive.commandTimeoutValue = 0; + pb.csParam.receive.rdsPtr = (Ptr)rds; + pb.csParam.receive.rdsLength = lenof(rds) - 1; + pb.csParam.receive.userDataPtr = (Ptr)s; + s->err = PBControlSync((ParmBlkPtr)&pb); + if (s->err != noErr) + return; + plug_receive(s->plug, 0, rds[0].ptr, rds[0].length); + len -= rds[0].length; + pb.csCode = TCPRcvBfrReturn; + s->err = PBControlSync((ParmBlkPtr)&pb); + if (s->err != noErr) + return; + } +} + +/* * Each socket abstraction contains a `void *' private field in * which the client can keep state. */ @@ -589,8 +660,11 @@ static char *mactcp_socket_error(Socket sock) static void mactcp_set_frozen(Socket sock, int is_frozen) { + Actual_Socket s = (Actual_Socket) sock; - fatalbox("mactcp_set_frozen"); + if (s->frozen == is_frozen) + return; + s->frozen = is_frozen; } /* -- 2.11.0