X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/27a3458f34afd8c533f33d980228acd2f7eef856..4fa38586e9af919db6853d0436ea96478bdec477:/mac/otnet.c diff --git a/mac/otnet.c b/mac/otnet.c index b4314785..eb24b85c 100644 --- a/mac/otnet.c +++ b/mac/otnet.c @@ -5,6 +5,8 @@ #include #include +#include + #define DEFINE_PLUG_METHOD_MACROS #include "putty.h" #include "network.h" @@ -13,7 +15,7 @@ struct Socket_tag { struct socket_function_table *fn; /* other stuff... */ - char *error; + OSStatus error; EndpointRef ep; Plug plug; void *private_ptr; @@ -37,19 +39,27 @@ struct Socket_tag { typedef struct Socket_tag *Actual_Socket; struct SockAddr_tag { - char *error; - DNSAddress address; + int resolved; + OSStatus error; + InetHostInfo hostinfo; + char hostname[512]; }; /* Globals */ static struct { Actual_Socket socklist; + InetSvcRef inetsvc; } ot; OSErr ot_init(void) { - return InitOpenTransport(); + OSStatus err; + + err = InitOpenTransport(); + if (err != kOTNoError) return err; + ot.inetsvc = OTOpenInternetServices(kDefaultInternetServicesPath, 0, &err); + return err; } void ot_cleanup(void) @@ -64,36 +74,47 @@ void ot_cleanup(void) CloseOpenTransport(); } -static char *error_string(int error) -{ - return "An error..."; -} - -SockAddr ot_namelookup(char *host, char **canonicalname) +SockAddr ot_namelookup(char const *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); + char *realhost; + + /* Casting away const -- hope OTInetStringToAddress is sensible */ + ret->error = OTInetStringToAddress(ot.inetsvc, (char *)host, + &ret->hostinfo); + ret->resolved = TRUE; + + if (ret->error == kOTNoError) + realhost = ret->hostinfo.name; + else + realhost = ""; + *canonicalname = smalloc(1+strlen(realhost)); + strcpy(*canonicalname, realhost); return ret; } -SockAddr ot_nonamelookup(char *host) +SockAddr ot_nonamelookup(char const *host) { SockAddr ret = smalloc(sizeof(struct SockAddr_tag)); - OTInitDNSAddress(&(ret->address), host); - + ret->resolved = FALSE; + ret->error = kOTNoError; + ret->hostname[0] = '\0'; + strncat(ret->hostname, host, lenof(ret->hostname) - 1); return ret; } void ot_getaddr(SockAddr addr, char *buf, int buflen) { - strncpy(buf, (addr->address).fName, buflen); + char mybuf[16]; + + buf[0] = '\0'; + if (addr->resolved) { + /* XXX only return first address */ + OTInetHostToString(addr->hostinfo.addrs[0], mybuf); + strncat(buf, mybuf, buflen - 1); + } else + strncat(buf, addr->hostname, buflen - 1); } /* I think "local" here really means "loopback" */ @@ -106,19 +127,28 @@ int ot_hostname_is_local(char *name) int ot_address_is_local(SockAddr addr) { + int i; - /* FIXME */ + if (addr->resolved) + for (i = 0; i < kMaxHostAddrs; i++) + if (addr->hostinfo.addrs[i] & 0xff000000 == 0x7f000000) + return TRUE; return FALSE; } int ot_addrtype(SockAddr addr) { - return ADDRTYPE_IPV4; + + if (addr->resolved) + return ADDRTYPE_IPV4; + return ADDRTYPE_NAME; } void ot_addrcopy(SockAddr addr, char *buf) { - + + /* XXX only return first address */ + memcpy(buf, &addr->hostinfo.addrs[0], 4); } void ot_addr_free(SockAddr addr) @@ -172,7 +202,7 @@ Socket ot_register(void *sock, Plug plug) ret = smalloc(sizeof(struct Socket_tag)); ret->fn = &fn_table; - ret->error = NULL; + ret->error = kOTNoError; ret->plug = plug; bufchain_init(&ret->output_data); ret->writable = 1; /* to start with */ @@ -216,11 +246,12 @@ Socket ot_new(SockAddr addr, int port, int privport, int oobinline, Actual_Socket ret; EndpointRef ep; OSStatus err; + InetAddress dest; TCall connectCall; ret = smalloc(sizeof(struct Socket_tag)); ret->fn = &fn_table; - ret->error = NULL; + ret->error = kOTNoError; ret->plug = plug; bufchain_init(&ret->output_data); ret->connected = 0; /* to start with */ @@ -241,7 +272,7 @@ Socket ot_new(SockAddr addr, int port, int privport, int oobinline, ret->ep = ep; if (err) { - ret->error = error_string(err); + ret->error = err; return (Socket) ret; } @@ -256,7 +287,7 @@ Socket ot_new(SockAddr addr, int port, int privport, int oobinline, err = OTBind(ep, NULL, NULL); /* OpenTransport always picks our address */ if (err) { - ret->error = error_string(err); + ret->error = err; return (Socket) ret; } @@ -264,16 +295,17 @@ Socket ot_new(SockAddr addr, int port, int privport, int oobinline, * Connect to remote address. */ - /* FIXME: bolt the port onto the end */ + /* XXX Try non-primary addresses */ + OTInitInetAddress(&dest, port, addr->hostinfo.addrs[0]); - OTMemzero(&connectCall, sizeof(TCall)); - connectCall.addr.buf = (UInt8 *) &(addr->address); - connectCall.addr.len = sizeof(DNSAddress); + memset(&connectCall, 0, sizeof(TCall)); + connectCall.addr.buf = (UInt8 *) &dest; + connectCall.addr.len = sizeof(dest); err = OTConnect(ep, &connectCall, nil); if (err) { - ret->error = error_string(err); + ret->error = err; return (Socket) ret; } else { ret->connected = 1; @@ -283,6 +315,8 @@ Socket ot_new(SockAddr addr, int port, int privport, int oobinline, /* Add this to the list of all sockets */ ret->next = ot.socklist; ret->prev = &ot.socklist; + if (ret->next != NULL) + ret->next->prev = &ret->next; ot.socklist = ret; return (Socket) ret; @@ -374,12 +408,22 @@ static void *ot_tcp_get_private_ptr(Socket sock) */ char *ot_addr_error(SockAddr addr) { - return addr->error; + static char buf[128]; + + if (addr->error == kOTNoError) + return NULL; + sprintf(buf, "error %d", addr->error); + return buf; } static char *ot_tcp_socket_error(Socket sock) { Actual_Socket s = (Actual_Socket) sock; - return s->error; + static char buf[128]; + + if (s->error == kOTNoError) + return NULL; + sprintf(buf, "error %d", s->error); + return buf; } static void ot_tcp_set_frozen(Socket sock, int is_frozen) @@ -422,9 +466,13 @@ void ot_recv(Actual_Socket s) if (s->frozen) return; - while ((o = OTRcv(s->ep, buf, sizeof(buf), &flags)) != kOTNoDataErr) { - plug_receive(s->plug, 0, buf, sizeof(buf)); - } + do { + o = OTRcv(s->ep, buf, sizeof(buf), &flags); + if (o > 0) + plug_receive(s->plug, 0, buf, o); + if (o < 0 && o != kOTNoDataErr) + plug_closing(s->plug, NULL, 0, 0); /* XXX Error msg */ + } while (o > 0); }