1 /* SOGoMailer.m - this file is part of SOGo
3 * Copyright (C) 2007 Inverse groupe conseil
5 * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
7 * This file is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * This file is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
23 #import <Foundation/NSArray.h>
24 #import <Foundation/NSEnumerator.h>
25 #import <Foundation/NSException.h>
26 #import <Foundation/NSString.h>
27 #import <Foundation/NSUserDefaults.h>
29 #import <NGObjWeb/NSException+HTTP.h>
30 #import <NGExtensions/NSObject+Logs.h>
31 #import <NGMail/NGSendMail.h>
32 #import <NGMail/NGSmtpClient.h>
33 #import <NGMime/NGMimePartGenerator.h>
35 #import "NSString+Utilities.h"
36 #import "SOGoMailer.h"
38 #define defaultMailingMechanism @"sendmail"
39 #define defaultSMTPServer @"localhost"
41 @implementation SOGoMailer
45 static id sharedMailer = nil;
48 sharedMailer = [self new];
57 if ((self = [super init]))
59 ud = [NSUserDefaults standardUserDefaults];
60 mailingMechanism = [ud stringForKey: @"SOGoMailingMechanism"];
63 if (!([mailingMechanism isEqualToString: @"sendmail"]
64 || [mailingMechanism isEqualToString: @"smtp"]))
66 [self logWithFormat: @"mechanism '%@' is invalid and"
67 @" should be set to 'sendmail' or 'smtp' instead",
69 [self logWithFormat: @"falling back to default '%@' mechanism",
70 defaultMailingMechanism];
71 mailingMechanism = defaultMailingMechanism;
76 [self logWithFormat: @"default mailing mechanism set to '%@'",
77 defaultMailingMechanism];
78 mailingMechanism = defaultMailingMechanism;
80 [mailingMechanism retain];
82 if ([mailingMechanism isEqualToString: @"smtp"])
84 smtpServer = [ud stringForKey: @"SOGoSMTPServer"];
87 [self logWithFormat: @"default smtp server set to '%@'",
89 smtpServer = defaultSMTPServer;
102 [mailingMechanism release];
103 [smtpServer release];
107 - (NSException *) _sendmailSendData: (NSData *) mailData
108 toRecipients: (NSArray *) recipients
109 sender: (NSString *) sender
114 mailer = [NGSendMail sharedSendMail];
115 if ([mailer isSendMailAvailable])
116 result = [mailer sendMailData: mailData
117 toRecipients: recipients
120 result = [NSException exceptionWithHTTPStatus: 500
121 reason: @"cannot send message:"
122 @" no sendmail binary!"];
127 - (NSException *) _sendMailData: (NSData *) mailData
128 withClient: (NGSmtpClient *) client
129 andRejections: (unsigned int) toErrors
134 [self logWithFormat: @"sending email despite address rejections"];
135 if ([client sendData: mailData])
138 result = [NSException exceptionWithHTTPStatus: 500
139 reason: @"cannot send message:"
140 @" (smtp) failure when sending data"];
145 - (NSException *) _smtpSendData: (NSData *) mailData
146 toRecipients: (NSArray *) recipients
147 sender: (NSString *) sender
149 NGSmtpClient *client;
150 NSEnumerator *addresses;
152 unsigned int toErrors;
155 client = [NGSmtpClient smtpClient];
156 if ([client connectToHost: smtpServer])
159 && [client mailFrom: sender])
162 addresses = [recipients objectEnumerator];
163 currentTo = [addresses nextObject];
166 if (![client recipientTo: [currentTo pureEMailAddress]])
168 [self logWithFormat: @"error with recipient '%@'", currentTo];
171 currentTo = [addresses nextObject];
173 if (toErrors == [recipients count])
174 result = [NSException exceptionWithHTTPStatus: 500
175 reason: @"cannot send message:"
176 @" (smtp) all recipients discarded"];
178 result = [self _sendMailData: mailData withClient: client
179 andRejections: toErrors];
182 result = [NSException exceptionWithHTTPStatus: 500
183 reason: @"cannot send message:"
184 @" (smtp) error when connecting"];
192 - (NSException *) sendMailData: (NSData *) data
193 toRecipients: (NSArray *) recipients
194 sender: (NSString *) sender
198 if (![recipients count])
199 result = [NSException exceptionWithHTTPStatus: 500
200 reason: @"cannot send message: no recipients set"];
203 if (![sender length])
204 result = [NSException exceptionWithHTTPStatus: 500
205 reason: @"cannot send message: no sender set"];
208 if ([mailingMechanism isEqualToString: @"sendmail"])
209 result = [self _sendmailSendData: data
210 toRecipients: recipients
211 sender: [sender pureEMailAddress]];
213 result = [self _smtpSendData: data
214 toRecipients: recipients
215 sender: [sender pureEMailAddress]];
222 - (NSException *) sendMimePart: (id <NGMimePart>) part
223 toRecipients: (NSArray *) recipients
224 sender: (NSString *) sender
228 mailData = [[NGMimePartGenerator mimePartGenerator]
229 generateMimeFromPart: part];
231 return [self sendMailData: mailData
232 toRecipients: recipients
236 - (NSException *) sendMailAtPath: (NSString *) filename
237 toRecipients: (NSArray *) recipients
238 sender: (NSString *) sender
243 mailData = [NSData dataWithContentsOfFile: filename];
244 if ([mailData length] > 0)
245 result = [self sendMailData: mailData
246 toRecipients: recipients
249 result = [NSException exceptionWithHTTPStatus: 500
250 reason: @"cannot send message: no data"
251 @" (missing or empty file?)"];