summaryrefslogtreecommitdiffabout
path: root/kmicromail/libetpan/maildir
Side-by-side diff
Diffstat (limited to 'kmicromail/libetpan/maildir') (more/less context) (ignore whitespace changes)
-rw-r--r--kmicromail/libetpan/maildir/maildir.c33
-rw-r--r--kmicromail/libetpan/maildir/maildir.h7
2 files changed, 33 insertions, 7 deletions
diff --git a/kmicromail/libetpan/maildir/maildir.c b/kmicromail/libetpan/maildir/maildir.c
index 320ef81..0e038b1 100644
--- a/kmicromail/libetpan/maildir/maildir.c
+++ b/kmicromail/libetpan/maildir/maildir.c
@@ -369,257 +369,276 @@ int maildir_update(struct maildir * md)
maildir_flush(md, 1);
/* messages in new */
r = add_directory(md, path_new, 1);
if (r != MAILDIR_NO_ERROR) {
res = r;
goto free;
}
}
/* did cur/ changed ? */
r = stat(path_cur, &stat_info);
if (r < 0) {
res = MAILDIR_ERROR_DIRECTORY;
goto free;
}
if (md->mdir_mtime_cur != stat_info.st_mtime) {
md->mdir_mtime_cur = stat_info.st_mtime;
maildir_flush(md, 0);
/* messages in cur */
r = add_directory(md, path_cur, 0);
if (r != MAILDIR_NO_ERROR) {
res = r;
goto free;
}
}
return MAILDIR_NO_ERROR;
free:
maildir_flush(md, 0);
maildir_flush(md, 1);
md->mdir_mtime_cur = (time_t) -1;
md->mdir_mtime_new = (time_t) -1;
return res;
}
#ifndef LIBETPAN_SYSTEM_BASENAME
static char * libetpan_basename(char * filename)
{
char * next;
char * p;
p = filename;
next = strchr(p, '/');
while (next != NULL) {
p = next;
next = strchr(p + 1, '/');
}
if (p == filename)
return filename;
else
return p + 1;
}
#else
#define libetpan_basename(a) basename(a)
#endif
-int maildir_message_add(struct maildir * md,
- const char * message, size_t size)
+int maildir_message_add_uid(struct maildir * md,
+ const char * message, size_t size,
+ char * uid, size_t max_uid_len)
{
char path_new[PATH_MAX];
char tmpname[PATH_MAX];
int fd;
int r;
char * mapping;
char * delivery_tmp_name;
char * delivery_tmp_basename;
char delivery_new_name[PATH_MAX];
char * delivery_new_basename;
int res;
struct stat stat_info;
r = maildir_update(md);
if (r != MAILDIR_NO_ERROR) {
res = r;
goto err;
}
/* write to tmp/ with a classic temporary file */
- snprintf(tmpname, sizeof(tmpname), "%s/tmp/etpan-maildir-XXXXXX", md->mdir_path);
+ snprintf(tmpname, sizeof(tmpname), "%s/tmp/etpan-maildir-XXXXXX",
+ md->mdir_path);
fd = mkstemp(tmpname);
if (fd < 0) {
res = MAILDIR_ERROR_FILE;
goto err;
}
r = ftruncate(fd, size);
if (r < 0) {
res = MAILDIR_ERROR_FILE;
goto close;
}
mapping = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (mapping == MAP_FAILED) {
res = MAILDIR_ERROR_FILE;
goto close;
}
memcpy(mapping, message, size);
msync(mapping, size, MS_SYNC);
munmap(mapping, size);
close(fd);
/* write to tmp/ with maildir standard name */
delivery_tmp_name = maildir_get_new_message_filename(md, tmpname);
if (delivery_tmp_name == NULL) {
res = MAILDIR_ERROR_FILE;
goto unlink;
}
/* write to new/ with maildir standard name */
strncpy(tmpname, delivery_tmp_name, sizeof(tmpname));
tmpname[sizeof(tmpname) - 1] = '\0';
delivery_tmp_basename = libetpan_basename(tmpname);
snprintf(delivery_new_name, sizeof(delivery_new_name), "%s/new/%s",
md->mdir_path, delivery_tmp_basename);
r = link(delivery_tmp_name, delivery_new_name);
if (r < 0) {
res = MAILDIR_ERROR_FILE;
goto unlink_tmp;
}
snprintf(path_new, sizeof(path_new), "%s/new", md->mdir_path);
r = stat(path_new, &stat_info);
if (r < 0) {
unlink(delivery_new_name);
res = MAILDIR_ERROR_FILE;
goto unlink_tmp;
}
md->mdir_mtime_new = stat_info.st_mtime;
delivery_new_basename = libetpan_basename(delivery_new_name);
r = add_message(md, delivery_new_basename, 1);
if (r != MAILDIR_NO_ERROR) {
unlink(delivery_new_name);
res = MAILDIR_ERROR_FILE;
goto unlink_tmp;
}
-
+
+ if (uid != NULL)
+ strncpy(uid, delivery_new_basename, max_uid_len);
+
unlink(delivery_tmp_name);
free(delivery_tmp_name);
return MAILDIR_NO_ERROR;
unlink_tmp:
unlink(delivery_tmp_name);
free(delivery_tmp_name);
goto err;
close:
close(fd);
unlink:
unlink(tmpname);
err:
return res;
}
-int maildir_message_add_file(struct maildir * md, int fd)
+int maildir_message_add(struct maildir * md,
+ const char * message, size_t size)
+{
+ return maildir_message_add_uid(md, message, size,
+ NULL, 0);
+}
+
+int maildir_message_add_file_uid(struct maildir * md, int fd,
+ char * uid, size_t max_uid_len)
{
char * message;
struct stat buf;
int r;
if (fstat(fd, &buf) == -1)
return MAILDIR_ERROR_FILE;
message = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (message == MAP_FAILED)
return MAILDIR_ERROR_FILE;
- r = maildir_message_add(md, message, buf.st_size);
+ r = maildir_message_add_uid(md, message, buf.st_size, uid, max_uid_len);
munmap(message, buf.st_size);
-
+
return r;
}
+int maildir_message_add_file(struct maildir * md, int fd)
+{
+ return maildir_message_add_file_uid(md, fd,
+ NULL, 0);
+}
+
char * maildir_message_get(struct maildir * md, const char * uid)
{
chashdatum key;
chashdatum value;
char filename[PATH_MAX];
char * dup_filename;
struct maildir_msg * msg;
char * dir;
int r;
key.data = (void *) uid;
key.len = strlen(uid);
r = chash_get(md->mdir_msg_hash, &key, &value);
if (r < 0)
return NULL;
msg = value.data;
if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0)
dir = "new";
else
dir = "cur";
snprintf(filename, sizeof(filename), "%s/%s/%s",
md->mdir_path, dir, msg->msg_filename);
dup_filename = strdup(filename);
if (dup_filename == NULL)
return NULL;
return dup_filename;
}
int maildir_message_remove(struct maildir * md, const char * uid)
{
chashdatum key;
chashdatum value;
char filename[PATH_MAX];
struct maildir_msg * msg;
char * dir;
int r;
int res;
key.data = (void *) uid;
key.len = strlen(uid);
r = chash_get(md->mdir_msg_hash, &key, &value);
if (r < 0) {
res = MAILDIR_ERROR_NOT_FOUND;
goto err;
}
msg = value.data;
if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0)
dir = "new";
else
dir = "cur";
snprintf(filename, sizeof(filename), "%s/%s/%s",
md->mdir_path, dir, msg->msg_filename);
r = unlink(filename);
if (r < 0) {
res = MAILDIR_ERROR_FILE;
goto err;
}
diff --git a/kmicromail/libetpan/maildir/maildir.h b/kmicromail/libetpan/maildir/maildir.h
index b782484..268dda1 100644
--- a/kmicromail/libetpan/maildir/maildir.h
+++ b/kmicromail/libetpan/maildir/maildir.h
@@ -1,60 +1,67 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001 - 2003 - DINH Viet Hoa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the libEtPan! project nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* $Id$
*/
#ifndef MAILDIR_H
#define MAILDIR_H
#include <libetpan/maildir_types.h>
struct maildir * maildir_new(const char * path);
void maildir_free(struct maildir * md);
int maildir_update(struct maildir * md);
+int maildir_message_add_uid(struct maildir * md,
+ const char * message, size_t size,
+ char * uid, size_t max_uid_len);
+
int maildir_message_add(struct maildir * md,
const char * message, size_t size);
+int maildir_message_add_file_uid(struct maildir * md, int fd,
+ char * uid, size_t max_uid_len);
+
int maildir_message_add_file(struct maildir * md, int fd);
char * maildir_message_get(struct maildir * md, const char * uid);
int maildir_message_remove(struct maildir * md, const char * uid);
int maildir_message_change_flags(struct maildir * md,
const char * uid, int new_flags);
#endif