aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-02-27 09:39:04 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-02-27 09:39:04 +0000
commit8195d20e36bfeeb30b3424e2635ba4757ec38137 (patch)
tree6226be7f2523f154546f5ad379efb343f57a1ee5
parent17db1a9ac1064a4847fd6a381260c68ab3449951 (diff)
downloadbusybox-w32-8195d20e36bfeeb30b3424e2635ba4757ec38137.tar.gz
busybox-w32-8195d20e36bfeeb30b3424e2635ba4757ec38137.tar.bz2
busybox-w32-8195d20e36bfeeb30b3424e2635ba4757ec38137.zip
sendmail: yet another maintainer's update
-rw-r--r--include/usage.h6
-rw-r--r--networking/Config.in30
-rw-r--r--networking/sendmail.c181
3 files changed, 92 insertions, 125 deletions
diff --git a/include/usage.h b/include/usage.h
index e9770cea9..95cb69c73 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -1035,10 +1035,8 @@ USE_FEATURE_BRCTL_FANCY("\n" \
1035 " -P password Authenticate with specified password\n" \ 1035 " -P password Authenticate with specified password\n" \
1036 " -X Use openssl connection helper for secured servers\n" \ 1036 " -X Use openssl connection helper for secured servers\n" \
1037 " -t Get only headers\n" \ 1037 " -t Get only headers\n" \
1038 " -z Delete messages on server" \ 1038 " -z Delete messages on server\n" \
1039USE_FEATURE_FETCHMAIL_FILTER("\n" \ 1039 " prog Run prog <message file> on message delivery"
1040 " prog Run prog <message file> on message delivery" \
1041)
1042 1040
1043#define findfs_trivial_usage \ 1041#define findfs_trivial_usage \
1044 "LABEL=label or UUID=uuid" 1042 "LABEL=label or UUID=uuid"
diff --git a/networking/Config.in b/networking/Config.in
index 202b65fce..3c53c1115 100644
--- a/networking/Config.in
+++ b/networking/Config.in
@@ -678,39 +678,11 @@ config SENDMAIL
678 help 678 help
679 Barebones sendmail. 679 Barebones sendmail.
680 680
681config FEATURE_SENDMAIL_EHLO
682 bool "Support EHLO command"
683 default n
684 depends on SENDMAIL
685 help
686 Support ESMTP EHLO command.
687
688config FEATURE_SENDMAIL_BLOATY
689 bool "Be more verbose"
690 default n
691 depends on SENDMAIL
692 help
693 Should be turned off.
694
695config FETCHMAIL 681config FETCHMAIL
696 bool "fetchmail" 682 bool "fetchmail"
697 default n 683 default n
698 help 684 help
699 Barebone fetchmail. 685 Barebones fetchmail.
700
701config FEATURE_FETCHMAIL_APOP
702 bool "Support APOP authentication"
703 default y
704 depends on FETCHMAIL
705 help
706 Support secure APOP authentication.
707
708config FEATURE_FETCHMAIL_FILTER
709 bool "Pipe through external filter"
710 default n
711 depends on FETCHMAIL
712 help
713 Support piping incoming messages through external filter.
714 686
715config SLATTACH 687config SLATTACH
716 bool "slattach" 688 bool "slattach"
diff --git a/networking/sendmail.c b/networking/sendmail.c
index adc6c7626..3a6078f79 100644
--- a/networking/sendmail.c
+++ b/networking/sendmail.c
@@ -63,20 +63,13 @@ static void uuencode(char *fname, const char *text)
63 close(fd); 63 close(fd);
64} 64}
65 65
66static const char *const init_xargs[9] = {
67 "openssl", "s_client", "-quiet", "-connect",
68 NULL, "-tls1", "-starttls", "smtp"
69};
70
71struct globals { 66struct globals {
72 pid_t helper_pid; 67 pid_t helper_pid;
73 unsigned timeout; 68 unsigned timeout;
74 // arguments for SSL connection helper 69 // arguments for SSL connection helper
75 const char *xargs[9]; 70 const char *xargs[9];
76#if ENABLE_FEATURE_FETCHMAIL_FILTER
77 // arguments for postprocess helper 71 // arguments for postprocess helper
78 const char *fargs[3]; 72 const char *fargs[3];
79#endif
80}; 73};
81#define G (*ptr_to_globals) 74#define G (*ptr_to_globals)
82#define helper_pid (G.helper_pid) 75#define helper_pid (G.helper_pid)
@@ -85,16 +78,21 @@ struct globals {
85#define fargs (G.fargs ) 78#define fargs (G.fargs )
86#define INIT_G() do { \ 79#define INIT_G() do { \
87 PTR_TO_GLOBALS = xzalloc(sizeof(G)); \ 80 PTR_TO_GLOBALS = xzalloc(sizeof(G)); \
88 memcpy(xargs, init_xargs, sizeof(init_xargs)); \ 81 xargs[0] = "openssl"; \
82 xargs[1] = "s_client"; \
83 xargs[2] = "-quiet"; \
84 xargs[3] = "-connect"; \
85 /*xargs[4] = "server[:port]";*/ \
86 xargs[5] = "-tls1"; \
87 xargs[6] = "-starttls"; \
88 xargs[7] = "smtp"; \
89 fargs[0] = "utf-8"; \ 89 fargs[0] = "utf-8"; \
90} while (0) 90} while (0)
91 91
92#define opt_connect (xargs[4]) 92#define opt_connect (xargs[4])
93#define opt_after_connect (xargs[5]) 93#define opt_after_connect (xargs[5])
94#if ENABLE_FEATURE_FETCHMAIL_FILTER
95#define opt_charset (fargs[0]) 94#define opt_charset (fargs[0])
96#define opt_subject (fargs[1]) 95#define opt_subject (fargs[1])
97#endif
98 96
99static void kill_helper(void) 97static void kill_helper(void)
100{ 98{
@@ -116,11 +114,7 @@ static void signal_handler(int signo)
116 // SIGCHLD. reap zombies 114 // SIGCHLD. reap zombies
117 if (wait_any_nohang(&err) > 0) 115 if (wait_any_nohang(&err) > 0)
118 if (WIFEXITED(err) && WEXITSTATUS(err)) 116 if (WIFEXITED(err) && WEXITSTATUS(err))
119#if ENABLE_FEATURE_SENDMAIL_BLOATY
120 bb_error_msg_and_die("child exited (%d)", WEXITSTATUS(err)); 117 bb_error_msg_and_die("child exited (%d)", WEXITSTATUS(err));
121#else
122 bb_error_msg_and_die("child failed");
123#endif
124} 118}
125 119
126static void launch_helper(const char **argv) 120static void launch_helper(const char **argv)
@@ -141,12 +135,11 @@ static void launch_helper(const char **argv)
141 if (pipes[i] > STDOUT_FILENO) 135 if (pipes[i] > STDOUT_FILENO)
142 close(pipes[i]); 136 close(pipes[i]);
143 if (!helper_pid) { 137 if (!helper_pid) {
144 // child - try to execute connection helper 138 // child: try to execute connection helper
145// close(STDERR_FILENO);
146 BB_EXECVP(*argv, (char **)argv); 139 BB_EXECVP(*argv, (char **)argv);
147 _exit(127); 140 _exit(127);
148 } 141 }
149 // parent - check whether child is alive 142 // parent: check whether child is alive
150 bb_signals(0 143 bb_signals(0
151 + (1 << SIGCHLD) 144 + (1 << SIGCHLD)
152 + (1 << SIGALRM) 145 + (1 << SIGALRM)
@@ -155,13 +148,12 @@ static void launch_helper(const char **argv)
155 // child seems OK -> parent goes on 148 // child seems OK -> parent goes on
156} 149}
157 150
158static char *command(const char *fmt, const char *param) 151static const char *command(const char *fmt, const char *param)
159{ 152{
160 char *msg = (char *)fmt; 153 const char *msg = fmt;
161 alarm(timeout); 154 alarm(timeout);
162 if (msg) { 155 if (msg) {
163// if (param) 156 msg = xasprintf(fmt, param);
164 msg = xasprintf(fmt, param);
165 printf("%s\r\n", msg); 157 printf("%s\r\n", msg);
166 } 158 }
167 fflush(stdout); 159 fflush(stdout);
@@ -171,25 +163,20 @@ static char *command(const char *fmt, const char *param)
171static int smtp_checkp(const char *fmt, const char *param, int code) 163static int smtp_checkp(const char *fmt, const char *param, int code)
172{ 164{
173 char *answer; 165 char *answer;
174 char *msg = command(fmt, param); 166 const char *msg = command(fmt, param);
175 // read stdin 167 // read stdin
176 // if the string has a form \d\d\d- -- read next string. E.g. EHLO response 168 // if the string has a form \d\d\d- -- read next string. E.g. EHLO response
177 // parse first bytes to a number 169 // parse first bytes to a number
178 // if code = -1 then just return this number 170 // if code = -1 then just return this number
179 // if code != -1 then checks whether the number equals the code 171 // if code != -1 then checks whether the number equals the code
180 // if not equal -> die saying msg 172 // if not equal -> die saying msg
181#if ENABLE_FEATURE_SENDMAIL_EHLO
182 while ((answer = xmalloc_getline(stdin)) != NULL) 173 while ((answer = xmalloc_getline(stdin)) != NULL)
183 if (strlen(answer) <= 3 || '-' != answer[3]) 174 if (strlen(answer) <= 3 || '-' != answer[3])
184 break; 175 break;
185#else
186 answer = xmalloc_getline(stdin);
187#endif
188 if (answer) { 176 if (answer) {
189 int n = atoi(answer); 177 int n = atoi(answer);
190 alarm(0); 178 alarm(0);
191 if (ENABLE_FEATURE_CLEAN_UP) { 179 if (ENABLE_FEATURE_CLEAN_UP) {
192 free(msg);
193 free(answer); 180 free(answer);
194 } 181 }
195 if (-1 == code || n == code) { 182 if (-1 == code || n == code) {
@@ -200,7 +187,7 @@ static int smtp_checkp(const char *fmt, const char *param, int code)
200 bb_error_msg_and_die("%s failed", msg); 187 bb_error_msg_and_die("%s failed", msg);
201} 188}
202 189
203static int smtp_check(const char *fmt, int code) 190static int inline smtp_check(const char *fmt, int code)
204{ 191{
205 return smtp_checkp(fmt, NULL, code); 192 return smtp_checkp(fmt, NULL, code);
206} 193}
@@ -223,7 +210,7 @@ static char *sane(char *str)
223#if ENABLE_FETCHMAIL 210#if ENABLE_FETCHMAIL
224static void pop3_checkr(const char *fmt, const char *param, char **ret) 211static void pop3_checkr(const char *fmt, const char *param, char **ret)
225{ 212{
226 char *msg = command(fmt, param); 213 const char *msg = command(fmt, param);
227 char *answer = xmalloc_getline(stdin); 214 char *answer = xmalloc_getline(stdin);
228 if (answer && '+' == *answer) { 215 if (answer && '+' == *answer) {
229 alarm(0); 216 alarm(0);
@@ -237,7 +224,7 @@ static void pop3_checkr(const char *fmt, const char *param, char **ret)
237 bb_error_msg_and_die("%s failed", msg); 224 bb_error_msg_and_die("%s failed", msg);
238} 225}
239 226
240static void pop3_check(const char *fmt, const char *param) 227static void inline pop3_check(const char *fmt, const char *param)
241{ 228{
242 pop3_checkr(fmt, param, NULL); 229 pop3_checkr(fmt, param, NULL);
243} 230}
@@ -249,7 +236,7 @@ static void pop3_message(const char *filename)
249 // create and open file filename 236 // create and open file filename
250 // read stdin, copy to created file 237 // read stdin, copy to created file
251 fd = xopen(filename, O_CREAT | O_WRONLY | O_TRUNC | O_EXCL); 238 fd = xopen(filename, O_CREAT | O_WRONLY | O_TRUNC | O_EXCL);
252 while ((answer = xmalloc_fgets_str(stdin, "\r\n"))) { 239 while ((answer = xmalloc_fgets_str(stdin, "\r\n")) != NULL) {
253 char *s = answer; 240 char *s = answer;
254 if ('.' == *answer) { 241 if ('.' == *answer) {
255 if ('.' == answer[1]) 242 if ('.' == answer[1])
@@ -268,10 +255,6 @@ int sendgetmail_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
268int sendgetmail_main(int argc, char **argv) 255int sendgetmail_main(int argc, char **argv)
269{ 256{
270 llist_t *opt_recipients = NULL; 257 llist_t *opt_recipients = NULL;
271#if !ENABLE_FEATURE_FETCHMAIL_FILTER
272 char *opt_subject;
273 char *opt_charset = (char *)"utf-8";
274#endif
275 258
276 const char *opt_user; 259 const char *opt_user;
277 const char *opt_pass; 260 const char *opt_pass;
@@ -295,8 +278,12 @@ int sendgetmail_main(int argc, char **argv)
295 const char *options; 278 const char *options;
296 unsigned opts; 279 unsigned opts;
297 280
281 // init global variables
298 INIT_G(); 282 INIT_G();
299 283
284 // parse options, different option sets for sendmail and fetchmail
285 // N.B. opt_after_connect hereafter is NULL if we are called as fetchmail
286 // and is NOT NULL if we are called as sendmail
300 if (!ENABLE_FETCHMAIL || 's' == applet_name[0]) { 287 if (!ENABLE_FETCHMAIL || 's' == applet_name[0]) {
301 // SENDMAIL 288 // SENDMAIL
302 // save initial stdin (body or attachements can be piped!) 289 // save initial stdin (body or attachements can be piped!)
@@ -313,7 +300,6 @@ int sendgetmail_main(int argc, char **argv)
313 &timeout, &opt_user, &opt_pass, 300 &timeout, &opt_user, &opt_pass,
314 &opt_subject, &opt_charset, &opt_recipients 301 &opt_subject, &opt_charset, &opt_recipients
315 ); 302 );
316
317 //argc -= optind; 303 //argc -= optind;
318 argv += optind; 304 argv += optind;
319 305
@@ -321,20 +307,29 @@ int sendgetmail_main(int argc, char **argv)
321 opt_connect = *argv++; 307 opt_connect = *argv++;
322 308
323 // connect to server 309 // connect to server
310 // SSL ordered? ->
324 if (opts & OPT_X) { 311 if (opts & OPT_X) {
312 // ... use openssl helper
325 launch_helper(xargs); 313 launch_helper(xargs);
314 // no SSL ordered? ->
326 } else { 315 } else {
327 // no connection helper provided -> make plain connect 316 // ... make plain connect
328 int fd = create_and_connect_stream_or_die(opt_connect, 0); 317 int fd = create_and_connect_stream_or_die(opt_connect, 25);
318 // make ourselves a simple IO filter
319 // from now we know nothing about network :)
329 xmove_fd(fd, STDIN_FILENO); 320 xmove_fd(fd, STDIN_FILENO);
330 xdup2(STDIN_FILENO, STDOUT_FILENO); 321 xdup2(STDIN_FILENO, STDOUT_FILENO);
331 } 322 }
332 323
333#if ENABLE_FETCHMAIL 324#if ENABLE_FETCHMAIL
325 // we are sendmail?
334 if (opt_after_connect) 326 if (opt_after_connect)
335#endif 327#endif
336 { 328 {
337 // SENDMAIL 329/***************************************************
330 * SENDMAIL
331 ***************************************************/
332
338 char *opt_from; 333 char *opt_from;
339 int code; 334 int code;
340 char *boundary; 335 char *boundary;
@@ -342,44 +337,45 @@ int sendgetmail_main(int argc, char **argv)
342 const char *p; 337 const char *p;
343 char *q; 338 char *q;
344 339
345 // wait for initial OK on plain connect 340 // we didn't use SSL helper? ->
346 if (!(opts & OPT_X)) 341 if (!(opts & OPT_X)) {
342 // ... wait for initial server OK
347 smtp_check(NULL, 220); 343 smtp_check(NULL, 220);
344 }
348 345
349 // get specified sender 346 // get the sender
350 opt_from = sane(*argv++); 347 opt_from = sane(*argv++);
351 348
352 // introduce to server 349 // introduce to server
353 // should we respect modern (but useless here) EHLO? 350 // we should start with modern EHLO
354 // or should they respect we wanna be tiny?! 351 if (250 != smtp_checkp("EHLO %s", opt_from, -1)) {
355 if (!ENABLE_FEATURE_SENDMAIL_EHLO || 250 != smtp_checkp("EHLO %s", opt_from, -1)) {
356 smtp_checkp("HELO %s", opt_from, 250); 352 smtp_checkp("HELO %s", opt_from, 250);
357 } 353 }
358 354
359 // set sender 355 // set sender
360 // NOTE: if password has not been specified -> 356 // NOTE: if password has not been specified
361 // no authentication is possible 357 // then no authentication is possible
362 code = (opts & OPT_P) ? -1 : 250; 358 code = (opts & OPT_P) ? -1 : 250;
363 // first try softly without authentication 359 // first try softly without authentication
364 while (250 != smtp_checkp("MAIL FROM:<%s>", opt_from, code)) { 360 while (250 != smtp_checkp("MAIL FROM:<%s>", opt_from, code)) {
365 // MAIL FROM failed -> authentication needed 361 // MAIL FROM failed -> authentication needed
366 // do we have username? 362 // have we got username?
367 if (!(opts & OPT_U)) { 363 if (!(opts & OPT_U)) {
368 // no! fetch it from "from" option 364 // no! fetch it from "from" option
369 //opts |= OPT_U; 365 //opts |= OPT_U;
370 opt_user = xstrdup(opt_from); 366 opt_user = xstrdup(opt_from);
371 *strchrnul(opt_user, '@') = '\0'; 367 *strchrnul(opt_user, '@') = '\0';
372 } 368 }
373 // now it seems we have username 369 // now we've got username
374 // try to authenticate 370 // so try to authenticate
375 if (334 == smtp_check("AUTH LOGIN", -1)) { 371 if (334 == smtp_check("AUTH LOGIN", -1)) {
376 uuencode(NULL, opt_user); 372 uuencode(NULL, opt_user);
377 smtp_check("", 334); 373 smtp_check("", 334);
378 uuencode(NULL, opt_pass); 374 uuencode(NULL, opt_pass);
379 smtp_check("", 235); 375 smtp_check("", 235);
380 } 376 }
381 // authenticated -> retry set sender 377 // authenticated OK? -> retry to set sender
382 // but now die on failure 378 // but this time die on failure!
383 code = 250; 379 code = 250;
384 } 380 }
385 381
@@ -388,13 +384,15 @@ int sendgetmail_main(int argc, char **argv)
388 smtp_checkp("RCPT TO:<%s>", sane(to->data), 250); 384 smtp_checkp("RCPT TO:<%s>", sane(to->data), 250);
389 } 385 }
390 386
391 // now put message 387 // enter "put message" mode
392 smtp_check("DATA", 354); 388 smtp_check("DATA", 354);
389
393 // put address headers 390 // put address headers
394 printf("From: %s\r\n", opt_from); 391 printf("From: %s\r\n", opt_from);
395 for (llist_t *to = opt_recipients; to; to = to->link) { 392 for (llist_t *to = opt_recipients; to; to = to->link) {
396 printf("To: %s\r\n", to->data); 393 printf("To: %s\r\n", to->data);
397 } 394 }
395
398 // put encoded subject 396 // put encoded subject
399 if (opts & OPTS_c) 397 if (opts & OPTS_c)
400 sane((char *)opt_charset); 398 sane((char *)opt_charset);
@@ -403,17 +401,17 @@ int sendgetmail_main(int argc, char **argv)
403 uuencode(NULL, opt_subject); 401 uuencode(NULL, opt_subject);
404 printf("?=\r\n"); 402 printf("?=\r\n");
405 } 403 }
404
406 // put notification 405 // put notification
407 if (opts & OPTS_n) 406 if (opts & OPTS_n)
408 printf("Disposition-Notification-To: %s\r\n", opt_from); 407 printf("Disposition-Notification-To: %s\r\n", opt_from);
408
409 // make a random string -- it will delimit message parts
410 srand(monotonic_us());
411 boundary = xasprintf("%d-%d-%d", rand(), rand(), rand());
412
409 // put common headers and body start 413 // put common headers and body start
410 // randomize
411#if ENABLE_FEATURE_SENDMAIL_BLOATY
412 srand(time(NULL));
413#endif
414 boundary = xasprintf("%d-%d-%d", rand(), rand(), rand());
415 printf( 414 printf(
416 USE_FEATURE_SENDMAIL_BLOATY("X-Mailer: busybox " BB_VER " sendmail\r\n")
417 "Message-ID: <%s>\r\n" 415 "Message-ID: <%s>\r\n"
418 "Mime-Version: 1.0\r\n" 416 "Mime-Version: 1.0\r\n"
419 "%smultipart/mixed; boundary=\"%s\"\r\n" 417 "%smultipart/mixed; boundary=\"%s\"\r\n"
@@ -421,8 +419,10 @@ int sendgetmail_main(int argc, char **argv)
421 , "Content-Type: " 419 , "Content-Type: "
422 , boundary 420 , boundary
423 ); 421 );
424 // put body + attachment(s)
425 422
423 // put body + attachment(s)
424 // N.B. all these weird things just to be tiny
425 // by reusing string patterns!
426 fmt = 426 fmt =
427 "\r\n--%s\r\n" 427 "\r\n--%s\r\n"
428 "%stext/plain; charset=%s\r\n" 428 "%stext/plain; charset=%s\r\n"
@@ -453,44 +453,50 @@ int sendgetmail_main(int argc, char **argv)
453 q = bb_get_last_path_component_strip(*argv); 453 q = bb_get_last_path_component_strip(*argv);
454 } 454 }
455 455
456 // put terminator 456 // put message terminator
457 printf("\r\n--%s--\r\n" "\r\n", boundary); 457 printf("\r\n--%s--\r\n" "\r\n", boundary);
458 if (ENABLE_FEATURE_CLEAN_UP)
459 free(boundary);
460 458
461 // end message and say goodbye 459 // leave "put message" mode
462 smtp_check(".", 250); 460 smtp_check(".", 250);
461 // ... and say goodbye
463 smtp_check("QUIT", 221); 462 smtp_check("QUIT", 221);
464 463
465#if ENABLE_FETCHMAIL 464#if ENABLE_FETCHMAIL
466 } else { 465 } else {
467 // FETCHMAIL 466/***************************************************
467 * FETCHMAIL
468 ***************************************************/
469
468 char *buf; 470 char *buf;
469 unsigned nmsg; 471 unsigned nmsg;
470 char *hostname; 472 char *hostname;
471 pid_t pid; 473 pid_t pid;
472 // cache fetch command 474
475 // cache fetch command:
476 // TOP will return only the headers
477 // RETR will dump the whole message
473 const char *retr = (opts & OPTF_t) ? "TOP %u 0" : "RETR %u"; 478 const char *retr = (opts & OPTF_t) ? "TOP %u 0" : "RETR %u";
474 479
475 // goto maildir 480 // goto maildir
476 xchdir(*argv++); 481 xchdir(*argv++);
477 482
478#if ENABLE_FEATURE_FETCHMAIL_FILTER
479 // cache postprocess program 483 // cache postprocess program
480 *fargs = *argv; 484 *fargs = *argv;
481#endif
482 485
483 // authenticate 486 // authenticate
484 if (!(opts & OPT_U)) { 487 if (!(opts & OPT_U)) {
485 //opts |= OPT_U; 488 //opts |= OPT_U;
486 opt_user = getenv("USER"); 489 // N.B. IMHO getenv("USER") can be way easily spoofed!
490 opt_user = bb_getpwuid(NULL, -1, getuid());
487 } 491 }
488#if ENABLE_FEATURE_FETCHMAIL_APOP 492
493 // get server greeting
489 pop3_checkr(NULL, NULL, &buf); 494 pop3_checkr(NULL, NULL, &buf);
495
490 // server supports APOP? 496 // server supports APOP?
491 if ('<' == *buf) { 497 if ('<' == *buf) {
492 md5_ctx_t md5; 498 md5_ctx_t md5;
493 // yes. compose <stamp><password> 499 // yes! compose <stamp><password>
494 char *s = strchr(buf, '>'); 500 char *s = strchr(buf, '>');
495 if (s) 501 if (s)
496 strcpy(s+1, opt_pass); 502 strcpy(s+1, opt_pass);
@@ -512,26 +518,22 @@ int sendgetmail_main(int argc, char **argv)
512 free(s); 518 free(s);
513 free(buf-4); // buf is "+OK " away from malloc'ed string 519 free(buf-4); // buf is "+OK " away from malloc'ed string
514 } 520 }
521 // server ignores APOP -> use simple text authentication
515 } else { 522 } else {
516#else
517 {
518 pop3_check(NULL, NULL);
519#endif
520 // USER 523 // USER
521 pop3_check("USER %s", opt_user); 524 pop3_check("USER %s", opt_user);
522 // PASS 525 // PASS
523 pop3_check("PASS %s", opt_pass); 526 pop3_check("PASS %s", opt_pass);
524 } 527 }
525 528
526 // get statistics 529 // get mailbox statistics
527 pop3_checkr("STAT", NULL, &buf); 530 pop3_checkr("STAT", NULL, &buf);
528 531
529 // prepare message filename suffix 532 // prepare message filename suffix
530 hostname = xzalloc(MAXHOSTNAMELEN+1); 533 hostname = safe_gethostname();
531 gethostname(hostname, MAXHOSTNAMELEN);
532 pid = getpid(); 534 pid = getpid();
533 535
534 // get number of messages 536 // get messages counter
535 // NOTE: we don't use xatou(buf) since buf is "nmsg nbytes" 537 // NOTE: we don't use xatou(buf) since buf is "nmsg nbytes"
536 // we only need nmsg and atoi is just exactly what we need 538 // we only need nmsg and atoi is just exactly what we need
537 // if atoi fails to convert buf into number it returns 0 539 // if atoi fails to convert buf into number it returns 0
@@ -542,19 +544,19 @@ int sendgetmail_main(int argc, char **argv)
542 544
543 // loop through messages 545 // loop through messages
544 for (; nmsg; nmsg--) { 546 for (; nmsg; nmsg--) {
547
548 // generate unique filename
545 char *filename = xasprintf("tmp/%llu.%u.%s", monotonic_us(), pid, hostname); 549 char *filename = xasprintf("tmp/%llu.%u.%s", monotonic_us(), pid, hostname);
546 char *target; 550 char *target;
547#if ENABLE_FEATURE_FETCHMAIL_FILTER 551 int rc;
548 int rc; 552
549#endif 553 // retrieve message in ./tmp/
550 // retrieve message in ./tmp
551 pop3_check(retr, (const char *)nmsg); 554 pop3_check(retr, (const char *)nmsg);
552 pop3_message(filename); 555 pop3_message(filename);
553 // delete message from server 556 // delete message from server
554 if (opts & OPTF_z) 557 if (opts & OPTF_z)
555 pop3_check("DELE %u", (const char*)nmsg); 558 pop3_check("DELE %u", (const char*)nmsg);
556 559
557#if ENABLE_FEATURE_FETCHMAIL_FILTER
558 // run postprocessing program 560 // run postprocessing program
559 if (*fargs) { 561 if (*fargs) {
560 fargs[1] = filename; 562 fargs[1] = filename;
@@ -564,23 +566,18 @@ int sendgetmail_main(int argc, char **argv)
564 if (1 == rc) 566 if (1 == rc)
565 goto skip; 567 goto skip;
566 } 568 }
567#endif 569
568 // atomically move message to ./new 570 // atomically move message to ./new/
569 target = xstrdup(filename); 571 target = xstrdup(filename);
570 strncpy(target, "new", 3); 572 strncpy(target, "new", 3);
571 // ... or just stop receiving on error 573 // ... or just stop receiving on error
572 if (rename_or_warn(filename, target)) 574 if (rename_or_warn(filename, target))
573 break; 575 break;
574 free(target); 576 free(target);
575#if ENABLE_FEATURE_FETCHMAIL_FILTER
576 skip: 577 skip:
577#endif
578 free(filename); 578 free(filename);
579 } 579 }
580 580
581 if (ENABLE_FEATURE_CLEAN_UP)
582 free(hostname);
583
584 // Bye 581 // Bye
585 pop3_check("QUIT", NULL); 582 pop3_check("QUIT", NULL);
586#endif // ENABLE_FETCHMAIL 583#endif // ENABLE_FETCHMAIL