summaryrefslogtreecommitdiffabout
path: root/kmicromail/libetpan/mh
Side-by-side diff
Diffstat (limited to 'kmicromail/libetpan/mh') (more/less context) (ignore whitespace changes)
-rw-r--r--kmicromail/libetpan/mh/mailmh.c28
-rw-r--r--kmicromail/libetpan/mh/mailmh.h7
2 files changed, 29 insertions, 6 deletions
diff --git a/kmicromail/libetpan/mh/mailmh.c b/kmicromail/libetpan/mh/mailmh.c
index d6ff950..119f217 100644
--- a/kmicromail/libetpan/mh/mailmh.c
+++ b/kmicromail/libetpan/mh/mailmh.c
@@ -662,257 +662,273 @@ int mailmh_folder_get_message_filename(struct mailmh_folder * folder,
#endif
len = strlen(folder->fl_filename) + 20;
filename = malloc(len);
if (filename == NULL)
return MAILMH_ERROR_MEMORY;
snprintf(filename, len, "%s%c%lu", folder->fl_filename, MAIL_DIR_SEPARATOR,
(unsigned long) index);
* result = filename;
return MAILMH_NO_ERROR;;
}
int mailmh_folder_get_message_fd(struct mailmh_folder * folder,
uint32_t index, int flags, int * result)
{
char * filename;
int fd;
int r;
#if 0
r = mailmh_folder_update(folder);
if (r != MAILMH_NO_ERROR)
return r;
#endif
r = mailmh_folder_get_message_filename(folder, index, &filename);
if (r != MAILMH_NO_ERROR)
return r;
fd = open(filename, flags);
free(filename);
if (fd == -1)
return MAILMH_ERROR_MSG_NOT_FOUND;
* result = fd;
return MAILMH_NO_ERROR;
}
int mailmh_folder_get_message_size(struct mailmh_folder * folder,
uint32_t index, size_t * result)
{
int r;
char * filename;
struct stat buf;
r = mailmh_folder_get_message_filename(folder, index, &filename);
if (r != MAILMH_NO_ERROR)
return r;
r = stat(filename, &buf);
free(filename);
if (r < 0)
return MAILMH_ERROR_FILE;
* result = buf.st_size;
return MAILMH_NO_ERROR;
}
-int mailmh_folder_add_message(struct mailmh_folder * folder,
- const char * message, size_t size)
+int mailmh_folder_add_message_uid(struct mailmh_folder * folder,
+ const char * message, size_t size,
+ uint32_t * pindex)
{
char * tmpname;
int fd;
size_t namesize;
size_t left;
ssize_t res;
struct mailmh_msg_info * msg_info;
uint32_t index;
int error;
int r;
unsigned int array_index;
struct stat buf;
chashdatum key;
chashdatum data;
#if 0
r = mailmh_folder_update(folder);
if (r != MAILMH_NO_ERROR) {
error = r;
goto err;
}
#endif
namesize = strlen(folder->fl_filename) + 20;
tmpname = malloc(namesize);
snprintf(tmpname, namesize, "%s%ctmpXXXXXX",
folder->fl_filename, MAIL_DIR_SEPARATOR);
fd = mkstemp(tmpname);
if (fd < 0) {
error = MAILMH_ERROR_FILE;
goto free;
}
left = size;
while (left > 0) {
res = write(fd, message, left);
if (res == -1) {
close(fd);
error = MAILMH_ERROR_FILE;
goto free;
}
left -= res;
}
close(fd);
r = stat(tmpname, &buf);
if (r < 0) {
error = MAILMH_ERROR_FILE;
goto free;
}
r = mailmh_folder_alloc_msg(folder, tmpname, &index);
if (r != MAILMH_NO_ERROR) {
unlink(tmpname);
error = MAILMH_ERROR_COULD_NOT_ALLOC_MSG;
goto free;
}
free(tmpname);
msg_info = mailmh_msg_info_new(index, size, buf.st_mtime);
if (msg_info == NULL) {
mailmh_folder_remove_message(folder, index);
error = MAILMH_ERROR_MEMORY;
goto err;
}
r = carray_add(folder->fl_msgs_tab, msg_info, &array_index);
if (r < 0) {
mailmh_folder_remove_message(folder, index);
mailmh_msg_info_free(msg_info);
error = MAILMH_ERROR_MEMORY;
goto err;
}
msg_info->msg_array_index = array_index;
#if 0
r = cinthash_add(folder->fl_msgs_hash, index, msg_info);
#endif
key.data = &index;
key.len = sizeof(index);
data.data = msg_info;
data.len = 0;
+ if (pindex != NULL)
+ * pindex = index;
+
r = chash_set(folder->fl_msgs_hash, &key, &data, NULL);
if (r < 0) {
carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index);
mailmh_msg_info_free(msg_info);
error = MAILMH_ERROR_MEMORY;
goto err;
}
return MAILMH_NO_ERROR;
free:
free(tmpname);
err:
return error;
}
-int mailmh_folder_add_message_file(struct mailmh_folder * folder,
- int fd)
+int mailmh_folder_add_message(struct mailmh_folder * folder,
+ const char * message, size_t size)
+{
+ return mailmh_folder_add_message_uid(folder, message, size, NULL);
+}
+
+int mailmh_folder_add_message_file_uid(struct mailmh_folder * folder,
+ int fd, uint32_t * pindex)
{
char * message;
struct stat buf;
int r;
#if 0
r = mailmh_folder_update(folder);
if (r != MAILMH_NO_ERROR)
return r;
#endif
if (fstat(fd, &buf) == -1)
return MAILMH_ERROR_FILE;
message = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (message == MAP_FAILED)
return MAILMH_ERROR_FILE;
- r = mailmh_folder_add_message(folder, message, buf.st_size);
-
+ r = mailmh_folder_add_message_uid(folder, message, buf.st_size, pindex);
+
munmap(message, buf.st_size);
return r;
}
+int mailmh_folder_add_message_file(struct mailmh_folder * folder,
+ int fd)
+{
+ 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);
}
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);
diff --git a/kmicromail/libetpan/mh/mailmh.h b/kmicromail/libetpan/mh/mailmh.h
index 40432cb..00199b8 100644
--- a/kmicromail/libetpan/mh/mailmh.h
+++ b/kmicromail/libetpan/mh/mailmh.h
@@ -58,86 +58,93 @@ enum {
};
struct mailmh {
struct mailmh_folder * mh_main;
};
struct mailmh_msg_info {
unsigned int msg_array_index;
uint32_t msg_index;
size_t msg_size;
time_t msg_mtime;
};
struct mailmh_folder {
char * fl_filename;
unsigned int fl_array_index;
char * fl_name;
time_t fl_mtime;
struct mailmh_folder * fl_parent;
uint32_t fl_max_index;
carray * fl_msgs_tab;
#if 0
cinthash_t * fl_msgs_hash;
#endif
chash * fl_msgs_hash;
carray * fl_subfolders_tab;
chash * fl_subfolders_hash;
};
struct mailmh * mailmh_new(const char * foldername);
void mailmh_free(struct mailmh * f);
struct mailmh_msg_info *
mailmh_msg_info_new(uint32_t index, size_t size, time_t mtime);
void mailmh_msg_info_free(struct mailmh_msg_info * msg_info);
struct mailmh_folder * mailmh_folder_new(struct mailmh_folder * parent,
const char * name);
void mailmh_folder_free(struct mailmh_folder * folder);
int mailmh_folder_add_subfolder(struct mailmh_folder * parent,
const char * name);
struct mailmh_folder * mailmh_folder_find(struct mailmh_folder * root,
const char * filename);
int mailmh_folder_remove_subfolder(struct mailmh_folder * folder);
int mailmh_folder_rename_subfolder(struct mailmh_folder * src_folder,
struct mailmh_folder * dst_folder,
const char * new_name);
int mailmh_folder_get_message_filename(struct mailmh_folder * folder,
uint32_t index, char ** result);
int mailmh_folder_get_message_fd(struct mailmh_folder * folder,
uint32_t index, int flags, int * result);
int mailmh_folder_get_message_size(struct mailmh_folder * folder,
uint32_t index, size_t * result);
+int mailmh_folder_add_message_uid(struct mailmh_folder * folder,
+ const char * message, size_t size,
+ uint32_t * pindex);
+
int mailmh_folder_add_message(struct mailmh_folder * folder,
const char * message, size_t size);
+int mailmh_folder_add_message_file_uid(struct mailmh_folder * folder,
+ int fd, uint32_t * pindex);
+
int mailmh_folder_add_message_file(struct mailmh_folder * folder,
int fd);
int mailmh_folder_remove_message(struct mailmh_folder * folder,
uint32_t index);
int mailmh_folder_move_message(struct mailmh_folder * dest_folder,
struct mailmh_folder * src_folder,
uint32_t index);
int mailmh_folder_update(struct mailmh_folder * folder);
unsigned int mailmh_folder_get_message_number(struct mailmh_folder * folder);
#ifdef __cplusplus
}
#endif
#endif