+2005-07-05 Helge Hess <helge.hess@opengroupware.org>
+
+ * NGImap4ResponseNormalizer.[hm], NGImap4Client.[hm],
+ NGImap4ResponseParser.m: added some ACL related commands (v4.5.221)
+
2005-04-24 Helge Hess <helge.hess@opengroupware.org>
* NGMime, NGImap4, NGMail: fixed gcc 4.0 warnings (v4.5.220)
- (NSDictionary *)searchWithQualifier:(EOQualifier *)_qualifier;
+/* ACLs */
+
+- (NSDictionary *)getACL:(NSString *)_folder;
+- (NSDictionary *)setACL:(NSString *)_folder rights:(NSString *)_r
+ uid:(NSString *)_uid;
+- (NSDictionary *)deleteACL:(NSString *)_folder uid:(NSString *)_uid;
+- (NSDictionary *)listRights:(NSString *)_folder uid:(NSString *)_uid;
+- (NSDictionary *)myRights:(NSString *)_folder;
+
/* context accessors (DEPRECATED) */
- (void)setContext:(NGImap4Context *)_ctx;
return [self->normer normalizeSearchResponse:[self processCommand:s]];
}
+/* ACLs */
+
+- (NSDictionary *)getACL:(NSString *)_folder {
+ NSString *cmd;
+
+ if ((_folder = [self _folder2ImapFolder:_folder]) == nil)
+ return nil;
+
+ cmd = [NSString stringWithFormat:@"getacl \"%@\"", _folder];
+ return [self->normer normalizeGetACLResponse:[self processCommand:cmd]];
+}
+
+- (NSDictionary *)setACL:(NSString *)_folder rights:(NSString *)_r
+ uid:(NSString *)_uid
+{
+ NSString *cmd;
+
+ if ((_folder = [self _folder2ImapFolder:_folder]) == nil)
+ return nil;
+
+ cmd = [NSString stringWithFormat:@"setacl \"%@\" \"%@\" \"%@\"",
+ _folder, _uid, _r];
+ return [self->normer normalizeResponse:[self processCommand:cmd]];
+}
+
+- (NSDictionary *)deleteACL:(NSString *)_folder uid:(NSString *)_uid {
+ NSString *cmd;
+
+ if ((_folder = [self _folder2ImapFolder:_folder]) == nil)
+ return nil;
+
+ cmd = [NSString stringWithFormat:@"deleteacl \"%@\" \"%@\"",
+ _folder, _uid];
+ return [self->normer normalizeResponse:[self processCommand:cmd]];
+}
+
+- (NSDictionary *)listRights:(NSString *)_folder uid:(NSString *)_uid {
+ NSString *cmd;
+
+ if ((_folder = [self _folder2ImapFolder:_folder]) == nil)
+ return nil;
+
+ cmd = [NSString stringWithFormat:@"listrights \"%@\" \"%@\"",
+ _folder, _uid];
+ return [self->normer normalizeListRightsResponse:[self processCommand:cmd]];
+}
+
+- (NSDictionary *)myRights:(NSString *)_folder {
+ NSString *cmd;
+
+ if ((_folder = [self _folder2ImapFolder:_folder]) == nil)
+ return nil;
+
+ cmd = [NSString stringWithFormat:@"myrights \"%@\"", _folder];
+ return [self->normer normalizeMyRightsResponse:[self processCommand:cmd]];
+}
+
/* Private Methods */
- (NSException *)_processCommandParserException:(NSException *)_exception {
- NSLog(@"ERROR(%s): catched IMAP4 parser exception %@: %@",
- __PRETTY_FUNCTION__, [_exception name], [_exception reason]);
+ [self logWithFormat:@"ERROR(%s): catched IMAP4 parser exception %@: %@",
+ __PRETTY_FUNCTION__, [_exception name], [_exception reason]];
[self closeConnection];
[self->context setLastException:_exception];
return nil;
}
- (NSException *)_processUnknownCommandParserException:(NSException *)_ex {
- NSLog(@"ERROR(%s): catched non-IMAP4 parsing exception %@: %@",
- __PRETTY_FUNCTION__, [_ex name], [_ex reason]);
+ [self logWithFormat:@"ERROR(%s): catched non-IMAP4 parsing exception %@: %@",
+ __PRETTY_FUNCTION__, [_ex name], [_ex reason]];
return nil;
}
- (NSException *)_handleShutdownDuringCommandException:(NSException *)_ex {
- NSLog(@"ERROR(%s): IMAP4 socket was shut down by server %@: %@",
- __PRETTY_FUNCTION__, [_ex name], [_ex reason]);
+ [self logWithFormat:
+ @"ERROR(%s): IMAP4 socket was shut down by server %@: %@",
+ __PRETTY_FUNCTION__, [_ex name], [_ex reason]];
[self closeConnection];
[self->context setLastException:_ex];
return nil;
- (NSDictionary *)normalizeCapabilityRespone:(NGHashMap *)_map;
- (NSDictionary *)normalizeQuotaResponse:(NGHashMap *)_map;
+/* ACL */
+
+- (NSDictionary *)normalizeGetACLResponse:(NGHashMap *)_map;
+- (NSDictionary *)normalizeListRightsResponse:(NGHashMap *)_map;
+- (NSDictionary *)normalizeMyRightsResponse:(NGHashMap *)_map;
+
@end
#endif /* __NGImap4_NGImap4ResponseNormalizer_H__ */
result = [self normalizeResponse:_map];
- if ((obj = [[_map objectEnumeratorForKey:@"sort"] nextObject]))
+ if ((obj = [[_map objectEnumeratorForKey:@"sort"] nextObject]) != nil)
[result setObject:obj forKey:@"sort"];
return result;
return result;
}
+/* ACL */
+
+- (NSDictionary *)normalizeGetACLResponse:(NGHashMap *)_map {
+ /*
+ Raw Sample (Cyrus):
+ 21 GETACL INBOX
+ * ACL INBOX test.et.di.cete-lyon lrswipcda helge lrwip
+ 21 OK Completed
+ */
+ NSMutableDictionary *result;
+ id obj;
+
+ result = [self normalizeResponse:_map];
+ if ((obj = [[_map objectEnumeratorForKey:@"acl"] nextObject]) != nil)
+ [result setObject:obj forKey:@"acl"];
+ if ((obj = [[_map objectEnumeratorForKey:@"mailbox"] nextObject]) != nil)
+ [result setObject:obj forKey:@"mailbox"];
+ return result;
+}
+
+- (NSDictionary *)normalizeListRightsResponse:(NGHashMap *)_map {
+ /*
+ Raw Sample (Cyrus):
+ 16 listrights INBOX anyone
+ * LISTRIGHTS INBOX anyone "" l r s w i p c d a 0 1 2 3 4 5 6 7 8 9
+ 16 OK Completed
+ */
+ NSMutableDictionary *result;
+ id obj;
+
+ result = [self normalizeResponse:_map];
+
+ if ((obj = [[_map objectEnumeratorForKey:@"listrights"] nextObject]))
+ [result setObject:obj forKey:@"listrights"];
+ if ((obj = [[_map objectEnumeratorForKey:@"requiredRights"] nextObject]))
+ [result setObject:obj forKey:@"requiredRights"];
+
+ if ((obj = [[_map objectEnumeratorForKey:@"mailbox"] nextObject]) != nil)
+ [result setObject:obj forKey:@"mailbox"];
+ if ((obj = [[_map objectEnumeratorForKey:@"uid"] nextObject]) != nil)
+ [result setObject:obj forKey:@"uid"];
+ return result;
+}
+
+- (NSDictionary *)normalizeMyRightsResponse:(NGHashMap *)_map {
+ /*
+ Raw Sample (Cyrus):
+ 18 myrights INBOX
+ * MYRIGHTS INBOX lrswipcda
+ 18 OK Completed
+ */
+ NSMutableDictionary *result;
+ id obj;
+
+ result = [self normalizeResponse:_map];
+ if ((obj = [[_map objectEnumeratorForKey:@"myrights"] nextObject]) != nil)
+ [result setObject:obj forKey:@"myrights"];
+ if ((obj = [[_map objectEnumeratorForKey:@"mailbox"] nextObject]) != nil)
+ [result setObject:obj forKey:@"mailbox"];
+ return result;
+}
+
@end /* NGImap4ResponseNormalizer */
- (BOOL)_parseQuotaRootResponseIntoHashMap:(NGMutableHashMap *)result_;
- (BOOL)_parseStatusResponseIntoHashMap:(NGMutableHashMap *)result_;
- (BOOL)_parseByeUntaggedResponseIntoHashMap:(NGMutableHashMap *)result_;
+- (BOOL)_parseACLResponseIntoHashMap:(NGMutableHashMap *)result_;
+- (BOOL)_parseMyRightsResponseIntoHashMap:(NGMutableHashMap *)result_;
+- (BOOL)_parseListRightsResponseIntoHashMap:(NGMutableHashMap *)result_;
- (NSArray *)_parseThread;
l0 = _la(self, 0);
switch (l0) {
+ case 'A':
+ if ([self _parseACLResponseIntoHashMap:result_])
+ return;
+ break;
+
case 'B':
l1 = _la(self, 1);
if (l1 == 'A' && _parseBadUntaggedResponse(self, result_)) // la: 3
if (_parseFlagsUntaggedResponse(self, result_)) // la: 5
return;
break;
-
+
case 'L':
+ if (_matchesString(self, "LISTRIGHTS")) {
+ if ([self _parseListRightsResponseIntoHashMap:result_])
+ return;
+ }
if ([self _parseListOrLSubResponseIntoHashMap:result_]) // la: 4
return;
break;
+ case 'M':
+ if ([self _parseMyRightsResponseIntoHashMap:result_])
+ return;
+ break;
+
case 'N':
if (_parseNoUntaggedResponse(self, result_)) // la: 2
return;
// TODO: what if none matches?
[self logWithFormat:@"%s: no matching tag specifier?", __PRETTY_FUNCTION__];
+ [self logWithFormat:@" line: '%@'", _parseUntil(self, '\n')];
}
- (void)_parseContinuationResponseIntoHashMap:(NGMutableHashMap *)result_ {
return YES;
}
+- (BOOL)_parseACLResponseIntoHashMap:(NGMutableHashMap *)result_ {
+ /*
+ 21 GETACL INBOX
+ * ACL INBOX test.et.di.cete-lyon lrswipcda helge lrwip
+ */
+ NSString *acls;
+ NSEnumerator *enumerator;
+ id obj;
+ NSMutableArray *uids;
+ NSMutableArray *rights;
+ NSDictionary *result;
+
+ if (!_matchesString(self, "ACL "))
+ return NO;
+ _consume(self, 4);
+
+ if ((obj = _parseUntil(self, ' ')) != nil)
+ [result_ setObject:obj forKey:@"mailbox"];
+
+ acls = _parseUntil(self, '\n');
+
+ uids = [[NSMutableArray alloc] initWithCapacity:8];
+ rights = [[NSMutableArray alloc] initWithCapacity:8];
+
+ enumerator = [[acls componentsSeparatedByString:@" "] objectEnumerator];
+ while ((obj = [enumerator nextObject]) != nil) {
+ [uids addObject:obj];
+ obj = [enumerator nextObject];
+ [rights addObject:(obj ? obj : @"")];
+ }
+
+ result = [[NSDictionary alloc] initWithObjects:rights forKeys:uids];
+ [result_ addObject:result forKey:@"acl"];
+
+ [uids release]; uids = nil;
+ [rights release]; rights = nil;
+ [result release]; result = nil;
+ return YES;
+}
+
+- (BOOL)_parseMyRightsResponseIntoHashMap:(NGMutableHashMap *)result_ {
+ /*
+ Raw Sample (Cyrus):
+ 18 myrights INBOX
+ * MYRIGHTS INBOX lrswipcda
+ 18 OK Completed
+ */
+ NSString *rights;
+ id obj;
+
+ if (!_matchesString(self, "MYRIGHTS "))
+ return NO;
+ _consume(self, 9);
+
+ if ((obj = _parseUntil(self, ' ')) != nil)
+ [result_ setObject:obj forKey:@"mailbox"];
+
+ rights = _parseUntil(self, '\n');
+ [result_ setObject:rights forKey:@"myrights"];
+ return YES;
+}
+
+- (BOOL)_parseListRightsResponseIntoHashMap:(NGMutableHashMap *)result_ {
+ /*
+ Raw Sample (Cyrus):
+ 22 LISTRIGHTS INBOX helge
+ * LISTRIGHTS INBOX helge "" l r s w i p c d a 0 1 2 3 4 5 6 7 8 9
+ 22 OK Completed
+ */
+ NSString *rights;
+ id obj;
+
+ if (!_matchesString(self, "LISTRIGHTS "))
+ return NO;
+ _consume(self, 11);
+
+ if ((obj = _parseUntil(self, ' ')) != nil)
+ [result_ setObject:obj forKey:@"mailbox"];
+ if ((obj = _parseUntil(self, ' ')) != nil)
+ [result_ setObject:obj forKey:@"uid"];
+
+ if ((obj = _parseUntil(self, ' ')) != nil) {
+ if ([obj isEqual:@"\"\""])
+ obj = @"";
+ [result_ setObject:obj forKey:@"requiredRights"];
+ }
+
+ rights = _parseUntil(self, '\n');
+ [result_ setObject:[rights componentsSeparatedByString:@" "]
+ forKey:@"listrights"];
+ return YES;
+}
+
- (BOOL)_parseSearchResponseIntoHashMap:(NGMutableHashMap *)result_ {
NSMutableArray *msn = nil;
_consume(self, 6);
quota = [result_ objectForKey:@"quota"];
-
- if (!quota) {
+
+ if (quota == nil) {
quota = [NSMutableDictionary dictionaryWithCapacity:2];
[result_ setObject:quota forKey:@"quota"];
}
MAJOR_VERSION:=4
MINOR_VERSION:=5
-SUBMINOR_VERSION:=220
+SUBMINOR_VERSION:=221
# v4.5.214 requires libNGExtensions v4.5.146
# v4.2.149 requires libNGStreams v4.2.34
+2005-07-05 Helge Hess <helge.hess@opengroupware.org>
+
+ * added imapacl tool to test ACL related IMAP4 commands
+
2005-03-03 Helge Hess <helge.hess@opengroupware.org>
* ImapListTool.m: improved output with directories
imapls \
test_qpdecode \
imapquota \
+ imapacl \
imap_tool \
sievetool
imapquota_OBJC_FILES = ImapQuotaTool.m ImapTool.m imapquota.m
+imapacl_OBJC_FILES = ImapQuotaTool.m ImapTool.m imapacl.m
imapget_OBJC_FILES = ImapTool.m imapget.m
imap_tool_OBJC_FILES = imap_tool.m
mime2xml_OBJC_FILES = Mime2XmlTool.m mime2xml.m
client = [[fm imapContext] client];
return [[client getQuotaRoot:_folder] objectForKey:@"quotas"];
-
}
@end /* ImapQuotaTool */
--- /dev/null
+/*
+ Copyright (C) 2000-2005 SKYRIX Software AG
+
+ This file is part of SOPE.
+
+ SOPE 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.
+
+ SOPE 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 SOPE; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA.
+*/
+
+#include <NGImap4/NGImap4Client.h>
+#include <NGImap4/NGImap4FileManager.h>
+#include <NGImap4/NGImap4Context.h>
+#include "ImapQuotaTool.h"
+#include "common.h"
+
+int main(int argc, char **argv, char **env) {
+ NSAutoreleasePool *pool;
+ ImapQuotaTool *tool;
+ int res = 0;
+
+ pool = [NSAutoreleasePool new];
+
+#if LIB_FOUNDATION_LIBRARY
+ [NSProcessInfo initializeWithArguments:argv count:argc environment:env];
+#endif
+
+ tool = [[ImapQuotaTool alloc] init];
+
+ {
+ NGImap4Client *client;
+ NSString *mailbox;
+
+ client = [[[tool fileManager] imapContext] client];
+
+ mailbox = [[NSUserDefaults standardUserDefaults] objectForKey:@"path"];
+ NSLog(@"acl test on path: %@", mailbox);
+ NSLog(@" acl %@", [[client getACL:mailbox] valueForKey:@"acl"]);
+
+ NSLog(@" set urks 'lr' %@",
+ [[client setACL:mailbox rights:@"lr" uid:@"urks"]
+ valueForKey:@"result"]);
+ NSLog(@" acl %@", [[client getACL:mailbox] valueForKey:@"acl"]);
+
+ NSLog(@" rm urks %@",
+ [[client deleteACL:mailbox uid:@"urks"] valueForKey:@"result"]);
+ NSLog(@" acl %@", [[client getACL:mailbox] valueForKey:@"acl"]);
+
+
+ NSLog(@" my rights: '%@'",
+ [[client myRights:mailbox] valueForKey:@"myrights"]);
+
+ NSLog(@" list rights: %@",
+ [[[client listRights:mailbox uid:@"urks"]
+ valueForKey:@"listrights"] componentsJoinedByString:@","]);
+ }
+ [tool release];
+
+ [pool release];
+ exit(res);
+ /* static linking */
+ [NGExtensions class];
+ return res;
+}
{
NSString *str;
-
+
str = [[NSUserDefaults standardUserDefaults] objectForKey:@"path"];
NSLog(@"quota for path: %@", str);
NSLog(@"result %@", [tool getQuotaRoot:str]);