Initial import of Owen's OpenTransport interface. It doesn't work yet, but
authorben <ben@cda61777-01e9-0310-a592-d414129be87e>
Sat, 11 Jan 2003 23:33:57 +0000 (23:33 +0000)
committerben <ben@cda61777-01e9-0310-a592-d414129be87e>
Sat, 11 Jan 2003 23:33:57 +0000 (23:33 +0000)
it does compile and link.

git-svn-id: svn://svn.tartarus.org/sgt/putty@2547 cda61777-01e9-0310-a592-d414129be87e

Recipe
mac/mac.c
mac/mac.h
mac/macnet.c
mac/mtcpnet.c
mac/otnet.c [new file with mode: 0644]
mkfiles.pl

diff --git a/Recipe b/Recipe
index deb9681..c838451 100644 (file)
--- a/Recipe
+++ b/Recipe
@@ -111,7 +111,7 @@ SFTP     = sftp int64 logging
 WINMISC  = misc version winstore settings tree234 winnet proxy cmdline
          + windefs winmisc
 UXMISC   = misc version uxstore settings tree234 uxnet proxy cmdline
-MACMISC  = misc version macstore settings tree234 macnet mtcpnet proxy
+MACMISC  = misc version macstore settings tree234 macnet mtcpnet otnet proxy
 
 # Character set library, for use in pterm.
 CHARSET  = sbcsdat slookup sbcs utf8 toucs fromucs xenc mimeenc macenc
index 632b6a4..76ba435 100644 (file)
--- a/mac/mac.c
+++ b/mac/mac.c
@@ -1,4 +1,4 @@
-/* $Id: mac.c,v 1.24 2003/01/11 19:43:59 ben Exp $ */
+/* $Id: mac.c,v 1.25 2003/01/11 23:33:57 ben Exp $ */
 /*
  * Copyright (c) 1999 Ben Harris
  * All rights reserved.
@@ -169,13 +169,21 @@ static void mac_startup(void) {
        mac_gestalts.uncvattr = (*ti)->tecUnicodeConverterFeatures;
        DisposeHandle((Handle)ti);
     }
-    /* MacTCP? */
-    if (Gestalt(FOUR_CHAR_CODE('mtcp'), &mac_gestalts.mtcpvers) != noErr)
-       mac_gestalts.mtcpvers = 0;
-    if (mac_gestalts.mtcpvers > 0) {
-       if (mactcp_init() != noErr)
+    /* OpenTransport? */
+    if (Gestalt(gestaltOpenTpt, &mac_gestalts.otptattr) != noErr ||
+       (mac_gestalts.otptattr & gestaltOpenTptTCPPresentMask) == 0 ||
+       ot_init() != noErr)
+       mac_gestalts.otptattr = 0;
+    if (mac_gestalts.otptattr == 0) {
+       /* MacTCP? */
+       if (Gestalt(FOUR_CHAR_CODE('mtcp'), &mac_gestalts.mtcpvers) != noErr)
            mac_gestalts.mtcpvers = 0;
-    }
+       if (mac_gestalts.mtcpvers > 0) {
+           if (mactcp_init() != noErr)
+               mac_gestalts.mtcpvers = 0;
+       }
+    } else
+       mac_gestalts.mtcpvers = 0;
 
     /* We've been tested with the Appearance Manager */
     if (mac_gestalts.apprvers != 0)
@@ -623,8 +631,7 @@ void cleanup_exit(int status)
     if (mac_gestalts.encvvers != 0)
        TerminateUnicodeConverter();
 #endif
-    if (mac_gestalts.mtcpvers != 0)
-       mactcp_shutdown();
+    sk_cleanup();
     exit(status);
 }
 
index d0db75e..88b02cd 100644 (file)
--- a/mac/mac.h
+++ b/mac/mac.h
@@ -24,6 +24,7 @@ struct mac_gestalts {
     long encvvers; /* TEC version (from TECGetInfo()) */
     long uncvattr; /* Unicode Converter attributes (frem TECGetInfo()) */
     long mtcpvers;
+    long otptattr;
 };
 
 extern struct mac_gestalts mac_gestalts;
@@ -94,7 +95,7 @@ extern void *open_settings_r_fsp(FSSpec *);
 extern void init_ucs(void);
 /* from mtcpnet.c */
 extern OSErr mactcp_init(void);
-extern void mactcp_shutdown(void);
+extern void mactcp_cleanup(void);
 extern void mactcp_poll(void);
 extern SockAddr mactcp_namelookup(char *, char **);
 extern SockAddr mactcp_nonamelookup(char *);
@@ -108,6 +109,22 @@ extern Socket mactcp_register(void *, Plug);
 extern Socket mactcp_new(SockAddr addr, int, int, int, int, Plug);
 extern Socket mactcp_newlistener(char *, int, Plug, int);
 extern char *mactcp_addr_error(SockAddr);
+/* from otnet.c */
+extern OSErr ot_init(void);
+extern void ot_cleanup(void);
+extern void ot_poll(void);
+extern SockAddr ot_namelookup(char *, char **);
+extern SockAddr ot_nonamelookup(char *);
+extern void ot_getaddr(SockAddr, char *, int);
+extern int ot_hostname_is_local(char *);
+extern int ot_address_is_local(SockAddr);
+extern int ot_addrtype(SockAddr);
+extern void ot_addrcopy(SockAddr, char *);
+extern void ot_addr_free(SockAddr);
+extern Socket ot_register(void *, Plug);
+extern Socket ot_new(SockAddr addr, int, int, int, int, Plug);
+extern Socket ot_newlistener(char *, int, Plug, int);
+extern char *ot_addr_error(SockAddr);
 
 #endif
 
index 88a5cab..d3044dd 100644 (file)
@@ -9,7 +9,9 @@
 SockAddr sk_namelookup(char *host, char **canonicalname)
 {
 
-    if (mac_gestalts.mtcpvers != 0)
+    if (mac_gestalts.otptattr != 0)
+       return ot_namelookup(host, canonicalname);
+    else if (mac_gestalts.mtcpvers != 0)
        return mactcp_namelookup(host, canonicalname);
     else
        return NULL;
@@ -18,7 +20,9 @@ SockAddr sk_namelookup(char *host, char **canonicalname)
 SockAddr sk_nonamelookup(char *host)
 {
 
-    if (mac_gestalts.mtcpvers != 0)
+    if (mac_gestalts.otptattr != 0)
+       return ot_nonamelookup(host);
+    else if (mac_gestalts.mtcpvers != 0)
        return mactcp_nonamelookup(host);
     else
        return NULL;
@@ -27,7 +31,9 @@ SockAddr sk_nonamelookup(char *host)
 void sk_getaddr(SockAddr addr, char *buf, int buflen)
 {
 
-    if (mac_gestalts.mtcpvers != 0)
+    if (mac_gestalts.otptattr != 0)
+       ot_getaddr(addr, buf, buflen);
+    else if (mac_gestalts.mtcpvers != 0)
        mactcp_getaddr(addr, buf, buflen);
     else
        *buf = '\0';
@@ -36,7 +42,9 @@ void sk_getaddr(SockAddr addr, char *buf, int buflen)
 int sk_hostname_is_local(char *name)
 {
 
-    if (mac_gestalts.mtcpvers != 0)
+    if (mac_gestalts.otptattr != 0)
+       return ot_hostname_is_local(name);
+    else if (mac_gestalts.mtcpvers != 0)
        return mactcp_hostname_is_local(name);
     else
        return 0;
@@ -45,7 +53,9 @@ int sk_hostname_is_local(char *name)
 int sk_address_is_local(SockAddr addr)
 {
 
-    if (mac_gestalts.mtcpvers != 0)
+    if (mac_gestalts.otptattr != 0)
+       return ot_address_is_local(addr);
+    else if (mac_gestalts.mtcpvers != 0)
        return mactcp_address_is_local(addr);
     else
        return 0;
@@ -54,7 +64,9 @@ int sk_address_is_local(SockAddr addr)
 int sk_addrtype(SockAddr addr)
 {
 
-    if (mac_gestalts.mtcpvers != 0)
+    if (mac_gestalts.otptattr != 0)
+       return ot_addrtype(addr);
+    else if (mac_gestalts.mtcpvers != 0)
        return mactcp_addrtype(addr);
     else
        return 0;
@@ -63,21 +75,27 @@ int sk_addrtype(SockAddr addr)
 void sk_addrcopy(SockAddr addr, char *buf)
 {
 
-    if (mac_gestalts.mtcpvers != 0)
+    if (mac_gestalts.otptattr != 0)
+       ot_addrcopy(addr, buf);
+    else if (mac_gestalts.mtcpvers != 0)
        mactcp_addrcopy(addr, buf);
 }
 
 void sk_addr_free(SockAddr addr)
 {
 
-    if (mac_gestalts.mtcpvers != 0)
+    if (mac_gestalts.otptattr != 0)
+       ot_addr_free(addr);
+    else if (mac_gestalts.mtcpvers != 0)
        mactcp_addr_free(addr);
 }
 
 Socket sk_register(void *sock, Plug plug)
 {
 
-    if (mac_gestalts.mtcpvers != 0)
+    if (mac_gestalts.otptattr != 0)
+       return ot_register(sock, plug);
+    else if (mac_gestalts.mtcpvers != 0)
        return mactcp_register(sock, plug);
     else
        return NULL;
@@ -87,7 +105,9 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
              int nodelay, Plug plug)
 {
 
-    if (mac_gestalts.mtcpvers != 0)
+    if (mac_gestalts.otptattr != 0)
+       return ot_new(addr, port, privport, oobinline, nodelay, plug);
+    else if (mac_gestalts.mtcpvers != 0)
        return mactcp_new(addr, port, privport, oobinline, nodelay, plug);
     else
        return NULL;
@@ -96,7 +116,9 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
 Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only)
 {
 
-    if (mac_gestalts.mtcpvers != 0)
+    if (mac_gestalts.otptattr != 0)
+       return ot_newlistener(srcaddr, port, plug, local_host_only);
+    else if (mac_gestalts.mtcpvers != 0)
        return mactcp_newlistener(srcaddr, port, plug, local_host_only);
     else
        return NULL;
@@ -105,12 +127,23 @@ Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only)
 char *sk_addr_error(SockAddr addr)
 {
 
-    if (mac_gestalts.mtcpvers != 0)
+    if (mac_gestalts.otptattr != 0)
+       return ot_addr_error(addr);
+    else if (mac_gestalts.mtcpvers != 0)
        return mactcp_addr_error(addr);
     else
        return "No TCP/IP stack installed";
 }
 
+void sk_cleanup(void)
+{
+
+    if (mac_gestalts.otptattr != 0)
+       ot_cleanup();
+    else if (mac_gestalts.mtcpvers != 0)
+       mactcp_cleanup();
+}
+
 /*
  * Local Variables:
  * c-file-style: "simon"
index 91b402d..9d40051 100644 (file)
@@ -244,7 +244,7 @@ OSErr mactcp_init(void)
     return noErr;
 }
 
-void mactcp_shutdown(void)
+void mactcp_cleanup(void)
 {
     Actual_Socket s, next;
 
diff --git a/mac/otnet.c b/mac/otnet.c
new file mode 100644 (file)
index 0000000..b431478
--- /dev/null
@@ -0,0 +1,435 @@
+/*
+ * Macintosh OpenTransport networking abstraction
+ */
+
+#include <OpenTransport.h>
+#include <OpenTptInternet.h>
+
+#define DEFINE_PLUG_METHOD_MACROS
+#include "putty.h"
+#include "network.h"
+#include "mac.h"
+
+struct Socket_tag {
+    struct socket_function_table *fn;
+    /* other stuff... */
+    char *error;
+    EndpointRef ep;
+    Plug plug;
+    void *private_ptr;
+    bufchain output_data;
+    int connected;
+    int writable;
+    int frozen; /* this causes readability notifications to be ignored */
+    int frozen_readable; /* this means we missed at least one readability
+                          * notification while we were frozen */
+    int localhost_only;                /* for listening sockets */
+    char oobdata[1];
+    int sending_oob;
+    int oobpending;        /* is there OOB data available to read?*/
+    int oobinline;
+    int pending_error;                 /* in case send() returns error */
+    int listener;
+    struct Socket_tag *next;
+    struct Socket_tag **prev;
+};
+
+typedef struct Socket_tag *Actual_Socket;
+
+struct SockAddr_tag {
+    char *error;
+    DNSAddress address;
+};
+
+/* Globals */
+
+static struct {
+    Actual_Socket socklist;
+} ot;
+
+OSErr ot_init(void)
+{
+    return InitOpenTransport();
+}
+
+void ot_cleanup(void)
+{
+    Actual_Socket s;
+
+    for (s = ot.socklist; s !=NULL; s = s->next) {
+       OTUnbind(s->ep);
+       OTCloseProvider(s->ep);
+    }
+
+    CloseOpenTransport();
+}
+
+static char *error_string(int error)
+{
+    return "An error...";
+}
+
+SockAddr ot_namelookup(char *host, char **canonicalname)
+{
+    SockAddr ret = smalloc(sizeof(struct SockAddr_tag));
+    
+    OTInitDNSAddress(&(ret->address), host);
+  
+    /* for now we'll pretend canonicalname is always just host */
+
+    *canonicalname = smalloc(1+strlen(host));
+    strcpy(*canonicalname, host);
+    return ret;
+}
+
+SockAddr ot_nonamelookup(char *host)
+{
+    SockAddr ret = smalloc(sizeof(struct SockAddr_tag));
+    
+    OTInitDNSAddress(&(ret->address), host);
+  
+    return ret;
+}
+
+void ot_getaddr(SockAddr addr, char *buf, int buflen)
+{
+    strncpy(buf, (addr->address).fName, buflen);
+}
+
+/* I think "local" here really means "loopback" */
+
+int ot_hostname_is_local(char *name)
+{
+
+    return !strcmp(name, "localhost");
+}
+
+int ot_address_is_local(SockAddr addr)
+{
+
+    /* FIXME */
+    return FALSE;
+}
+
+int ot_addrtype(SockAddr addr)
+{
+    return ADDRTYPE_IPV4;
+}
+
+void ot_addrcopy(SockAddr addr, char *buf)
+{
+  
+}
+
+void ot_addr_free(SockAddr addr)
+{
+    sfree(addr);
+}
+
+
+static Plug ot_tcp_plug(Socket sock, Plug p)
+{
+    Actual_Socket s = (Actual_Socket) sock;
+    Plug ret = s->plug;
+    if (p)
+       s->plug = p;
+    return ret;
+}
+
+static void ot_tcp_flush(Socket s)
+{
+    /*
+     * We send data to the socket as soon as we can anyway,
+     * so we don't need to do anything here.  :-)
+     */
+}
+
+static void ot_tcp_close(Socket s);
+static int ot_tcp_write(Socket s, char const *data, int len);
+static int ot_tcp_write_oob(Socket s, char const *data, int len);
+static void ot_tcp_set_private_ptr(Socket s, void *ptr);
+static void *ot_tcp_get_private_ptr(Socket s);
+static void ot_tcp_set_frozen(Socket s, int is_frozen);
+static char *ot_tcp_socket_error(Socket s);
+static void ot_recv(Actual_Socket s);
+void ot_poll(void);
+
+Socket ot_register(void *sock, Plug plug)
+{
+    static struct socket_function_table fn_table = {
+       ot_tcp_plug,
+       ot_tcp_close,
+       ot_tcp_write,
+       ot_tcp_write_oob,
+       ot_tcp_flush,
+       ot_tcp_set_private_ptr,
+       ot_tcp_get_private_ptr,
+       ot_tcp_set_frozen,
+       ot_tcp_socket_error
+    };
+    
+    Actual_Socket ret;
+
+    ret = smalloc(sizeof(struct Socket_tag));
+    ret->fn = &fn_table;
+    ret->error = NULL;
+    ret->plug = plug;
+    bufchain_init(&ret->output_data);
+    ret->writable = 1;                 /* to start with */
+    ret->sending_oob = 0;
+    ret->frozen = 1;
+    ret->frozen_readable = 0;
+    ret->localhost_only = 0;           /* unused, but best init anyway */
+    ret->pending_error = 0;
+    ret->oobpending = FALSE;
+    ret->listener = 0;
+
+    ret->ep = (EndpointRef)sock;
+  
+    /* some sort of error checking */
+
+    ret->oobinline = 0;
+  
+    /* Add this to the list of all sockets */
+    ret->next = ot.socklist;
+    ret->prev = &ot.socklist;
+    ot.socklist = ret;
+
+    return (Socket) ret;
+}
+
+Socket ot_new(SockAddr addr, int port, int privport, int oobinline,
+             int nodelay, Plug plug)
+{
+    static struct socket_function_table fn_table = {
+       ot_tcp_plug,
+       ot_tcp_close,
+       ot_tcp_write,
+       ot_tcp_write_oob,
+       ot_tcp_flush,
+       ot_tcp_set_private_ptr,
+       ot_tcp_get_private_ptr,
+       ot_tcp_set_frozen,
+       ot_tcp_socket_error
+    };
+
+    Actual_Socket ret;
+    EndpointRef ep;
+    OSStatus err;
+    TCall connectCall;
+
+    ret = smalloc(sizeof(struct Socket_tag));
+    ret->fn = &fn_table;
+    ret->error = NULL;
+    ret->plug = plug;
+    bufchain_init(&ret->output_data);
+    ret->connected = 0;                /* to start with */
+    ret->writable = 0;                 /* to start with */
+    ret->sending_oob = 0;
+    ret->frozen = 0;
+    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;
+
+    /* Open Endpoint, configure it for TCP over anything */
+
+    ep = OTOpenEndpoint(OTCreateConfiguration("tcp"), 0, NULL, &err);
+
+    ret->ep = ep;
+
+    if (err) {
+       ret->error = error_string(err);
+       return (Socket) ret;
+    }
+
+    /* TODO: oobinline, nodelay */
+
+    /*
+     * Bind to local address.
+     */
+  
+    /* FIXME: pay attention to privport */
+
+    err = OTBind(ep, NULL, NULL); /* OpenTransport always picks our address */
+
+    if (err) {
+       ret->error = error_string(err);
+       return (Socket) ret;
+    }
+
+    /*
+     * Connect to remote address.
+     */
+
+    /* FIXME: bolt the port onto the end */
+
+    OTMemzero(&connectCall, sizeof(TCall));
+    connectCall.addr.buf = (UInt8 *) &(addr->address);
+    connectCall.addr.len = sizeof(DNSAddress);
+
+    err = OTConnect(ep, &connectCall, nil);
+  
+    if (err) {
+       ret->error = error_string(err);
+       return (Socket) ret;
+    } else {
+       ret->connected = 1;
+       ret->writable = 1;
+    }
+
+    /* Add this to the list of all sockets */
+    ret->next = ot.socklist;
+    ret->prev = &ot.socklist;
+    ot.socklist = ret;
+
+    return (Socket) ret;
+}
+    
+Socket ot_newlistener(char *foobar, int port, Plug plug, int local_host_only)
+{
+    Actual_Socket s;
+
+    return (Socket) s;
+}
+
+static void ot_tcp_close(Socket sock)
+{
+    Actual_Socket s = (Actual_Socket) sock;
+    
+    OTCloseProvider(s->ep);
+
+    /* Unhitch from list of sockets */
+    *s->prev = s->next;
+    if (s->next != NULL)
+       s->next->prev = s->prev;
+
+    sfree(s);
+}
+
+static void try_send(Actual_Socket s)
+{
+    while (bufchain_size(&s->output_data) > 0) {
+       int nsent;
+       void *data;
+       int len;
+
+       /* Don't care about oob right now */
+
+       bufchain_prefix(&s->output_data, &data, &len);
+
+       nsent = OTSnd(s->ep, data, len, 0);
+       noise_ultralight(nsent);
+
+       if (nsent <= 0) {
+           /* something bad happened, hey ho */
+       } else {
+           /* still don't care about oob */
+           bufchain_consume(&s->output_data, nsent);
+       }
+    }
+}
+
+static int ot_tcp_write(Socket sock, char const *buf, int len)
+{
+    Actual_Socket s = (Actual_Socket) sock;
+
+    bufchain_add(&s->output_data, buf, len);
+
+    if (s->writable)
+       try_send(s);
+    return bufchain_size(&s->output_data);
+}
+
+static int ot_tcp_write_oob(Socket sock, char const *buf, int len)
+{
+    /* Don't care about oob */
+    return 0;
+}
+
+
+/*
+ * Each socket abstraction contains a `void *' private field in
+ * which the client can keep state.
+ */
+static void ot_tcp_set_private_ptr(Socket sock, void *ptr)
+{
+    Actual_Socket s = (Actual_Socket) sock;
+    s->private_ptr = ptr;
+}
+
+static void *ot_tcp_get_private_ptr(Socket sock)
+{
+    Actual_Socket s = (Actual_Socket) sock;
+    return s->private_ptr;
+}
+
+
+/*
+ * Special error values are returned from ot_namelookup and ot_new
+ * if there's a problem. These functions extract an error message,
+ * or return NULL if there's no problem.
+ */
+char *ot_addr_error(SockAddr addr)
+{
+    return addr->error;
+}
+static char *ot_tcp_socket_error(Socket sock)
+{
+    Actual_Socket s = (Actual_Socket) sock;
+    return s->error;
+}
+
+static void ot_tcp_set_frozen(Socket sock, int is_frozen)
+{
+    Actual_Socket s = (Actual_Socket) sock;
+
+    if (s->frozen == is_frozen)
+       return;
+    s->frozen = is_frozen;
+}
+
+/*
+ * Poll all our sockets from an event loop
+ */
+
+void ot_poll(void)
+{
+    Actual_Socket s;
+    OTResult o;
+
+    for (s = ot.socklist; s != NULL; s = s->next) {
+       o = OTLook(s->ep);
+
+       switch(o) {
+         case T_DATA: /* Normal Data */
+           ot_recv(s);
+           break;
+         case T_EXDATA: /* Expedited Data (urgent?) */
+           ot_recv(s);
+           break;
+       }
+    }
+}
+
+void ot_recv(Actual_Socket s)
+{
+    OTResult o;
+    char buf[20480];
+    OTFlags flags;
+
+    if (s->frozen) return;
+
+    while ((o = OTRcv(s->ep, buf, sizeof(buf), &flags)) != kOTNoDataErr) {
+       plug_receive(s->plug, 0, buf, sizeof(buf));
+    }
+}
+
+
+/*
+ * Local Variables:
+ * c-file-style: "simon"
+ * End:
+ */
index 74ffc0b..206c39b 100755 (executable)
@@ -622,6 +622,9 @@ Libs_68K =  "{CLibraries}StdCLib.far.o" \xb6
                "{Libraries}MathLib.far.o" \xb6
                "{Libraries}IntEnv.far.o" \xb6
                "{Libraries}Interface.o" \xb6
+               "{Libraries}OpenTransport.o" \xb6
+               "{Libraries}OpenTransportApp.o" \xb6
+               "{Libraries}OpenTptInet.o" \xb6
                "{Libraries}UnicodeConverterLib.far.o"
 
 Libs_CFM =     "{SharedLibraries}InterfaceLib" \xb6
@@ -641,9 +644,17 @@ Libs_PPC = {Libs_CFM} \xb6
                        -weaklib ControlsLib \xb6
                "{SharedLibraries}WindowsLib" \xb6
                        -weaklib WindowsLib \xb6
+               "{SharedLibraries}OpenTransportLib" \xb6
+                       -weaklib OTClientLib \xb6
+                       -weaklib OTClientUtilLib \xb6
+                       -weaklib OTUtilityLib \xb6
+               "{SharedLibraries}OpenTptInternetLib" \xb6
+                       -weaklib OTInetClientLib \xb6
                "{PPCLibraries}StdCRuntime.o" \xb6
                "{PPCLibraries}PPCCRuntime.o" \xb6
-               "{PPCLibraries}CarbonAccessors.o"
+               "{PPCLibraries}CarbonAccessors.o" \xb6
+               "{PPCLibraries}OpenTransportAppPPC.o" \xb6
+               "{PPCLibraries}OpenTptInetPPC.o"
 
 END
 print &splitline("all \xc4 " . join(" ", &progrealnames("M")), undef, "\xb6");