1 package com.nilhcem.fakesmtp.server;
2
3 import com.nilhcem.fakesmtp.core.ArgsHandler;
4 import com.nilhcem.fakesmtp.core.Configuration;
5 import com.nilhcem.fakesmtp.core.I18n;
6 import com.nilhcem.fakesmtp.model.EmailModel;
7 import com.nilhcem.fakesmtp.model.UIModel;
8 import org.apache.commons.io.FileUtils;
9 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory;
11
12 import java.io.BufferedReader;
13 import java.io.File;
14 import java.io.InputStream;
15 import java.io.InputStreamReader;
16 import java.io.IOException;
17 import java.io.StringReader;
18 import java.nio.charset.Charset;
19 import java.text.SimpleDateFormat;
20 import java.util.Date;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Observable;
24 import java.util.regex.Matcher;
25 import java.util.regex.Pattern;
26
27
28
29
30
31
32
33 public final class MailSaver extends Observable {
34
35 private static final Logger LOGGER = LoggerFactory.getLogger(MailSaver.class);
36 private static final String LINE_SEPARATOR = System.getProperty("line.separator");
37
38 private static final Pattern SUBJECT_PATTERN = Pattern.compile("^Subject: (.*)$");
39
40 private final SimpleDateFormat dateFormat = new SimpleDateFormat("ddMMyyhhmmssSSS");
41
42
43
44
45
46
47
48
49
50 public void saveEmailAndNotify(String from, String to, InputStream data) {
51 List<String> relayDomains = UIModel.INSTANCE.getRelayDomains();
52
53 if (relayDomains != null) {
54 boolean matches = false;
55 for (String domain : relayDomains) {
56 if (to.endsWith(domain)) {
57 matches = true;
58 break;
59 }
60 }
61
62 if (!matches) {
63 LOGGER.debug("Destination {} doesn't match relay domains", to);
64 return;
65 }
66 }
67
68
69 EmailModel model = new EmailModel();
70 model.setFrom(from);
71 model.setTo(to);
72 String mailContent = convertStreamToString(data);
73 model.setSubject(getSubjectFromStr(mailContent));
74 model.setEmailStr(mailContent);
75
76 synchronized (getLock()) {
77 String filePath = saveEmailToFile(mailContent);
78
79 model.setReceivedDate(new Date());
80 model.setFilePath(filePath);
81
82 setChanged();
83 notifyObservers(model);
84 }
85 }
86
87
88
89
90 public void deleteEmails() {
91 Map<Integer, String> mails = UIModel.INSTANCE.getListMailsMap();
92 if (ArgsHandler.INSTANCE.memoryModeEnabled()) {
93 return;
94 }
95 for (String value : mails.values()) {
96 File file = new File(value);
97 if (file.exists()) {
98 try {
99 if (!file.delete()) {
100 LOGGER.error("Impossible to delete file {}", value);
101 }
102 } catch (SecurityException e) {
103 LOGGER.error("", e);
104 }
105 }
106 }
107 }
108
109
110
111
112
113
114
115
116
117
118 public Object getLock() {
119 return this;
120 }
121
122
123
124
125
126
127
128
129
130
131
132 private String convertStreamToString(InputStream is) {
133 final long lineNbToStartCopy = 4;
134 BufferedReader reader = new BufferedReader(new InputStreamReader(is, Charset.forName(I18n.UTF8)));
135 StringBuilder sb = new StringBuilder();
136
137 String line;
138 long lineNb = 0;
139 try {
140 while ((line = reader.readLine()) != null) {
141 if (++lineNb > lineNbToStartCopy) {
142 sb.append(line).append(LINE_SEPARATOR);
143 }
144 }
145 } catch (IOException e) {
146 LOGGER.error("", e);
147 }
148 return sb.toString();
149 }
150
151
152
153
154
155
156
157 private String saveEmailToFile(String mailContent) {
158 if (ArgsHandler.INSTANCE.memoryModeEnabled()) {
159 return null;
160 }
161 String filePath = String.format("%s%s%s", UIModel.INSTANCE.getSavePath(), File.separator,
162 dateFormat.format(new Date()));
163
164
165 int i = 0;
166 File file = null;
167 while (file == null || file.exists()) {
168 String iStr;
169 if (i++ > 0) {
170 iStr = Integer.toString(i);
171 } else {
172 iStr = "";
173 }
174 file = new File(filePath + iStr + Configuration.INSTANCE.get("emails.suffix"));
175 }
176
177
178 try {
179 FileUtils.writeStringToFile(file, mailContent);
180 } catch (IOException e) {
181
182 Logger smtpLogger = LoggerFactory.getLogger(org.subethamail.smtp.server.Session.class);
183 smtpLogger.error("Error: Can't save email: {}", e.getMessage());
184 }
185 return file.getAbsolutePath();
186 }
187
188
189
190
191
192
193
194 private String getSubjectFromStr(String data) {
195 try {
196 BufferedReader reader = new BufferedReader(new StringReader(data));
197
198 String line;
199 while ((line = reader.readLine()) != null) {
200 Matcher matcher = SUBJECT_PATTERN.matcher(line);
201 if (matcher.matches()) {
202 return matcher.group(1);
203 }
204 }
205 } catch (IOException e) {
206 LOGGER.error("", e);
207 }
208 return "";
209 }
210 }