2010-03-31 22:15:11 +02:00
|
|
|
/* SOGoSockD.m - this file is part of SOGo
|
|
|
|
*
|
|
|
|
* Copyright (C) 2010 Inverse inc.
|
|
|
|
*
|
|
|
|
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
|
|
|
*
|
|
|
|
* This file is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
|
|
* any later version.
|
|
|
|
*
|
|
|
|
* This file 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 General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; see the file COPYING. If not, write to
|
|
|
|
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
* Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#import <Foundation/NSAutoreleasePool.h>
|
|
|
|
#import <Foundation/NSData.h>
|
|
|
|
#import <Foundation/NSRunLoop.h>
|
|
|
|
#import <Foundation/NSUserDefaults.h>
|
|
|
|
|
|
|
|
#import <NGStreams/NGActiveSocket.h>
|
|
|
|
#import <NGStreams/NGLocalSocketAddress.h>
|
|
|
|
#import <NGStreams/NGPassiveSocket.h>
|
|
|
|
|
|
|
|
#import <NGExtensions/NSObject+Logs.h>
|
|
|
|
|
|
|
|
#import "SOGoSockDScanner.h"
|
|
|
|
#import "SOGoSockD.h"
|
|
|
|
|
|
|
|
@implementation SOGoSockD
|
|
|
|
|
|
|
|
- (void) _setupListeningSocket
|
|
|
|
{
|
|
|
|
NGLocalSocketAddress *address;
|
|
|
|
NSString *path;
|
|
|
|
NSUserDefaults *ud;
|
|
|
|
|
|
|
|
ud = [NSUserDefaults standardUserDefaults];
|
|
|
|
path = [ud stringForKey: @"SOGoSLAPDSocketPath"];
|
|
|
|
if (!path)
|
|
|
|
path = @"/var/run/sogo/sogo-sockd.sock";
|
|
|
|
|
|
|
|
address = [NGLocalSocketAddress addressWithPath: path];
|
|
|
|
ASSIGN (listeningSocket, [NGPassiveSocket socketBoundToAddress: address]);
|
|
|
|
[listeningSocket listenWithBacklog: 5];
|
|
|
|
[self logWithFormat: @"listening on %@", path];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) _startRunLoopWithSocket: (NGPassiveSocket *) socket
|
|
|
|
{
|
|
|
|
NSRunLoop *runLoop;
|
|
|
|
NSDate *limitDate;
|
|
|
|
BOOL terminate;
|
|
|
|
void *fdPtr;
|
|
|
|
|
|
|
|
runLoop = [NSRunLoop currentRunLoop];
|
|
|
|
#if LONG_MAX > INT_MAX
|
|
|
|
fdPtr = (void *) ([socket fileDescriptor] & 0xFFFFFFFFFFFFFFFF);
|
|
|
|
#else
|
|
|
|
fdPtr = (void *) [socket fileDescriptor];
|
|
|
|
#endif
|
|
|
|
[runLoop addEvent: fdPtr type: ET_RDESC
|
|
|
|
watcher: self forMode: NSDefaultRunLoopMode];
|
|
|
|
|
|
|
|
terminate = NO;
|
|
|
|
while (!terminate)
|
|
|
|
{
|
2010-11-04 15:54:05 +01:00
|
|
|
limitDate = [runLoop limitDateForMode: NSDefaultRunLoopMode];
|
2010-03-31 22:15:11 +02:00
|
|
|
[runLoop runMode: NSDefaultRunLoopMode beforeDate: limitDate];
|
|
|
|
}
|
|
|
|
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) run
|
|
|
|
{
|
|
|
|
BOOL rc;
|
|
|
|
|
|
|
|
[self _setupListeningSocket];
|
|
|
|
if (listeningSocket)
|
|
|
|
rc = [self _startRunLoopWithSocket: listeningSocket];
|
|
|
|
else
|
|
|
|
rc = NO;
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) _handleData: (NSData *) socketData
|
2010-04-20 23:30:17 +02:00
|
|
|
onSocket: (id <NGActiveSocket>) responseSocket
|
2010-03-31 22:15:11 +02:00
|
|
|
{
|
|
|
|
NSString *stringData;
|
|
|
|
SOGoSockDScanner *scanner;
|
|
|
|
SOGoSockDOperation *operation;
|
|
|
|
BOOL rc;
|
|
|
|
|
|
|
|
stringData = [[NSString alloc] initWithData: socketData
|
|
|
|
encoding: NSASCIIStringEncoding];
|
|
|
|
if (stringData)
|
|
|
|
{
|
|
|
|
scanner = [SOGoSockDScanner scannerWithString: stringData];
|
|
|
|
operation = [scanner operation];
|
|
|
|
if (operation)
|
|
|
|
{
|
|
|
|
rc = YES;
|
2010-04-20 23:30:17 +02:00
|
|
|
[operation respondOnSocket: (NGActiveSocket *) responseSocket];
|
2010-03-31 22:15:11 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
rc = NO;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
rc = NO;
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) _acceptAndHandle
|
|
|
|
{
|
2010-04-20 23:30:17 +02:00
|
|
|
id <NGActiveSocket> socket;
|
2010-03-31 22:15:11 +02:00
|
|
|
char buffer[1024];
|
|
|
|
unsigned int count;
|
|
|
|
NSMutableData *socketData;
|
|
|
|
BOOL done;
|
|
|
|
NSAutoreleasePool *pool;
|
|
|
|
|
|
|
|
pool = [NSAutoreleasePool new];
|
|
|
|
socketData = [NSMutableData dataWithCapacity: 16384];
|
|
|
|
|
|
|
|
socket = [listeningSocket accept];
|
|
|
|
done = NO;
|
|
|
|
|
|
|
|
while (!done)
|
|
|
|
{
|
|
|
|
count = [socket readBytes: buffer count: 1024];
|
|
|
|
if (count == NGStreamError)
|
|
|
|
done = YES;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (buffer[count-2] == '\n' && buffer[count-1] == '\n')
|
|
|
|
{
|
|
|
|
done = YES;
|
|
|
|
count -= 2;
|
|
|
|
}
|
|
|
|
[socketData appendBytes: buffer length: count];
|
|
|
|
[self _handleData: socketData onSocket: socket];
|
|
|
|
socketData = [NSMutableData dataWithCapacity: 16384];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[pool release];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) receivedEvent: (void*) data
|
|
|
|
type: (RunLoopEventType) type
|
|
|
|
extra: (void*) extra
|
|
|
|
forMode: (NSString*) mode
|
|
|
|
{
|
|
|
|
if (type == ET_RDESC)
|
|
|
|
[self _acceptAndHandle];
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|