From a9ac85a970629b911cebfd8ec5f0f7704742f47f Mon Sep 17 00:00:00 2001 From: helge Date: Mon, 11 Jul 2005 12:26:39 +0000 Subject: [PATCH] consolidated imap client objects to NGImap4 git-svn-id: http://svn.opengroupware.org/SOGo/trunk@709 d1b88da0-ebda-0310-925b-ed51d893ca5b --- SOGo/SoObjects/Mailer/ChangeLog | 5 + SOGo/SoObjects/Mailer/GNUmakefile | 2 - SOGo/SoObjects/Mailer/SOGoMailBaseObject.h | 5 +- SOGo/SoObjects/Mailer/SOGoMailBaseObject.m | 4 +- .../Mailer/SOGoMailConnectionEntry.h | 136 --- .../Mailer/SOGoMailConnectionEntry.m | 875 ------------------ SOGo/SoObjects/Mailer/SOGoMailFolder.h | 8 +- SOGo/SoObjects/Mailer/SOGoMailFolder.m | 2 +- .../Mailer/SOGoMailFolderDataSource.m | 7 +- SOGo/SoObjects/Mailer/SOGoMailManager.h | 18 +- SOGo/SoObjects/Mailer/SOGoMailManager.m | 267 +----- SOGo/SoObjects/Mailer/SOGoMailboxInfo.h | 60 -- SOGo/SoObjects/Mailer/SOGoMailboxInfo.m | 101 -- SOGo/SoObjects/Mailer/Version | 3 +- SOGo/SoObjects/Sieve/ChangeLog | 4 + SOGo/SoObjects/Sieve/SOGoSieveBaseObject.h | 4 +- SOGo/SoObjects/Sieve/SOGoSieveBaseObject.m | 2 +- SOGo/SoObjects/Sieve/Version | 3 +- 18 files changed, 76 insertions(+), 1430 deletions(-) delete mode 100644 SOGo/SoObjects/Mailer/SOGoMailConnectionEntry.h delete mode 100644 SOGo/SoObjects/Mailer/SOGoMailConnectionEntry.m delete mode 100644 SOGo/SoObjects/Mailer/SOGoMailboxInfo.h delete mode 100644 SOGo/SoObjects/Mailer/SOGoMailboxInfo.m diff --git a/SOGo/SoObjects/Mailer/ChangeLog b/SOGo/SoObjects/Mailer/ChangeLog index a26ab25b..6f7e8464 100644 --- a/SOGo/SoObjects/Mailer/ChangeLog +++ b/SOGo/SoObjects/Mailer/ChangeLog @@ -1,3 +1,8 @@ +2005-07-11 Helge Hess + + * moved SOGoMailManager related API to NGImap4 (NGImap4Connection, + NGImap4ConnectionManager, etc) (v0.9.96) + 2005-07-11 Helge Hess * v0.9.95 diff --git a/SOGo/SoObjects/Mailer/GNUmakefile b/SOGo/SoObjects/Mailer/GNUmakefile index 3072cb38..db0556ea 100644 --- a/SOGo/SoObjects/Mailer/GNUmakefile +++ b/SOGo/SoObjects/Mailer/GNUmakefile @@ -10,8 +10,6 @@ Mailer_OBJC_FILES += \ Product.m \ \ SOGoMailManager.m \ - SOGoMailboxInfo.m \ - SOGoMailConnectionEntry.m \ \ SOGoMailBaseObject.m \ SOGoMailAccounts.m \ diff --git a/SOGo/SoObjects/Mailer/SOGoMailBaseObject.h b/SOGo/SoObjects/Mailer/SOGoMailBaseObject.h index da6b83c9..4731a928 100644 --- a/SOGo/SoObjects/Mailer/SOGoMailBaseObject.h +++ b/SOGo/SoObjects/Mailer/SOGoMailBaseObject.h @@ -39,8 +39,7 @@ */ @class NSString, NSArray, NSURL; -@class NGImap4Client; -@class SOGoMailManager; +@class NGImap4Client, NGImap4ConnectionManager, NGImap4Connection; @class SOGoMailAccount; @interface SOGoMailBaseObject : SOGoObject @@ -56,7 +55,7 @@ /* IMAP4 */ -- (SOGoMailManager *)mailManager; +- (NGImap4ConnectionManager *)mailManager; - (NSURL *)imap4URL; - (NSString *)imap4Login; - (NSString *)imap4Password; diff --git a/SOGo/SoObjects/Mailer/SOGoMailBaseObject.m b/SOGo/SoObjects/Mailer/SOGoMailBaseObject.m index d366f40e..270f471f 100644 --- a/SOGo/SoObjects/Mailer/SOGoMailBaseObject.m +++ b/SOGo/SoObjects/Mailer/SOGoMailBaseObject.m @@ -61,8 +61,8 @@ static BOOL debugOn = YES; /* IMAP4 */ -- (SOGoMailManager *)mailManager { - return [SOGoMailManager defaultMailManager]; +- (NGImap4ConnectionManager *)mailManager { + return [NGImap4ConnectionManager defaultConnectionManager]; } - (NSString *)relativeImap4Name { diff --git a/SOGo/SoObjects/Mailer/SOGoMailConnectionEntry.h b/SOGo/SoObjects/Mailer/SOGoMailConnectionEntry.h deleted file mode 100644 index 962df8b3..00000000 --- a/SOGo/SoObjects/Mailer/SOGoMailConnectionEntry.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - Copyright (C) 2004-2005 SKYRIX Software AG - - This file is part of OpenGroupware.org. - - OGo is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - OGo 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 Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with OGo; see the file COPYING. If not, write to the - Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -#ifndef __SOGo_SOGoMailConnectionEntry_H__ -#define __SOGo_SOGoMailConnectionEntry_H__ - -#import - -/* - SOGoMailConnectionEntry - - A cached connection to an IMAP4 server plus some cached objects. - - It caches: - - the folder hierarchy - - uid sets? - - 'myrights' permissions of mailboxes - ? -*/ - -@class NSString, NSDate, NSArray, NSDictionary, NSURL, NSMutableDictionary; -@class NSException, NSData; -@class NGImap4Client; - -@interface SOGoMailConnectionEntry : NSObject -{ -@public - NGImap4Client *client; - NSString *password; - NSDate *creationTime; - - /* hierarchy cache */ - NSDictionary *subfolders; - - /* permission cache */ - NSMutableDictionary *urlToRights; - - /* uids cache */ - NSArray *cachedUIDs; - NSURL *uidFolderURL; - id uidSortOrdering; -} - -- (id)initWithClient:(NGImap4Client *)_client password:(NSString *)_pwd; - -/* accessors */ - -- (NGImap4Client *)client; -- (BOOL)isValidPassword:(NSString *)_pwd; - -- (NSDate *)creationTime; - -- (void)cacheHierarchyResults:(NSDictionary *)_hierarchy; -- (NSDictionary *)cachedHierarchyResults; -- (void)flushFolderHierarchyCache; - -- (id)cachedUIDsForURL:(NSURL *)_url qualifier:(id)_q sortOrdering:(id)_so; -- (void)cacheUIDs:(NSArray *)_uids forURL:(NSURL *)_url - qualifier:(id)_q sortOrdering:(id)_so; - -- (NSString *)cachedMyRightsForURL:(NSURL *)_url; -- (void)cacheMyRights:(NSString *)_rights forURL:(NSURL *)_url; - -- (void)flushMailCaches; - -/* folder operations */ - -- (NSArray *)subfoldersForURL:(NSURL *)_url; -- (NSArray *)allFoldersForURL:(NSURL *)_url; - -/* message operations */ - -- (NSArray *)fetchUIDsInURL:(NSURL *)_url qualifier:(id)_qualifier - sortOrdering:(id)_so; -- (NSArray *)fetchUIDs:(NSArray *)_uids inURL:(NSURL *)_url - parts:(NSArray *)_parts; -- (id)fetchURL:(NSURL *)_url parts:(NSArray *)_parts; -- (NSData *)fetchContentOfBodyPart:(NSString *)_partId atURL:(NSURL *)_url; - -/* message flags */ - -- (NSException *)addOrRemove:(BOOL)_flag flags:(id)_f toURL:(NSURL *)_url; -- (NSException *)addFlags:(id)_f toURL:(NSURL *)_u; -- (NSException *)removeFlags:(id)_f toURL:(NSURL *)_u; -- (NSException *)markURLDeleted:(NSURL *)_url; -- (NSException *)addFlags:(id)_f toAllMessagesInURL:(NSURL *)_url; - -/* posting new data */ - -- (NSException *)postData:(NSData *)_data flags:(id)_f toFolderURL:(NSURL *)_u; - -/* operations */ - -- (NSException *)expungeAtURL:(NSURL *)_url; - -/* copying and moving */ - -- (NSException *)copyMailURL:(NSURL *)_srcurl toFolderURL:(NSURL *)_desturl; - -/* managing folders */ - -- (BOOL)doesMailboxExistAtURL:(NSURL *)_url; -- (id)infoForMailboxAtURL:(NSURL *)_url; -- (NSException *)createMailbox:(NSString *)_mailbox atURL:(NSURL *)_url; -- (NSException *)deleteMailboxAtURL:(NSURL *)_url; -- (NSException *)moveMailboxAtURL:(NSURL *)_srcurl toURL:(NSURL *)_desturl; - -/* ACLs */ - -- (NSDictionary *)aclForMailboxAtURL:(NSURL *)_url; -- (NSString *)myRightsForMailboxAtURL:(NSURL *)_url; - -@end - -extern NSArray *SOGoMailGetDirectChildren(NSArray *_array, NSString *_fn); -extern NSArray *SOGoMailExtractSubfolders(NSURL *_url, NSDictionary *_result); - -#endif /* __SOGo_SOGoMailConnectionEntry_H__ */ diff --git a/SOGo/SoObjects/Mailer/SOGoMailConnectionEntry.m b/SOGo/SoObjects/Mailer/SOGoMailConnectionEntry.m deleted file mode 100644 index bfb7a166..00000000 --- a/SOGo/SoObjects/Mailer/SOGoMailConnectionEntry.m +++ /dev/null @@ -1,875 +0,0 @@ -/* - Copyright (C) 2004-2005 SKYRIX Software AG - - This file is part of OpenGroupware.org. - - OGo is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - OGo 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 Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with OGo; see the file COPYING. If not, write to the - Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -#include "SOGoMailConnectionEntry.h" -#include "SOGoMailboxInfo.h" -#include "common.h" - -@implementation SOGoMailConnectionEntry - -static BOOL debugOn = NO; -static BOOL debugCache = NO; -static BOOL debugKeys = NO; -static BOOL alwaysSelect = NO; -static BOOL onlyFetchInbox = NO; -static NSString *imap4Separator = nil; - -+ (void)initialize { - NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; - - debugOn = [ud boolForKey:@"SOGoEnableIMAP4Debug"]; - debugCache = [ud boolForKey:@"SOGoEnableIMAP4CacheDebug"]; - alwaysSelect = [ud boolForKey:@"SOGoAlwaysSelectIMAP4Folder"]; - if (debugOn) NSLog(@"Note: SOGoEnableIMAP4Debug is enabled!"); - if (alwaysSelect) - NSLog(@"WARNING: 'SOGoAlwaysSelectIMAP4Folder' enabled (slow down)"); - - imap4Separator = [[ud stringForKey:@"SOGoIMAP4StringSeparator"] copy]; - if ([imap4Separator length] == 0) - imap4Separator = @"/"; - NSLog(@"Note(SOGoMailManager): using '%@' as the IMAP4 folder separator.", - imap4Separator); -} - -- (id)initWithClient:(NGImap4Client *)_client password:(NSString *)_pwd { - if (_client == nil || _pwd == nil) { - [self release]; - return nil; - } - - if ((self = [super init])) { - self->client = [_client retain]; - self->password = [_pwd copy]; - - self->creationTime = [[NSDate alloc] init]; - } - return self; -} -- (id)init { - return [self initWithClient:nil password:nil]; -} - -- (void)dealloc { - [self->urlToRights release]; - [self->cachedUIDs release]; - [self->uidFolderURL release]; - [self->uidSortOrdering release]; - [self->creationTime release]; - [self->subfolders release]; - [self->password release]; - [self->client release]; - [super dealloc]; -} - -/* accessors */ - -- (NGImap4Client *)client { - return self->client; -} -- (BOOL)isValidPassword:(NSString *)_pwd { - return [self->password isEqualToString:_pwd]; -} - -- (NSDate *)creationTime { - return self->creationTime; -} - -- (void)cacheHierarchyResults:(NSDictionary *)_hierarchy { - ASSIGNCOPY(self->subfolders, _hierarchy); -} -- (NSDictionary *)cachedHierarchyResults { - return self->subfolders; -} -- (void)flushFolderHierarchyCache { - [self->subfolders release]; self->subfolders = nil; - [self->urlToRights release]; self->urlToRights = nil; -} - -/* rights */ - -- (NSString *)cachedMyRightsForURL:(NSURL *)_url { - return (_url != nil) ? [self->urlToRights objectForKey:_url] : nil; -} -- (void)cacheMyRights:(NSString *)_rights forURL:(NSURL *)_url { - if (self->urlToRights == nil) - self->urlToRights = [[NSMutableDictionary alloc] initWithCapacity:8]; - [self->urlToRights setObject:_rights forKey:_url]; -} - -/* UIDs */ - -- (id)cachedUIDsForURL:(NSURL *)_url qualifier:(id)_q sortOrdering:(id)_so { - if (_q != nil) - return nil; - if (![_so isEqual:self->uidSortOrdering]) - return nil; - if (![self->uidFolderURL isEqual:_url]) - return nil; - - return self->cachedUIDs; -} - -- (void)cacheUIDs:(NSArray *)_uids forURL:(NSURL *)_url - qualifier:(id)_q sortOrdering:(id)_so -{ - if (_q != nil) - return; - - ASSIGNCOPY(self->uidSortOrdering, _so); - ASSIGNCOPY(self->uidFolderURL, _url); - ASSIGNCOPY(self->cachedUIDs, _uids); -} - -- (void)flushMailCaches { - ASSIGN(self->uidSortOrdering, nil); - ASSIGN(self->uidFolderURL, nil); - ASSIGN(self->cachedUIDs, nil); -} - -/* IMAP4 path/url processing methods */ - -NSArray *SOGoMailGetDirectChildren(NSArray *_array, NSString *_fn) { - /* - Scans string '_array' for strings which start with the string in '_fn'. - Then split on '/'. - */ - NSMutableArray *ma; - unsigned i, count, prefixlen; - - if ((count = [_array count]) < 2) - /* one entry is the folder itself, so we need at least two */ - return [NSArray array]; - -#if __APPLE__ - // TODO: somehow results are different on OSX - prefixlen = [_fn isEqualToString:@""] ? 0 : [_fn length] + 1; -#else - prefixlen = [_fn isEqualToString:@"/"] ? 1 : [_fn length] + 1; -#endif - ma = [NSMutableArray arrayWithCapacity:count]; - for (i = 0; i < count; i++) { - NSString *p; - - p = [_array objectAtIndex:i]; - if ([p length] <= prefixlen) - continue; - if (prefixlen != 0 && ![p hasPrefix:_fn]) - continue; - - /* cut of common part */ - p = [p substringFromIndex:prefixlen]; - - /* check whether the path is a sub-subfolder path */ - if ([p rangeOfString:@"/"].length > 0) - continue; - - [ma addObject:p]; - } - - [ma sortUsingSelector:@selector(compare:)]; - return ma; -} - -NSArray *SOGoMailExtractSubfolders(NSURL *_url, NSDictionary *_result) { - NSString *folderName; - NSDictionary *result; - NSArray *names; - NSArray *flags; - - /* Note: the result is normalized, that is, it contains / as the separator */ - folderName = [_url path]; -#if __APPLE__ - /* normalized results already have the / in front on libFoundation?! */ - if ([folderName hasPrefix:@"/"]) - folderName = [folderName substringFromIndex:1]; -#endif - - result = [_result valueForKey:@"list"]; - - /* Cyrus already tells us whether we need to check for children */ - flags = [result objectForKey:folderName]; - if ([flags containsObject:@"hasnochildren"]) { - if (debugKeys) - NSLog(@"%s: folder %@ has no children.", __PRETTY_FUNCTION__,folderName); - return nil; - } - - if (debugKeys) { - NSLog(@"%s: all keys %@: %@", __PRETTY_FUNCTION__, folderName, - [[result allKeys] componentsJoinedByString:@", "]); - } - - names = SOGoMailGetDirectChildren([result allKeys], folderName); - if (debugKeys) { - NSLog(@"%s: subfolders of '%@': %@", __PRETTY_FUNCTION__, folderName, - [names componentsJoinedByString:@","]); - } - return names; -} - -- (NSArray *)_getDirectChildren:(NSArray *)_array folderName:(NSString *)_fn { - return SOGoMailGetDirectChildren(_array, _fn); -} -- (NSArray *)extractSubfoldersForURL:(NSURL *)_url - fromResultSet:(NSDictionary *)_result -{ - return SOGoMailExtractSubfolders(_url, _result); -} - -- (NSString *)imap4Separator { - // TODO: make server specific ivar! - return imap4Separator; -} - -- (NSString *)imap4FolderNameForURL:(NSURL *)_url removeFileName:(BOOL)_delfn { - /* a bit hackish, but should be OK */ - NSString *folderName; - NSArray *names; - - if (_url == nil) - return nil; - - folderName = [_url path]; - if ([folderName length] == 0) - return nil; - if ([folderName characterAtIndex:0] == '/') - folderName = [folderName substringFromIndex:1]; - - if (_delfn) folderName = [folderName stringByDeletingLastPathComponent]; - - if ([[self imap4Separator] isEqualToString:@"/"]) - return folderName; - - names = [folderName pathComponents]; - return [names componentsJoinedByString:[self imap4Separator]]; -} -- (NSString *)imap4FolderNameForURL:(NSURL *)_url { - return [self imap4FolderNameForURL:_url removeFileName:NO]; -} - -- (NSArray *)extractFoldersFromResultSet:(NSDictionary *)_result { - /* Note: the result is normalized, that is, it contains / as the separator */ - return [[_result valueForKey:@"list"] allKeys]; -} - -/* folder selections */ - -- (BOOL)selectFolder:(id)_url { - NSDictionary *result; - NSString *newFolder; - - newFolder = [_url isKindOfClass:[NSURL class]] - ? [self imap4FolderNameForURL:_url] - : _url; - - if (!alwaysSelect) { - if ([[[self client] selectedFolderName] isEqualToString:newFolder]) - return YES; - } - - result = [[self client] select:newFolder]; - if (![[result valueForKey:@"result"] boolValue]) { - [self errorWithFormat:@"could not select URL: %@: %@", _url, result]; - return NO; - } - - return YES; -} - -- (BOOL)isPermissionDeniedResult:(id)_result { - if ([[_result valueForKey:@"result"] intValue] != 0) - return NO; - - return [[_result valueForKey:@"reason"] - isEqualToString:@"Permission denied"]; -} - -/* folder operations */ - -- (NSArray *)subfoldersForURL:(NSURL *)_url { - NSDictionary *result; - - /* check hierarchy cache */ - - if ((result = [self cachedHierarchyResults]) != nil) - return [self extractSubfoldersForURL:_url fromResultSet:result]; - - [self debugWithFormat:@" no folders cached yet .."]; - - /* fetch _all_ folders */ - - result = [[self client] list:(onlyFetchInbox ? @"INBOX" : @"*") - pattern:@"*"]; - if (![[result valueForKey:@"result"] boolValue]) { - [self errorWithFormat:@"listing of folder failed!"]; - return nil; - } - - /* cache results */ - - if ([result isNotNull]) { - [self cacheHierarchyResults:result]; - if (debugCache) { - [self logWithFormat:@"cached results in entry %@: 0x%08X(%d)", - self, result, [result count]]; - } - } - - /* extract list */ - - return [self extractSubfoldersForURL:_url fromResultSet:result]; -} - -- (NSArray *)allFoldersForURL:(NSURL *)_url { - NSDictionary *result; - - /* check hierarchy cache */ - - if ((result = [self cachedHierarchyResults]) != nil) - return [self extractFoldersFromResultSet:result]; - - [self debugWithFormat:@" no folders cached yet .."]; - - /* fetch _all_ folders */ - - result = [[self client] list:@"INBOX" pattern:@"*"]; - if (![[result valueForKey:@"result"] boolValue]) { - [self logWithFormat:@"ERROR: listing of folder failed!"]; - return nil; - } - - /* cache results */ - - if ([result isNotNull]) { - [self cacheHierarchyResults:result]; - if (debugCache) { - [self logWithFormat:@"cached results in entry %@: 0x%08X(%d)", - self, result, [result count]]; - } - } - - /* extract list */ - return [self extractFoldersFromResultSet:result]; -} - -/* message operations */ - -- (NSArray *)fetchUIDsInURL:(NSURL *)_url qualifier:(id)_qualifier - sortOrdering:(id)_so -{ - /* - sortOrdering can be an NSString, an EOSortOrdering or an array of EOS. - */ - NSDictionary *result; - NSArray *uids; - - /* check cache */ - - uids = [self cachedUIDsForURL:_url qualifier:_qualifier sortOrdering:_so]; - if (uids != nil) { - if (debugCache) [self logWithFormat:@"reusing uid cache!"]; - return [uids isNotNull] ? uids : nil; - } - - /* select folder and fetch */ - - if (![self selectFolder:_url]) - return nil; - - result = [[self client] sort:_so qualifier:_qualifier encoding:@"UTF-8"]; - if (![[result valueForKey:@"result"] boolValue]) { - [self errorWithFormat:@"could not sort contents of URL: %@", _url]; - return nil; - } - - uids = [result valueForKey:@"sort"]; - if (![uids isNotNull]) { - [self errorWithFormat:@"got no UIDs for URL: %@: %@", _url, result]; - return nil; - } - - /* cache */ - - [self cacheUIDs:uids forURL:_url qualifier:_qualifier sortOrdering:_so]; - return uids; -} - -- (NSArray *)fetchUIDs:(NSArray *)_uids inURL:(NSURL *)_url - parts:(NSArray *)_parts -{ - // currently returns a dict?! - /* - Allowed fetch keys: - UID - BODY.PEEK[
]<> - BODY [this is the bodystructure, supported] - BODYSTRUCTURE [not supported yet!] - ENVELOPE [this is a parsed header, but does not include type] - FLAGS - INTERNALDATE - RFC822 - RFC822.HEADER - RFC822.SIZE - RFC822.TEXT - */ - NSDictionary *result; - - if (_uids == nil) - return nil; - if ([_uids count] == 0) - return nil; // TODO: might break empty folders?! return a dict! - - /* select folder */ - - if (![self selectFolder:_url]) - return nil; - - /* fetch parts */ - - // TODO: split uids into batches, otherwise Cyrus will complain - // => not really important because we batch before (in the sort) - // if the list is too long, we get a: - // "* BYE Fatal error: word too long" - - result = [[self client] fetchUids:_uids parts:_parts]; - if (![[result valueForKey:@"result"] boolValue]) { - [self errorWithFormat:@"could not fetch %d uids for url: %@", - [_uids count],_url]; - return nil; - } - - //[self logWithFormat:@"RESULT: %@", result]; - return (id)result; -} - -- (id)fetchURL:(NSURL *)_url parts:(NSArray *)_parts { - // currently returns a dict - NSDictionary *result; - NSString *uid; - - if (![_url isNotNull]) return nil; - - /* select folder */ - - uid = [self imap4FolderNameForURL:_url removeFileName:YES]; - if (![self selectFolder:uid]) - return nil; - - /* fetch parts */ - - uid = [[_url path] lastPathComponent]; - - result = [client fetchUids:[NSArray arrayWithObject:uid] parts:_parts]; - if (![[result valueForKey:@"result"] boolValue]) { - [self errorWithFormat:@"could not fetch url: %@", _url]; - return nil; - } - //[self logWithFormat:@"RESULT: %@", result]; - return (id)result; -} - -- (NSData *)fetchContentOfBodyPart:(NSString *)_partId atURL:(NSURL *)_url { - NSString *key; - NSArray *parts; - id result, fetch, body; - - if (_partId == nil) return nil; - - key = [@"body[" stringByAppendingString:_partId]; - key = [key stringByAppendingString:@"]"]; - parts = [NSArray arrayWithObjects:&key count:1]; - - /* fetch */ - - result = [self fetchURL:_url parts:parts]; - - /* process results */ - - result = [result objectForKey:@"fetch"]; - if ([result count] == 0) { /* did not find part */ - [self errorWithFormat:@"did not find part: %@", _partId]; - return nil; - } - - fetch = [result objectAtIndex:0]; - if ((body = [fetch objectForKey:@"body"]) == nil) { - [self errorWithFormat:@"did not find body in response: %@", result]; - return nil; - } - - if ((result = [body objectForKey:@"data"]) == nil) { - [self errorWithFormat:@"did not find data in body: %@", fetch]; - return nil; - } - return result; -} - -/* message flags */ - -- (NSException *)addOrRemove:(BOOL)_flag flags:(id)_f toURL:(NSURL *)_url { - id result; - - if (![_url isNotNull]) return nil; - if (![_f isNotNull]) return nil; - - if (![_f isKindOfClass:[NSArray class]]) - _f = [NSArray arrayWithObjects:&_f count:1]; - - /* select folder */ - - if (![self selectFolder: - [self imap4FolderNameForURL:_url removeFileName:YES]]) { - return [NSException exceptionWithHTTPStatus:404 /* server error */ - reason:@"could not select IMAP4 folder"]; - } - - /* store flags */ - - result = [[self client] storeUid:[[[_url path] lastPathComponent] intValue] - add:[NSNumber numberWithBool:_flag] - flags:_f]; - if (![[result valueForKey:@"result"] boolValue]) { - unsigned int status; - NSString *r; - - r = [result valueForKey:@"reason"]; - if ([r isEqualToString:@"Permission denied"]) { - /* different for each server?, no error codes in IMAP4 ... */ - status = 403 /* Forbidden */; - } - else - status = 500 /* internal server error */; - - [self logWithFormat:@"DEBUG: fail result %@", result]; - - r = [@"Failed to add flag to IMAP4 message: " stringByAppendingString:r]; - - return [NSException exceptionWithHTTPStatus:status /* server error */ - reason:r]; - } - /* result contains 'fetch' key with the current flags */ - return nil; -} -- (NSException *)addFlags:(id)_f toURL:(NSURL *)_u { - return [self addOrRemove:YES flags:_f toURL:_u]; -} -- (NSException *)removeFlags:(id)_f toURL:(NSURL *)_u { - return [self addOrRemove:NO flags:_f toURL:_u]; -} - -- (NSException *)markURLDeleted:(NSURL *)_url { - return [self addOrRemove:YES flags:@"Deleted" toURL:_url]; -} - -- (NSException *)addFlags:(id)_f toAllMessagesInURL:(NSURL *)_url { - id result; - - if (![_url isNotNull]) return nil; - if (![_f isNotNull]) return nil; - - if (![_f isKindOfClass:[NSArray class]]) - _f = [NSArray arrayWithObjects:&_f count:1]; - - /* select folder */ - - if (![self selectFolder:[self imap4FolderNameForURL:_url]]) { - return [NSException exceptionWithHTTPStatus:404 /* not found */ - reason:@"could not select IMAP4 folder"]; - } - - /* fetch all sequence numbers */ - - result = [client searchWithQualifier:nil /* means: ALL */]; - if (![[result valueForKey:@"result"] boolValue]) { - return [NSException exceptionWithHTTPStatus:500 /* server error */ - reason:@"could not search in IMAP4 folder"]; - } - - result = [result valueForKey:@"search"]; - if ([result count] == 0) /* no messages in there, nothin' to be done */ - return nil; - - /* store flags */ - - result = [[self client] storeFlags:_f forMSNs:result addOrRemove:YES]; - if (![[result valueForKey:@"result"] boolValue]) { - return [NSException exceptionWithHTTPStatus:500 /* server error */ - reason:@"could not change flags in IMAP4 folder"]; - } - - return nil; -} - -/* posting new data */ - -- (NSException *)postData:(NSData *)_data flags:(id)_f - toFolderURL:(NSURL *)_url -{ - id result; - - if (![_url isNotNull]) return nil; - if (![_f isNotNull]) _f = [NSArray array]; - - if (![_f isKindOfClass:[NSArray class]]) - _f = [NSArray arrayWithObjects:&_f count:1]; - - result = [[self client] append:_data - toFolder:[self imap4FolderNameForURL:_url] - withFlags:_f]; - if (![[result valueForKey:@"result"] boolValue]) { - [self logWithFormat:@"DEBUG: fail result %@", result]; - return [NSException exceptionWithHTTPStatus:500 /* server error */ - reason:@"failed to store message to IMAP4 message"]; - } - /* result contains 'fetch' key with the current flags */ - - // TODO: need to flush any caches? - return nil; -} - -/* operations */ - -- (NSException *)expungeAtURL:(NSURL *)_url { - NSString *p; - id result; - - /* select folder */ - - p = [self imap4FolderNameForURL:_url removeFileName:NO]; - if (![self selectFolder:p]) { - return [NSException exceptionWithHTTPStatus:501 /* Server Error */ - reason:@"could not select IMAP4 folder!"]; - } - - /* expunge */ - - result = [[self client] expunge]; - - if (![[result valueForKey:@"result"] boolValue]) { - [self errorWithFormat:@"could not expunge url: %@", _url]; - return nil; - } - //[self logWithFormat:@"RESULT: %@", result]; - return nil; -} - -/* copying and moving */ - -- (NSException *)copyMailURL:(NSURL *)_srcurl toFolderURL:(NSURL *)_desturl { - NSString *srcname, *destname; - unsigned uid; - id result; - - /* names */ - - srcname = [self imap4FolderNameForURL:_srcurl removeFileName:YES]; - uid = [[[_srcurl path] lastPathComponent] unsignedIntValue]; - destname = [self imap4FolderNameForURL:_desturl]; - - /* select source folder */ - - if (![self selectFolder:srcname]) { - return [NSException exceptionWithHTTPStatus:404 /* Not Found */ - reason:@"did not find source folder"]; - } - - /* copy */ - - result = [[self client] copyUid:uid toFolder:destname]; - if (![[result valueForKey:@"result"] boolValue]) { - return [NSException exceptionWithHTTPStatus:500 /* Server Error */ - reason:@"copy operation failed"]; - } - - // TODO: need to flush some caches? - - return nil; -} - -/* managing folders */ - -- (BOOL)doesMailboxExistAtURL:(NSURL *)_url { - NSString *folderName; - id result; - - /* check in hierarchy cache */ - - if ((result = [self cachedHierarchyResults]) != nil) { - result = [result objectForKey:@"list"]; - return ([result objectForKey:[_url path]] != nil) ? YES : NO; - } - - /* check using IMAP4 select */ - // TODO: we should probably just fetch the whole hierarchy? - - folderName = [self imap4FolderNameForURL:_url]; - result = [[self client] select:folderName]; - if (![[result valueForKey:@"result"] boolValue]) - return NO; - - return YES; -} - -- (id)infoForMailboxAtURL:(NSURL *)_url { - SOGoMailboxInfo *info; - NSString *folderName; - id result; - - folderName = [self imap4FolderNameForURL:_url]; - result = [[self client] select:folderName]; - if (![[result valueForKey:@"result"] boolValue]) { - return [NSException exceptionWithHTTPStatus:404 /* Not Found */ - reason:@"did not find IMAP4 folder (select failed)"]; - } - - info = [[SOGoMailboxInfo alloc] initWithURL:_url folderName:folderName - selectDictionary:result]; - return [info autorelease]; -} - -- (NSException *)createMailbox:(NSString *)_mailbox atURL:(NSURL *)_url { - NSString *newPath; - id result; - - /* construct path */ - - newPath = [self imap4FolderNameForURL:_url]; - newPath = [newPath stringByAppendingString:[self imap4Separator]]; - newPath = [newPath stringByAppendingString:_mailbox]; - - /* create */ - - result = [[self client] create:newPath]; - if ([self isPermissionDeniedResult:result]) { - return [NSException exceptionWithHTTPStatus:403 /* forbidden */ - reason:@"creation of folders not allowed"]; - } - else if ([[result valueForKey:@"result"] intValue] == 0) { - return [NSException exceptionWithHTTPStatus:500 /* server error */ - reason:[result valueForKey:@"reason"]]; - } - - [self flushFolderHierarchyCache]; - // [self debugWithFormat:@"created mailbox: %@: %@", newPath, result]; - return nil; -} - -- (NSException *)deleteMailboxAtURL:(NSURL *)_url { - NSString *path; - id result; - - /* delete */ - - path = [self imap4FolderNameForURL:_url]; - result = [[self client] delete:path]; - - if ([self isPermissionDeniedResult:result]) { - return [NSException exceptionWithHTTPStatus:403 /* forbidden */ - reason:@"creation of folders not allowed"]; - } - else if ([[result valueForKey:@"result"] intValue] == 0) { - return [NSException exceptionWithHTTPStatus:500 /* server error */ - reason:[result valueForKey:@"reason"]]; - } - - [self flushFolderHierarchyCache]; -#if 0 - [self debugWithFormat:@"delete mailbox %@: %@", _url, result]; -#endif - return nil; -} - -- (NSException *)moveMailboxAtURL:(NSURL *)_srcurl toURL:(NSURL *)_desturl { - NSString *srcname, *destname; - id result; - - /* rename */ - - srcname = [self imap4FolderNameForURL:_srcurl]; - destname = [self imap4FolderNameForURL:_desturl]; - - result = [[self client] rename:srcname to:destname]; - - if ([self isPermissionDeniedResult:result]) { - return [NSException exceptionWithHTTPStatus:403 /* forbidden */ - reason:@"creation of folders not allowed"]; - } - else if ([[result valueForKey:@"result"] intValue] == 0) { - return [NSException exceptionWithHTTPStatus:500 /* server error */ - reason:[result valueForKey:@"reason"]]; - } - - [self flushFolderHierarchyCache]; -#if 0 - [self debugWithFormat:@"renamed mailbox %@: %@", _srcurl, result]; -#endif - return nil; -} - -/* ACLs */ - -- (NSDictionary *)aclForMailboxAtURL:(NSURL *)_url { - /* - Returns a mapping of uid => permission strings, eg: - guizmo.g = lrs; - root = lrswipcda; - */ - NSString *folderName; - id result; - - folderName = [self imap4FolderNameForURL:_url]; - result = [[self client] getACL:folderName]; - if (![[result valueForKey:@"result"] boolValue]) { - [self logWithFormat:@"ERROR: getacl failed: %@", result]; - return [NSException exceptionWithHTTPStatus:404 /* Not Found */ - reason:@"did not find ACL for IMAP4 folder"]; - } - - return [result valueForKey:@"acl"]; -} - -- (NSString *)myRightsForMailboxAtURL:(NSURL *)_url { - NSString *folderName; - id result; - - /* check cache */ - - if ((result = [self cachedMyRightsForURL:_url]) != nil) - return result; - - /* run IMAP4 op */ - - folderName = [self imap4FolderNameForURL:_url]; - result = [[self client] myRights:folderName]; - if (![[result valueForKey:@"result"] boolValue]) { - [self logWithFormat:@"ERROR: myrights failed: %@", result]; - return [NSException exceptionWithHTTPStatus:404 /* Not Found */ - reason:@"did not find myrights for IMAP4 folder"]; - } - - /* cache results */ - - if ((result = [result valueForKey:@"myrights"]) != nil) - [self cacheMyRights:result forURL:_url]; - return result; -} - -@end /* SOGoMailConnectionEntry */ diff --git a/SOGo/SoObjects/Mailer/SOGoMailFolder.h b/SOGo/SoObjects/Mailer/SOGoMailFolder.h index c4e49612..3da76ac7 100644 --- a/SOGo/SoObjects/Mailer/SOGoMailFolder.h +++ b/SOGo/SoObjects/Mailer/SOGoMailFolder.h @@ -34,13 +34,13 @@ */ @class NSData, NSArray, NSException; -@class SOGoMailboxInfo; +@class NGImap4MailboxInfo; @interface SOGoMailFolder : SOGoMailBaseObject { - NSArray *filenames; - NSString *folderType; - SOGoMailboxInfo *selectInfo; + NSArray *filenames; + NSString *folderType; + NGImap4MailboxInfo *selectInfo; struct { int didCheckMyRights:1; int isDeleteAndExpungeAllowed:1; diff --git a/SOGo/SoObjects/Mailer/SOGoMailFolder.m b/SOGo/SoObjects/Mailer/SOGoMailFolder.m index 262278f0..38f61194 100644 --- a/SOGo/SoObjects/Mailer/SOGoMailFolder.m +++ b/SOGo/SoObjects/Mailer/SOGoMailFolder.m @@ -23,7 +23,7 @@ #include "SOGoMailObject.h" #include "SOGoMailAccount.h" #include "SOGoMailManager.h" -#include "SOGoMailboxInfo.h" +#include #include "SOGoMailFolderDataSource.h" #include "common.h" diff --git a/SOGo/SoObjects/Mailer/SOGoMailFolderDataSource.m b/SOGo/SoObjects/Mailer/SOGoMailFolderDataSource.m index 8f5f33bf..f9aba487 100644 --- a/SOGo/SoObjects/Mailer/SOGoMailFolderDataSource.m +++ b/SOGo/SoObjects/Mailer/SOGoMailFolderDataSource.m @@ -68,9 +68,10 @@ static BOOL debugOn = NO; return self->imap4URL; } -- (SOGoMailManager *)mailManager { - static SOGoMailManager *mm = nil; - if (mm == nil) mm = [[SOGoMailManager defaultMailManager] retain]; +- (NGImap4ConnectionManager *)mailManager { + static NGImap4ConnectionManager *mm = nil; + if (mm == nil) + mm = [[NGImap4ConnectionManager defaultConnectionManager] retain]; return mm; } diff --git a/SOGo/SoObjects/Mailer/SOGoMailManager.h b/SOGo/SoObjects/Mailer/SOGoMailManager.h index 7cd9f7ed..fb357502 100644 --- a/SOGo/SoObjects/Mailer/SOGoMailManager.h +++ b/SOGo/SoObjects/Mailer/SOGoMailManager.h @@ -24,29 +24,19 @@ #import #import +#include /* - SOGoMailManager + NGImap4ConnectionManager(SOGoMailManager) - Coordinates access to IMAP4 mailboxes, caches folder hierarchies, etc. + Legacy methods, the methods were used prior the move to NGImap4. */ @class NSString, NSData, NSURL, NSArray, NSMutableDictionary, NSTimer; @class NSException; @class NGImap4Client; -@interface SOGoMailManager : NSObject -{ - NSMutableDictionary *urlToEntry; - NSTimer *gcTimer; -} - -+ (id)defaultMailManager; - -/* client object */ - -- (NGImap4Client *)imap4ClientForURL:(NSURL *)_url password:(NSString *)_pwd; -- (void)flushCachesForURL:(NSURL *)_url; +@interface NGImap4ConnectionManager(SOGoMailManager) /* folder hierarchy */ diff --git a/SOGo/SoObjects/Mailer/SOGoMailManager.m b/SOGo/SoObjects/Mailer/SOGoMailManager.m index 0049d6bd..f3e947a3 100644 --- a/SOGo/SoObjects/Mailer/SOGoMailManager.m +++ b/SOGo/SoObjects/Mailer/SOGoMailManager.m @@ -20,7 +20,8 @@ */ #include "SOGoMailManager.h" -#include "SOGoMailConnectionEntry.h" +#include +#include #include "common.h" /* @@ -34,118 +35,12 @@ NGImap4Client. */ -@implementation SOGoMailManager - -static BOOL debugOn = NO; -static BOOL debugCache = NO; -static BOOL debugKeys = NO; -static BOOL poolingOff = NO; -static NSTimeInterval PoolScanInterval = 5 * 60 /* every five minutes */; - -+ (void)initialize { - NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; - - debugOn = [ud boolForKey:@"SOGoEnableIMAP4Debug"]; - debugCache = [ud boolForKey:@"SOGoEnableIMAP4CacheDebug"]; - poolingOff = [ud boolForKey:@"SOGoDisableIMAP4Pooling"]; - - if (debugOn) NSLog(@"Note: SOGoEnableIMAP4Debug is enabled!"); - if (poolingOff) NSLog(@"WARNING: IMAP4 connection pooling is disabled!"); -} +@implementation NGImap4ConnectionManager(SOGoMailManager) + (id)defaultMailManager { - static SOGoMailManager *manager = nil; // THREAD - if (manager == nil) - manager = [[self alloc] init]; - return manager; -} - -- (id)init { - if ((self = [super init])) { - if (!poolingOff) { - self->urlToEntry = [[NSMutableDictionary alloc] initWithCapacity:256]; - } - - self->gcTimer = [[NSTimer scheduledTimerWithTimeInterval: - PoolScanInterval - target:self selector:@selector(_garbageCollect:) - userInfo:nil repeats:YES] retain]; - } - return self; -} - -- (void)dealloc { - if (self->gcTimer) [self->gcTimer invalidate]; - [self->gcTimer release]; - - [self->urlToEntry release]; - [super dealloc]; -} - -/* cache */ - -- (id)cacheKeyForURL:(NSURL *)_url { - // protocol, user, host, port - return [NSString stringWithFormat:@"%@://%@@%@:%@", - [_url scheme], [_url user], [_url host], [_url port]]; + return [self defaultConnectionManager]; } -- (SOGoMailConnectionEntry *)entryForURL:(NSURL *)_url { - if (_url == nil) - return nil; - - return [self->urlToEntry objectForKey:[self cacheKeyForURL:_url]]; -} -- (void)cacheEntry:(SOGoMailConnectionEntry *)_entry forURL:(NSURL *)_url { - if (_entry == nil) _entry = (id)[NSNull null]; - [self->urlToEntry setObject:_entry forKey:[self cacheKeyForURL:_url]]; -} - -- (void)_garbageCollect:(NSTimer *)_timer { - // TODO: scan for old IMAP4 channels - [self debugWithFormat:@"should collect IMAP4 channels (%d active)", - [self->urlToEntry count]]; -} - -- (id)entryForURL:(NSURL *)_url password:(NSString *)_pwd { - /* - Three cases: - a) not yet connected => create new entry and connect - b) connected, correct password => return cached entry - c) connected, different password => try to recreate entry - */ - SOGoMailConnectionEntry *entry; - NGImap4Client *client; - - /* check cache */ - - if ((entry = [self entryForURL:_url]) != nil) { - if ([entry isValidPassword:_pwd]) { - if (debugCache) - [self logWithFormat:@"valid password, reusing cache entry ..."]; - return entry; - } - - /* different password, password could have changed! */ - if (debugCache) - [self logWithFormat:@"different password than cached entry: %@", _url]; - entry = nil; - } - else - [self debugWithFormat:@"no connection cached yet for url: %@", _url]; - - /* try to login */ - - client = [entry isValidPassword:_pwd] - ? [entry client] - : [self imap4ClientForURL:_url password:_pwd]; - - if (client == nil) - return nil; - - /* sideeffect of -imap4ClientForURL:password: is to create a cache entry */ - return [self entryForURL:_url]; -} - (NSException *)errorForMissingEntryAtURL:(NSURL *)_url { // TODO: improve @@ -155,94 +50,24 @@ static NSTimeInterval PoolScanInterval = 5 * 60 /* every five minutes */; /* client object */ -- (NGImap4Client *)imap4ClientForURL:(NSURL *)_url password:(NSString *)_pwd { - // TODO: move to some global IMAP4 connection pool manager - SOGoMailConnectionEntry *entry; - NGImap4Client *client; - NSDictionary *result; - - if (_url == nil) - return nil; - - /* check connection pool */ - - if ((entry = [self entryForURL:_url]) != nil) { - if ([entry isValidPassword:_pwd]) { - [self debugWithFormat:@"reused IMAP4 connection for URL: %@", _url]; - return [entry client]; - } - - /* different password, password could have changed! */ - entry = nil; - } - - /* setup connection and attempt login */ - - if ((client = [NGImap4Client clientWithURL:_url]) == nil) - return nil; - - result = [client login:[_url user] password:_pwd]; - if (![[result valueForKey:@"result"] boolValue]) { - [self errorWithFormat: - @"IMAP4 login failed:\n" - @" host=%@, user=%@, pwd=%s\n" - @" url=%@\n base=%@\n base-class=%@)\n" - @" = %@", - [_url host], [_url user], [_pwd length] > 0 ? "yes" : "no", - [_url absoluteString], - [_url baseURL], - NSStringFromClass([[_url baseURL] class]), - client]; - return nil; - } - - [self debugWithFormat:@"created new IMAP4 connection for URL: %@", _url]; - - /* cache connection in pool */ - - entry = [[SOGoMailConnectionEntry alloc] initWithClient:client - password:_pwd]; - [self cacheEntry:entry forURL:_url]; - [entry release]; entry = nil; - - return client; -} - -- (void)flushCachesForURL:(NSURL *)_url { - SOGoMailConnectionEntry *entry; - - if ((entry = [self entryForURL:_url]) == nil) /* nothing cached */ - return; - - [entry flushFolderHierarchyCache]; - [entry flushMailCaches]; -} /* folder hierarchy */ - (NSArray *)subfoldersForURL:(NSURL *)_url password:(NSString *)_pwd { - SOGoMailConnectionEntry *entry; + NGImap4Connection *entry; - if (debugKeys) - [self debugWithFormat:@"subfolders for URL: %@ ...",[_url absoluteString]]; - /* check connection cache */ - - if ((entry = [self entryForURL:_url password:_pwd]) == nil) + if ((entry = [self connectionForURL:_url password:_pwd]) == nil) return nil; return [entry subfoldersForURL:_url]; } - (NSArray *)allFoldersForURL:(NSURL *)_url password:(NSString *)_pwd { - SOGoMailConnectionEntry *entry; - - if (debugKeys) - [self debugWithFormat:@"folders for URL: %@ ...",[_url absoluteString]]; + NGImap4Connection *entry; /* check connection cache */ - - if ((entry = [self entryForURL:_url password:_pwd]) == nil) + if ((entry = [self connectionForURL:_url password:_pwd]) == nil) return nil; return [entry allFoldersForURL:_url]; @@ -256,10 +81,10 @@ static NSTimeInterval PoolScanInterval = 5 * 60 /* every five minutes */; /* sortOrdering can be an NSString, an EOSortOrdering or an array of EOS. */ - SOGoMailConnectionEntry *entry; + NGImap4Connection *entry; /* check connection cache */ - if ((entry = [self entryForURL:_url password:_pwd]) == nil) + if ((entry = [self connectionForURL:_url password:_pwd]) == nil) return nil; return [entry fetchUIDsInURL:_url qualifier:_qualifier sortOrdering:_so]; @@ -283,7 +108,7 @@ static NSTimeInterval PoolScanInterval = 5 * 60 /* every five minutes */; RFC822.SIZE RFC822.TEXT */ - SOGoMailConnectionEntry *entry; + NGImap4Connection *entry; if (_uids == nil) return nil; @@ -291,26 +116,26 @@ static NSTimeInterval PoolScanInterval = 5 * 60 /* every five minutes */; return nil; // TODO: might break empty folders?! return a dict! /* check connection cache */ - if ((entry = [self entryForURL:_url password:_pwd]) == nil) + if ((entry = [self connectionForURL:_url password:_pwd]) == nil) return nil; return [entry fetchUIDs:_uids inURL:_url parts:_parts]; } - (NSException *)expungeAtURL:(NSURL *)_url password:(NSString *)_pwd { - SOGoMailConnectionEntry *entry; + NGImap4Connection *entry; - if ((entry = [self entryForURL:_url password:_pwd]) == nil) + if ((entry = [self connectionForURL:_url password:_pwd]) == nil) return [self errorForMissingEntryAtURL:_url]; return [entry expungeAtURL:_url]; } - (id)fetchURL:(NSURL *)_url parts:(NSArray *)_parts password:(NSString *)_pwd{ - SOGoMailConnectionEntry *entry; + NGImap4Connection *entry; if (![_url isNotNull]) return nil; - if ((entry = [self entryForURL:_url password:_pwd]) == nil) + if ((entry = [self connectionForURL:_url password:_pwd]) == nil) return [self errorForMissingEntryAtURL:_url]; return [entry fetchURL:_url parts:_parts]; @@ -319,9 +144,9 @@ static NSTimeInterval PoolScanInterval = 5 * 60 /* every five minutes */; - (NSData *)fetchContentOfBodyPart:(NSString *)_partId atURL:(NSURL *)_url password:(NSString *)_pwd { - SOGoMailConnectionEntry *entry; + NGImap4Connection *entry; - if ((entry = [self entryForURL:_url password:_pwd]) == nil) + if ((entry = [self connectionForURL:_url password:_pwd]) == nil) return nil; // TODO: improve? return [entry fetchContentOfBodyPart:_partId atURL:_url]; @@ -330,9 +155,9 @@ static NSTimeInterval PoolScanInterval = 5 * 60 /* every five minutes */; - (NSException *)addOrRemove:(BOOL)_flag flags:(id)_f toURL:(NSURL *)_url password:(NSString *)_p { - SOGoMailConnectionEntry *entry; + NGImap4Connection *entry; - if ((entry = [self entryForURL:_url password:_p]) == nil) + if ((entry = [self connectionForURL:_url password:_p]) == nil) return [self errorForMissingEntryAtURL:_url]; return [entry addOrRemove:_flag flags:_f toURL:_url]; @@ -351,11 +176,11 @@ static NSTimeInterval PoolScanInterval = 5 * 60 /* every five minutes */; - (NSException *)postData:(NSData *)_data flags:(id)_f toFolderURL:(NSURL *)_url password:(NSString *)_p { - SOGoMailConnectionEntry *entry; + NGImap4Connection *entry; if (![_url isNotNull]) return nil; - if ((entry = [self entryForURL:_url password:_p]) == nil) + if ((entry = [self connectionForURL:_url password:_p]) == nil) return [self errorForMissingEntryAtURL:_url]; return [entry postData:_data flags:_f toFolderURL:_url]; @@ -364,16 +189,16 @@ static NSTimeInterval PoolScanInterval = 5 * 60 /* every five minutes */; - (NSException *)copyMailURL:(NSURL *)_srcurl toFolderURL:(NSURL *)_desturl password:(NSString *)_pwd { - SOGoMailConnectionEntry *entry; + NGImap4Connection *entry; /* check connection cache */ - if ((entry = [self entryForURL:_srcurl password:_pwd]) == nil) + if ((entry = [self connectionForURL:_srcurl password:_pwd]) == nil) return [self errorForMissingEntryAtURL:_srcurl]; /* check whether URLs are on different servers */ - if ([self entryForURL:_desturl password:_pwd] != entry) { + if ([self connectionForURL:_desturl password:_pwd] != entry) { // TODO: find a better error code return [NSException exceptionWithHTTPStatus:502 /* Bad Gateway */ reason:@"source and destination on different servers"]; @@ -393,18 +218,18 @@ static NSTimeInterval PoolScanInterval = 5 * 60 /* every five minutes */; } - (BOOL)doesMailboxExistAtURL:(NSURL *)_url password:(NSString *)_pwd { - SOGoMailConnectionEntry *entry; + NGImap4Connection *entry; - if ((entry = [self entryForURL:_url password:_pwd]) == nil) + if ((entry = [self connectionForURL:_url password:_pwd]) == nil) return NO; return [entry doesMailboxExistAtURL:_url]; } - (id)infoForMailboxAtURL:(NSURL *)_url password:(NSString *)_pwd { - SOGoMailConnectionEntry *entry; + NGImap4Connection *entry; - if ((entry = [self entryForURL:_url password:_pwd]) == nil) + if ((entry = [self connectionForURL:_url password:_pwd]) == nil) return [self errorForMissingEntryAtURL:_url]; return [entry infoForMailboxAtURL:_url]; @@ -413,21 +238,21 @@ static NSTimeInterval PoolScanInterval = 5 * 60 /* every five minutes */; - (NSException *)createMailbox:(NSString *)_mailbox atURL:(NSURL *)_url password:(NSString *)_pwd { - SOGoMailConnectionEntry *entry; + NGImap4Connection *entry; /* check connection cache */ - if ((entry = [self entryForURL:_url password:_pwd]) == nil) + if ((entry = [self connectionForURL:_url password:_pwd]) == nil) return [self errorForMissingEntryAtURL:_url]; return [entry createMailbox:_mailbox atURL:_url]; } - (NSException *)deleteMailboxAtURL:(NSURL *)_url password:(NSString *)_pwd { - SOGoMailConnectionEntry *entry; + NGImap4Connection *entry; /* check connection cache */ - if ((entry = [self entryForURL:_url password:_pwd]) == nil) + if ((entry = [self connectionForURL:_url password:_pwd]) == nil) return [self errorForMissingEntryAtURL:_url]; return [entry deleteMailboxAtURL:_url]; @@ -436,16 +261,16 @@ static NSTimeInterval PoolScanInterval = 5 * 60 /* every five minutes */; - (NSException *)moveMailboxAtURL:(NSURL *)_srcurl toURL:(NSURL *)_desturl password:(NSString *)_pwd { - SOGoMailConnectionEntry *entry; + NGImap4Connection *entry; /* check connection cache */ - if ((entry = [self entryForURL:_srcurl password:_pwd]) == nil) + if ((entry = [self connectionForURL:_srcurl password:_pwd]) == nil) return [self errorForMissingEntryAtURL:_srcurl]; /* check whether URLs are on different servers */ - if ([self entryForURL:_desturl password:_pwd] != entry) { + if ([self connectionForURL:_desturl password:_pwd] != entry) { // TODO: find a better error code return [NSException exceptionWithHTTPStatus:502 /* Bad Gateway */ reason:@"source and destination on different servers"]; @@ -460,18 +285,18 @@ static NSTimeInterval PoolScanInterval = 5 * 60 /* every five minutes */; guizmo.g = lrs; root = lrswipcda; */ - SOGoMailConnectionEntry *entry; + NGImap4Connection *entry; - if ((entry = [self entryForURL:_url password:_pwd]) == nil) + if ((entry = [self connectionForURL:_url password:_pwd]) == nil) return (id)[self errorForMissingEntryAtURL:_url]; return [entry aclForMailboxAtURL:_url]; } - (NSString *)myRightsForMailboxAtURL:(NSURL *)_url password:(NSString *)_pwd { - SOGoMailConnectionEntry *entry; + NGImap4Connection *entry; - if ((entry = [self entryForURL:_url password:_pwd]) == nil) + if ((entry = [self connectionForURL:_url password:_pwd]) == nil) return (id)[self errorForMissingEntryAtURL:_url]; return [entry myRightsForMailboxAtURL:_url]; @@ -482,21 +307,15 @@ static NSTimeInterval PoolScanInterval = 5 * 60 /* every five minutes */; - (NSException *)addFlags:(id)_f toAllMessagesInURL:(NSURL *)_url password:(NSString *)_p { - SOGoMailConnectionEntry *entry; + NGImap4Connection *entry; if (![_url isNotNull]) return nil; if (![_f isNotNull]) return nil; - if ((entry = [self entryForURL:_url password:_p]) == nil) + if ((entry = [self connectionForURL:_url password:_p]) == nil) return [self errorForMissingEntryAtURL:_url]; return [entry addFlags:_f toAllMessagesInURL:_url]; } -/* debugging */ - -- (BOOL)isDebuggingEnabled { - return debugOn; -} - -@end /* SOGoMailManager */ +@end /* NGImap4ConnectionManager(SOGoMailManager) */ diff --git a/SOGo/SoObjects/Mailer/SOGoMailboxInfo.h b/SOGo/SoObjects/Mailer/SOGoMailboxInfo.h deleted file mode 100644 index 8f4b0f2b..00000000 --- a/SOGo/SoObjects/Mailer/SOGoMailboxInfo.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - Copyright (C) 2005 SKYRIX Software AG - - This file is part of OpenGroupware.org. - - OGo is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - OGo 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 Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with OGo; see the file COPYING. If not, write to the - Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -#ifndef __Mailer_SOGoMailboxInfo_H__ -#define __Mailer_SOGoMailboxInfo_H__ - -#import - -/* - SOGoMailboxInfo - - Represents the info returned by an IMAP4 select. Use SOGoMailManager to - retrieve the data. -*/ - -@class NSString, NSDate, NSArray, NSURL, NSDictionary; - -@interface SOGoMailboxInfo : NSObject -{ - NSDate *timestamp; - NSURL *url; - NSString *name; - NSArray *allowedFlags; - NSString *access; - unsigned int recent; -} - -- (id)initWithURL:(NSURL *)_url folderName:(NSString *)_name - selectDictionary:(NSDictionary *)_dict; - -/* accessors */ - -- (NSDate *)timestamp; -- (NSURL *)url; -- (NSString *)name; -- (NSArray *)allowedFlags; -- (NSString *)access; -- (unsigned int)recent; - -@end - -#endif /* __Mailer_SOGoMailboxInfo_H__ */ diff --git a/SOGo/SoObjects/Mailer/SOGoMailboxInfo.m b/SOGo/SoObjects/Mailer/SOGoMailboxInfo.m deleted file mode 100644 index 54c626a6..00000000 --- a/SOGo/SoObjects/Mailer/SOGoMailboxInfo.m +++ /dev/null @@ -1,101 +0,0 @@ -/* - Copyright (C) 2005 SKYRIX Software AG - - This file is part of OpenGroupware.org. - - OGo is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - OGo 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 Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with OGo; see the file COPYING. If not, write to the - Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -#include "SOGoMailboxInfo.h" -#include "common.h" - -@implementation SOGoMailboxInfo - -- (id)initWithURL:(NSURL *)_url folderName:(NSString *)_name - selectDictionary:(NSDictionary *)_dict -{ - if (_dict == nil || (_url == nil && _name == nil)) { - [self release]; - return nil; - } - - if ((self = [super init])) { - self->timestamp = [[NSDate alloc] init]; - self->url = [_url copy]; - self->name = [_name copy]; - self->allowedFlags = [[_dict objectForKey:@"flags"] copy]; - self->access = [[_dict objectForKey:@"access"] copy]; - self->recent = [[_dict objectForKey:@"recent"] unsignedIntValue]; - } - return self; -} -- (id)init { - return [self initWithURL:nil folderName: nil selectDictionary:nil]; -} - -- (void)dealloc { - [self->timestamp release]; - [self->url release]; - [self->name release]; - [self->allowedFlags release]; - [self->access release]; - [super dealloc]; -} - -/* accessors */ - -- (NSDate *)timestamp { - return self->timestamp; -} -- (NSURL *)url { - return self->url; -} -- (NSString *)name { - return self->name; -} -- (NSArray *)allowedFlags { - return self->allowedFlags; -} -- (NSString *)access { - return self->access; -} -- (unsigned int)recent { - return self->recent; -} - -/* description */ - -- (void)appendAttributesToDescription:(NSMutableString *)_ms { - if (self->name) [_ms appendFormat:@" name=%@", self->name]; - if (self->access) [_ms appendFormat:@" access=%@", self->access]; - - if (self->recent != 0) [_ms appendFormat:@" recent=%d", self->recent]; - - [_ms appendFormat:@" flags=%@", - [[self allowedFlags] componentsJoinedByString:@","]]; -} - -- (NSString *)description { - NSMutableString *ms; - - ms = [NSMutableString stringWithCapacity:64]; - [ms appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])]; - [self appendAttributesToDescription:ms]; - [ms appendString:@">"]; - return ms; -} - -@end /* SOGoMailboxInfo */ diff --git a/SOGo/SoObjects/Mailer/Version b/SOGo/SoObjects/Mailer/Version index 67dd1fc6..1c3b6e33 100644 --- a/SOGo/SoObjects/Mailer/Version +++ b/SOGo/SoObjects/Mailer/Version @@ -1,7 +1,8 @@ # Version file -SUBMINOR_VERSION:=95 +SUBMINOR_VERSION:=96 +# v0.9.96 requires libNGMime v4.5.223 # v0.9.91 requires libNGMime v4.5.222 # v0.9.69 requires libNGMime v4.5.210 # v0.9.55 requires libNGExtensions v4.5.136 diff --git a/SOGo/SoObjects/Sieve/ChangeLog b/SOGo/SoObjects/Sieve/ChangeLog index 4fb39a90..924add86 100644 --- a/SOGo/SoObjects/Sieve/ChangeLog +++ b/SOGo/SoObjects/Sieve/ChangeLog @@ -1,3 +1,7 @@ +2005-07-11 Helge Hess + + * SOGoSieveBaseObject.m: updated to use new NGImap4 API (v0.9.9) + 2005-02-10 Helge Hess * SOGoSieveScriptObject.m: fixed a compile warning on MacOSX (v0.9.8) diff --git a/SOGo/SoObjects/Sieve/SOGoSieveBaseObject.h b/SOGo/SoObjects/Sieve/SOGoSieveBaseObject.h index b96de2ca..35b75b66 100644 --- a/SOGo/SoObjects/Sieve/SOGoSieveBaseObject.h +++ b/SOGo/SoObjects/Sieve/SOGoSieveBaseObject.h @@ -32,7 +32,7 @@ @class NSString, NSArray, NSURL; @class NGImap4Client, NGSieveClient; -@class SOGoMailManager; +@class NGImap4ConnectionManager; @class SOGoMailAccount; @interface SOGoSieveBaseObject : SOGoObject @@ -46,7 +46,7 @@ /* IMAP4 */ -- (SOGoMailManager *)mailManager; +- (NGImap4ConnectionManager *)mailManager; - (NSURL *)imap4URL; - (NSString *)imap4Password; - (NGImap4Client *)imap4Client; diff --git a/SOGo/SoObjects/Sieve/SOGoSieveBaseObject.m b/SOGo/SoObjects/Sieve/SOGoSieveBaseObject.m index ccd47c29..224199c6 100644 --- a/SOGo/SoObjects/Sieve/SOGoSieveBaseObject.m +++ b/SOGo/SoObjects/Sieve/SOGoSieveBaseObject.m @@ -49,7 +49,7 @@ /* IMAP4 */ -- (SOGoMailManager *)mailManager { +- (NGImap4ConnectionManager *)mailManager { return [[self mailAccountFolder] mailManager]; } - (NSURL *)imap4URL { diff --git a/SOGo/SoObjects/Sieve/Version b/SOGo/SoObjects/Sieve/Version index f44ca3dc..0d642ced 100644 --- a/SOGo/SoObjects/Sieve/Version +++ b/SOGo/SoObjects/Sieve/Version @@ -1,6 +1,7 @@ # Version file -SUBMINOR_VERSION:=8 +SUBMINOR_VERSION:=9 +# v0.9.9 requires libNGMime v4.5.223 # v0.9.6 requires libNGMime v4.5.207 # v0.9.1 requires libNGMime v4.3.194 -- 2.39.2