/* call - Program to test NSFileHandle TCP/IP connection. Copyright (C) 2002 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. Written by: Richard Frith-Macdonald Date: Jun 2002 This file is part of the GNUstep Base Library. */ #include GS_EXPORT NSString * const GSTelnetNotification; GS_EXPORT NSString * const GSTelnetErrorKey; GS_EXPORT NSString * const GSTelnetTextKey; @class GSTelnetHandle; @interface Call : NSObject { NSFileHandle *ichan; NSFileHandle *ochan; id remote; NSMutableData *buf; } - (void) didRead: (NSNotification*)notification; - (void) didWrite: (NSNotification*)notification; - (void) gotTelnet: (NSNotification*)notification; @end @implementation Call - (void) dealloc { RELEASE(ichan); RELEASE(ochan); RELEASE(remote); RELEASE(buf); [super dealloc]; } - (void) didRead: (NSNotification*)notification { NSDictionary *userInfo = [notification userInfo]; NSData *d; d = [userInfo objectForKey: NSFileHandleNotificationDataItem]; if (d == nil || [d length] == 0) { NSLog(@"Read EOF"); exit(0); } else { char *ptr; unsigned len; int i; [buf appendData: d]; ptr = [buf mutableBytes]; len = [buf length]; for (i = 0; i < len; i++) { if (ptr[i] == '\n') { NSString *s; if (i > 0 && ptr[i-1] == '\r') { s = [NSString stringWithUTF8String: ptr length: i-1]; } else { s = [NSString stringWithUTF8String: ptr length: i]; } len -= (i + 1); if (len > 0) { memcpy(ptr, &ptr[i+1], len); } [buf setLength: len]; ptr = [buf mutableBytes]; i = -1; [remote putTelnetLine: s]; } } [ichan readInBackgroundAndNotify]; } } - (void) didWrite: (NSNotification*)notification { NSDictionary *userInfo = [notification userInfo]; NSString *e; e = [userInfo objectForKey: GSFileHandleNotificationError]; if (e) { NSLog(@"%@", e); exit(0); } } - (void) gotTelnet: (NSNotification*)notification { NSDictionary *info = [notification userInfo]; NSArray *text; text = [info objectForKey: GSTelnetTextKey]; if (text == nil) { NSLog(@"Lost telnet - %@", [info objectForKey: GSTelnetErrorKey]); exit(0); } else { unsigned i; for (i = 0; i < [text count]; i++) { [ochan writeInBackgroundAndNotify: [[text objectAtIndex: i] dataUsingEncoding: NSUTF8StringEncoding]]; } } } - (id) init { NSArray *args = [[NSProcessInfo processInfo] arguments]; NSString *host = @"localhost"; NSString *service = @"telnet"; NSString *protocol = @"tcp"; if ([args count] > 1) { host = [args objectAtIndex: 1]; if ([args count] > 2) { service = [args objectAtIndex: 2]; if ([args count] > 3) { protocol = [args objectAtIndex: 3]; } } } buf = [NSMutableData new]; ichan = RETAIN([NSFileHandle fileHandleWithStandardInput]); ochan = RETAIN([NSFileHandle fileHandleWithStandardOutput]); remote = [[GSTelnetHandle alloc] initWithHandle: [NSFileHandle fileHandleAsClientAtAddress: host service: service protocol: protocol] isConnected: YES]; if (remote == nil) { NSLog(@"Failed to create connection"); DESTROY(self); } else { NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc addObserver: self selector: @selector(didRead:) name: NSFileHandleReadCompletionNotification object: ichan]; [nc addObserver: self selector: @selector(didWrite:) name: GSFileHandleWriteCompletionNotification object: ochan]; [nc addObserver: self selector: @selector(gotTelnet:) name: GSTelnetNotification object: remote]; [ichan readInBackgroundAndNotify]; } return self; } @end int main() { Call *console; CREATE_AUTORELEASE_POOL(arp); console = [Call new]; RELEASE(arp); [[NSRunLoop currentRunLoop] run]; RELEASE(console); return 0; }