mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-05-20 19:05:25 +00:00
Monotone-Parent: 1386ff575a581ce153a4d70c50dc0bed29d339ed
Monotone-Revision: 2f9e650d437ad6f3b4629d6df38c98b8151e4f0f Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2010-03-31T20:15:11 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
/* 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)
|
||||
{
|
||||
limitDate = [runLoop limitDateForMode:NSDefaultRunLoopMode];
|
||||
[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
|
||||
onSocket: (NGActiveSocket *) responseSocket
|
||||
{
|
||||
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;
|
||||
[operation respondOnSocket: responseSocket];
|
||||
}
|
||||
else
|
||||
rc = NO;
|
||||
}
|
||||
else
|
||||
rc = NO;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (void) _acceptAndHandle
|
||||
{
|
||||
NGActiveSocket *socket;
|
||||
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
|
||||
Reference in New Issue
Block a user