569 |
return p; |
return p; |
570 |
} |
} |
571 |
|
|
572 |
|
struct msg_envelope { |
573 |
|
char *from; |
574 |
|
char *date; |
575 |
|
}; |
576 |
|
|
577 |
static int |
static int |
578 |
restore_envelope (stream_t str, char **pptr) |
restore_envelope (stream_t str, struct msg_envelope **pmenv) |
579 |
{ |
{ |
580 |
size_t offset = 0; |
size_t offset = 0; |
581 |
char *from = NULL; |
char *from = NULL; |
631 |
env_date = strdup (date); |
env_date = strdup (date); |
632 |
} |
} |
633 |
|
|
634 |
asprintf (pptr, "From %s %s\n", env_from, env_date); |
*pmenv = xmalloc (sizeof (**pmenv) |
635 |
|
+ strlen (env_from) |
636 |
|
+ strlen (env_date) |
637 |
|
+ 2); |
638 |
|
(*pmenv)->from = (char*) (*pmenv + 1); |
639 |
|
(*pmenv)->date = (char*) ((*pmenv)->from + strlen (env_from) + 1); |
640 |
|
|
641 |
|
strcpy ((*pmenv)->from, env_from); |
642 |
|
strcpy ((*pmenv)->date, env_date); |
643 |
|
|
644 |
free (env_from); |
free (env_from); |
645 |
free (env_date); |
free (env_date); |
646 |
free (from); |
free (from); |
647 |
return 0; |
return 0; |
648 |
} |
} |
649 |
|
|
650 |
mailbox_t |
static int |
651 |
mh_open_msg_file (char *folder, char *file_name) |
_env_msg_date (envelope_t envelope, char *buf, size_t len, size_t *pnwrite) |
652 |
|
{ |
653 |
|
message_t msg = envelope_get_owner (envelope); |
654 |
|
struct msg_envelope *env = message_get_owner (msg); |
655 |
|
|
656 |
|
if (!env || !env->date) |
657 |
|
return EINVAL; |
658 |
|
strncpy (buf, env->date, len); |
659 |
|
buf[len-1] = 0; |
660 |
|
return 0; |
661 |
|
} |
662 |
|
|
663 |
|
static int |
664 |
|
_env_msg_sender (envelope_t envelope, char *buf, size_t len, size_t *pnwrite) |
665 |
|
{ |
666 |
|
message_t msg = envelope_get_owner (envelope); |
667 |
|
struct msg_envelope *env = message_get_owner (msg); |
668 |
|
|
669 |
|
if (!env || !env->from) |
670 |
|
return EINVAL; |
671 |
|
strncpy (buf, env->from, len); |
672 |
|
buf[len-1] = 0; |
673 |
|
return 0; |
674 |
|
} |
675 |
|
|
676 |
|
message_t |
677 |
|
mh_stream_to_message (stream_t instream) |
678 |
|
{ |
679 |
|
struct msg_envelope *mp; |
680 |
|
envelope_t env; |
681 |
|
message_t msg; |
682 |
|
|
683 |
|
restore_envelope (instream, &mp); |
684 |
|
if (message_create (&msg, mp)) |
685 |
|
return NULL; |
686 |
|
|
687 |
|
message_set_stream (msg, instream, mp); |
688 |
|
|
689 |
|
if (envelope_create (&env, msg)) |
690 |
|
return NULL; |
691 |
|
|
692 |
|
envelope_set_date (env, _env_msg_date, msg); |
693 |
|
envelope_set_sender (env, _env_msg_sender, msg); |
694 |
|
message_set_envelope (msg, env, mp); |
695 |
|
|
696 |
|
return msg; |
697 |
|
} |
698 |
|
|
699 |
|
message_t |
700 |
|
mh_file_to_message (char *folder, char *file_name) |
701 |
{ |
{ |
702 |
struct stat st; |
struct stat st; |
703 |
char buffer[512]; |
int rc; |
704 |
size_t len = 0; |
stream_t instream; |
|
mailbox_t tmp; |
|
|
stream_t stream, instream; |
|
|
int rc, headers; |
|
705 |
|
|
706 |
if (folder) |
if (folder) |
707 |
file_name = mh_expand_name (folder, file_name, 0); |
file_name = mh_expand_name (folder, file_name, 0); |
711 |
mh_error (_("can't stat file %s: %s"), file_name, strerror (errno)); |
mh_error (_("can't stat file %s: %s"), file_name, strerror (errno)); |
712 |
return NULL; |
return NULL; |
713 |
} |
} |
714 |
|
|
715 |
if ((rc = file_stream_create (&instream, file_name, MU_STREAM_READ))) |
if ((rc = file_stream_create (&instream, file_name, MU_STREAM_READ))) |
716 |
{ |
{ |
717 |
mh_error (_("can't create input stream (file %s): %s"), |
mh_error (_("can't create input stream (file %s): %s"), |
718 |
file_name, mu_strerror (rc)); |
file_name, mu_strerror (rc)); |
719 |
return NULL; |
return NULL; |
720 |
} |
} |
721 |
|
|
722 |
if ((rc = stream_open (instream))) |
if ((rc = stream_open (instream))) |
723 |
{ |
{ |
724 |
mh_error (_("can't open input stream (file %s): %s"), |
mh_error (_("can't open input stream (file %s): %s"), |
726 |
stream_destroy (&instream, stream_get_owner (instream)); |
stream_destroy (&instream, stream_get_owner (instream)); |
727 |
return NULL; |
return NULL; |
728 |
} |
} |
|
|
|
|
if (memory_stream_create (&stream, 0, MU_STREAM_RDWR) |
|
|
|| stream_open (stream)) |
|
|
{ |
|
|
mh_error (_("can't create temporary stream")); |
|
|
stream_destroy (&instream, stream_get_owner (instream)); |
|
|
return NULL; |
|
|
} |
|
729 |
|
|
730 |
stream_readline (instream, buffer, sizeof buffer, 0, NULL); |
return mh_stream_to_message (instream); |
|
if (strncmp (buffer, "From ", 5)) |
|
|
{ |
|
|
char *envstr; |
|
|
restore_envelope (instream, &envstr); |
|
|
stream_sequential_write (stream, envstr, strlen (envstr)); |
|
|
free (envstr); |
|
|
} |
|
|
|
|
|
headers = 1; |
|
|
while ((rc = stream_sequential_readline (instream, |
|
|
buffer, sizeof buffer, &len)) == 0 |
|
|
&& len > 0) |
|
|
{ |
|
|
buffer[len] = 0; |
|
|
if (headers && _mh_delim (buffer)) |
|
|
{ |
|
|
headers = 0; |
|
|
buffer[0] = '\n'; |
|
|
buffer[1] = 0; |
|
|
len = 1; |
|
|
} |
|
|
rc = stream_sequential_write (stream, buffer, len); |
|
|
if (rc) |
|
|
{ |
|
|
mh_error (_("write error: %s"), mu_strerror (rc)); |
|
|
stream_destroy (&instream, stream_get_owner (instream)); |
|
|
stream_destroy (&stream, stream_get_owner (stream)); |
|
|
return NULL; |
|
|
} |
|
|
} |
|
|
|
|
|
stream_destroy (&instream, stream_get_owner (instream)); |
|
|
if (rc) |
|
|
{ |
|
|
mh_error (_("error reading file %s: %s"), file_name, mu_strerror (rc)); |
|
|
stream_destroy (&stream, stream_get_owner (stream)); |
|
|
return NULL; |
|
|
} |
|
|
|
|
|
if (mailbox_create (&tmp, "/dev/null") |
|
|
|| mailbox_open (tmp, MU_STREAM_READ) != 0) |
|
|
{ |
|
|
mh_error (_("can't create temporary mailbox")); |
|
|
return NULL; |
|
|
} |
|
|
|
|
|
|
|
|
mailbox_set_stream (tmp, stream); |
|
|
if (mailbox_messages_count (tmp, &len) |
|
|
|| len < 1) |
|
|
{ |
|
|
mh_error (_("input file %s is not a valid message file"), file_name); |
|
|
return NULL; |
|
|
} |
|
|
else if (len > 1) |
|
|
{ |
|
|
mh_error (ngettext ("input file %s contains %lu message", |
|
|
"input file %s contains %lu messages", |
|
|
len), |
|
|
(unsigned long) len); |
|
|
return NULL; |
|
|
} |
|
|
return tmp; |
|
731 |
} |
} |
732 |
|
|
733 |
void |
void |