mirror of
https://github.com/gnustep/libs-base.git
synced 2025-06-01 01:01:03 +00:00
Various updates
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@3473 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
c316ccd6eb
commit
a7da79ae97
7 changed files with 124 additions and 478 deletions
17
ChangeLog
17
ChangeLog
|
@ -1,3 +1,20 @@
|
||||||
|
Wed Dec 16 20:30:00 1998 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
|
||||||
|
Various modifications suggested by <mguesdon@sbuilders.com> and
|
||||||
|
<jagapen@whitewater.chem.wisc.edu>. All untested.
|
||||||
|
src/include/Port.h: ([+newForReceivingFromRegisteredName:fromPort:])
|
||||||
|
Additional method for DO through firewalls.
|
||||||
|
src/include/NSConnection.h: Addittional method for DO through firewall
|
||||||
|
([+newRegisteringAtName:atPort:withRootObject:])
|
||||||
|
Additional method for DO through firewalls.
|
||||||
|
src/NSTask.h: Updated to MacOS-X spec - accepts NSPipes.
|
||||||
|
src/TcpPort.m: ([+newForReceivingFromRegisteredName:fromPort:])
|
||||||
|
Additional method for DO through firewalls. Removed obsolete name
|
||||||
|
server code.
|
||||||
|
src/NSConnection.m: Addittional method for DO through firewall
|
||||||
|
([+newRegisteringAtName:atPort:withRootObject:])
|
||||||
|
src/NSTask.m: Updated to MacOS-X spec - accepts NSPipes.
|
||||||
|
|
||||||
Tue Dec 15 13:25:10 1998 Adam Fedor <fedor@doc.com>
|
Tue Dec 15 13:25:10 1998 Adam Fedor <fedor@doc.com>
|
||||||
|
|
||||||
* src/NSUser.m (NSFullUserName): New function (not implemented).
|
* src/NSUser.m (NSFullUserName): New function (not implemented).
|
||||||
|
|
|
@ -169,7 +169,11 @@ extern NSString *NSConnectionProxyCount; /* Objects received */
|
||||||
it's unclear if we're connecting to another NSConnection that already
|
it's unclear if we're connecting to another NSConnection that already
|
||||||
registered with that name. */
|
registered with that name. */
|
||||||
+ (NSConnection*) newWithRootObject: anObj;
|
+ (NSConnection*) newWithRootObject: anObj;
|
||||||
+ (NSConnection*) newRegisteringAtName: (NSString*)n withRootObject: anObj;
|
+ (NSConnection*) newRegisteringAtName: (NSString*)n
|
||||||
|
withRootObject: anObj;
|
||||||
|
+ (NSConnection*) newRegisteringAtName: (NSString*)n
|
||||||
|
atPort: (int)portn
|
||||||
|
withRootObject: anObj;
|
||||||
|
|
||||||
/* Get a proxy to a remote server object.
|
/* Get a proxy to a remote server object.
|
||||||
A new connection is created if necessary. */
|
A new connection is created if necessary. */
|
||||||
|
|
|
@ -33,22 +33,23 @@
|
||||||
|
|
||||||
@interface NSTask : NSObject
|
@interface NSTask : NSObject
|
||||||
{
|
{
|
||||||
NSString *currentDirectoryPath;
|
NSString *currentDirectoryPath;
|
||||||
NSString *launchPath;
|
NSString *launchPath;
|
||||||
NSArray *arguments;
|
NSArray *arguments;
|
||||||
NSDictionary *environment;
|
NSDictionary *environment;
|
||||||
NSFileHandle *standardError;
|
id standardError;
|
||||||
NSFileHandle *standardInput;
|
id standardInput;
|
||||||
NSFileHandle *standardOutput;
|
id standardOutput;
|
||||||
int taskId;
|
int taskId;
|
||||||
int terminationStatus;
|
int terminationStatus;
|
||||||
BOOL hasLaunched;
|
BOOL hasLaunched;
|
||||||
BOOL hasTerminated;
|
BOOL hasTerminated;
|
||||||
BOOL hasCollected;
|
BOOL hasCollected;
|
||||||
BOOL hasNotified;
|
BOOL hasNotified;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSTask*)launchedTaskWithLaunchPath:(NSString*)path arguments: (NSArray*)args;
|
+ (NSTask*) launchedTaskWithLaunchPath: (NSString*)path
|
||||||
|
arguments: (NSArray*)args;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Querying task parameters.
|
* Querying task parameters.
|
||||||
|
@ -57,20 +58,20 @@
|
||||||
- (NSString*) currentDirectoryPath;
|
- (NSString*) currentDirectoryPath;
|
||||||
- (NSDictionary*) environment;
|
- (NSDictionary*) environment;
|
||||||
- (NSString*) launchPath;
|
- (NSString*) launchPath;
|
||||||
- (NSFileHandle*) standardError;
|
- (id) standardError;
|
||||||
- (NSFileHandle*) standardInput;
|
- (id) standardInput;
|
||||||
- (NSFileHandle*) standardOutput;
|
- (id) standardOutput;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setting task parameters.
|
* Setting task parameters.
|
||||||
*/
|
*/
|
||||||
- (void)setArguments: (NSArray*)args;
|
- (void) setArguments: (NSArray*)args;
|
||||||
- (void)setCurrentDirectoryPath: (NSString*)path;
|
- (void) setCurrentDirectoryPath: (NSString*)path;
|
||||||
- (void)setEnvironment: (NSDictionary*)env;
|
- (void) setEnvironment: (NSDictionary*)env;
|
||||||
- (void)setLaunchPath: (NSString*)path;
|
- (void) setLaunchPath: (NSString*)path;
|
||||||
- (void)setStandardError: (NSFileHandle*)hdl;
|
- (void) setStandardError: (id)hdl;
|
||||||
- (void)setStandardInput: (NSFileHandle*)hdl;
|
- (void) setStandardInput: (id)hdl;
|
||||||
- (void)setStandardOutput: (NSFileHandle*)hdl;
|
- (void) setStandardOutput: (id)hdl;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Obtaining task state
|
* Obtaining task state
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
|
|
||||||
+ newForReceiving;
|
+ newForReceiving;
|
||||||
+ newForReceivingFromRegisteredName: (NSString*)name;
|
+ newForReceivingFromRegisteredName: (NSString*)name;
|
||||||
|
+ newForReceivingFromRegisteredName: (NSString*)name fromPort: (int)port;
|
||||||
|
|
||||||
/* Register/Unregister this port for input handling through RunLoop
|
/* Register/Unregister this port for input handling through RunLoop
|
||||||
RUN_LOOP in mode MODE. */
|
RUN_LOOP in mode MODE. */
|
||||||
|
|
|
@ -831,15 +831,25 @@ static int messages_received_count;
|
||||||
with that name. */
|
with that name. */
|
||||||
|
|
||||||
+ (NSConnection*) newRegisteringAtName: (NSString*)n withRootObject: anObj
|
+ (NSConnection*) newRegisteringAtName: (NSString*)n withRootObject: anObj
|
||||||
|
{
|
||||||
|
return [self newRegisteringAtName: n
|
||||||
|
atPort: 0
|
||||||
|
withRootObject: anObj];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSConnection*) newRegisteringAtName: (NSString*)n
|
||||||
|
atPort: (int)p
|
||||||
|
withRootObject: anObj
|
||||||
{
|
{
|
||||||
id newPort;
|
id newPort;
|
||||||
id newConn;
|
id newConn;
|
||||||
|
|
||||||
newPort = [default_receive_port_class newForReceivingFromRegisteredName: n];
|
newPort = [default_receive_port_class newForReceivingFromRegisteredName: n
|
||||||
newConn = [self newForInPort:[newPort autorelease]
|
fromPort: p];
|
||||||
outPort:nil
|
newConn = [self newForInPort: [newPort autorelease]
|
||||||
ancestorConnection:nil];
|
outPort: nil
|
||||||
[self setRootObject:anObj forInPort:newPort];
|
ancestorConnection: nil];
|
||||||
|
[self setRootObject: anObj forInPort: newPort];
|
||||||
return newConn;
|
return newConn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,8 @@ NSString *NSTaskDidTerminateNotification = @"NSTaskDidTerminateNotification";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSTask*)launchedTaskWithLaunchPath:(NSString*)path arguments: (NSArray*)args
|
+ (NSTask*) launchedTaskWithLaunchPath: (NSString*)path
|
||||||
|
arguments: (NSArray*)args
|
||||||
{
|
{
|
||||||
NSTask* task = [NSTask new];
|
NSTask* task = [NSTask new];
|
||||||
|
|
||||||
|
@ -113,7 +114,7 @@ NSString *NSTaskDidTerminateNotification = @"NSTaskDidTerminateNotification";
|
||||||
return launchPath;
|
return launchPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSFileHandle*) standardError
|
- (id) standardError
|
||||||
{
|
{
|
||||||
if (standardError == nil)
|
if (standardError == nil)
|
||||||
{
|
{
|
||||||
|
@ -122,7 +123,7 @@ NSString *NSTaskDidTerminateNotification = @"NSTaskDidTerminateNotification";
|
||||||
return standardError;
|
return standardError;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSFileHandle*) standardInput
|
- (id) standardInput
|
||||||
{
|
{
|
||||||
if (standardInput == nil)
|
if (standardInput == nil)
|
||||||
{
|
{
|
||||||
|
@ -131,7 +132,7 @@ NSString *NSTaskDidTerminateNotification = @"NSTaskDidTerminateNotification";
|
||||||
return standardInput;
|
return standardInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSFileHandle*) standardOutput
|
- (id) standardOutput
|
||||||
{
|
{
|
||||||
if (standardOutput == nil)
|
if (standardOutput == nil)
|
||||||
{
|
{
|
||||||
|
@ -192,8 +193,10 @@ NSString *NSTaskDidTerminateNotification = @"NSTaskDidTerminateNotification";
|
||||||
launchPath = path;
|
launchPath = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setStandardError: (NSFileHandle*)hdl
|
- (void) setStandardError: (id)hdl
|
||||||
{
|
{
|
||||||
|
NSAssert([hdl isKindOfClass: [NSFileHandle class]] ||
|
||||||
|
[hdl isKindOfClass: [NSPipe class]], NSInvalidArgumentException);
|
||||||
if (hasLaunched)
|
if (hasLaunched)
|
||||||
{
|
{
|
||||||
[NSException raise: NSInvalidArgumentException
|
[NSException raise: NSInvalidArgumentException
|
||||||
|
@ -206,6 +209,8 @@ NSString *NSTaskDidTerminateNotification = @"NSTaskDidTerminateNotification";
|
||||||
|
|
||||||
- (void) setStandardInput: (NSFileHandle*)hdl
|
- (void) setStandardInput: (NSFileHandle*)hdl
|
||||||
{
|
{
|
||||||
|
NSAssert([hdl isKindOfClass: [NSFileHandle class]] ||
|
||||||
|
[hdl isKindOfClass: [NSPipe class]], NSInvalidArgumentException);
|
||||||
if (hasLaunched)
|
if (hasLaunched)
|
||||||
{
|
{
|
||||||
[NSException raise: NSInvalidArgumentException
|
[NSException raise: NSInvalidArgumentException
|
||||||
|
@ -218,6 +223,8 @@ NSString *NSTaskDidTerminateNotification = @"NSTaskDidTerminateNotification";
|
||||||
|
|
||||||
- (void) setStandardOutput: (NSFileHandle*)hdl
|
- (void) setStandardOutput: (NSFileHandle*)hdl
|
||||||
{
|
{
|
||||||
|
NSAssert([hdl isKindOfClass: [NSFileHandle class]] ||
|
||||||
|
[hdl isKindOfClass: [NSPipe class]], NSInvalidArgumentException);
|
||||||
if (hasLaunched)
|
if (hasLaunched)
|
||||||
{
|
{
|
||||||
[NSException raise: NSInvalidArgumentException
|
[NSException raise: NSInvalidArgumentException
|
||||||
|
@ -278,6 +285,7 @@ NSString *NSTaskDidTerminateNotification = @"NSTaskDidTerminateNotification";
|
||||||
|
|
||||||
- (void) launch
|
- (void) launch
|
||||||
{
|
{
|
||||||
|
NSMutableArray *toClose;
|
||||||
int pid;
|
int pid;
|
||||||
const char *executable;
|
const char *executable;
|
||||||
const char *path;
|
const char *path;
|
||||||
|
@ -291,6 +299,7 @@ NSString *NSTaskDidTerminateNotification = @"NSTaskDidTerminateNotification";
|
||||||
int ac = [a count];
|
int ac = [a count];
|
||||||
const char *args[ac+2];
|
const char *args[ac+2];
|
||||||
const char *envl[ec+1];
|
const char *envl[ec+1];
|
||||||
|
id hdl;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (hasLaunched)
|
if (hasLaunched)
|
||||||
|
@ -339,9 +348,37 @@ NSString *NSTaskDidTerminateNotification = @"NSTaskDidTerminateNotification";
|
||||||
envl[ec] = 0;
|
envl[ec] = 0;
|
||||||
|
|
||||||
path = [[self currentDirectoryPath] cString];
|
path = [[self currentDirectoryPath] cString];
|
||||||
idesc = [[self standardInput] fileDescriptor];
|
|
||||||
odesc = [[self standardError] fileDescriptor];
|
toClose = [NSMutableArray arrayWithCapacity: 3];
|
||||||
edesc = [[self standardOutput] fileDescriptor];
|
hdl = [self standardInput];
|
||||||
|
if ([hdl isKindOfClass: [NSPipe class]])
|
||||||
|
{
|
||||||
|
hdl = [hdl fileHandleForReading];
|
||||||
|
[toClose addObject: hdl];
|
||||||
|
}
|
||||||
|
idesc = [hdl fileDescriptor];
|
||||||
|
|
||||||
|
hdl = [self standardOutput];
|
||||||
|
if ([hdl isKindOfClass: [NSPipe class]])
|
||||||
|
{
|
||||||
|
hdl = [hdl fileHandleForWriting];
|
||||||
|
[toClose addObject: hdl];
|
||||||
|
}
|
||||||
|
odesc = [hdl fileDescriptor];
|
||||||
|
|
||||||
|
hdl = [self standardError];
|
||||||
|
if ([hdl isKindOfClass: [NSPipe class]])
|
||||||
|
{
|
||||||
|
hdl = [hdl fileHandleForWriting];
|
||||||
|
/*
|
||||||
|
* If we have the same pipe twice we don't want to close it twice
|
||||||
|
*/
|
||||||
|
if ([toClose indexOfObjectIdenticalTo: hdl] == NSNotFound)
|
||||||
|
{
|
||||||
|
[toClose addObject: hdl];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
edesc = [hdl fileDescriptor];
|
||||||
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if (pid < 0)
|
if (pid < 0)
|
||||||
|
@ -371,6 +408,15 @@ NSString *NSTaskDidTerminateNotification = @"NSTaskDidTerminateNotification";
|
||||||
{
|
{
|
||||||
taskId = pid;
|
taskId = pid;
|
||||||
hasLaunched = YES;
|
hasLaunched = YES;
|
||||||
|
/*
|
||||||
|
* Close the ends of any pipes used by the child.
|
||||||
|
*/
|
||||||
|
while ([toClose count] > 0)
|
||||||
|
{
|
||||||
|
hdl = [toClose objectAtIndex: 0];
|
||||||
|
[hdl closeFile];
|
||||||
|
[toClose removeObjectAtIndex: 0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
447
Source/TcpPort.m
447
Source/TcpPort.m
|
@ -69,8 +69,6 @@
|
||||||
#define NBLK_OPT FNDELAY
|
#define NBLK_OPT FNDELAY
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define NSPORTNAMESERVER 1
|
|
||||||
#define GDOMAP 1 /* 1 = Use name server. */
|
|
||||||
#define stringify_it(X) #X
|
#define stringify_it(X) #X
|
||||||
#define make_gdomap_cmd(X) stringify_it(X) "/Tools/"GNUSTEP_TARGET_DIR"/gdomap &"
|
#define make_gdomap_cmd(X) stringify_it(X) "/Tools/"GNUSTEP_TARGET_DIR"/gdomap &"
|
||||||
#define make_gdomap_err(X) "check that " stringify_it(X) "/Tools/"GNUSTEP_TARGET_DIR"/gdomap is running and owned by root."
|
#define make_gdomap_err(X) "check that " stringify_it(X) "/Tools/"GNUSTEP_TARGET_DIR"/gdomap is running and owned by root."
|
||||||
|
@ -163,12 +161,6 @@ static int debug_tcp_port = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef GDOMAP
|
|
||||||
/*
|
|
||||||
* Code to contact distributed objects name server.
|
|
||||||
*/
|
|
||||||
#include "../Tools/gdomap.h"
|
|
||||||
|
|
||||||
extern int errno; /* For systems where it is not in the include */
|
extern int errno; /* For systems where it is not in the include */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -339,376 +331,6 @@ tryWrite(int desc, int tim, unsigned char* dat, int len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Name - tryHost()
|
|
||||||
* Purpose - Perform a name server operation with a given
|
|
||||||
* request packet to a server at specified address.
|
|
||||||
* On error - return non-zero with reason in 'errno'
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
tryHost(unsigned char op, unsigned char len, const unsigned char* name,
|
|
||||||
struct sockaddr_in* addr, unsigned short* p, unsigned char **v)
|
|
||||||
{
|
|
||||||
int desc = socket(AF_INET, SOCK_STREAM, 0);
|
|
||||||
int e = 0;
|
|
||||||
unsigned long port = *p;
|
|
||||||
gdo_req msg;
|
|
||||||
struct sockaddr_in sin;
|
|
||||||
|
|
||||||
*p = 0;
|
|
||||||
if (desc < 0) {
|
|
||||||
return(1); /* Couldn't create socket. */
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((e = fcntl(desc, F_GETFL, 0)) >= 0) {
|
|
||||||
e |= NBLK_OPT;
|
|
||||||
if (fcntl(desc, F_SETFL, e) < 0) {
|
|
||||||
e = errno;
|
|
||||||
close(desc);
|
|
||||||
errno = e;
|
|
||||||
return(2); /* Couldn't set non-blocking. */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
e = errno;
|
|
||||||
close(desc);
|
|
||||||
errno = e;
|
|
||||||
return(2); /* Couldn't set non-blocking. */
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(&sin, addr, sizeof(sin));
|
|
||||||
if (connect(desc, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
|
|
||||||
if (errno == EINPROGRESS) {
|
|
||||||
e = tryWrite(desc, 10, 0, 0);
|
|
||||||
if (e == -2) {
|
|
||||||
e = errno;
|
|
||||||
close(desc);
|
|
||||||
errno = e;
|
|
||||||
return(3); /* Connect timed out. */
|
|
||||||
}
|
|
||||||
else if (e == -1) {
|
|
||||||
e = errno;
|
|
||||||
close(desc);
|
|
||||||
errno = e;
|
|
||||||
return(3); /* Select failed. */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
e = errno;
|
|
||||||
close(desc);
|
|
||||||
errno = e;
|
|
||||||
return(3); /* Failed connect. */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
memset((char*)&msg, '\0', GDO_REQ_SIZE);
|
|
||||||
msg.rtype = op;
|
|
||||||
msg.nsize = len;
|
|
||||||
msg.ptype = GDO_TCP_GDO;
|
|
||||||
if (op != GDO_REGISTER) {
|
|
||||||
port = 0;
|
|
||||||
}
|
|
||||||
msg.port = htonl(port);
|
|
||||||
memcpy(msg.name, name, len);
|
|
||||||
|
|
||||||
e = tryWrite(desc, 10, (unsigned char*)&msg, GDO_REQ_SIZE);
|
|
||||||
if (e != GDO_REQ_SIZE) {
|
|
||||||
e = errno;
|
|
||||||
close(desc);
|
|
||||||
errno = e;
|
|
||||||
return(4);
|
|
||||||
}
|
|
||||||
e = tryRead(desc, 3, (unsigned char*)&port, 4);
|
|
||||||
if (e != 4) {
|
|
||||||
e = errno;
|
|
||||||
close(desc);
|
|
||||||
errno = e;
|
|
||||||
return(5); /* Read timed out. */
|
|
||||||
}
|
|
||||||
port = ntohl(port);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Special case for GDO_SERVERS - allocate buffer and read list.
|
|
||||||
*/
|
|
||||||
if (op == GDO_SERVERS) {
|
|
||||||
int len = port * sizeof(struct in_addr);
|
|
||||||
unsigned char* b;
|
|
||||||
|
|
||||||
b = (unsigned char*)objc_malloc(len);
|
|
||||||
if (tryRead(desc, 3, b, len) != len) {
|
|
||||||
objc_free(b);
|
|
||||||
e = errno;
|
|
||||||
close(desc);
|
|
||||||
errno = e;
|
|
||||||
return(5);
|
|
||||||
}
|
|
||||||
*v = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
*p = (unsigned short)port;
|
|
||||||
close(desc);
|
|
||||||
errno = 0;
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Name - nameFail()
|
|
||||||
* Purpose - If given a failure status from tryHost()
|
|
||||||
* raise an appropriate exception.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
nameFail(int why)
|
|
||||||
{
|
|
||||||
switch (why) {
|
|
||||||
case 0: break;
|
|
||||||
case 1:
|
|
||||||
[NSException raise: NSInternalInconsistencyException
|
|
||||||
format: @"failed to contact name server - socket - %s - %s",
|
|
||||||
strerror(errno),
|
|
||||||
make_gdomap_err(GNUSTEP_INSTALL_PREFIX)];
|
|
||||||
case 2:
|
|
||||||
[NSException raise: NSInternalInconsistencyException
|
|
||||||
format: @"failed to contact name server - socket - %s - %s",
|
|
||||||
strerror(errno),
|
|
||||||
make_gdomap_err(GNUSTEP_INSTALL_PREFIX)];
|
|
||||||
case 3:
|
|
||||||
[NSException raise: NSInternalInconsistencyException
|
|
||||||
format: @"failed to contact name server - socket - %s - %s",
|
|
||||||
strerror(errno),
|
|
||||||
make_gdomap_err(GNUSTEP_INSTALL_PREFIX)];
|
|
||||||
case 4:
|
|
||||||
[NSException raise: NSInternalInconsistencyException
|
|
||||||
format: @"failed to contact name server - socket - %s - %s",
|
|
||||||
strerror(errno),
|
|
||||||
make_gdomap_err(GNUSTEP_INSTALL_PREFIX)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Name - nameServer()
|
|
||||||
* Purpose - Perform name server lookup or registration.
|
|
||||||
* Return success/failure status and set up an
|
|
||||||
* address structure for use in bind or connect.
|
|
||||||
* Restrictions - 0xffff byte name limit
|
|
||||||
* Uses old style host lookup - only handles the
|
|
||||||
* primary network interface for each host!
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
nameServer(const char* name, const char* host, int op, struct sockaddr_in* addr, int pnum, int max)
|
|
||||||
{
|
|
||||||
struct sockaddr_in sin;
|
|
||||||
struct servent* sp;
|
|
||||||
struct hostent* hp;
|
|
||||||
unsigned short p = htons(GDOMAP_PORT);
|
|
||||||
unsigned short port = 0;
|
|
||||||
int len = strlen(name);
|
|
||||||
int multi = 0;
|
|
||||||
int found = 0;
|
|
||||||
int rval;
|
|
||||||
char local_hostname[MAXHOSTNAMELEN];
|
|
||||||
|
|
||||||
if (len == 0)
|
|
||||||
{
|
|
||||||
[NSException raise: NSInternalInconsistencyException
|
|
||||||
format: @"no name specified"];
|
|
||||||
}
|
|
||||||
if (len > 255)
|
|
||||||
{
|
|
||||||
[NSException raise: NSInternalInconsistencyException
|
|
||||||
format: @"name length to large (>255 characters)"];
|
|
||||||
}
|
|
||||||
|
|
||||||
#if GDOMAP_PORT_OVERRIDE
|
|
||||||
p = htons(GDOMAP_PORT_OVERRIDE);
|
|
||||||
#else
|
|
||||||
/*
|
|
||||||
* Ensure we have port number to connect to name server.
|
|
||||||
* The TCP service name 'gdomap' overrides the default port.
|
|
||||||
*/
|
|
||||||
if ((sp = getservbyname("gdomap", "tcp")) != 0)
|
|
||||||
{
|
|
||||||
p = sp->s_port; /* Network byte order. */
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The host name '*' matches any host on the local network.
|
|
||||||
*/
|
|
||||||
if (host && host[0] == '*' && host[1] == '\0')
|
|
||||||
{
|
|
||||||
multi = 1;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* If no host name is given, we use the name of the local host.
|
|
||||||
* NB. This should always be the case for operations other than lookup.
|
|
||||||
*/
|
|
||||||
if (multi || host == 0 || *host == '\0')
|
|
||||||
{
|
|
||||||
char *first_dot;
|
|
||||||
|
|
||||||
if (gethostname(local_hostname, sizeof(local_hostname)) < 0)
|
|
||||||
{
|
|
||||||
[NSException raise: NSInternalInconsistencyException
|
|
||||||
format: @"gethostname() failed: %s", strerror(errno)];
|
|
||||||
}
|
|
||||||
first_dot = strchr(local_hostname, '.');
|
|
||||||
if (first_dot)
|
|
||||||
{
|
|
||||||
*first_dot = '\0';
|
|
||||||
}
|
|
||||||
host = local_hostname;
|
|
||||||
}
|
|
||||||
if ((hp = gethostbyname(host)) == 0)
|
|
||||||
{
|
|
||||||
[NSException raise: NSInternalInconsistencyException
|
|
||||||
format: @"get host address for %s", host];
|
|
||||||
}
|
|
||||||
if (hp->h_addrtype != AF_INET)
|
|
||||||
{
|
|
||||||
[NSException raise: NSInternalInconsistencyException
|
|
||||||
format: @"non-internet network not supported for %s", host];
|
|
||||||
}
|
|
||||||
|
|
||||||
memset((char*)&sin, '\0', sizeof(sin));
|
|
||||||
sin.sin_family = AF_INET;
|
|
||||||
sin.sin_port = p;
|
|
||||||
memcpy((caddr_t)&sin.sin_addr, hp->h_addr, hp->h_length);
|
|
||||||
|
|
||||||
if (multi)
|
|
||||||
{
|
|
||||||
unsigned short num;
|
|
||||||
struct in_addr* b;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A host name of '*' is a special case which should do lookup on
|
|
||||||
* all machines on the local network until one is found which has
|
|
||||||
* the specified server on it.
|
|
||||||
*/
|
|
||||||
rval = tryHost(GDO_SERVERS, 0, 0, &sin, &num, (unsigned char**)&b);
|
|
||||||
/*
|
|
||||||
* If the connection to the local name server fails,
|
|
||||||
* attempt to start it us and retry the lookup.
|
|
||||||
*/
|
|
||||||
if (rval != 0 && host == local_hostname)
|
|
||||||
{
|
|
||||||
system(make_gdomap_cmd(GNUSTEP_INSTALL_PREFIX));
|
|
||||||
sleep(5);
|
|
||||||
rval = tryHost(GDO_SERVERS, 0, 0, &sin, &num, (unsigned char**)&b);
|
|
||||||
}
|
|
||||||
if (rval == 0)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; found == 0 && i < num; i++)
|
|
||||||
{
|
|
||||||
memset((char*)&sin, '\0', sizeof(sin));
|
|
||||||
sin.sin_family = AF_INET;
|
|
||||||
sin.sin_port = p;
|
|
||||||
memcpy((caddr_t)&sin.sin_addr, &b[i], sizeof(struct in_addr));
|
|
||||||
if (sin.sin_addr.s_addr == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (tryHost(GDO_LOOKUP, len, name, &sin, &port, 0) == 0)
|
|
||||||
{
|
|
||||||
if (port != 0)
|
|
||||||
{
|
|
||||||
memset((char*)&addr[found], '\0', sizeof(*addr));
|
|
||||||
memcpy((caddr_t)&addr[found].sin_addr, &sin.sin_addr,
|
|
||||||
sizeof(sin.sin_addr));
|
|
||||||
addr[found].sin_family = AF_INET;
|
|
||||||
addr[found].sin_port = htons(port);
|
|
||||||
found++;
|
|
||||||
if (found == max)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
objc_free(b);
|
|
||||||
return(found);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nameFail(rval);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (op == GDO_REGISTER)
|
|
||||||
{
|
|
||||||
port = (unsigned short)pnum;
|
|
||||||
}
|
|
||||||
rval = tryHost(op, len, name, &sin, &port, 0);
|
|
||||||
/*
|
|
||||||
* If the connection to the local name server fails,
|
|
||||||
* attempt to start it us and retry the lookup.
|
|
||||||
*/
|
|
||||||
if (rval != 0 && host == local_hostname)
|
|
||||||
{
|
|
||||||
system(make_gdomap_cmd(GNUSTEP_INSTALL_PREFIX));
|
|
||||||
sleep(5);
|
|
||||||
if (op == GDO_REGISTER)
|
|
||||||
{
|
|
||||||
port = (unsigned short)pnum;
|
|
||||||
}
|
|
||||||
rval = tryHost(op, len, name, &sin, &port, 0);
|
|
||||||
}
|
|
||||||
nameFail(rval);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (op == GDO_REGISTER)
|
|
||||||
{
|
|
||||||
if (port == 0 || (pnum != 0 && port != pnum))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If the name server thinks we are already registered on this
|
|
||||||
* port, we must have crashed, restarted, and got the same port
|
|
||||||
* number we used to have before we crashed. The solution is to
|
|
||||||
* unregister our name from the port and retry the registration.
|
|
||||||
*/
|
|
||||||
rval = tryHost(GDO_UNREG, len, name, &sin, &port, 0);
|
|
||||||
nameFail(rval);
|
|
||||||
port = (unsigned short)pnum;
|
|
||||||
rval = tryHost(op, len, name, &sin, &port, 0);
|
|
||||||
nameFail(rval);
|
|
||||||
if (port == 0 || (pnum != 0 && port != pnum))
|
|
||||||
{
|
|
||||||
[NSException raise: NSInternalInconsistencyException
|
|
||||||
format: @"service already registered"];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (port == 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
memset((char*)addr, '\0', sizeof(*addr));
|
|
||||||
memcpy((caddr_t)&addr->sin_addr, &sin.sin_addr, sizeof(sin.sin_addr));
|
|
||||||
addr->sin_family = AF_INET;
|
|
||||||
addr->sin_port = htons(port);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
/* The old hash code for a name server. */
|
|
||||||
|
|
||||||
static unsigned short
|
|
||||||
name_2_port_number (const char *name)
|
|
||||||
{
|
|
||||||
unsigned int ret = 0;
|
|
||||||
unsigned int ctr = 0;
|
|
||||||
|
|
||||||
while (*name)
|
|
||||||
{
|
|
||||||
ret ^= *name++ << ctr;
|
|
||||||
ctr = (ctr + 1) % sizeof (void *);
|
|
||||||
}
|
|
||||||
return (ret % (65535 - IPPORT_USERRESERVED - 1)) + IPPORT_USERRESERVED;
|
|
||||||
/* return strlen (name) + IPPORT_USERRESERVED; */
|
|
||||||
}
|
|
||||||
#endif /* GDOMAP */
|
|
||||||
|
|
||||||
|
|
||||||
/* Both TcpInPort's and TcpOutPort's are entered in this maptable. */
|
/* Both TcpInPort's and TcpOutPort's are entered in this maptable. */
|
||||||
|
|
||||||
|
@ -915,28 +537,20 @@ static NSMapTable* port_number_2_port;
|
||||||
|
|
||||||
+ newForReceivingFromRegisteredName: (NSString*)name
|
+ newForReceivingFromRegisteredName: (NSString*)name
|
||||||
{
|
{
|
||||||
#ifdef GDOMAP
|
return [self newForReceivingFromRegisteredName: name fromPort: 0];
|
||||||
TcpInPort* p = [self newForReceivingFromPortNumber: 0];
|
}
|
||||||
|
|
||||||
|
+ newForReceivingFromRegisteredName: (NSString*)name
|
||||||
|
fromPort: (int)portn
|
||||||
|
{
|
||||||
|
TcpInPort* p = [self newForReceivingFromPortNumber: portn];
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
#if NSPORTNAMESERVER
|
|
||||||
[[NSPortNameServer defaultPortNameServer] registerPort: p
|
[[NSPortNameServer defaultPortNameServer] registerPort: p
|
||||||
forName: name];
|
forName: name];
|
||||||
#else
|
|
||||||
int port = [p portNumber];
|
|
||||||
|
|
||||||
if (nameServer([name cString], 0, GDO_REGISTER, &sin, port, 1) == 0) {
|
|
||||||
[p release];
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
#else
|
|
||||||
return [self newForReceivingFromPortNumber:
|
|
||||||
name_2_port_number ([name cString])];
|
|
||||||
#endif /* GDOMAP */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+ newForReceiving
|
+ newForReceiving
|
||||||
|
@ -1655,33 +1269,11 @@ static NSMapTable *out_port_bag = NULL;
|
||||||
+ newForSendingToRegisteredName: (NSString*)name
|
+ newForSendingToRegisteredName: (NSString*)name
|
||||||
onHost: (NSString*)hostname
|
onHost: (NSString*)hostname
|
||||||
{
|
{
|
||||||
#ifdef GDOMAP
|
|
||||||
#if NSPORTNAMESERVER
|
|
||||||
id c;
|
id c;
|
||||||
|
|
||||||
c = [[NSPortNameServer defaultPortNameServer] portForName: name
|
c = [[NSPortNameServer defaultPortNameServer] portForName: name
|
||||||
onHost: hostname];
|
onHost: hostname];
|
||||||
return [c retain];
|
return [c retain];
|
||||||
#else
|
|
||||||
struct sockaddr_in sin[100];
|
|
||||||
int found;
|
|
||||||
int i;
|
|
||||||
id c = nil;
|
|
||||||
|
|
||||||
found = nameServer([name cString], [hostname cString],
|
|
||||||
GDO_LOOKUP, sin, 0, 100);
|
|
||||||
for (i = 0; c == nil && i < found; i++)
|
|
||||||
{
|
|
||||||
c = [self newForSendingToSockaddr: &sin[i]
|
|
||||||
withAcceptedSocket: 0
|
|
||||||
pollingInPort: nil];
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
return [self newForSendingToPortNumber:
|
|
||||||
name_2_port_number ([name cString]) onHost: hostname];;
|
|
||||||
#endif /* GDOMAP */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+ _newWithAcceptedSocket: (int)s
|
+ _newWithAcceptedSocket: (int)s
|
||||||
|
@ -1917,15 +1509,7 @@ static NSMapTable *out_port_bag = NULL;
|
||||||
char prefix_buffer[PREFIX_SIZE];
|
char prefix_buffer[PREFIX_SIZE];
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
#ifdef GDOMAP
|
|
||||||
c = tryRead (s, 3, prefix_buffer, PREFIX_SIZE);
|
c = tryRead (s, 3, prefix_buffer, PREFIX_SIZE);
|
||||||
#else
|
|
||||||
#ifdef __WIN32__
|
|
||||||
c = recv (s, prefix_buffer, PREFIX_SIZE, 0);
|
|
||||||
#else
|
|
||||||
c = read (s, prefix_buffer, PREFIX_SIZE);
|
|
||||||
#endif /* __WIN32__ */
|
|
||||||
#endif /* GDOMAP */
|
|
||||||
if (c <= 0)
|
if (c <= 0)
|
||||||
{
|
{
|
||||||
*packet_size = EOF; *rp = nil;
|
*packet_size = EOF; *rp = nil;
|
||||||
|
@ -1972,16 +1556,7 @@ static NSMapTable *out_port_bag = NULL;
|
||||||
int remaining;
|
int remaining;
|
||||||
|
|
||||||
remaining = [data length] - prefix - eof_position;
|
remaining = [data length] - prefix - eof_position;
|
||||||
#ifdef GDOMAP
|
|
||||||
c = tryRead(s, 1, [data mutableBytes] + prefix + eof_position, -remaining);
|
c = tryRead(s, 1, [data mutableBytes] + prefix + eof_position, -remaining);
|
||||||
#else
|
|
||||||
/* xxx We need to make sure this read() is non-blocking. */
|
|
||||||
#ifdef __WIN32__
|
|
||||||
c = recv (s, [data mutableBytes] + prefix + eof_position, remaining, 0);
|
|
||||||
#else
|
|
||||||
c = read (s, [data mutableBytes] + prefix + eof_position, remaining);
|
|
||||||
#endif /* __WIN32 */
|
|
||||||
#endif /* GDOMAP */
|
|
||||||
if (c <= 0) {
|
if (c <= 0) {
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
|
@ -2021,15 +1596,7 @@ static NSMapTable *out_port_bag = NULL;
|
||||||
memset ([data mutableBytes]+PREFIX_LENGTH_SIZE, 0, PREFIX_ADDRESS_SIZE);
|
memset ([data mutableBytes]+PREFIX_LENGTH_SIZE, 0, PREFIX_ADDRESS_SIZE);
|
||||||
|
|
||||||
/* Write the packet on the socket. */
|
/* Write the packet on the socket. */
|
||||||
#ifdef GDOMAP
|
|
||||||
c = tryWrite (s, (int)timeout, (unsigned char*)[data bytes], prefix + eof_position);
|
c = tryWrite (s, (int)timeout, (unsigned char*)[data bytes], prefix + eof_position);
|
||||||
#else
|
|
||||||
#ifdef __WIN32__
|
|
||||||
c = send (s, [data bytes], prefix + eof_position, 0);
|
|
||||||
#else
|
|
||||||
c = write (s, [data bytes], prefix + eof_position);
|
|
||||||
#endif /* __WIN32__ */
|
|
||||||
#endif /* GDOMAP */
|
|
||||||
if (c == -2) {
|
if (c == -2) {
|
||||||
[NSException raise: NSPortTimeoutException
|
[NSException raise: NSPortTimeoutException
|
||||||
format: @"[TcpOutPort -_writeToSocket:] write() timed out"];
|
format: @"[TcpOutPort -_writeToSocket:] write() timed out"];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue