1 /* $Id: test_ncbi_sendmail.c,v 6.36 2014/12/08 16:44:27 kazimird Exp $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Author: Anton Lavrentiev
27 *
28 * File Description:
29 * Simple test for CORE_Sendmail
30 *
31 */
32
33 #include <connect/ncbi_connutil.h>
34 #include <connect/ncbi_sendmail.h>
35 #include "../ncbi_ansi_ext.h"
36 #include "../ncbi_priv.h" /* CORE logging facilities */
37 #include <errno.h>
38 #include <stdlib.h>
39 #include <time.h>
40
41 #include "test_assert.h" /* This header must go last */
42
43 #define TEST_HUGE_BODY_SIZE (1024*100)
44
45
main(int argc,const char * argv[])46 int main(int argc, const char* argv[])
47 {
48 static const char custom_body[] =
49 "Subject: Custom sized body\n"
50 "\n"
51 "Custom sized body\n"
52 "0123456789\n"; /* these 11 chars to ignore */
53 const char* mx_host;
54 SSendMailInfo info;
55 const char* retval;
56 STimeout mx_tmo;
57 char* huge_body;
58 short mx_port;
59 char val[32];
60 FILE* fp;
61 size_t n;
62
63 g_NCBI_ConnectRandomSeed = (int) time(0) ^ NCBI_CONNECT_SRAND_ADDEND;
64 srand(g_NCBI_ConnectRandomSeed);
65
66 CORE_SetLOGFormatFlags(fLOG_None | fLOG_Level |
67 fLOG_OmitNoteLevel | fLOG_DateTime);
68 CORE_SetLOGFILE(stderr, 0/*false*/);
69
70 ConnNetInfo_GetValue(0, REG_CONN_DEBUG_PRINTOUT, val, sizeof(val),
71 DEF_CONN_DEBUG_PRINTOUT);
72 if (ConnNetInfo_Boolean(val)
73 || (*val && (strcasecmp(val, "all") == 0 ||
74 strcasecmp(val, "some") == 0 ||
75 strcasecmp(val, "data") == 0))) {
76 SOCK_SetDataLoggingAPI(eOn);
77 }
78
79 SendMailInfo_InitEx(&info, 0, eCORE_UsernameReal);
80 CORE_LOGF(eLOG_Note, ("REAL: <%s>", info.from));
81 SendMailInfo_InitEx(&info, 0, eCORE_UsernameLogin);
82 CORE_LOGF(eLOG_Note, ("LOGIN: <%s>", info.from));
83 SendMailInfo_InitEx(&info, 0, eCORE_UsernameCurrent);
84 CORE_LOGF(eLOG_Note, ("CURRENT: <%s>", info.from));
85
86 #if 1
87 strcpy(info.from, "@");
88 SendMailInfo_InitEx(&info, info.from, eCORE_UsernameCurrent);
89 CORE_LOGF(eLOG_Note, ("@ - <%s>", info.from));
90 assert(!*info.from);
91
92 strcpy(val, "@");
93 SendMailInfo_InitEx(&info, val, eCORE_UsernameCurrent);
94 CORE_LOGF(eLOG_Note, ("@ - <%s>", info.from));
95 assert(!*info.from);
96
97 strcpy(info.from, "user0");
98 SendMailInfo_InitEx(&info, info.from, eCORE_UsernameCurrent);
99 CORE_LOGF(eLOG_Note, ("user0 - <%s>", info.from));
100 assert(strcmp(info.from, "user0") == 0);
101
102 strcpy(val, "user1");
103 SendMailInfo_InitEx(&info, val, eCORE_UsernameCurrent);
104 CORE_LOGF(eLOG_Note, ("user1 - <%s>", info.from));
105 assert(strcmp(info.from, "user1") == 0);
106
107 strcpy(info.from, "user2@");
108 SendMailInfo_InitEx(&info, info.from, eCORE_UsernameCurrent);
109 CORE_LOGF(eLOG_Note, ("user2@ - <%s>", info.from));
110 assert(strncmp(info.from, "user2@", 6) == 0);
111
112 strcpy(val, "user3@");
113 SendMailInfo_InitEx(&info, val, eCORE_UsernameCurrent);
114 CORE_LOGF(eLOG_Note, ("user3@ - <%s>", info.from));
115 assert(strncmp(info.from, "user3@", 6) == 0);
116
117 strcpy(info.from, "@host4.net");
118 SendMailInfo_InitEx(&info, info.from, eCORE_UsernameLogin);
119 CORE_LOGF(eLOG_Note, ("@host4.net - <%s>", info.from));
120 assert(*info.from != '@' && !strcmp(strchr(info.from, '@'), "@host4.net"));
121
122 strcpy(val, "@host5.net");
123 SendMailInfo_InitEx(&info, val, eCORE_UsernameLogin);
124 CORE_LOGF(eLOG_Note, ("@host5.net - <%s>", info.from));
125 assert(*info.from != '@' && !strcmp(strchr(info.from, '@'), "@host5.net"));
126
127 strcpy(info.from, "user6@host6.net");
128 SendMailInfo_InitEx(&info, info.from, eCORE_UsernameReal);
129 CORE_LOGF(eLOG_Note, ("user6@host6.net - <%s>", info.from));
130 assert(strcmp(info.from, "user6@host6.net") == 0);
131
132 strcpy(val, "user7@host7.net");
133 SendMailInfo_InitEx(&info, val, eCORE_UsernameReal);
134 CORE_LOGF(eLOG_Note, ("user7@host7.net - <%s>", info.from));
135 assert(strcmp(info.from, "user7@host7.net") == 0);
136
137 SendMailInfo_InitEx(&info, 0, eCORE_UsernameReal);
138 CORE_LOGF(eLOG_Note, ("NULL - <%s>", info.from));
139 assert(info.from[0] && info.from[0] != '@' && strchr(info.from, '@'));
140
141 if ((huge_body = (char*) malloc(TEST_HUGE_BODY_SIZE)) != 0) {
142
143 strcpy(huge_body, "user8@");
144 for (n = 0; n < TEST_HUGE_BODY_SIZE - 6; n++)
145 huge_body[n + 6] = "abcdefghijklmnopqrstuvwxyz."[rand() % 27];
146 huge_body[TEST_HUGE_BODY_SIZE - 1] = '\0';
147 SendMailInfo_InitEx(&info, huge_body, eCORE_UsernameCurrent);
148 CORE_LOGF(eLOG_Note, ("HUGE user8@host - <%s>", info.from));
149 assert(strcmp(info.from, "user8") == 0);
150
151 SendMailInfo_InitEx(&info, huge_body + 5, eCORE_UsernameLogin);
152 CORE_LOGF(eLOG_Note, ("HUGE @hostA - <%s>", info.from));
153 assert(!strchr(info.from, '@'));
154
155 huge_body[4] = 'B';
156 huge_body[5] = '_';
157 for (n = 6; n < sizeof(info.from) + 1; n++) {
158 if (huge_body[n] == '.')
159 huge_body[n] = '_';
160 }
161 huge_body[sizeof(info.from) + 1] = '@';
162 SendMailInfo_InitEx(&info, huge_body, eCORE_UsernameReal);
163 CORE_LOGF(eLOG_Note, ("HUGE userB - <%s>", info.from));
164 assert(strncmp(info.from, huge_body, sizeof(info.from) - 1) == 0);
165 assert(strlen(info.from) == sizeof(info.from) - 1);
166 assert(!strchr(info.from, '@'));
167
168 huge_body[4] = 'C';
169 huge_body[sizeof(info.from) - 10] = '@';
170 SendMailInfo_InitEx(&info, huge_body, eCORE_UsernameReal);
171 CORE_LOGF(eLOG_Note, ("LONG userC - <%s>", info.from));
172 assert(strncmp(info.from, huge_body, sizeof(info.from) - 10) == 0);
173 assert(strlen(info.from) == sizeof(info.from) - 10);
174 assert(!strchr(info.from, '@'));
175
176 memcpy(huge_body + sizeof(info.from) - 10, "userD", 5);
177 huge_body[sizeof(info.from) << 1] = '\0';
178 SendMailInfo_InitEx(&info, huge_body + sizeof(info.from) - 10,
179 eCORE_UsernameReal);
180 CORE_LOGF(eLOG_Note, ("LONG userD - <%s>", info.from));
181 assert(strncmp(info.from, "userD", 5) == 0);
182
183 SendMailInfo_InitEx(&info, huge_body + sizeof(info.from) + 1,
184 eCORE_UsernameReal);
185 CORE_LOGF(eLOG_Note, ("LONG @hostE - <%s>", info.from));
186 assert(!strchr(info.from, '@'));
187
188 free(huge_body);
189 }
190 #endif
191
192 #if 0
193 if (argc > 1) {
194 CORE_LOG(eLOG_Note, "Special test requested");
195 SendMailInfo_InitEx(&info, "@", eCORE_UsernameCurrent);
196 strcpy(info.from, "Friend <>");
197 info.header = "Sender: \"Your Sender\" <lavr@ncbi.nlm.nih.gov>\n"
198 "Reply-To: Coremake <coremake@ncbi.nlm.nih.gov>";
199 if ((fp = fopen(argv[1], "rb")) != 0 &&
200 fseek(fp, 0, SEEK_END) == 0 &&
201 (n = ftell(fp)) != (size_t)(-1) &&
202 fseek(fp, 0, SEEK_SET) == 0 &&
203 (huge_body = (char*) malloc(n + 1)) != 0 &&
204 fread(huge_body, n, 1, fp) == 1) {
205 huge_body[n] = '\0';
206 CORE_LOGF(eLOG_Note, ("Sending file (%lu bytes)",
207 (unsigned long) n));
208 retval = CORE_SendMailEx("lavr", "File", huge_body, &info);
209 if (retval) {
210 CORE_LOGF(eLOG_Fatal, ("Test failed: %s", retval));
211 } else {
212 CORE_LOG(eLOG_Note, "Test passed");
213 }
214 } else
215 CORE_LOG_ERRNO(eLOG_Error, errno, "Test failed");
216 return 0;
217 }
218 #endif
219
220 #if 0
221 {
222 static const char* body[] = {
223 "This is a simple test",
224 "This is a test with\n.",
225 0,
226 ".",
227 "\n.\n",
228 ".\n",
229 "",
230 "a\nb\nc\nd\n.",
231 "a\r\n\rb\r\nc\r\nd\r\n.",
232 ".\na"
233 };
234 static const char* subject[] = {
235 0,
236 "CORE_SendMail Test",
237 "",
238 };
239 static const char* to[] = {
240 "lavr",
241 "lavr@pavo",
242 " \"Anton Lavrentiev\" <lavr@pavo> , lavr, <lavr> ",
243 };
244 size_t i, j, k, m = 0;
245
246 CORE_LOG(eLOG_Note, "Phase 1 of 2: Testing CORE_SendMail");
247
248 n = (sizeof(to)/sizeof(to[0]))*
249 (sizeof(subject)/sizeof(subject[0]))*
250 (sizeof(body)/sizeof(body[0]));
251 for (i = 0; i < sizeof(to) / sizeof(to[0]); ++i) {
252 for (j = 0; j < sizeof(subject) / sizeof(subject[0]); ++j)
253 for (k = 0; k < sizeof(body) / sizeof(body[0]); ++k) {
254 CORE_LOGF(eLOG_Note, (" Test %u of %u",
255 (unsigned int) ++m,
256 (unsigned int) n));
257 retval = CORE_SendMail(to[i], subject[j], body[k]);
258 if (retval != 0)
259 CORE_LOGF(eLOG_Fatal, ("Test failed: %s", retval));
260 }
261 }
262 }
263 #else
264 CORE_LOG(eLOG_Note, "Phase 1 of 2: Skipping CORE_SendMail tests");
265 #endif
266
267 if (argc > 1) {
268 CORE_LOG(eLOG_Note, "Phase 2 of 2: Testing CORE_SendMailEx");
269
270 SendMailInfo_Init(&info);
271 mx_host = info.mx_host;
272 mx_port = info.mx_port;
273 mx_tmo = info.mx_timeout;
274
275 info.mx_host = "localhost";
276
277 CORE_LOG(eLOG_Note, "Testing bad port");
278 info.mx_port = 10/*BAD*/;
279 retval = CORE_SendMailEx("lavr", "CORE_SendMailEx", "Bad port", &info);
280 if (!retval)
281 CORE_LOG(eLOG_Fatal, "Test failed");
282 CORE_LOGF(eLOG_Note, ("Test passed: %s", retval));
283
284 CORE_LOG(eLOG_Note, "Testing bad protocol");
285 info.mx_port = CONN_PORT_FTP;
286 retval = CORE_SendMailEx("lavr", "CORE_SendMailEx", "Protocol", &info);
287 if (!retval)
288 CORE_LOG(eLOG_Fatal, "Test failed");
289 CORE_LOGF(eLOG_Note, ("Test passed: %s", retval));
290
291 CORE_LOG(eLOG_Note, "Testing timeout");
292 info.mx_host = "www.ncbi.nlm.nih.gov";
293 info.mx_timeout.sec = 5;
294 info.mx_port = CONN_PORT_HTTP;
295 retval = CORE_SendMailEx("lavr", "CORE_SendMailEx", "Timeout", &info);
296 if (!retval)
297 CORE_LOG(eLOG_Error, "Test failed");
298 else
299 CORE_LOGF(eLOG_Note, ("Test passed: %s", retval));
300
301 info.mx_port = mx_port;
302 info.mx_timeout = mx_tmo;
303
304 CORE_LOG(eLOG_Note, "Testing bad host");
305 info.mx_host = "abrakadabra";
306 retval = CORE_SendMailEx("lavr", "CORE_SendMailEx", "Bad host", &info);
307 if (!retval)
308 CORE_LOG(eLOG_Fatal, "Test failed");
309 CORE_LOGF(eLOG_Note, ("Test passed: %s", retval));
310
311 info.mx_host = "localhost";
312
313 CORE_LOG(eLOG_Note, "Testing cc");
314 info.cc = "vakatov";
315 retval = CORE_SendMailEx("", "CORE_SendMailEx", "CC", &info);
316 if (retval)
317 CORE_LOGF(eLOG_Fatal, ("Test failed: %s", retval));
318 CORE_LOG(eLOG_Note, "Test passed");
319
320 CORE_LOG(eLOG_Note, "Testing bcc");
321 info.cc = 0;
322 info.bcc = "vakatov";
323 retval = CORE_SendMailEx(0, "CORE_SendMailEx", "Bcc", &info);
324 if (retval)
325 CORE_LOGF(eLOG_Fatal, ("Test failed: %s", retval));
326 CORE_LOG(eLOG_Note, "Test passed");
327
328 CORE_LOG(eLOG_Note, "Testing huge body");
329 info.cc = 0;
330 info.bcc = 0;
331 if (!(huge_body = (char*) malloc(TEST_HUGE_BODY_SIZE)))
332 CORE_LOG(eLOG_Fatal, "Test failed: Cannot allocate memory");
333 for (n = 0; n < TEST_HUGE_BODY_SIZE - 1; ++n)
334 huge_body[n] = "0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZ ."[rand() % 39];
335 huge_body[n] = 0;
336 retval = CORE_SendMailEx("lavr", "CORE_SendMailEx", huge_body, &info);
337 if (retval)
338 CORE_LOGF(eLOG_Fatal, ("Test failed: %s", retval));
339 if (!(fp = fopen("test_ncbi_sendmail.out", "w")) ||
340 fwrite(huge_body, TEST_HUGE_BODY_SIZE - 1, 1, fp) != 1) {
341 CORE_LOG(eLOG_Error, "Test failed: Cannot store huge body to file");
342 } else {
343 fclose(fp);
344 CORE_LOG(eLOG_Note, "Success: Check test_ncbi_sendmail.out");
345 }
346 free(huge_body);
347
348 CORE_LOG(eLOG_Note, "Testing custom headers");
349 info.header = "Organization: NCBI/NLM/NIH\nReference: abcdefghijk";
350 retval = CORE_SendMailEx("lavr", "CORE_SendMailEx", "Custom header",&info);
351 if (retval)
352 CORE_LOGF(eLOG_Fatal, ("Test failed: %s", retval));
353 CORE_LOG(eLOG_Note, "Test passed");
354
355 CORE_LOG(eLOG_Note, "Testing no recipients");
356 retval = CORE_SendMailEx(0, "CORE_SendMailEx", "No recipients", &info);
357 if (!retval)
358 CORE_LOG(eLOG_Fatal, "Test failed");
359 CORE_LOGF(eLOG_Note, ("Test passed: %s", retval));
360
361 CORE_LOG(eLOG_Note, "Testing AS-IS message");
362 info.mx_options = fSendMail_NoMxHeader;
363 retval = CORE_SendMailEx("lavr",
364 "BAD SUBJECT SHOULD NOT APPEAR BUT IGNORED",
365 "From: yourself\n"
366 "To: yourself\n"
367 "Subject: AS-IS message\n"
368 "\n"
369 "AS-IS",
370 &info);
371 if (retval)
372 CORE_LOGF(eLOG_Fatal, ("Test failed: %s", retval));
373 CORE_LOG(eLOG_Note, "Test passed");
374
375 CORE_LOG(eLOG_Note, "Testing AS-IS custom sized message");
376 info.body_size = strlen(custom_body) - 11/*to ignore*/;
377 retval = CORE_SendMailEx("<lavr@pavo>",
378 "BAD SUBJECT SHOULD NOT APPEAR BUT IGNORED",
379 custom_body,
380 &info);
381 if (retval)
382 CORE_LOGF(eLOG_Fatal, ("Test failed: %s", retval));
383 CORE_LOG(eLOG_Note, "Test passed");
384
385 info.body_size = 0;
386 info.mx_options = 0;
387 info.mx_host = mx_host;
388
389 CORE_LOG(eLOG_Note, "Testing bad from");
390 strcpy(info.from, "blahblah@blahblah");
391 retval = CORE_SendMailEx("lavr", "CORE_SendMailEx", "Bad from",&info);
392 if (!retval)
393 CORE_LOG(eLOG_Error, "Test failed");
394 else
395 CORE_LOGF(eLOG_Note, ("Test passed: %s", retval));
396
397 SendMailInfo_Init(&info);
398 CORE_LOG(eLOG_Note, "Testing drop no FQDN option");
399 info.mx_options |= fSendMail_StripNonFQDNHost;
400 retval = CORE_SendMailEx("lavr", "CORE_SendMailEx", "No FQDN", &info);
401 if (retval)
402 CORE_LOGF(eLOG_Error, ("Test failed: %s", retval));
403 else
404 CORE_LOG(eLOG_Note, "Test passed");
405
406 CORE_LOG(eLOG_Note, "Testing bad magic");
407 info.magic_cookie = 0;
408 retval = CORE_SendMailEx("lavr", "CORE_SendMailEx", "Bad Magic", &info);
409 if (!retval)
410 CORE_LOG(eLOG_Fatal, "Test failed");
411 CORE_LOGF(eLOG_Note, ("Test passed: %s", retval));
412 } else
413 CORE_LOG(eLOG_Note, "Phase 2 of 2: Skipping CORE_SendMailEx tests");
414
415 CORE_LOG(eLOG_Note, "TEST completed successfully");
416 CORE_SetLOG(0);
417 return 0;
418 }
419