summaryrefslogtreecommitdiffabout
path: root/libetpan
Side-by-side diff
Diffstat (limited to 'libetpan') (more/less context) (show whitespace changes)
-rw-r--r--libetpan/src/data-types/mailstream_helper.c9
-rw-r--r--libetpan/src/driver/implementation/pop3/pop3driver.c6
-rw-r--r--libetpan/src/low-level/imap/mailimap_parser.c20
-rw-r--r--libetpan/src/low-level/maildir/maildir.c15
-rw-r--r--libetpan/src/low-level/mh/mailmh.c3
-rw-r--r--libetpan/src/low-level/pop3/mailpop3.c5
6 files changed, 54 insertions, 4 deletions
diff --git a/libetpan/src/data-types/mailstream_helper.c b/libetpan/src/data-types/mailstream_helper.c
index 2f0b9ae..f0ddf51 100644
--- a/libetpan/src/data-types/mailstream_helper.c
+++ b/libetpan/src/data-types/mailstream_helper.c
@@ -53,100 +53,107 @@ static void remove_trailing_eol(MMAPString * mmapstr)
char * mailstream_read_line(mailstream * stream, MMAPString * line)
{
if (mmap_string_assign(line, "") == NULL)
return NULL;
return mailstream_read_line_append(stream, line);
}
static char * mailstream_read_len_append(mailstream * stream,
MMAPString * line,
size_t i)
{
size_t cur_size;
cur_size = line->len;
if (mmap_string_set_size(line, line->len + i) == NULL)
return NULL;
if (mailstream_read(stream, line->str + cur_size, i) < 0)
return NULL;
return line->str;
}
char * mailstream_read_line_append(mailstream * stream, MMAPString * line)
{
if (stream == NULL)
return NULL;
do {
if (stream->read_buffer_len > 0) {
size_t i;
i = 0;
while (i < stream->read_buffer_len) {
if (stream->read_buffer[i] == '\n')
return mailstream_read_len_append(stream, line, i + 1);
i++;
}
if (mailstream_read_len_append(stream, line,
stream->read_buffer_len) == NULL)
return NULL;
}
else {
ssize_t r;
r = mailstream_feed_read_buffer(stream);
if (r == -1)
return NULL;
- if (r == 0)
+ if (r == 0) {
+ // LR
+ // this avoids a memory access violation later when trying
+ // to remove_trailing_eol from a null string
+ if ( line->len == 0 )
+ return NULL;
+ else
break;
}
}
+ }
while (1);
return line->str;
}
char * mailstream_read_line_remove_eol(mailstream * stream, MMAPString * line)
{
if (!mailstream_read_line(stream, line))
return NULL;
remove_trailing_eol(line);
return line->str;
}
int mailstream_is_end_multiline(const char * line)
{
if (line[0] != '.')
return FALSE;
if (line[1] != 0)
return FALSE;
return TRUE;
}
#if 1
char * mailstream_read_multiline(mailstream * s, size_t size,
MMAPString * stream_buffer,
MMAPString * multiline_buffer,
size_t progr_rate,
progress_function * progr_fun)
{
size_t count;
char * line;
size_t last;
if (mmap_string_assign(multiline_buffer, "") == NULL)
return NULL;
count = 0;
last = 0;
while ((line = mailstream_read_line_remove_eol(s, stream_buffer)) != NULL) {
if (mailstream_is_end_multiline(line))
return multiline_buffer->str;
if (line[0] == '.') {
if (mmap_string_append(multiline_buffer, line + 1) == NULL)
return NULL;
diff --git a/libetpan/src/driver/implementation/pop3/pop3driver.c b/libetpan/src/driver/implementation/pop3/pop3driver.c
index ea69923..6cc6a9a 100644
--- a/libetpan/src/driver/implementation/pop3/pop3driver.c
+++ b/libetpan/src/driver/implementation/pop3/pop3driver.c
@@ -204,119 +204,125 @@ static int pop3driver_starttls(mailsession * session)
switch (r) {
case MAILPOP3_NO_ERROR:
break;
default:
return pop3driver_pop3_error_to_mail_error(r);
}
low = mailstream_get_low(pop3->pop3_stream);
fd = mailstream_low_get_fd(low);
if (fd == -1)
return MAIL_ERROR_STREAM;
new_low = mailstream_low_ssl_open(fd);
if (new_low == NULL)
return MAIL_ERROR_STREAM;
mailstream_low_free(low);
mailstream_set_low(pop3->pop3_stream, new_low);
return MAIL_NO_ERROR;
}
static int pop3driver_parameters(mailsession * session,
int id, void * value)
{
struct pop3_session_state_data * data;
data = get_data(session);
switch (id) {
case POP3DRIVER_SET_AUTH_TYPE:
{
int * param;
param = value;
data->pop3_auth_type = * param;
return MAIL_NO_ERROR;
}
}
return MAIL_ERROR_INVAL;
}
static int pop3driver_login(mailsession * session,
char * userid, char * password)
{
int r;
+ //LR
+ int ret;
carray * msg_tab;
struct pop3_session_state_data * data;
data = get_data(session);
switch (data->pop3_auth_type) {
case POP3DRIVER_AUTH_TYPE_TRY_APOP:
r = mailpop3_login_apop(get_pop3_session(session), userid, password);
if (r != MAILPOP3_NO_ERROR)
r = mailpop3_login(get_pop3_session(session), userid, password);
break;
case POP3DRIVER_AUTH_TYPE_APOP:
r = mailpop3_login_apop(get_pop3_session(session), userid, password);
break;
default:
case POP3DRIVER_AUTH_TYPE_PLAIN:
r = mailpop3_login(get_pop3_session(session), userid, password);
break;
}
+ // LR 2 lines
+ ret = pop3driver_pop3_error_to_mail_error(r);
+ if ( ret == MAIL_NO_ERROR )
mailpop3_list(get_pop3_session(session), &msg_tab);
+ // LR
return pop3driver_pop3_error_to_mail_error(r);
}
static int pop3driver_logout(mailsession * session)
{
int r;
r = mailpop3_quit(get_pop3_session(session));
return pop3driver_pop3_error_to_mail_error(r);
}
static int pop3driver_noop(mailsession * session)
{
int r;
r = mailpop3_noop(get_pop3_session(session));
return pop3driver_pop3_error_to_mail_error(r);
}
static int pop3driver_status_folder(mailsession * session, char * mb,
uint32_t * result_messages,
uint32_t * result_recent,
uint32_t * result_unseen)
{
uint32_t count;
int r;
r = pop3driver_messages_number(session, mb, &count);
if (r != MAIL_NO_ERROR)
return r;
* result_messages = count;
* result_recent = count;
* result_unseen = count;
return MAIL_NO_ERROR;
}
static int pop3driver_messages_number(mailsession * session, char * mb,
uint32_t * result)
{
carray * msg_tab;
mailpop3_list(get_pop3_session(session), &msg_tab);
diff --git a/libetpan/src/low-level/imap/mailimap_parser.c b/libetpan/src/low-level/imap/mailimap_parser.c
index ab4db67..071891c 100644
--- a/libetpan/src/low-level/imap/mailimap_parser.c
+++ b/libetpan/src/low-level/imap/mailimap_parser.c
@@ -2354,99 +2354,117 @@ mailimap_body_fld_known_enc_parse(mailstream * fd, MMAPString * buffer,
if (type == -1) {
res = MAILIMAP_ERROR_PARSE;
goto err;
}
r = mailimap_dquote_parse(fd, buffer, &cur_token);
if (r != MAILIMAP_NO_ERROR) {
res = r;
goto err;
}
* result = type;
* index = cur_token;
return MAILIMAP_NO_ERROR;
err:
return res;
}
static int
mailimap_body_fld_enc_parse(mailstream * fd, MMAPString * buffer,
size_t * index,
struct mailimap_body_fld_enc ** result,
size_t progr_rate,
progress_function * progr_fun)
{
size_t cur_token;
int type;
char * value;
struct mailimap_body_fld_enc * body_fld_enc;
int r;
int res;
cur_token = * index;
r = mailimap_body_fld_known_enc_parse(fd, buffer, &cur_token,
&type, progr_rate, progr_fun);
if (r == MAILIMAP_NO_ERROR) {
value = NULL;
}
else if (r == MAILIMAP_ERROR_PARSE) {
type = MAILIMAP_BODY_FLD_ENC_OTHER;
r = mailimap_string_parse(fd, buffer, &cur_token, &value, NULL,
progr_rate, progr_fun);
if (r != MAILIMAP_NO_ERROR) {
- res = r;
+ // LR start
+ // accept NIL and set type to utf8
+ int ret = r;
+ r = mailimap_char_parse(fd, buffer, &cur_token, 'N');
+ if (r == MAILIMAP_NO_ERROR) {
+ r = mailimap_char_parse(fd, buffer, &cur_token, 'I');
+ if (r == MAILIMAP_NO_ERROR) {
+ r = mailimap_char_parse(fd, buffer, &cur_token, 'L');
+ if (r == MAILIMAP_NO_ERROR) {
+ type = 4;
+ ret = MAILIMAP_NO_ERROR;
+ value = NULL;
+ }
+ }
+ }
+ if ( ret != MAILIMAP_NO_ERROR ) {
+ res = ret;
goto err;
}
+ // LR end
+ }
}
else {
res = r;
goto err;
}
body_fld_enc = mailimap_body_fld_enc_new(type, value);
if (body_fld_enc == NULL) {
res = MAILIMAP_ERROR_MEMORY;
goto value_free;
}
* result = body_fld_enc;
* index = cur_token;
return MAILIMAP_NO_ERROR;
value_free:
if (value)
mailimap_string_free(value);
err:
return res;
}
/*
body-fld-id = nstring
*/
static int mailimap_body_fld_id_parse(mailstream * fd, MMAPString * buffer,
size_t * index, char ** result,
size_t progr_rate,
progress_function * progr_fun)
{
return mailimap_nstring_parse(fd, buffer, index, result, NULL,
progr_rate, progr_fun);
}
/*
body-fld-lang = nstring / "(" string *(SP string) ")"
*/
/*
"(" string *(SP string) ")"
*/
static int
mailimap_body_fld_lang_list_parse(mailstream * fd, MMAPString * buffer,
diff --git a/libetpan/src/low-level/maildir/maildir.c b/libetpan/src/low-level/maildir/maildir.c
index 98b9f87..e81625d 100644
--- a/libetpan/src/low-level/maildir/maildir.c
+++ b/libetpan/src/low-level/maildir/maildir.c
@@ -65,134 +65,147 @@ struct maildir * maildir_new(const char * path)
md->mdir_counter = 0;
md->mdir_mtime_new = (time_t) -1;
md->mdir_mtime_cur = (time_t) -1;
md->mdir_pid = getpid();
gethostname(md->mdir_hostname, sizeof(md->mdir_hostname));
strncpy(md->mdir_path, path, sizeof(md->mdir_path));
md->mdir_path[PATH_MAX - 1] = '\0';
md->mdir_msg_list = carray_new(128);
if (md->mdir_msg_list == NULL)
goto free;
md->mdir_msg_hash = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYNONE);
if (md->mdir_msg_hash == NULL)
goto free_msg_list;
return md;
free_msg_list:
carray_free(md->mdir_msg_list);
free:
free(md);
err:
return NULL;
}
static void maildir_flush(struct maildir * md, int msg_new);
void maildir_free(struct maildir * md)
{
maildir_flush(md, 0);
maildir_flush(md, 1);
chash_free(md->mdir_msg_hash);
carray_free(md->mdir_msg_list);
free(md);
}
#define MAX_TRY_ALLOC 32
static char * maildir_get_new_message_filename(struct maildir * md,
char * tmpfile)
{
char filename[PATH_MAX];
char basename[PATH_MAX];
int k;
time_t now;
+ //LR
+ struct stat f_stat;
int got_file;
int r;
got_file = 0;
now = time(NULL);
k = 0;
while (k < MAX_TRY_ALLOC) {
snprintf(basename, sizeof(basename), "%lu.%u_%u.%s",
(unsigned long) now, md->mdir_pid, md->mdir_counter, md->mdir_hostname);
snprintf(filename, sizeof(filename), "%s/tmp/%s",
md->mdir_path, basename);
+ // LR changed following lines
+ if ( stat( filename, &f_stat ) == -1 ) {
+ char * dup_filename;
+
+ dup_filename = strdup(filename);
+ if (dup_filename == NULL) {
+ //unlink(filename);
+ return NULL;
+ }
+ rename (tmpfile,dup_filename );
+#if 0
if (link(tmpfile, filename) == 0) {
got_file = 1;
unlink(tmpfile);
}
else if (errno == EXDEV) {
unlink(tmpfile);
return NULL;
}
else if (errno == EPERM) {
r = rename(tmpfile, filename);
if (r < 0) {
unlink(tmpfile);
return NULL;
}
got_file = 1;
}
if (got_file) {
char * dup_filename;
dup_filename = strdup(filename);
if (dup_filename == NULL) {
unlink(filename);
return NULL;
}
-
+#endif
md->mdir_counter ++;
return dup_filename;
}
md->mdir_counter ++;
k ++;
}
return NULL;
}
static void msg_free(struct maildir_msg * msg)
{
free(msg->msg_uid);
free(msg->msg_filename);
free(msg);
}
/*
msg_new()
filename is given without path
*/
static struct maildir_msg * msg_new(char * filename, int new_msg)
{
struct maildir_msg * msg;
char * p;
int flags;
size_t uid_len;
char * begin_uid;
/* name of file : xxx-xxx_xxx-xxx:2,SRFT */
msg = malloc(sizeof(* msg));
if (msg == NULL)
goto err;
msg->msg_filename = strdup(filename);
if (msg->msg_filename == NULL)
goto free;
begin_uid = filename;
uid_len = strlen(begin_uid);
diff --git a/libetpan/src/low-level/mh/mailmh.c b/libetpan/src/low-level/mh/mailmh.c
index 42cab9d..f8c694d 100644
--- a/libetpan/src/low-level/mh/mailmh.c
+++ b/libetpan/src/low-level/mh/mailmh.c
@@ -875,96 +875,99 @@ int mailmh_folder_add_message_file(struct mailmh_folder * folder,
{
return mailmh_folder_add_message_file_uid(folder, fd, NULL);
}
int mailmh_folder_remove_message(struct mailmh_folder * folder,
uint32_t index)
{
char * filename;
struct mailmh_msg_info * msg_info;
int res;
int r;
chashdatum key;
chashdatum data;
#if 0
r = mailmh_folder_update(folder);
if (r != MAILMH_NO_ERROR) {
res = r;
goto err;
}
#endif
r = mailmh_folder_get_message_filename(folder, index, &filename);
if (filename == NULL) {
res = r;
goto err;
}
if (unlink(filename) == -1) {
res = MAILMH_ERROR_FILE;
goto free;
}
key.data = &index;
key.len = sizeof(index);
r = chash_get(folder->fl_msgs_hash, &key, &data);
#if 0
msg_info = cinthash_find(folder->fl_msgs_hash, index);
#endif
if (r == 0) {
msg_info = data.data;
carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index);
#if 0
cinthash_remove(folder->fl_msgs_hash, index);
#endif
chash_delete(folder->fl_msgs_hash, &key, NULL);
}
+ // LR memory leak fixed
+ mailmh_msg_info_free( msg_info );
+ free(filename);
return MAILMH_NO_ERROR;
free:
free(filename);
err:
return res;
}
int mailmh_folder_move_message(struct mailmh_folder * dest_folder,
struct mailmh_folder * src_folder,
uint32_t index)
{
int fd;
char * filename;
int r;
#if 0
r = mailmh_folder_update(dest_folder);
if (r != MAILMH_NO_ERROR)
return r;
r = mailmh_folder_update(src_folder);
if (r != MAILMH_NO_ERROR)
return r;
#endif
/* move on the same filesystem */
r = mailmh_folder_get_message_filename(src_folder, index, &filename);
if (r != MAILMH_NO_ERROR)
return r;
r = mailmh_folder_alloc_msg(dest_folder, filename, &index);
free(filename);
if (r == MAILMH_NO_ERROR)
return MAILMH_NO_ERROR;
/* move on the different filesystems */
r = mailmh_folder_get_message_fd(src_folder, index, O_RDONLY, &fd);
if (r != MAILMH_NO_ERROR)
return r;
r = mailmh_folder_add_message_file(dest_folder, fd);
if (r != MAILMH_NO_ERROR) {
close(fd);
return r;
}
diff --git a/libetpan/src/low-level/pop3/mailpop3.c b/libetpan/src/low-level/pop3/mailpop3.c
index 6f77a3a..bca62d5 100644
--- a/libetpan/src/low-level/pop3/mailpop3.c
+++ b/libetpan/src/low-level/pop3/mailpop3.c
@@ -463,98 +463,101 @@ int mailpop3_apop(mailpop3 * f,
int mailpop3_user(mailpop3 * f, const char * user)
{
char command[POP3_STRING_SIZE];
int r;
char * response;
if (f->pop3_state != POP3_STATE_AUTHORIZATION)
return MAILPOP3_ERROR_BAD_STATE;
/* send user command */
snprintf(command, POP3_STRING_SIZE, "USER %s\r\n", user);
r = send_command(f, command);
if (r == -1)
return MAILPOP3_ERROR_STREAM;
response = read_line(f);
if (response == NULL)
return MAILPOP3_ERROR_STREAM;
r = parse_response(f, response);
if (r != RESPONSE_OK)
return MAILPOP3_ERROR_BAD_USER;
return MAILPOP3_NO_ERROR;
}
int mailpop3_pass(mailpop3 * f, const char * password)
{
char command[POP3_STRING_SIZE];
int r;
char * response;
if (f->pop3_state != POP3_STATE_AUTHORIZATION)
return MAILPOP3_ERROR_BAD_STATE;
/* send password command */
snprintf(command, POP3_STRING_SIZE, "PASS %s\r\n", password);
r = send_command(f, command);
if (r == -1)
return MAILPOP3_ERROR_STREAM;
response = read_line(f);
if (response == NULL)
return MAILPOP3_ERROR_STREAM;
r = parse_response(f, response);
- if (r != RESPONSE_OK)
+ if (r != RESPONSE_OK) {
+ // LR
+ fprintf(stderr,"POP3 login error. Response from server:\n%s\n",response );
return MAILPOP3_ERROR_BAD_PASSWORD;
+ }
f->pop3_state = POP3_STATE_TRANSACTION;
return MAILPOP3_NO_ERROR;
}
static int read_list(mailpop3 * f, carray ** result);
static int read_uidl(mailpop3 * f, carray * msg_tab);
static int mailpop3_do_uidl(mailpop3 * f, carray * msg_tab)
{
char command[POP3_STRING_SIZE];
int r;
char * response;
if (f->pop3_state != POP3_STATE_TRANSACTION)
return MAILPOP3_ERROR_BAD_STATE;
/* send list command */
snprintf(command, POP3_STRING_SIZE, "UIDL\r\n");
r = send_command(f, command);
if (r == -1)
return MAILPOP3_ERROR_STREAM;
response = read_line(f);
if (response == NULL)
return MAILPOP3_ERROR_STREAM;
r = parse_response(f, response);
if (r != RESPONSE_OK)
return MAILPOP3_ERROR_CANT_LIST;
r = read_uidl(f, msg_tab);
if (r != MAILPOP3_NO_ERROR)
return r;
return MAILPOP3_NO_ERROR;
}
static int mailpop3_do_list(mailpop3 * f)