summaryrefslogtreecommitdiffabout
path: root/libetpan/src/low-level/maildir/maildir.c
Side-by-side diff
Diffstat (limited to 'libetpan/src/low-level/maildir/maildir.c') (more/less context) (show whitespace changes)
-rw-r--r--libetpan/src/low-level/maildir/maildir.c15
1 files changed, 14 insertions, 1 deletions
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
@@ -17,230 +17,243 @@
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS 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$
*/
#include "maildir.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <errno.h>
#include <fcntl.h>
#ifdef LIBETPAN_SYSTEM_BASENAME
#include <libgen.h>
#endif
/*
We suppose the maildir mailbox remains on one unique filesystem.
*/
struct maildir * maildir_new(const char * path)
{
struct maildir * md;
md = malloc(sizeof(* md));
if (md == NULL)
goto err;
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);
flags = 0;
p = strstr(filename, ":2,");
if (p != NULL) {
uid_len = p - begin_uid;
p += 3;
/* parse flags */
while (* p != '\0') {
switch (* p) {
case 'S':
flags |= MAILDIR_FLAG_SEEN;
break;
case 'R':
flags |= MAILDIR_FLAG_REPLIED;
break;
case 'F':
flags |= MAILDIR_FLAG_FLAGGED;
break;
case 'T':
flags |= MAILDIR_FLAG_TRASHED;
break;
}
p ++;
}
}
if (new_msg)
flags |= MAILDIR_FLAG_NEW;
msg->msg_flags = flags;
msg->msg_uid = malloc(uid_len + 1);
if (msg->msg_uid == NULL)
goto free_filename;
strncpy(msg->msg_uid, begin_uid, uid_len);
msg->msg_uid[uid_len] = '\0';
return msg;
free_filename:
free(msg->msg_filename);
free:
free(msg);
err:
return NULL;
}