+2005-07-11 Helge Hess <helge.hess@opengroupware.org>
+
+ * moved SOGoMailManager related API to NGImap4 (NGImap4Connection,
+ NGImap4ConnectionManager, etc) (v0.9.96)
+
2005-07-11 Helge Hess <helge.hess@opengroupware.org>
* v0.9.95
Product.m \
\
SOGoMailManager.m \
- SOGoMailboxInfo.m \
- SOGoMailConnectionEntry.m \
\
SOGoMailBaseObject.m \
SOGoMailAccounts.m \
*/
@class NSString, NSArray, NSURL;
-@class NGImap4Client;
-@class SOGoMailManager;
+@class NGImap4Client, NGImap4ConnectionManager, NGImap4Connection;
@class SOGoMailAccount;
@interface SOGoMailBaseObject : SOGoObject
/* IMAP4 */
-- (SOGoMailManager *)mailManager;
+- (NGImap4ConnectionManager *)mailManager;
- (NSURL *)imap4URL;
- (NSString *)imap4Login;
- (NSString *)imap4Password;
/* IMAP4 */
-- (SOGoMailManager *)mailManager {
- return [SOGoMailManager defaultMailManager];
+- (NGImap4ConnectionManager *)mailManager {
+ return [NGImap4ConnectionManager defaultConnectionManager];
}
- (NSString *)relativeImap4Name {
+++ /dev/null
-/*
- 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 <Foundation/NSObject.h>
-
-/*
- 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__ */
+++ /dev/null
-/*
- 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[<section>]<<partial>>
- 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 */
*/
@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;
#include "SOGoMailObject.h"
#include "SOGoMailAccount.h"
#include "SOGoMailManager.h"
-#include "SOGoMailboxInfo.h"
+#include <NGImap4/NGImap4MailboxInfo.h>
#include "SOGoMailFolderDataSource.h"
#include "common.h"
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;
}
#import <Foundation/NSObject.h>
#import <Foundation/NSRange.h>
+#include <NGImap4/NGImap4ConnectionManager.h>
/*
- 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 */
*/
#include "SOGoMailManager.h"
-#include "SOGoMailConnectionEntry.h"
+#include <NGImap4/NGImap4Connection.h>
+#include <NGImap4/NGImap4ConnectionManager.h>
#include "common.h"
/*
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
/* 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];
/*
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];
RFC822.SIZE
RFC822.TEXT
*/
- SOGoMailConnectionEntry *entry;
+ NGImap4Connection *entry;
if (_uids == nil)
return nil;
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];
- (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];
- (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];
- (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];
- (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"];
}
- (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];
- (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];
- (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"];
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];
- (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) */
+++ /dev/null
-/*
- 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 <Foundation/NSObject.h>
-
-/*
- 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__ */
+++ /dev/null
-/*
- 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 */
# 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
+2005-07-11 Helge Hess <helge.hess@opengroupware.org>
+
+ * SOGoSieveBaseObject.m: updated to use new NGImap4 API (v0.9.9)
+
2005-02-10 Helge Hess <helge.hess@opengroupware.org>
* SOGoSieveScriptObject.m: fixed a compile warning on MacOSX (v0.9.8)
@class NSString, NSArray, NSURL;
@class NGImap4Client, NGSieveClient;
-@class SOGoMailManager;
+@class NGImap4ConnectionManager;
@class SOGoMailAccount;
@interface SOGoSieveBaseObject : SOGoObject
/* IMAP4 */
-- (SOGoMailManager *)mailManager;
+- (NGImap4ConnectionManager *)mailManager;
- (NSURL *)imap4URL;
- (NSString *)imap4Password;
- (NGImap4Client *)imap4Client;
/* IMAP4 */
-- (SOGoMailManager *)mailManager {
+- (NGImap4ConnectionManager *)mailManager {
return [[self mailAccountFolder] mailManager];
}
- (NSURL *)imap4URL {
# 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