1997-03-03 19:40:50 +00:00
|
|
|
/* Implementation of host class
|
1999-12-15 02:24:57 +00:00
|
|
|
Copyright (C) 1996, 1997,1999 Free Software Foundation, Inc.
|
1999-12-15 08:51:16 +00:00
|
|
|
|
|
|
|
Written by: Luke Howard <lukeh@xedoc.com.au>
|
1997-03-03 19:40:50 +00:00
|
|
|
Date: 1996
|
1999-12-15 02:24:57 +00:00
|
|
|
Rewrite by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
|
|
|
Date: 1999
|
1999-12-15 08:51:16 +00:00
|
|
|
|
1997-03-03 19:40:50 +00:00
|
|
|
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.
|
1999-12-15 08:51:16 +00:00
|
|
|
|
1997-03-03 19:40:50 +00:00
|
|
|
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.
|
1999-12-15 08:51:16 +00:00
|
|
|
|
1997-03-03 19:40:50 +00:00
|
|
|
You should have received a copy of the GNU Library General Public
|
|
|
|
License along with this library; if not, write to the Free
|
1999-09-09 02:56:20 +00:00
|
|
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
|
1999-12-15 08:51:16 +00:00
|
|
|
*/
|
1997-03-03 19:40:50 +00:00
|
|
|
|
1997-11-06 00:51:23 +00:00
|
|
|
#include <config.h>
|
1998-12-20 21:27:47 +00:00
|
|
|
#include <base/preface.h>
|
1997-03-03 19:40:50 +00:00
|
|
|
#include <Foundation/NSLock.h>
|
|
|
|
#include <Foundation/NSHost.h>
|
1997-09-01 21:59:51 +00:00
|
|
|
#include <Foundation/NSArray.h>
|
1997-05-03 20:38:42 +00:00
|
|
|
#include <Foundation/NSDictionary.h>
|
1997-09-01 21:59:51 +00:00
|
|
|
#include <Foundation/NSString.h>
|
1998-03-05 00:37:44 +00:00
|
|
|
#include <Foundation/NSCoder.h>
|
1997-03-03 19:40:50 +00:00
|
|
|
#include <netdb.h>
|
1999-09-16 07:21:34 +00:00
|
|
|
/* #include <libc.h>*/
|
1997-03-03 19:40:50 +00:00
|
|
|
|
1999-06-02 04:11:19 +00:00
|
|
|
#if defined(__WIN32__) && !defined(__CYGWIN__)
|
1997-03-03 19:40:50 +00:00
|
|
|
#include <Windows32/Sockets.h>
|
1997-09-01 21:59:51 +00:00
|
|
|
#else
|
1997-12-11 19:09:56 +00:00
|
|
|
#include <unistd.h>
|
1997-09-01 21:59:51 +00:00
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <netinet/in.h>
|
1999-06-24 19:30:29 +00:00
|
|
|
#include <arpa/inet.h>
|
1999-09-16 07:21:34 +00:00
|
|
|
#endif /* __WIN32__*/
|
1997-03-03 19:40:50 +00:00
|
|
|
|
1999-12-15 02:20:56 +00:00
|
|
|
#ifndef INADDR_NONE
|
|
|
|
#define INADDR_NONE -1
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static NSLock *_hostCacheLock = nil;
|
|
|
|
static BOOL _hostCacheEnabled = YES;
|
|
|
|
static NSMutableDictionary *_hostCache = nil;
|
1997-03-03 19:40:50 +00:00
|
|
|
|
|
|
|
@interface NSHost (Private)
|
1999-12-15 02:20:56 +00:00
|
|
|
- (id) _initWithHostEntry: (struct hostent*)entry;
|
1997-03-03 19:40:50 +00:00
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation NSHost (Private)
|
|
|
|
|
1999-12-15 02:20:56 +00:00
|
|
|
- (id) _initWithHostEntry: (struct hostent*)entry
|
1997-03-03 19:40:50 +00:00
|
|
|
{
|
1999-12-15 02:20:56 +00:00
|
|
|
int i;
|
|
|
|
char *ptr;
|
|
|
|
struct in_addr in;
|
|
|
|
NSString *h_name;
|
1997-03-03 19:40:50 +00:00
|
|
|
|
1999-12-15 02:20:56 +00:00
|
|
|
if ((self = [super init]) == nil)
|
1997-03-03 19:40:50 +00:00
|
|
|
{
|
1999-12-15 02:20:56 +00:00
|
|
|
return nil;
|
1997-03-03 19:40:50 +00:00
|
|
|
}
|
1999-09-16 07:21:34 +00:00
|
|
|
if (entry == (struct hostent*)NULL)
|
1997-03-03 19:40:50 +00:00
|
|
|
{
|
1999-12-15 02:20:56 +00:00
|
|
|
RELEASE(self);
|
1997-03-03 19:40:50 +00:00
|
|
|
return nil;
|
|
|
|
}
|
1999-12-15 02:20:56 +00:00
|
|
|
|
|
|
|
_names = [NSMutableArray new];
|
|
|
|
_addresses = [NSMutableArray new];
|
|
|
|
|
1999-07-03 19:59:44 +00:00
|
|
|
h_name = [NSString stringWithCString: entry->h_name];
|
1999-12-15 02:20:56 +00:00
|
|
|
[_names addObject: h_name];
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
while ((ptr = entry->h_aliases[i++]) != 0)
|
1997-03-03 19:40:50 +00:00
|
|
|
{
|
1999-09-16 07:21:34 +00:00
|
|
|
[_names addObject: [NSString stringWithCString: ptr]];
|
1997-03-03 19:40:50 +00:00
|
|
|
}
|
|
|
|
|
1999-12-15 02:20:56 +00:00
|
|
|
i = 0;
|
|
|
|
while ((ptr = entry->h_addr_list[i++]) != 0)
|
1997-03-03 19:40:50 +00:00
|
|
|
{
|
1999-12-15 02:20:56 +00:00
|
|
|
NSString *addr;
|
|
|
|
|
|
|
|
memcpy((void*)&in.s_addr, (const void*)ptr, entry->h_length);
|
|
|
|
addr = [NSString stringWithCString: (char*)inet_ntoa(in)];
|
|
|
|
[_addresses addObject: addr];
|
1997-03-03 19:40:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (_hostCacheEnabled == YES)
|
|
|
|
{
|
1999-12-15 02:20:56 +00:00
|
|
|
NSEnumerator *enumerator;
|
|
|
|
NSString *key;
|
|
|
|
|
|
|
|
enumerator = [_names objectEnumerator];
|
|
|
|
while ((key = [enumerator nextObject]) != nil)
|
|
|
|
{
|
|
|
|
[_hostCache setObject: self forKey: key];
|
|
|
|
}
|
|
|
|
enumerator = [_addresses objectEnumerator];
|
|
|
|
while ((key = [enumerator nextObject]) != nil)
|
|
|
|
{
|
|
|
|
[_hostCache setObject: self forKey: key];
|
|
|
|
}
|
1997-03-03 19:40:50 +00:00
|
|
|
}
|
1999-12-15 08:51:16 +00:00
|
|
|
|
1997-03-03 19:40:50 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation NSHost
|
|
|
|
|
1999-09-16 07:21:34 +00:00
|
|
|
- (id) init
|
1997-03-03 19:40:50 +00:00
|
|
|
{
|
1999-09-16 07:21:34 +00:00
|
|
|
[self dealloc];
|
1997-03-03 19:40:50 +00:00
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
1999-09-16 07:21:34 +00:00
|
|
|
+ (void) initialize
|
1997-03-03 19:40:50 +00:00
|
|
|
{
|
1999-09-16 07:21:34 +00:00
|
|
|
if (self == [NSHost class])
|
|
|
|
{
|
1999-12-15 08:51:16 +00:00
|
|
|
_hostCacheLock = [[NSLock alloc] init];
|
1999-09-16 07:21:34 +00:00
|
|
|
_hostCache = [NSMutableDictionary new];
|
|
|
|
}
|
1997-03-03 19:40:50 +00:00
|
|
|
}
|
|
|
|
|
1999-10-31 09:48:26 +00:00
|
|
|
/*
|
|
|
|
* Max hostname length in line with RFC 1123
|
|
|
|
*/
|
|
|
|
#define GSMAXHOSTNAMELEN 255
|
|
|
|
|
1999-09-16 07:21:34 +00:00
|
|
|
+ (NSHost*) currentHost
|
1997-03-03 19:40:50 +00:00
|
|
|
{
|
1999-12-15 02:20:56 +00:00
|
|
|
char name[GSMAXHOSTNAMELEN+1];
|
|
|
|
int res;
|
1999-12-15 08:51:16 +00:00
|
|
|
|
1999-10-31 09:48:26 +00:00
|
|
|
res = gethostname(name, GSMAXHOSTNAMELEN);
|
1997-03-03 19:40:50 +00:00
|
|
|
if (res < 0)
|
|
|
|
{
|
|
|
|
return nil;
|
|
|
|
}
|
1999-10-31 09:48:26 +00:00
|
|
|
name[GSMAXHOSTNAMELEN] = '\0';
|
1999-12-15 02:20:56 +00:00
|
|
|
return [self hostWithName: [NSString stringWithCString: name]];
|
1997-03-03 19:40:50 +00:00
|
|
|
}
|
|
|
|
|
1999-09-16 07:21:34 +00:00
|
|
|
+ (NSHost*) hostWithName: (NSString*)name
|
1997-03-03 19:40:50 +00:00
|
|
|
{
|
1999-12-15 02:20:56 +00:00
|
|
|
NSHost *host = nil;
|
1999-02-19 21:47:15 +00:00
|
|
|
|
|
|
|
if (name == nil)
|
|
|
|
{
|
|
|
|
NSLog(@"Nil host name sent to +[NSHost hostWithName]");
|
|
|
|
return nil;
|
|
|
|
}
|
1999-12-15 02:20:56 +00:00
|
|
|
|
|
|
|
[_hostCacheLock lock];
|
|
|
|
if (_hostCacheEnabled == YES)
|
|
|
|
{
|
|
|
|
host = [_hostCache objectForKey: name];
|
|
|
|
}
|
|
|
|
if (host == nil)
|
|
|
|
{
|
|
|
|
struct hostent *h;
|
|
|
|
|
|
|
|
h = gethostbyname((char*)[name cString]);
|
1999-12-15 08:51:16 +00:00
|
|
|
|
1999-12-15 02:20:56 +00:00
|
|
|
host = [[self alloc] _initWithHostEntry: h];
|
|
|
|
AUTORELEASE(host);
|
|
|
|
}
|
|
|
|
[_hostCacheLock unlock];
|
|
|
|
return host;
|
1997-03-03 19:40:50 +00:00
|
|
|
}
|
|
|
|
|
1999-09-16 07:21:34 +00:00
|
|
|
+ (NSHost*) hostWithAddress: (NSString*)address
|
1997-03-03 19:40:50 +00:00
|
|
|
{
|
1999-12-15 02:20:56 +00:00
|
|
|
NSHost *host = nil;
|
|
|
|
|
1999-02-19 21:47:15 +00:00
|
|
|
if (address == nil)
|
|
|
|
{
|
1999-12-15 02:20:56 +00:00
|
|
|
NSLog(@"Nil host address sent to +[NSHost hostWithName]");
|
1999-02-19 21:47:15 +00:00
|
|
|
return nil;
|
|
|
|
}
|
1999-12-15 02:20:56 +00:00
|
|
|
|
|
|
|
[_hostCacheLock lock];
|
|
|
|
if (_hostCacheEnabled == YES)
|
1997-03-03 19:40:50 +00:00
|
|
|
{
|
1999-12-15 02:20:56 +00:00
|
|
|
host = [_hostCache objectForKey: address];
|
1997-03-03 19:40:50 +00:00
|
|
|
}
|
1999-12-15 02:20:56 +00:00
|
|
|
|
|
|
|
if (host == nil)
|
1999-11-21 06:39:35 +00:00
|
|
|
{
|
1999-12-15 02:20:56 +00:00
|
|
|
struct hostent *h;
|
|
|
|
struct in_addr hostaddr;
|
|
|
|
BOOL addrOk = YES;
|
1999-12-15 08:51:16 +00:00
|
|
|
|
1999-12-15 02:20:56 +00:00
|
|
|
#ifndef HAVE_INET_ATON
|
|
|
|
hostaddr.s_addr = inet_addr([address cString]);
|
|
|
|
if (hostaddr.s_addr == INADDR_NONE)
|
|
|
|
{
|
|
|
|
addrOk = NO;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
if (inet_aton([address cString], (struct in_addr*)&hostaddr.s_addr) == 0)
|
|
|
|
{
|
|
|
|
addrOk = NO;
|
|
|
|
}
|
1999-11-21 06:39:35 +00:00
|
|
|
#endif
|
1999-12-15 02:20:56 +00:00
|
|
|
if (addrOk == YES)
|
|
|
|
{
|
|
|
|
h = gethostbyaddr((char*)&hostaddr, sizeof(hostaddr), AF_INET);
|
|
|
|
host = [[self alloc] _initWithHostEntry: h];
|
|
|
|
AUTORELEASE(host);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[_hostCacheLock unlock];
|
|
|
|
return host;
|
1997-03-03 19:40:50 +00:00
|
|
|
}
|
|
|
|
|
1999-09-16 07:21:34 +00:00
|
|
|
+ (void) setHostCacheEnabled: (BOOL)flag
|
1997-03-03 19:40:50 +00:00
|
|
|
{
|
|
|
|
[_hostCacheLock lock];
|
|
|
|
_hostCacheEnabled = flag;
|
|
|
|
[_hostCacheLock unlock];
|
|
|
|
}
|
|
|
|
|
1999-09-16 07:21:34 +00:00
|
|
|
+ (BOOL) isHostCacheEnabled;
|
1997-03-03 19:40:50 +00:00
|
|
|
{
|
|
|
|
BOOL res;
|
1999-12-15 08:51:16 +00:00
|
|
|
|
1997-03-03 19:40:50 +00:00
|
|
|
[_hostCacheLock lock];
|
|
|
|
res = _hostCacheEnabled;
|
|
|
|
[_hostCacheLock unlock];
|
1999-12-15 08:51:16 +00:00
|
|
|
|
1997-03-03 19:40:50 +00:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
1999-09-16 07:21:34 +00:00
|
|
|
+ (void) flushHostCache
|
1997-03-03 19:40:50 +00:00
|
|
|
{
|
|
|
|
[_hostCacheLock lock];
|
|
|
|
[_hostCache removeAllObjects];
|
|
|
|
[_hostCacheLock unlock];
|
|
|
|
}
|
|
|
|
|
1999-09-16 07:21:34 +00:00
|
|
|
/* Methods for encoding/decoding*/
|
1998-03-05 00:37:44 +00:00
|
|
|
- (Class) classForPortCoder
|
|
|
|
{
|
|
|
|
return [self class];
|
|
|
|
}
|
1999-09-16 07:21:34 +00:00
|
|
|
|
|
|
|
- (id) replacementObjectForPortCoder: (NSPortCoder*)aCoder
|
1998-03-05 00:37:44 +00:00
|
|
|
{
|
1999-12-15 02:20:56 +00:00
|
|
|
return self;
|
1998-03-05 00:37:44 +00:00
|
|
|
}
|
1998-03-12 14:21:20 +00:00
|
|
|
|
1999-12-15 02:20:56 +00:00
|
|
|
- (void) encodeWithCoder: (NSCoder*)aCoder
|
1998-03-12 14:21:20 +00:00
|
|
|
{
|
1999-12-15 02:20:56 +00:00
|
|
|
[super encodeWithCoder: aCoder];
|
|
|
|
[aCoder encodeObject: [self address]];
|
1998-03-12 14:21:20 +00:00
|
|
|
}
|
|
|
|
|
1998-03-05 00:37:44 +00:00
|
|
|
- (id) initWithCoder: (NSCoder*)aCoder
|
|
|
|
{
|
1999-12-15 02:20:56 +00:00
|
|
|
NSString *address;
|
|
|
|
NSHost *host;
|
|
|
|
|
|
|
|
self = [super initWithCoder: aCoder];
|
|
|
|
address = [aCoder decodeObject];
|
|
|
|
host = RETAIN([NSHost hostWithAddress: address]);
|
|
|
|
RELEASE(self);
|
|
|
|
return host;
|
1998-03-05 00:37:44 +00:00
|
|
|
}
|
|
|
|
|
1998-11-11 06:09:36 +00:00
|
|
|
/*
|
1999-12-15 02:20:56 +00:00
|
|
|
* The OpenStep spec says that [-hash] must be the same for any two
|
|
|
|
* objects that [-isEqual: ] returns YES for. We have a problem in
|
|
|
|
* that [-isEqualToHost: ] is specified to return YES if any name or
|
|
|
|
* address part of two hosts is the same. That means we can't
|
|
|
|
* reasonably calculate a hash since two hosts with radically
|
|
|
|
* different ivar contents may be 'equal'. The best I can think of
|
|
|
|
* is for all hosts to hash to the same value - which makes it very
|
|
|
|
* inefficient to store them in a set, dictionary, map or hash table.
|
|
|
|
*/
|
1998-11-11 06:09:36 +00:00
|
|
|
- (unsigned) hash
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) isEqual: (id)other
|
|
|
|
{
|
|
|
|
if (other == self)
|
|
|
|
return YES;
|
|
|
|
if ([other isKindOfClass: [NSHost class]])
|
|
|
|
return [self isEqualToHost: (NSHost*)other];
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
1999-09-16 07:21:34 +00:00
|
|
|
- (BOOL) isEqualToHost: (NSHost*)aHost
|
1997-03-03 19:40:50 +00:00
|
|
|
{
|
1997-09-01 21:59:51 +00:00
|
|
|
NSArray* a;
|
|
|
|
int i;
|
|
|
|
|
1998-11-11 06:09:36 +00:00
|
|
|
if (aHost == self)
|
|
|
|
return YES;
|
|
|
|
|
1997-09-01 21:59:51 +00:00
|
|
|
a = [aHost addresses];
|
|
|
|
for (i = 0; i < [a count]; i++)
|
1999-09-16 07:21:34 +00:00
|
|
|
if ([_addresses containsObject: [a objectAtIndex: i]])
|
1997-09-01 21:59:51 +00:00
|
|
|
return YES;
|
|
|
|
|
|
|
|
a = [aHost names];
|
|
|
|
for (i = 0; i < [a count]; i++)
|
1999-09-16 07:21:34 +00:00
|
|
|
if ([_addresses containsObject: [a objectAtIndex: i]])
|
1997-09-01 21:59:51 +00:00
|
|
|
return YES;
|
|
|
|
|
|
|
|
return NO;
|
1997-03-03 19:40:50 +00:00
|
|
|
}
|
|
|
|
|
1999-09-16 07:21:34 +00:00
|
|
|
- (NSString*) name
|
1997-03-03 19:40:50 +00:00
|
|
|
{
|
1999-09-16 07:21:34 +00:00
|
|
|
return [_names objectAtIndex: 0];
|
1997-03-03 19:40:50 +00:00
|
|
|
}
|
|
|
|
|
1999-09-16 07:21:34 +00:00
|
|
|
- (NSArray*) names
|
1997-03-03 19:40:50 +00:00
|
|
|
{
|
1999-09-16 07:21:34 +00:00
|
|
|
return _names;
|
1997-03-03 19:40:50 +00:00
|
|
|
}
|
|
|
|
|
1999-09-16 07:21:34 +00:00
|
|
|
- (NSString*) address
|
1997-03-03 19:40:50 +00:00
|
|
|
{
|
1999-09-16 07:21:34 +00:00
|
|
|
return [_addresses objectAtIndex: 0];
|
1997-03-03 19:40:50 +00:00
|
|
|
}
|
|
|
|
|
1999-09-16 07:21:34 +00:00
|
|
|
- (NSArray*) addresses
|
1997-03-03 19:40:50 +00:00
|
|
|
{
|
1999-09-16 07:21:34 +00:00
|
|
|
return _addresses;
|
1997-03-03 19:40:50 +00:00
|
|
|
}
|
|
|
|
|
1999-09-16 07:21:34 +00:00
|
|
|
- (NSString*) description
|
1997-03-03 19:40:50 +00:00
|
|
|
{
|
1999-09-16 07:21:34 +00:00
|
|
|
return [NSString stringWithFormat: @"Host %@ (%@ %@)",
|
1999-12-15 02:20:56 +00:00
|
|
|
[self name], [self names], [self addresses]];
|
1997-03-03 19:40:50 +00:00
|
|
|
}
|
|
|
|
|
1999-07-03 19:59:44 +00:00
|
|
|
- (void) dealloc
|
1997-03-03 19:40:50 +00:00
|
|
|
{
|
1999-09-16 07:21:34 +00:00
|
|
|
RELEASE(_names);
|
|
|
|
RELEASE(_addresses);
|
1997-03-03 19:40:50 +00:00
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|