2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
6 SOPE is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with SOPE; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 #if !defined(WIN32) || defined(__CYGWIN32__)
24 #include "NGSocketExceptions.h"
25 #include "NGLocalSocketAddress.h"
26 #include "NGLocalSocketDomain.h"
27 #import <Foundation/NSString.h>
31 #if defined(__APPLE__) || defined(__FreeBSD__)
32 # include <sys/types.h>
37 #if defined(HAVE_UNISTD_H) || defined(__APPLE__)
43 (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
49 # define AF_LOCAL AF_UNIX
52 #if defined(__WIN32__) && !defined(__CYGWIN32__)
53 static NSString *socketDirectoryPath = @"\\\\.\\pipe\\";
55 static NSString *socketDirectoryPath = @"/tmp";
58 @implementation NGLocalSocketAddress
60 + (id)addressWithPath:(NSString *)_p {
61 return [[(NGLocalSocketAddress *)[self alloc] initWithPath:_p] autorelease];
64 return [[[self alloc] init] autorelease];
67 - (id)initWithPath:(NSString *)_path {
68 if ((self = [super init])) {
69 self->address = calloc(1, sizeof(struct sockaddr_un));
71 memset(self->address, 0, sizeof(struct sockaddr_un));
73 #if defined(__WIN32__) && !defined(__CYGWIN32__)
74 self->path = [_path copyWithZone:[self zone]];
76 if ([_path cStringLength] >=
77 sizeof(((struct sockaddr_un *)self->address)->sun_path)) {
79 NSLog(@"LocalDomain name too long: maxlen=%i, len=%i, path=%@",
80 sizeof(((struct sockaddr_un *)self->address)->sun_path),
81 [_path cStringLength],
83 [NSException raise:NSInvalidArgumentException
84 format:@"path to long as local domain socket address !"];
89 ((struct sockaddr_un *)self->address)->sun_family =
90 [[self domain] socketDomain];
92 [_path getCString:((struct sockaddr_un *)self->address)->sun_path
93 maxLength:sizeof(((struct sockaddr_un *)self->address)->sun_path)];
100 int addressCounter = 0;
103 newPath = [NSString stringWithFormat:@"_ngsocket_%p_%p_%03d",
104 getpid(), [NSThread currentThread], addressCounter];
105 newPath = [socketDirectoryPath stringByAppendingPathComponent:newPath];
107 return [self initWithPath:newPath];
110 - (id)initWithDomain:(id)_domain
111 internalRepresentation:(void *)_representation
114 // this method is used by the address factory
115 struct sockaddr_un *nun = _representation;
120 : [[NSString alloc] initWithCString:nun->sun_path];
122 self = [self initWithPath:path];
123 [path release]; path = nil;
128 if (self->address) free(self->address);
137 sp = ((struct sockaddr_un *)self->address)->sun_path;
141 return [NSString stringWithCString:sp];
149 sp = ((struct sockaddr_un *)self->address)->sun_path;
156 // NGSocketAddress protocol
158 - (void *)internalAddressRepresentation {
159 return self->address;
161 - (int)addressRepresentationSize { // varies in length
162 return SUN_LEN(((struct sockaddr_un *)self->address));
165 return [NGLocalSocketDomain domain];
168 /* test for accessibility */
170 - (BOOL)canSendOnAddress {
171 return (access(((struct sockaddr_un *)self->address)->sun_path, W_OK) == 0)
174 - (BOOL)canReceiveOnAddress {
175 return (access(((struct sockaddr_un *)self->address)->sun_path, R_OK) == 0)
179 /* testing for equality */
181 - (BOOL)isEqualToAddress:(NGLocalSocketAddress *)_addr {
182 return [[_addr path] isEqualToString:[self path]];
185 - (BOOL)isEqual:(id)_object {
186 if (_object == self) return YES;
187 if ([_object class] != [self class]) return NO;
188 return [self isEqualToAddress:_object];
193 - (id)copyWithZone:(NSZone *)_zone {
194 /* socket addresses are immutable, just retain on copy ... */
195 return [self retain];
200 - (void)encodeWithCoder:(NSCoder *)_encoder {
201 [_encoder encodeObject:[[NSHost currentHost] name]];
202 [_encoder encodeObject:[self path]];
205 - (id)initWithCoder:(NSCoder *)_decoder {
206 NSString *hostName = [_decoder decodeObject];
207 NSString *path = [_decoder decodeObject];
209 NSAssert([path isKindOfClass:[NSString class]], @"path must be a string ..");
211 if (![hostName isEqualToString:[[NSHost currentHost] name]]) {
212 NSLog(@"unarchived local socket address on a different host, "
213 @"encoded on %@, decoded on %@ (path=%@)",
214 hostName, [[NSHost currentHost] name], path);
217 return [self initWithPath:path];
222 - (NSString *)stringValue {
223 NSString *p = [self path];
224 return [p length] == 0 ? (NSString *)@"*" : p;
227 - (NSString *)description {
228 NSString *p = [self path];
233 return [NSString stringWithFormat:@"<0x%p[%@]: %@>",
234 self, NSStringFromClass([self class]), p];
237 @end /* NGLocalSocketAddress */