Skip to content

Commit

Permalink
Working on a remote Nu command handler, importing AGSocket.
Browse files Browse the repository at this point in the history
  • Loading branch information
Tim Burks committed Apr 23, 2008
1 parent fdd1e4d commit 4ab2486
Show file tree
Hide file tree
Showing 22 changed files with 1,931 additions and 8 deletions.
6 changes: 3 additions & 3 deletions NuNetwork/Nukefile → NuBonjour/Nukefile
Expand Up @@ -2,12 +2,12 @@
(set @m_files (filelist "^objc/.*.m$"))
(set @nu_files (filelist "^nu/.*nu$"))

(set @cflags "-g -DDARWIN")
(set @cflags "-g -DDARWIN -Iobjc")
(set @ldflags "-framework Foundation -framework Nu -levent")

;; framework description
(set @framework "NuNetwork")
(set @framework_identifier "nu.programming.nunetwork")
(set @framework "NuBonjour")
(set @framework_identifier "nu.programming.nubonjour")
(set @framework_creator_code "????")

(compilation-tasks)
Expand Down
34 changes: 34 additions & 0 deletions NuBonjour/SocketTest.m
@@ -0,0 +1,34 @@
// SocketTest.m
//
// Copyright (c) 2002 Aram Greenman. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
// 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#import <Foundation/Foundation.h>
#import <AGSocket/AGSocket.h>
#import "SocketTestDelegate.h"

int main(int argc, const char *argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

if (argc != 2) {
NSLog(@"Usage: %s url", argv[0]);
exit(1);
}

NSURL *url = [NSURL URLWithString:[NSString stringWithUTF8String:argv[1]]];

SocketTestDelegate *test = [[SocketTestDelegate alloc] initWithURL:url];

[[NSRunLoop currentRunLoop] run];

[test release];
[pool release];
return 0;
}
24 changes: 24 additions & 0 deletions NuBonjour/SocketTestDelegate.h
@@ -0,0 +1,24 @@
// SocketTestDelegate.h
//
// Copyright (c) 2002 Aram Greenman. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
// 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#import <Foundation/NSObject.h>

@class AGSocket, NSMutableData, NSURL;

@interface SocketTestDelegate : NSObject {
AGSocket *socket;
NSMutableData *request;
}

- (id)initWithURL:(NSURL *)url;

@end
81 changes: 81 additions & 0 deletions NuBonjour/SocketTestDelegate.m
@@ -0,0 +1,81 @@
// SocketTestDelegate.m
//
// Copyright (c) 2002 Aram Greenman. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
// 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#import "SocketTestDelegate.h"
#import <Foundation/Foundation.h>
#import <AGSocket/AGSocket.h>

@implementation SocketTestDelegate

- (id)initWithURL:(NSURL *)url {
if (self = [super init]) {
socket = [[AGSocket tcpSocket] retain];
[socket setDelegate:self];

NSString *host = [url host];
NSNumber *port = [url port];
AGInetSocketAddress *addr = [AGInetSocketAddress addressWithHostname:host ? host : @"localhost" port:htons(port ? [port unsignedShortValue] : 80)];

if (!addr) {
[self release];
return nil;
}

[socket connectToAddressInBackground:addr];

request = [[NSMutableData alloc] initWithData:[[NSString stringWithFormat:@"GET %@ HTTP/1.0\r\n\r\n", url] dataUsingEncoding:NSUTF8StringEncoding]];
}
return self;
}

- (void)dealloc {
[socket release];
[request release];
[super dealloc];
}


- (void)socketConnected:(AGSocket *)sock {
NSLog(@"Connected");
}

- (void)socketConnectFailed:(AGSocket *)sock {
NSLog(@"Connect failed: %s", strerror([socket error]));
[socket close];
}

- (void)socketBecameReadable:(AGSocket *)sock {
NSData *data;
NS_DURING
data = [socket readData];
NS_HANDLER
NSLog([localException description]);
[socket close];
NS_ENDHANDLER
[[NSFileHandle fileHandleWithStandardOutput] writeData:data];
if (![data length])
[socket close];
}

- (void)socketBecameWritable:(AGSocket *)sock {
if (![request length])
return;
NS_DURING
NSData *dataLeft = [socket writeData:request];
[request setData:dataLeft];
NS_HANDLER
NSLog([localException description]);
[socket close];
NS_ENDHANDLER
}

@end
153 changes: 153 additions & 0 deletions NuBonjour/objc/AGInet6SocketAddress.m
@@ -0,0 +1,153 @@
// AGInet6SocketAddress.m
//
// Copyright (c) 2002 Aram Greenman. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
// 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#import <AGSocket/AGInet6SocketAddress.h>
#import <Foundation/Foundation.h>
#include <arpa/inet.h>
#include <netdb.h>

@implementation AGInet6SocketAddress

+ (NSString *)stringForHostAddress:(const uint8_t *)host {
char buf[INET6_ADDRSTRLEN];
struct in6_addr addr;
memcpy(addr.s6_addr, host, sizeof(addr.s6_addr));
if (!inet_ntop(AF_INET6, &addr, buf, INET6_ADDRSTRLEN))
return nil;
return [NSString stringWithUTF8String:buf];
}

+ (NSArray *)addressesForHostname:(NSString *)name port:(uint16_t)port {
NSMutableArray *addrs = [NSMutableArray array];
struct hostent *hent;
if (!(hent = gethostbyname2([name UTF8String], AF_INET6)))
return addrs;
int i;
for (i = 0; hent->h_addr_list[i]; i++)
[addrs addObject:[self addressWithHostAddress:((struct in6_addr *)hent->h_addr_list[i])->s6_addr port:port]];
return addrs;
}

+ (id)addressWithHostname:(NSString *)name port:(uint16_t)port {
return [[[self alloc] initWithHostname:name port:port] autorelease];
}

+ (id)addressWithHostAddress:(const uint8_t *)host port:(uint16_t)port {
return [[[self alloc] initWithHostAddress:host port:port] autorelease];
}

+ (id)addressWithInet6SocketAddress:(const struct sockaddr_in6 *)addr {
return [[[self alloc] initWithInet6SocketAddress:addr] autorelease];
}

- (id)initWithHostname:(NSString *)name port:(uint16_t)port {
struct hostent *hent;
if (!(hent = gethostbyname2([name UTF8String], AF_INET6))) {
[self release];
return nil;
}
return [self initWithHostAddress:((struct in6_addr *)hent->h_addr)->s6_addr port:port];
}

- (id)initWithHostAddress:(const uint8_t *)host port:(uint16_t)port {
struct sockaddr_in6 addr;
memset(&addr, 0, sizeof(struct sockaddr_in6));
addr.sin6_family = AF_INET6;
addr.sin6_port = port;
memcpy(addr.sin6_addr.s6_addr, host, sizeof(addr.sin6_addr.s6_addr));
return [self initWithInet6SocketAddress:&addr];
}

- (id)initWithInet6SocketAddress:(const struct sockaddr_in6 *)addr {
if (self = [super init])
[self setInet6SocketAddress:addr];
return self;
}

- (id)init {
return [self initWithHostAddress:in6addr_any.s6_addr port:0];
}

- (const uint8_t *)hostAddress {
return address.sin6_addr.s6_addr;
}

- (const struct sockaddr_in6 *)inet6SocketAddress {
return &address;
}

- (uint16_t)port {
return address.sin6_port;
}

- (void)setHostAddress:(const uint8_t *)host {
memcpy(address.sin6_addr.s6_addr, host, sizeof(address.sin6_addr.s6_addr));
}

- (void)setInet6SocketAddress:(const struct sockaddr_in6 *)addr {
memcpy(&address, addr, sizeof(struct sockaddr_in6));
}

- (void)setPort:(uint16_t)port {
address.sin6_port = port;
}

- (NSString *)hostname {
struct hostent *hent;
struct in6_addr addr;
memcpy(addr.s6_addr, [self hostAddress], sizeof(addr.s6_addr));
if (!(hent = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET6)))
return nil;
return [NSString stringWithUTF8String:hent->h_name];
}

- (NSArray *)aliases {
NSMutableArray *aliases = [NSMutableArray array];
struct hostent *hent;
struct in6_addr addr;
memcpy(addr.s6_addr, [self hostAddress], sizeof(addr.s6_addr));
if (!(hent = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET6)))
return aliases;
int i;
for (i = 0; hent->h_aliases[i]; i++)
[aliases addObject:[NSString stringWithUTF8String:hent->h_aliases[i]]];
return aliases;
}

- (void)setSocketAddress:(const struct sockaddr *)addr length:(unsigned)len {
if (addr->sa_family != AF_INET6)
[NSException raise:NSInvalidArgumentException format:@"invalid address family"];
[self setInet6SocketAddress:(struct sockaddr_in6 *)addr];
}

- (const struct sockaddr *)socketAddress {
return (struct sockaddr *)&address;
}

- (unsigned)length {
return sizeof(struct sockaddr_in6);
}

- (NSString *)description {
return [NSString stringWithFormat:@"%@ {\n\
address = %@,\n\
port = %u,\n\
hostname = %@,\n\
aliases = %@\n\
}",
[super description],
[[self class] stringForHostAddress:[self hostAddress]], ntohs([self port]),
[self hostname],
[self aliases]];
}

@end

0 comments on commit 4ab2486

Please sign in to comment.