summaryrefslogtreecommitdiffabout
path: root/kmicromail/libetpan/mbox/mailmbox.c
Side-by-side diff
Diffstat (limited to 'kmicromail/libetpan/mbox/mailmbox.c') (more/less context) (ignore whitespace changes)
-rw-r--r--kmicromail/libetpan/mbox/mailmbox.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/kmicromail/libetpan/mbox/mailmbox.c b/kmicromail/libetpan/mbox/mailmbox.c
index 280c313..b3fce02 100644
--- a/kmicromail/libetpan/mbox/mailmbox.c
+++ b/kmicromail/libetpan/mbox/mailmbox.c
@@ -152,96 +152,99 @@ int mailmbox_map(struct mailmbox_folder * folder)
}
folder->mb_mapping = str;
folder->mb_mapping_size = buf.st_size;
return MAILMBOX_NO_ERROR;
err:
return res;
}
/*
unmap the file
*/
void mailmbox_unmap(struct mailmbox_folder * folder)
{
munmap(folder->mb_mapping, folder->mb_mapping_size);
folder->mb_mapping = NULL;
folder->mb_mapping_size = 0;
}
void mailmbox_sync(struct mailmbox_folder * folder)
{
msync(folder->mb_mapping, folder->mb_mapping_size, MS_SYNC);
}
void mailmbox_timestamp(struct mailmbox_folder * folder)
{
int r;
struct stat buf;
r = stat(folder->mb_filename, &buf);
if (r < 0)
folder->mb_mtime = (time_t) -1;
else
folder->mb_mtime = buf.st_mtime;
}
/*
open the file
*/
int mailmbox_open(struct mailmbox_folder * folder)
{
int fd;
int read_only;
+ fd = -1;
+ read_only = TRUE;
+
if (!folder->mb_read_only) {
read_only = FALSE;
fd = open(folder->mb_filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
}
if (folder->mb_read_only || (fd < 0)) {
read_only = TRUE;
fd = open(folder->mb_filename, O_RDONLY);
if (fd < 0)
return MAILMBOX_ERROR_FILE_NOT_FOUND;
}
folder->mb_fd = fd;
folder->mb_read_only = read_only;
return MAILMBOX_NO_ERROR;
}
/*
close the file
*/
void mailmbox_close(struct mailmbox_folder * folder)
{
close(folder->mb_fd);
folder->mb_fd = -1;
}
static int mailmbox_validate_lock(struct mailmbox_folder * folder,
int (* custom_lock)(struct mailmbox_folder *),
int (* custom_unlock)(struct mailmbox_folder *))
{
struct stat buf;
int res;
int r;
r = stat(folder->mb_filename, &buf);
if (r < 0) {
buf.st_mtime = (time_t) -1;
}
if ((buf.st_mtime != folder->mb_mtime) ||
((size_t) buf.st_size != folder->mb_mapping_size)) {
int r;
mailmbox_unmap(folder);
mailmbox_close(folder);
@@ -572,96 +575,98 @@ static char * write_fixed_message(char * str,
left -= count;
}
return str;
}
#define DEFAULT_FROM_LINE "From - Wed Jun 30 21:49:08 1993\n"
int
mailmbox_append_message_list_no_lock(struct mailmbox_folder * folder,
carray * append_tab)
{
size_t extra_size;
int r;
char from_line[MAX_FROM_LINE_SIZE] = DEFAULT_FROM_LINE;
struct tm time_info;
time_t date;
int res;
size_t old_size;
char * str;
unsigned int i;
size_t from_size;
size_t maxuid;
size_t left;
size_t crlf_count;
if (folder->mb_read_only) {
res = MAILMBOX_ERROR_READONLY;
goto err;
}
date = time(NULL);
from_size = strlen(DEFAULT_FROM_LINE);
if (localtime_r(&date, &time_info) != NULL)
from_size = strftime(from_line, MAX_FROM_LINE_SIZE, "From - %c\n", &time_info);
maxuid = /* */ folder->mb_max_uid;
extra_size = 0;
for(i = 0 ; i < carray_count(append_tab) ; i ++) {
struct mailmbox_append_info * info;
info = carray_get(append_tab, i);
extra_size += from_size;
extra_size += get_fixed_message_size(info->ai_message, info->ai_size,
folder->mb_max_uid + i + 1,
folder->mb_no_uid);
extra_size += 2; /* CR LF */
+
+ info->ai_uid = folder->mb_max_uid + i + 1;
}
left = folder->mb_mapping_size;
crlf_count = 0;
while (left >= 1) {
if (folder->mb_mapping[left - 1] == '\n') {
crlf_count ++;
left --;
}
else if (folder->mb_mapping[left - 1] == '\r') {
left --;
}
else
break;
if (crlf_count == 2)
break;
}
old_size = folder->mb_mapping_size;
mailmbox_unmap(folder);
if (old_size != 0) {
if (crlf_count != 2)
extra_size += (2 - crlf_count) * 2;
}
r = ftruncate(folder->mb_fd, extra_size + old_size);
if (r < 0) {
mailmbox_map(folder);
res = MAILMBOX_ERROR_FILE;
goto err;
}
r = mailmbox_map(folder);
if (r < 0) {
ftruncate(folder->mb_fd, old_size);
return MAILMBOX_ERROR_FILE;
}
str = folder->mb_mapping + old_size;
if (old_size != 0) {
for(i = 0 ; i < 2 - crlf_count ; i ++) {
* str = '\r';
str ++;
* str = '\n';
str ++;
@@ -699,137 +704,147 @@ int
mailmbox_append_message_list(struct mailmbox_folder * folder,
carray * append_tab)
{
int r;
int res;
size_t cur_token;
r = mailmbox_validate_write_lock(folder);
if (r != MAILMBOX_NO_ERROR) {
res = r;
goto err;
}
r = mailmbox_expunge_no_lock(folder);
if (r != MAILMBOX_NO_ERROR) {
res = r;
goto unlock;
}
cur_token = folder->mb_mapping_size;
r = mailmbox_append_message_list_no_lock(folder, append_tab);
if (r != MAILMBOX_NO_ERROR) {
res = r;
goto unlock;
}
mailmbox_sync(folder);
r = mailmbox_parse_additionnal(folder, &cur_token);
if (r != MAILMBOX_NO_ERROR) {
res = r;
goto unlock;
}
mailmbox_timestamp(folder);
mailmbox_write_unlock(folder);
return MAILMBOX_NO_ERROR;
unlock:
mailmbox_write_unlock(folder);
err:
return res;
}
int
-mailmbox_append_message(struct mailmbox_folder * folder,
- const char * data, size_t len)
+mailmbox_append_message_uid(struct mailmbox_folder * folder,
+ const char * data, size_t len, unsigned int * puid)
{
carray * tab;
struct mailmbox_append_info * append_info;
int res;
int r;
tab = carray_new(1);
if (tab == NULL) {
res = MAILMBOX_ERROR_MEMORY;
goto err;
}
append_info = mailmbox_append_info_new(data, len);
if (append_info == NULL) {
res = MAILMBOX_ERROR_MEMORY;
goto free_list;
}
r = carray_add(tab, append_info, NULL);
if (r < 0) {
res = MAILMBOX_ERROR_MEMORY;
goto free_append_info;
}
r = mailmbox_append_message_list(folder, tab);
-
+
+ if (puid != NULL)
+ * puid = append_info->ai_uid;
+
mailmbox_append_info_free(append_info);
carray_free(tab);
return r;
free_append_info:
mailmbox_append_info_free(append_info);
free_list:
carray_free(tab);
err:
return res;
}
+int
+mailmbox_append_message(struct mailmbox_folder * folder,
+ const char * data, size_t len)
+{
+ return mailmbox_append_message_uid(folder, data, len, NULL);
+}
+
/* ********************************************************************** */
int mailmbox_fetch_msg_no_lock(struct mailmbox_folder * folder,
uint32_t num, char ** result,
size_t * result_len)
{
struct mailmbox_msg_info * info;
int res;
chashdatum key;
chashdatum data;
int r;
key.data = &num;
key.len = sizeof(num);
r = chash_get(folder->mb_hash, &key, &data);
if (r < 0) {
res = MAILMBOX_ERROR_MSG_NOT_FOUND;
goto err;
}
info = data.data;
if (info->msg_deleted) {
res = MAILMBOX_ERROR_MSG_NOT_FOUND;
goto err;
}
* result = folder->mb_mapping + info->msg_headers;
* result_len = info->msg_size - info->msg_start_len;
return MAILMBOX_NO_ERROR;
err:
return res;
}
int mailmbox_fetch_msg_headers_no_lock(struct mailmbox_folder * folder,
uint32_t num, char ** result,
size_t * result_len)
{
struct mailmbox_msg_info * info;
int res;
chashdatum key;
chashdatum data;
int r;
key.data = &num;