snprintf() on some platforms return -1 for error on others
the count that would have been written, the latter is C99 conformant but the former is also in wide use since snprintf () was not part of ANSI C, or posix.
Showing
7 changed files
with
97 additions
and
55 deletions
... | @@ -308,7 +308,7 @@ _file_open (stream_t stream, const char *filename, int port, int flags) | ... | @@ -308,7 +308,7 @@ _file_open (stream_t stream, const char *filename, int port, int flags) |
308 | } | 308 | } |
309 | #if BUFSIZ <= 1024 | 309 | #if BUFSIZ <= 1024 |
310 | /* Give us some room to breath, for OS with two small stdio buffers. */ | 310 | /* Give us some room to breath, for OS with two small stdio buffers. */ |
311 | setvbuf (fs->file, iobuffer, _IOFBF, 8192); | 311 | setvbuf (fs->file, NULL, _IOFBF, 8192); |
312 | #endif | 312 | #endif |
313 | stream_set_flags (stream, flags |MU_STREAM_NO_CHECK); | 313 | stream_set_flags (stream, flags |MU_STREAM_NO_CHECK); |
314 | return 0; | 314 | return 0; | ... | ... |
... | @@ -51,9 +51,10 @@ extern "C" { | ... | @@ -51,9 +51,10 @@ extern "C" { |
51 | #define MIME_PARSER_ACTIVE 0x80000000 | 51 | #define MIME_PARSER_ACTIVE 0x80000000 |
52 | #define MIME_PARSER_HAVE_CR 0x40000000 | 52 | #define MIME_PARSER_HAVE_CR 0x40000000 |
53 | #define MIME_NEW_MESSAGE 0x20000000 | 53 | #define MIME_NEW_MESSAGE 0x20000000 |
54 | #define MIME_ADDED_CONTENT_TYPE 0x10000000 | 54 | #define MIME_ADDED_CT 0x10000000 |
55 | #define MIME_ADDED_MULTIPART 0x08000000 | 55 | #define MIME_ADDED_MULTIPART_CT 0x08000000 |
56 | #define MIME_INSERT_BOUNDARY 0x04000000 | 56 | #define MIME_INSERT_BOUNDARY 0x04000000 |
57 | #define MIME_ADDING_BOUNDARY 0x02000000 | ||
57 | 58 | ||
58 | struct _mime | 59 | struct _mime |
59 | { | 60 | { |
... | @@ -70,7 +71,9 @@ struct _mime | ... | @@ -70,7 +71,9 @@ struct _mime |
70 | int cur_offset; | 71 | int cur_offset; |
71 | int cur_part; | 72 | int cur_part; |
72 | int part_offset; | 73 | int part_offset; |
73 | 74 | int boundary_len; | |
75 | int preamble; | ||
76 | int postamble; | ||
74 | /* parser state */ | 77 | /* parser state */ |
75 | char *cur_line; | 78 | char *cur_line; |
76 | int line_ndx; | 79 | int line_ndx; | ... | ... |
... | @@ -21,10 +21,13 @@ | ... | @@ -21,10 +21,13 @@ |
21 | 21 | ||
22 | #include <string.h> | 22 | #include <string.h> |
23 | #include <stdlib.h> | 23 | #include <stdlib.h> |
24 | #include <paths.h> | ||
25 | #include <errno.h> | 24 | #include <errno.h> |
26 | #include <stdio.h> | 25 | #include <stdio.h> |
27 | 26 | ||
27 | #ifdef HAVE_PATHS_H | ||
28 | # include <paths.h> | ||
29 | #endif | ||
30 | |||
28 | #include <mailutils/mailbox.h> | 31 | #include <mailutils/mailbox.h> |
29 | 32 | ||
30 | #ifndef _PATH_MAILDIR | 33 | #ifndef _PATH_MAILDIR | ... | ... |
... | @@ -1551,25 +1551,35 @@ pop_retr (pop_message_t mpm, char *buffer, size_t buflen, off_t offset, | ... | @@ -1551,25 +1551,35 @@ pop_retr (pop_message_t mpm, char *buffer, size_t buflen, off_t offset, |
1551 | return 0; | 1551 | return 0; |
1552 | } | 1552 | } |
1553 | 1553 | ||
1554 | /* C99 says that a conforming implementations of snprintf () | ||
1555 | should return the number of char that would have been call | ||
1556 | but many GNU/Linux && BSD implementations return -1 on error. | ||
1557 | Worse QnX/Neutrino actually does not put the terminal | ||
1558 | null char. So let's try to cope. */ | ||
1554 | static int | 1559 | static int |
1555 | pop_writeline (pop_data_t mpd, const char *format, ...) | 1560 | pop_writeline (pop_data_t mpd, const char *format, ...) |
1556 | { | 1561 | { |
1557 | int len; | 1562 | int len; |
1558 | va_list ap; | 1563 | va_list ap; |
1564 | int done = 1; | ||
1559 | 1565 | ||
1560 | va_start(ap, format); | 1566 | va_start(ap, format); |
1561 | do | 1567 | do |
1562 | { | 1568 | { |
1563 | len = vsnprintf (mpd->buffer, mpd->buflen - 1, format, ap); | 1569 | len = vsnprintf (mpd->buffer, mpd->buflen - 1, format, ap); |
1564 | if (len >= (int)mpd->buflen) | 1570 | if (len < 0 || len >= (int)mpd->buflen |
1571 | || !memchr (mpd->buffer, '\0', len + 1)) | ||
1565 | { | 1572 | { |
1566 | mpd->buflen *= 2; | 1573 | mpd->buflen *= 2; |
1567 | mpd->buffer = realloc (mpd->buffer, mpd->buflen); | 1574 | mpd->buffer = realloc (mpd->buffer, mpd->buflen); |
1568 | if (mpd->buffer == NULL) | 1575 | if (mpd->buffer == NULL) |
1569 | return ENOMEM; | 1576 | return ENOMEM; |
1577 | done = 0; | ||
1570 | } | 1578 | } |
1579 | else | ||
1580 | done = 1; | ||
1571 | } | 1581 | } |
1572 | while (len > (int)mpd->buflen); | 1582 | while (!done); |
1573 | va_end(ap); | 1583 | va_end(ap); |
1574 | mpd->ptr = mpd->buffer + len; | 1584 | mpd->ptr = mpd->buffer + len; |
1575 | return 0; | 1585 | return 0; | ... | ... |
... | @@ -86,6 +86,7 @@ static int _mime_append_part(mime_t mime, message_t msg, int offset, int len, in | ... | @@ -86,6 +86,7 @@ static int _mime_append_part(mime_t mime, message_t msg, int offset, int len, in |
86 | mime_part->lines = lines; | 86 | mime_part->lines = lines; |
87 | mime_part->offset = offset; | 87 | mime_part->offset = offset; |
88 | } else { | 88 | } else { |
89 | message_ref(msg); | ||
89 | message_size(msg, &mime_part->len); | 90 | message_size(msg, &mime_part->len); |
90 | message_lines(msg, &mime_part->lines); | 91 | message_lines(msg, &mime_part->lines); |
91 | if ( mime->nmtp_parts > 1 ) | 92 | if ( mime->nmtp_parts > 1 ) |
... | @@ -372,7 +373,7 @@ static int _mime_set_content_type(mime_t mime) | ... | @@ -372,7 +373,7 @@ static int _mime_set_content_type(mime_t mime) |
372 | size_t size; | 373 | size_t size; |
373 | 374 | ||
374 | if ( mime->nmtp_parts > 1 ) { | 375 | if ( mime->nmtp_parts > 1 ) { |
375 | if ( mime->flags & MIME_ADDED_MULTIPART ) | 376 | if ( mime->flags & MIME_ADDED_MULTIPART_CT ) |
376 | return 0; | 377 | return 0; |
377 | if ( mime->flags & MIME_MULTIPART_MIXED ) | 378 | if ( mime->flags & MIME_MULTIPART_MIXED ) |
378 | strcpy(content_type, "multipart/mixed; boundary="); | 379 | strcpy(content_type, "multipart/mixed; boundary="); |
... | @@ -386,11 +387,11 @@ static int _mime_set_content_type(mime_t mime) | ... | @@ -386,11 +387,11 @@ static int _mime_set_content_type(mime_t mime) |
386 | strcat(content_type, "\""); | 387 | strcat(content_type, "\""); |
387 | strcat(content_type, mime->boundary); | 388 | strcat(content_type, mime->boundary); |
388 | strcat(content_type, "\""); | 389 | strcat(content_type, "\""); |
389 | mime->flags |= MIME_ADDED_MULTIPART; | 390 | mime->flags |= MIME_ADDED_MULTIPART_CT; |
390 | } else { | 391 | } else { |
391 | if ( (mime->flags & (MIME_ADDED_CONTENT_TYPE|MIME_ADDED_MULTIPART)) == MIME_ADDED_CONTENT_TYPE ) | 392 | if ( (mime->flags & (MIME_ADDED_CT|MIME_ADDED_MULTIPART_CT)) == MIME_ADDED_CT ) |
392 | return 0; | 393 | return 0; |
393 | mime->flags &= ~MIME_ADDED_MULTIPART; | 394 | mime->flags &= ~MIME_ADDED_MULTIPART_CT; |
394 | if ( mime->nmtp_parts ) | 395 | if ( mime->nmtp_parts ) |
395 | message_get_header(mime->mtp_parts[0]->msg, &hdr); | 396 | message_get_header(mime->mtp_parts[0]->msg, &hdr); |
396 | if ( hdr == NULL || header_get_value(hdr, "Content-Type", NULL, 0, &size) != 0 || size == 0 ) | 397 | if ( hdr == NULL || header_get_value(hdr, "Content-Type", NULL, 0, &size) != 0 || size == 0 ) |
... | @@ -398,10 +399,12 @@ static int _mime_set_content_type(mime_t mime) | ... | @@ -398,10 +399,12 @@ static int _mime_set_content_type(mime_t mime) |
398 | else | 399 | else |
399 | header_get_value(hdr, "Content-Type", content_type, sizeof(content_type), &size); | 400 | header_get_value(hdr, "Content-Type", content_type, sizeof(content_type), &size); |
400 | } | 401 | } |
401 | mime->flags |= MIME_ADDED_CONTENT_TYPE; | 402 | mime->flags |= MIME_ADDED_CT; |
402 | return header_set_value(mime->hdrs, "Content-Type", content_type, 1); | 403 | return header_set_value(mime->hdrs, "Content-Type", content_type, 1); |
403 | } | 404 | } |
404 | 405 | ||
406 | #define ADD_CHAR(buf, c, offset, buflen, nbytes) {*(buf)++ = c; (offset)++; (nbytes)++;if (--(buflen) == 0) return 0;} | ||
407 | |||
405 | static int _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off, size_t *nbytes) | 408 | static int _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off, size_t *nbytes) |
406 | { | 409 | { |
407 | body_t body = stream_get_owner(stream); | 410 | body_t body = stream_get_owner(stream); |
... | @@ -417,6 +420,8 @@ static int _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off, | ... | @@ -417,6 +420,8 @@ static int _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off, |
417 | if ( off == 0 ) { /* reset message */ | 420 | if ( off == 0 ) { /* reset message */ |
418 | mime->cur_offset = 0; | 421 | mime->cur_offset = 0; |
419 | mime->cur_part = 0; | 422 | mime->cur_part = 0; |
423 | if ( mime->nmtp_parts > 1 ) | ||
424 | mime->flags |= MIME_INSERT_BOUNDARY; | ||
420 | } | 425 | } |
421 | 426 | ||
422 | if ( off != mime->cur_offset ) | 427 | if ( off != mime->cur_offset ) |
... | @@ -425,39 +430,37 @@ static int _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off, | ... | @@ -425,39 +430,37 @@ static int _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off, |
425 | if ( nbytes ) | 430 | if ( nbytes ) |
426 | *nbytes = 0; | 431 | *nbytes = 0; |
427 | 432 | ||
428 | if ( mime->cur_part == mime->nmtp_parts ) | ||
429 | return 0; | ||
430 | |||
431 | if ( ( ret = _mime_set_content_type(mime) ) == 0 ) { | 433 | if ( ( ret = _mime_set_content_type(mime) ) == 0 ) { |
432 | do { | 434 | do { |
433 | len = 0; | 435 | len = 0; |
434 | if ( mime->nmtp_parts > 1 ) { | 436 | if ( mime->nmtp_parts > 1 ) { |
435 | if ( ( mime->flags & MIME_INSERT_BOUNDARY || mime->cur_offset == 0 ) ) { | 437 | if ( mime->flags & MIME_INSERT_BOUNDARY ) { |
436 | mime->cur_part++; | 438 | if ( ( mime->flags & MIME_ADDING_BOUNDARY ) == 0 ) { |
437 | len = 2; | 439 | mime->boundary_len = strlen(mime->boundary); |
438 | buf[0] = buf[1] = '-'; | 440 | mime->preamble = 2; |
439 | buf+=2; | 441 | if ( mime->cur_part == mime->nmtp_parts ) |
440 | len += strlen(mime->boundary); | 442 | mime->postamble = 2; |
441 | strcpy(buf, mime->boundary); | 443 | mime->flags |= MIME_ADDING_BOUNDARY; |
442 | buf+= strlen(mime->boundary); | ||
443 | if ( mime->cur_part == mime->nmtp_parts ) { | ||
444 | len+=2; | ||
445 | buf[0] = buf[1] = '-'; | ||
446 | buf+=2; | ||
447 | } | 444 | } |
448 | len++; | 445 | while(mime->preamble) { |
449 | buf[0] = '\n'; | 446 | mime->preamble--; |
450 | buf++; | 447 | ADD_CHAR(buf, '-', mime->cur_offset, buflen, *nbytes); |
451 | mime->flags &= ~MIME_INSERT_BOUNDARY; | 448 | } |
452 | buflen =- len; | 449 | len = strlen(mime->boundary) - mime->boundary_len; |
453 | mime->part_offset = 0; | 450 | while(mime->boundary_len) { |
454 | if ( mime->cur_part == mime->nmtp_parts ) { | 451 | mime->boundary_len--; |
455 | if ( nbytes ) | 452 | ADD_CHAR(buf, mime->boundary[len++], mime->cur_offset, buflen, *nbytes); |
456 | *nbytes += len; | ||
457 | mime->cur_offset +=len; | ||
458 | break; | ||
459 | } | 453 | } |
454 | while(mime->postamble) { | ||
455 | mime->postamble--; | ||
456 | ADD_CHAR(buf, '-', mime->cur_offset, buflen, *nbytes); | ||
457 | } | ||
458 | mime->flags &= ~(MIME_INSERT_BOUNDARY|MIME_ADDING_BOUNDARY); | ||
459 | mime->part_offset = 0; | ||
460 | ADD_CHAR(buf, '\n',mime->cur_offset, buflen, *nbytes); | ||
460 | } | 461 | } |
462 | if ( mime->cur_part >= mime->nmtp_parts ) | ||
463 | return 0; | ||
461 | message_get_stream(mime->mtp_parts[mime->cur_part]->msg, &msg_stream); | 464 | message_get_stream(mime->mtp_parts[mime->cur_part]->msg, &msg_stream); |
462 | } else { | 465 | } else { |
463 | body_t body; | 466 | body_t body; |
... | @@ -470,8 +473,10 @@ static int _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off, | ... | @@ -470,8 +473,10 @@ static int _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off, |
470 | if ( nbytes ) | 473 | if ( nbytes ) |
471 | *nbytes += len; | 474 | *nbytes += len; |
472 | mime->cur_offset += len; | 475 | mime->cur_offset += len; |
473 | if ( ret == 0 && part_nbytes == 0 && mime->nmtp_parts > 1 ) | 476 | if ( ret == 0 && part_nbytes == 0 && mime->nmtp_parts > 1 ) { |
474 | mime->flags |= MIME_INSERT_BOUNDARY; | 477 | mime->flags |= MIME_INSERT_BOUNDARY; |
478 | mime->cur_part++; | ||
479 | } | ||
475 | } while( ret == 0 && part_nbytes == 0 ); | 480 | } while( ret == 0 && part_nbytes == 0 ); |
476 | } | 481 | } |
477 | return ret; | 482 | return ret; |
... | @@ -494,13 +499,14 @@ static int _mime_body_size (body_t body, size_t *psize) | ... | @@ -494,13 +499,14 @@ static int _mime_body_size (body_t body, size_t *psize) |
494 | { | 499 | { |
495 | message_t msg = body_get_owner(body); | 500 | message_t msg = body_get_owner(body); |
496 | mime_t mime = message_get_owner(msg); | 501 | mime_t mime = message_get_owner(msg); |
497 | int i; | 502 | int i, ret; |
498 | size_t size; | 503 | size_t size; |
499 | 504 | ||
500 | if ( mime->nmtp_parts == 0 ) | 505 | if ( mime->nmtp_parts == 0 ) |
501 | return EINVAL; | 506 | return EINVAL; |
502 | 507 | ||
503 | _mime_set_content_type(mime); | 508 | if ( (ret = _mime_set_content_type(mime) ) != 0 ) |
509 | return ret; | ||
504 | for ( i=0;i<mime->nmtp_parts;i++ ) { | 510 | for ( i=0;i<mime->nmtp_parts;i++ ) { |
505 | message_size(mime->mtp_parts[i]->msg, &size); | 511 | message_size(mime->mtp_parts[i]->msg, &size); |
506 | *psize+=size; | 512 | *psize+=size; |
... | @@ -517,13 +523,14 @@ static int _mime_body_lines (body_t body, size_t *plines) | ... | @@ -517,13 +523,14 @@ static int _mime_body_lines (body_t body, size_t *plines) |
517 | { | 523 | { |
518 | message_t msg = body_get_owner(body); | 524 | message_t msg = body_get_owner(body); |
519 | mime_t mime = message_get_owner(msg); | 525 | mime_t mime = message_get_owner(msg); |
520 | int i; | 526 | int i, ret; |
521 | size_t lines; | 527 | size_t lines; |
522 | 528 | ||
523 | if ( mime->nmtp_parts == 0 ) | 529 | if ( mime->nmtp_parts == 0 ) |
524 | return EINVAL; | 530 | return EINVAL; |
525 | 531 | ||
526 | _mime_set_content_type(mime); | 532 | if ( (ret = _mime_set_content_type(mime) ) != 0 ) |
533 | return ret; | ||
527 | for ( i = 0; i < mime->nmtp_parts; i++ ) { | 534 | for ( i = 0; i < mime->nmtp_parts; i++ ) { |
528 | message_lines(mime->mtp_parts[i]->msg, &lines); | 535 | message_lines(mime->mtp_parts[i]->msg, &lines); |
529 | plines+=lines; | 536 | plines+=lines; |
... | @@ -566,7 +573,7 @@ int mime_create(mime_t *pmime, message_t msg, int flags) | ... | @@ -566,7 +573,7 @@ int mime_create(mime_t *pmime, message_t msg, int flags) |
566 | } | 573 | } |
567 | } | 574 | } |
568 | else { | 575 | else { |
569 | mime->flags |= MIME_NEW_MESSAGE; | 576 | mime->flags |= MIME_NEW_MESSAGE | MIME_MULTIPART_MIXED; |
570 | } | 577 | } |
571 | if ( ret != 0 ) { | 578 | if ( ret != 0 ) { |
572 | if ( mime->content_type ) | 579 | if ( mime->content_type ) |
... | @@ -591,13 +598,16 @@ void mime_destroy(mime_t *pmime) | ... | @@ -591,13 +598,16 @@ void mime_destroy(mime_t *pmime) |
591 | if ( mime->mtp_parts != NULL ) { | 598 | if ( mime->mtp_parts != NULL ) { |
592 | for ( i = 0; i < mime->nmtp_parts; i++ ) { | 599 | for ( i = 0; i < mime->nmtp_parts; i++ ) { |
593 | mime_part = mime->mtp_parts[i]; | 600 | mime_part = mime->mtp_parts[i]; |
594 | if ( mime_part->msg ) { | 601 | if ( mime_part->msg && mime->flags & MIME_NEW_MESSAGE ) |
602 | message_unref(mime_part->msg); | ||
603 | else | ||
595 | message_destroy(&mime_part->msg, mime_part); | 604 | message_destroy(&mime_part->msg, mime_part); |
596 | free (mime_part); | 605 | free (mime_part); |
597 | } | ||
598 | } | 606 | } |
599 | free (mime->mtp_parts); | 607 | free (mime->mtp_parts); |
600 | } | 608 | } |
609 | if ( mime->msg && mime->flags & MIME_NEW_MESSAGE ) | ||
610 | message_destroy(&mime->msg, mime); | ||
601 | if ( mime->content_type ) | 611 | if ( mime->content_type ) |
602 | free(mime->content_type); | 612 | free(mime->content_type); |
603 | if ( mime->cur_buf ) | 613 | if ( mime->cur_buf ) |
... | @@ -662,9 +672,13 @@ int mime_get_num_parts(mime_t mime, int *nmtp_parts) | ... | @@ -662,9 +672,13 @@ int mime_get_num_parts(mime_t mime, int *nmtp_parts) |
662 | 672 | ||
663 | int mime_add_part(mime_t mime, message_t msg) | 673 | int mime_add_part(mime_t mime, message_t msg) |
664 | { | 674 | { |
675 | int ret; | ||
676 | |||
665 | if ( mime == NULL || msg == NULL || ( mime->flags & MIME_NEW_MESSAGE ) == 0 ) | 677 | if ( mime == NULL || msg == NULL || ( mime->flags & MIME_NEW_MESSAGE ) == 0 ) |
666 | return EINVAL; | 678 | return EINVAL; |
667 | return _mime_append_part(mime, msg, 0, 0, 0); | 679 | if ( ( ret = _mime_append_part(mime, msg, 0, 0, 0) ) == 0 ) |
680 | ret = _mime_set_content_type(mime); | ||
681 | return ret; | ||
668 | } | 682 | } |
669 | 683 | ||
670 | int mime_get_message(mime_t mime, message_t *msg) | 684 | int mime_get_message(mime_t mime, message_t *msg) | ... | ... |
... | @@ -285,7 +285,7 @@ smtp_open (mailer_t mailer, int flags) | ... | @@ -285,7 +285,7 @@ smtp_open (mailer_t mailer, int flags) |
285 | /* allocate a working io buffer. */ | 285 | /* allocate a working io buffer. */ |
286 | if (smtp->buffer == NULL) | 286 | if (smtp->buffer == NULL) |
287 | { | 287 | { |
288 | smtp->buflen = 255; /* Initial guess. */ | 288 | smtp->buflen = 512; /* Initial guess. */ |
289 | smtp->buffer = malloc (smtp->buflen + 1); | 289 | smtp->buffer = malloc (smtp->buflen + 1); |
290 | if (smtp->buffer == NULL) | 290 | if (smtp->buffer == NULL) |
291 | { | 291 | { |
... | @@ -305,7 +305,7 @@ smtp_open (mailer_t mailer, int flags) | ... | @@ -305,7 +305,7 @@ smtp_open (mailer_t mailer, int flags) |
305 | smtp->state = SMTP_OPEN; | 305 | smtp->state = SMTP_OPEN; |
306 | 306 | ||
307 | case SMTP_OPEN: | 307 | case SMTP_OPEN: |
308 | MAILER_DEBUG2 (mailer, MU_DEBUG_PROT, "smtp_open (%s:%d)\n", smtp->localhost, port); | 308 | MAILER_DEBUG2 (mailer, MU_DEBUG_PROT, "smtp_open (%s:%d)\n", smtp->mailhost, port); |
309 | status = stream_open (mailer->stream, smtp->mailhost, port, | 309 | status = stream_open (mailer->stream, smtp->mailhost, port, |
310 | mailer->flags); | 310 | mailer->flags); |
311 | CHECK_EAGAIN (smtp, status); | 311 | CHECK_EAGAIN (smtp, status); |
... | @@ -565,7 +565,8 @@ smtp_send_message(mailer_t mailer, message_t msg) | ... | @@ -565,7 +565,8 @@ smtp_send_message(mailer_t mailer, message_t msg) |
565 | CHECK_ERROR (smtp, status); | 565 | CHECK_ERROR (smtp, status); |
566 | } | 566 | } |
567 | smtp->offset += n; | 567 | smtp->offset += n; |
568 | status = smtp_write (smtp); | 568 | MAILER_DEBUG0 (mailer, MU_DEBUG_PROT, smtp->buffer); |
569 | status = smtp_write (smtp); | ||
569 | CHECK_EAGAIN (smtp, status); | 570 | CHECK_EAGAIN (smtp, status); |
570 | } | 571 | } |
571 | smtp->offset = 0; | 572 | smtp->offset = 0; |
... | @@ -716,25 +717,36 @@ get_rcpt (message_t msg, address_t *prcpt_to) | ... | @@ -716,25 +717,36 @@ get_rcpt (message_t msg, address_t *prcpt_to) |
716 | } | 717 | } |
717 | return EINVAL; | 718 | return EINVAL; |
718 | } | 719 | } |
719 | static int | 720 | |
721 | /* C99 says that a conforming implementations of snprintf () | ||
722 | should return the number of char that would have been call | ||
723 | but many GNU/Linux && BSD implementations return -1 on error. | ||
724 | Worse QNX/Neutrino actually does not put the terminal | ||
725 | null char. So let's try to cope. */ | ||
726 | static int | ||
720 | smtp_writeline (smtp_t smtp, const char *format, ...) | 727 | smtp_writeline (smtp_t smtp, const char *format, ...) |
721 | { | 728 | { |
722 | int len; | 729 | int len; |
723 | va_list ap; | 730 | va_list ap; |
731 | int done = 1; | ||
724 | 732 | ||
725 | va_start(ap, format); | 733 | va_start(ap, format); |
726 | do | 734 | do |
727 | { | 735 | { |
728 | len = vsnprintf (smtp->buffer, smtp->buflen - 1, format, ap); | 736 | len = vsnprintf (smtp->buffer, smtp->buflen - 1, format, ap); |
729 | if (len >= (int)smtp->buflen) | 737 | if (len < 0 || (len >= (int)smtp->buflen) |
738 | || !memchr (smtp->buffer, '\0', len + 1)) | ||
730 | { | 739 | { |
731 | smtp->buflen *= 2; | 740 | smtp->buflen *= 2; |
732 | smtp->buffer = realloc (smtp->buffer, smtp->buflen); | 741 | smtp->buffer = realloc (smtp->buffer, smtp->buflen); |
733 | if (smtp->buffer == NULL) | 742 | if (smtp->buffer == NULL) |
734 | return ENOMEM; | 743 | return ENOMEM; |
744 | done = 0; | ||
735 | } | 745 | } |
746 | else | ||
747 | done = 1; | ||
736 | } | 748 | } |
737 | while (len > (int)smtp->buflen); | 749 | while (!done); |
738 | va_end(ap); | 750 | va_end(ap); |
739 | smtp->ptr = smtp->buffer + len; | 751 | smtp->ptr = smtp->buffer + len; |
740 | return 0; | 752 | return 0; | ... | ... |
... | @@ -231,7 +231,7 @@ stream_readline (stream_t is, char *buf, size_t count, | ... | @@ -231,7 +231,7 @@ stream_readline (stream_t is, char *buf, size_t count, |
231 | 231 | ||
232 | *buf = '\0'; | 232 | *buf = '\0'; |
233 | if (pnread) | 233 | if (pnread) |
234 | *pnread = n; | 234 | *pnread = (n == count) ? n - 1: n; |
235 | 235 | ||
236 | return 0; | 236 | return 0; |
237 | } | 237 | } | ... | ... |
-
Please register or sign in to post a comment