From f5378d52280f155612384eebc5cb3fde7d1e4b4b Mon Sep 17 00:00:00 2001 From: Ludovic Marcotte Date: Wed, 23 Feb 2011 23:06:55 +0000 Subject: [PATCH] See ChangeLog Monotone-Parent: 93bde4643a2fb0ad0e86c36a29a73bc23ad39c64 Monotone-Revision: 04f443d215f2bc7c0d902f56f363c597ecffbcff Monotone-Author: ludovic@Sophos.ca Monotone-Date: 2011-02-23T23:06:55 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 7 ++ SoObjects/Mailer/SOGoDraftObject.m | 119 ++++++++++++++++++++++++-- SoObjects/Mailer/SOGoMailObject.h | 1 + SoObjects/Mailer/SOGoMailObject.m | 5 ++ UI/MailerUI/UIxMailView.m | 5 ++ UI/Templates/MailerUI/UIxMailView.wox | 15 ++++ 6 files changed, 146 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index de28d39b5..021e768a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-02-23 Ludovic Marcotte + + * We now strip the bcc header in SOGoDraftObject instead + of doing it in SOPE. Prior to stripping the bcc header, + we keep a copy of the message for proper saving in the + Sent IMAP folder. + 2011-02-23 Francis Lachapelle * SoObjects/Mailer/SOGoMailObject.m (-lookupInfoForBodyPart:): we diff --git a/SoObjects/Mailer/SOGoDraftObject.m b/SoObjects/Mailer/SOGoDraftObject.m index 4d6754aff..6937fc9ef 100644 --- a/SoObjects/Mailer/SOGoDraftObject.m +++ b/SoObjects/Mailer/SOGoDraftObject.m @@ -22,6 +22,7 @@ #import #import +#import #import #import #import @@ -85,6 +86,87 @@ static NSString *headerKeys[] = {@"subject", @"to", @"cc", @"bcc", @end +// +// Useful extension that comes from Pantomime which is also +// released under the LGPL. We should eventually merge +// this with the same category found in SOPE's NGSmtpClient.m +// or simply drop sope-mime in favor of Pantomime +// +@interface NSMutableData (DataCleanupExtension) + +- (NSRange) rangeOfCString: (const char *) theCString; +- (NSRange) rangeOfCString: (const char *) theCString + options: (unsigned int) theOptions + range: (NSRange) theRange; +@end + +@implementation NSMutableData (DataCleanupExtension) + +- (NSRange) rangeOfCString: (const char *) theCString +{ + return [self rangeOfCString: theCString + options: 0 + range: NSMakeRange(0,[self length])]; +} + +-(NSRange) rangeOfCString: (const char *) theCString + options: (unsigned int) theOptions + range: (NSRange) theRange +{ + const char *b, *bytes; + int i, len, slen; + + if (!theCString) + { + return NSMakeRange(NSNotFound,0); + } + + bytes = [self bytes]; + len = [self length]; + slen = strlen(theCString); + + b = bytes; + + if (len > theRange.location + theRange.length) + { + len = theRange.location + theRange.length; + } + + if (theOptions == NSCaseInsensitiveSearch) + { + i = theRange.location; + b += i; + + for (; i <= len-slen; i++, b++) + { + if (!strncasecmp(theCString,b,slen)) + { + return NSMakeRange(i,slen); + } + } + } + else + { + i = theRange.location; + b += i; + + for (; i <= len-slen; i++, b++) + { + if (!memcmp(theCString,b,slen)) + { + return NSMakeRange(i,slen); + } + } + } + + return NSMakeRange(NSNotFound,0); +} + +@end + +// +// +// @implementation SOGoDraftObject static NGMimeType *MultiMixedType = nil; @@ -1440,12 +1522,14 @@ static NSString *userAgent = nil; - (NSException *) sendMail { - NSException *error; + NSMutableData *cleaned_message; SOGoMailFolder *sentFolder; - NSData *message; - NSURL *sourceIMAP4URL; SOGoDomainDefaults *dd; - + NSURL *sourceIMAP4URL; + NSException *error; + NSData *message; + NSRange r1, r2; + /* send mail */ sentFolder = [[self mailAccountFolder] sentFolderInContext: context]; if ([sentFolder isKindOfClass: [NSException class]]) @@ -1457,11 +1541,34 @@ static NSString *userAgent = nil; generator = [[[NGMimeMessageGenerator alloc] init] autorelease]; message = [generator generateMimeFromPart: [self mimeMessageWithHeaders: nil - excluding: [NSArray arrayWithObject: @"bcc"]]]; + excluding: nil]]; + // + // We now look for the Bcc: header. If it is present, we remove it. + // Some servers, like qmail, do not remove it automatically. + // +#warning FIXME - we should fix the case issue when we switch to Pantomime + cleaned_message = [NSMutableData dataWithData: message]; + r1 = [cleaned_message rangeOfCString: "\r\n\r\n"]; + r1 = [cleaned_message rangeOfCString: "\r\nbcc: " + options: 0 + range: NSMakeRange(0,r1.location-1)]; + + if (r1.location != NSNotFound) + { + // We search for the first \r\n AFTER the Bcc: header and + // replace the whole thing with \r\n. + r2 = [cleaned_message rangeOfCString: "\r\n" + options: 0 + range: NSMakeRange(NSMaxRange(r1)+1,[cleaned_message length]-NSMaxRange(r1)-1)]; + [cleaned_message replaceBytesInRange: NSMakeRange(r1.location, NSMaxRange(r2)-r1.location) + withBytes: "\r\n" + length: 2]; + } + dd = [[context activeUser] domainDefaults]; error = [[SOGoMailer mailerWithDomainDefaults: dd] - sendMailData: message + sendMailData: cleaned_message toRecipients: [self allBareRecipients] sender: [self sender]]; if (!error) diff --git a/SoObjects/Mailer/SOGoMailObject.h b/SoObjects/Mailer/SOGoMailObject.h index 4b136b0ec..148d8cf85 100644 --- a/SoObjects/Mailer/SOGoMailObject.h +++ b/SoObjects/Mailer/SOGoMailObject.h @@ -72,6 +72,7 @@ - (NSArray *) replyToEnvelopeAddresses; - (NSArray *) toEnvelopeAddresses; - (NSArray *) ccEnvelopeAddresses; +- (NSArray *) bccEnvelopeAddresses; - (NSDictionary *) mailHeaders; diff --git a/SoObjects/Mailer/SOGoMailObject.m b/SoObjects/Mailer/SOGoMailObject.m index 7db3d8d69..20337d8a4 100644 --- a/SoObjects/Mailer/SOGoMailObject.m +++ b/SoObjects/Mailer/SOGoMailObject.m @@ -289,6 +289,11 @@ static BOOL debugSoParts = NO; return [[self envelope] cc]; } +- (NSArray *) bccEnvelopeAddresses +{ + return [[self envelope] bcc]; +} + - (NSArray *) replyToEnvelopeAddresses { return [[self envelope] replyTo]; diff --git a/UI/MailerUI/UIxMailView.m b/UI/MailerUI/UIxMailView.m index e49fee405..d81bb1c26 100644 --- a/UI/MailerUI/UIxMailView.m +++ b/UI/MailerUI/UIxMailView.m @@ -133,6 +133,11 @@ static NSString *mailETag = nil; return [[[self clientObject] ccEnvelopeAddresses] count] > 0 ? YES : NO; } +- (BOOL) hasBCC +{ + return [[[self clientObject] bccEnvelopeAddresses] count] > 0 ? YES : NO; +} + - (BOOL) hasReplyTo { return [[[self clientObject] replyToEnvelopeAddresses] count] > 0 ? YES : NO; diff --git a/UI/Templates/MailerUI/UIxMailView.wox b/UI/Templates/MailerUI/UIxMailView.wox index 7c8dce1ad..005df4d43 100644 --- a/UI/Templates/MailerUI/UIxMailView.wox +++ b/UI/Templates/MailerUI/UIxMailView.wox @@ -64,6 +64,21 @@ + + + : + + + + + + + + :