/** Implementation for NSFileHandle for GNUStep Copyright (C) 1997 Free Software Foundation, Inc. Written by: Richard Frith-Macdonald Date: 1997 This file is part of the GNUstep Base Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. NSFileHandle class reference $Date$ $Revision$ */ #include #include #include #include #include #include #include #include #ifdef __MINGW__ #include #else #include #endif // GNUstep Notification names NSString * const GSFileHandleConnectCompletionNotification = @"GSFileHandleConnectCompletionNotification"; NSString * const GSFileHandleWriteCompletionNotification = @"GSFileHandleWriteCompletionNotification"; // GNUstep key for getting error message. NSString * const GSFileHandleNotificationError = @"GSFileHandleNotificationError"; static Class NSFileHandle_abstract_class = nil; static Class NSFileHandle_concrete_class = nil; static Class NSFileHandle_ssl_class = nil; @implementation NSFileHandle + (void) initialize { if (self == [NSFileHandle class]) { NSFileHandle_abstract_class = self; #ifdef __MINGW__ NSFileHandle_concrete_class = [WindowsFileHandle class]; #else NSFileHandle_concrete_class = [UnixFileHandle class]; #endif } } + (id) allocWithZone: (NSZone*)z { if (self == NSFileHandle_abstract_class) { return NSAllocateObject (NSFileHandle_concrete_class, 0, z); } else { return NSAllocateObject (self, 0, z); } } // Allocating and Initializing a FileHandle Object + (id) fileHandleForReadingAtPath: (NSString*)path { id o = [self allocWithZone: NSDefaultMallocZone()]; return AUTORELEASE([o initForReadingAtPath: path]); } + (id) fileHandleForWritingAtPath: (NSString*)path { id o = [self allocWithZone: NSDefaultMallocZone()]; return AUTORELEASE([o initForWritingAtPath: path]); } + (id) fileHandleForUpdatingAtPath: (NSString*)path { id o = [self allocWithZone: NSDefaultMallocZone()]; return AUTORELEASE([o initForUpdatingAtPath: path]); } + (id) fileHandleWithStandardError { id o = [self allocWithZone: NSDefaultMallocZone()]; return AUTORELEASE([o initWithStandardError]); } + (id) fileHandleWithStandardInput { id o = [self allocWithZone: NSDefaultMallocZone()]; return AUTORELEASE([o initWithStandardInput]); } + (id) fileHandleWithStandardOutput { id o = [self allocWithZone: NSDefaultMallocZone()]; return AUTORELEASE([o initWithStandardOutput]); } + (id) fileHandleWithNullDevice { id o = [self allocWithZone: NSDefaultMallocZone()]; return AUTORELEASE([o initWithNullDevice]); } - (id) initWithFileDescriptor: (int)desc { return [self initWithFileDescriptor: desc closeOnDealloc: NO]; } - (id) initWithFileDescriptor: (int)desc closeOnDealloc: (BOOL)flag { [self subclassResponsibility: _cmd]; return nil; } - (id) initWithNativeHandle: (void*)hdl { return [self initWithNativeHandle: hdl closeOnDealloc: NO]; } // This is the designated initializer. - (id) initWithNativeHandle: (void*)hdl closeOnDealloc: (BOOL)flag { [self subclassResponsibility: _cmd]; return nil; } // Returning file handles - (int) fileDescriptor { [self subclassResponsibility: _cmd]; return -1; } - (void*) nativeHandle { [self subclassResponsibility: _cmd]; return 0; } // Synchronous I/O operations - (NSData*) availableData { [self subclassResponsibility: _cmd]; return nil; } - (NSData*) readDataToEndOfFile { [self subclassResponsibility: _cmd]; return nil; } - (NSData*) readDataOfLength: (unsigned int)len { [self subclassResponsibility: _cmd]; return nil; } - (void) writeData: (NSData*)item { [self subclassResponsibility: _cmd]; } // Asynchronous I/O operations - (void) acceptConnectionInBackgroundAndNotify { [self acceptConnectionInBackgroundAndNotifyForModes: nil]; } - (void) acceptConnectionInBackgroundAndNotifyForModes: (NSArray*)modes { [self subclassResponsibility: _cmd]; } /** * Call -readInBackgroundAndNotifyForModes: with nil modes. */ - (void) readInBackgroundAndNotify { [self readInBackgroundAndNotifyForModes: nil]; } /** * Set up an asynchonous read operation which will cause a notification to * be sent when any amount of data (or end of file) is read. */ - (void) readInBackgroundAndNotifyForModes: (NSArray*)modes { [self subclassResponsibility: _cmd]; } /** * Call -readToEndOfFileInBackgroundAndNotifyForModes: with nil modes. */ - (void) readToEndOfFileInBackgroundAndNotify { [self readToEndOfFileInBackgroundAndNotifyForModes: nil]; } /** * Set up an asynchonous read operation which will cause a notification to * be sent when end of file is read. */ - (void) readToEndOfFileInBackgroundAndNotifyForModes: (NSArray*)modes { [self subclassResponsibility: _cmd]; } /** * Call -waitForDataInBackgroundAndNotifyForModes: with nil modes. */ - (void) waitForDataInBackgroundAndNotify { [self waitForDataInBackgroundAndNotifyForModes: nil]; } /** * Set up to provide a notification when data can be read from the handle. */ - (void) waitForDataInBackgroundAndNotifyForModes: (NSArray*)modes { [self subclassResponsibility: _cmd]; } // Seeking within a file - (unsigned long long) offsetInFile { [self subclassResponsibility: _cmd]; return 0; } - (unsigned long long) seekToEndOfFile { [self subclassResponsibility: _cmd]; return 0; } - (void) seekToFileOffset: (unsigned long long)pos { [self subclassResponsibility: _cmd]; } // Operations on file - (void) closeFile { [self subclassResponsibility: _cmd]; } - (void) synchronizeFile { [self subclassResponsibility: _cmd]; } - (void) truncateFileAtOffset: (unsigned long long)pos { [self subclassResponsibility: _cmd]; } @end // Keys for accessing userInfo dictionary in notification handlers. NSString * const NSFileHandleNotificationDataItem = @"NSFileHandleNotificationDataItem"; NSString * const NSFileHandleNotificationFileHandleItem = @"NSFileHandleNotificationFileHandleItem"; NSString * const NSFileHandleNotificationMonitorModes = @"NSFileHandleNotificationMonitorModes"; // Notification names NSString * const NSFileHandleConnectionAcceptedNotification = @"NSFileHandleConnectionAcceptedNotification"; NSString * const NSFileHandleDataAvailableNotification = @"NSFileHandleDataAvailableNotification"; NSString * const NSFileHandleReadCompletionNotification = @"NSFileHandleReadCompletionNotification"; NSString * const NSFileHandleReadToEndOfFileCompletionNotification = @"NSFileHandleReadToEndOfFileCompletionNotification"; // Exceptions NSString * const NSFileHandleOperationException = @"NSFileHandleOperationException"; // GNUstep class extensions @implementation NSFileHandle (GNUstepExtensions) /** * Opens an outgoing network connection by initiating an asynchronous * connection (see * [+fileHandleAsClientInBackgroundAtAddress:service:protocol:forModes:]) * and waiting for it to succeed, fail, or time out. */ + (id) fileHandleAsClientAtAddress: (NSString*)address service: (NSString*)service protocol: (NSString*)protocol { id o = [self allocWithZone: NSDefaultMallocZone()]; return AUTORELEASE([o initAsClientAtAddress: address service: service protocol: protocol]); } /** * Opens an outgoing network connection asynchronously using * [+fileHandleAsClientInBackgroundAtAddress:service:protocol:forModes:] */ + (id) fileHandleAsClientInBackgroundAtAddress: (NSString*)address service: (NSString*)service protocol: (NSString*)protocol { id o = [self allocWithZone: NSDefaultMallocZone()]; return AUTORELEASE([o initAsClientInBackgroundAtAddress: address service: service protocol: protocol forModes: nil]); } /** *

* Opens an outgoing network connection asynchronously. *

* * * The address is the name (or IP dotted quad) of the machine to * which the connection should be made. * * * The service is the name (or number) of the port to * which the connection should be made. * * * The protocol is provided so support different network protocols, * but at present only 'tcp' is supported. However, a protocol * specification of the form 'socks-...' can be used to control socks5 * support.
* If '...' is empty (ie the string is just 'socks-' then the connection * is not made via a socks server.
* Otherwise, the text '...' must be the name of the host on which the * socks5 server is running, with an optional port number separated * from the host name by a colon. *
* * If modes is nil or empty, uses NSDefaultRunLoopMode. * *
*

* This method supports connection through a firewall via socks5. The * socks5 connection may be controlled via the protocol argument, but if * no socks infromation is supplied here, the GSSOCKS user default * will be used, and failing that, the SOCKS5_SERVER or * SOCKS_SERVER environment variables will be used to set the * socks server. If none of these mechanisms specify a socks server, the * connection will be made directly rather than through socks. *

*/ + (id) fileHandleAsClientInBackgroundAtAddress: (NSString*)address service: (NSString*)service protocol: (NSString*)protocol forModes: (NSArray*)modes { id o = [self allocWithZone: NSDefaultMallocZone()]; return AUTORELEASE([o initAsClientInBackgroundAtAddress: address service: service protocol: protocol forModes: modes]); } + (id) fileHandleAsServerAtAddress: (NSString*)address service: (NSString*)service protocol: (NSString*)protocol { id o = [self allocWithZone: NSDefaultMallocZone()]; return AUTORELEASE([o initAsServerAtAddress: address service: service protocol: protocol]); } /** * Call -readDataInBackgroundAndNotifyLength:forModes: with nil modes. */ - (void) readDataInBackgroundAndNotifyLength: (unsigned)len { [self readDataInBackgroundAndNotifyLength: len forModes: nil]; } /** * Set up an asynchonous read operation which will cause a notification to * be sent when the specified amount of data (or end of file) is read. */ - (void) readDataInBackgroundAndNotifyLength: (unsigned)len forModes: (NSArray*)modes { [self subclassResponsibility: _cmd]; } - (BOOL) readInProgress { [self subclassResponsibility: _cmd]; return NO; } - (NSString*) socketAddress { return nil; } - (NSString*) socketService { return nil; } - (NSString*) socketProtocol { return nil; } - (BOOL) useCompression { return NO; } /** * Call -writeInBackgroundAndNotify:forModes: with nil modes. */ - (void) writeInBackgroundAndNotify: (NSData*)item { [self writeInBackgroundAndNotify: item forModes: nil]; } /** * Write the specified data asynchronously, and notify on completion. */ - (void) writeInBackgroundAndNotify: (NSData*)item forModes: (NSArray*)modes { [self subclassResponsibility: _cmd]; } - (BOOL) writeInProgress { [self subclassResponsibility: _cmd]; return NO; } @end @implementation NSFileHandle (GNUstepOpenSSL) + (Class) sslClass { if (NSFileHandle_ssl_class == 0) { NSBundle *bundle; NSString *path; path = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSSystemDomainMask, NO) lastObject]; path = [path stringByAppendingPathComponent: @"Bundles"]; path = [path stringByAppendingPathComponent: @"SSL.bundle"]; bundle = [NSBundle bundleWithPath: path]; NSFileHandle_ssl_class = [bundle principalClass]; } return NSFileHandle_ssl_class; } - (BOOL) sslConnect { return NO; } - (void) sslDisconnect { } - (void) sslSetCertificate: (NSString*)certFile privateKey: (NSString*)privateKey PEMpasswd: (NSString*)PEMpasswd { } @end