mbox-save.c revision 468bb8fbe53f28a18a47b8dc6761171d5d8ce706
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen/* Copyright (C) 2002 Timo Sirainen */
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen#include "lib.h"
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen#include "hostpid.h"
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen#include "iobuffer.h"
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen#include "mbox-index.h"
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen#include "mbox-lock.h"
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen#include "mbox-storage.h"
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen#include <stdlib.h>
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen#include <unistd.h>
e074ffeaee1ce283bd42f167c6810e3d013f8218Timo Sirainen#include <fcntl.h>
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen#include <netdb.h>
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenstatic char my_hostdomain[256] = "";
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenstatic int write_from_line(MailStorage *storage, int fd, time_t internal_date)
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen{
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen const char *sender, *line, *name;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen size_t len;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen if (*my_hostdomain == '\0') {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen struct hostent *hent;
24c4835905c0a7ba5a7caa1666af5daef6233303Timo Sirainen
24c4835905c0a7ba5a7caa1666af5daef6233303Timo Sirainen hostpid_init();
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen hent = gethostbyname(my_hostname);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen name = hent != NULL ? hent->h_name : NULL;
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen if (name == NULL) {
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen /* failed, use just the hostname */
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen name = my_hostname;
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen }
405aa3bff8ca00739ebeaab59afb593bcfc8edccTimo Sirainen
405aa3bff8ca00739ebeaab59afb593bcfc8edccTimo Sirainen strncpy(my_hostdomain, name, 255);
405aa3bff8ca00739ebeaab59afb593bcfc8edccTimo Sirainen my_hostdomain[255] = '\0';
405aa3bff8ca00739ebeaab59afb593bcfc8edccTimo Sirainen }
01ff322068d8cb54d37b478efc1348087b1f9f78Timo Sirainen
01ff322068d8cb54d37b478efc1348087b1f9f78Timo Sirainen sender = t_strconcat(storage->user, "@", my_hostdomain, NULL);
01ff322068d8cb54d37b478efc1348087b1f9f78Timo Sirainen
01ff322068d8cb54d37b478efc1348087b1f9f78Timo Sirainen line = mbox_from_create(sender, internal_date);
01ff322068d8cb54d37b478efc1348087b1f9f78Timo Sirainen len = strlen(line);
01ff322068d8cb54d37b478efc1348087b1f9f78Timo Sirainen
01ff322068d8cb54d37b478efc1348087b1f9f78Timo Sirainen return (size_t)write(fd, line, len) == len;
01ff322068d8cb54d37b478efc1348087b1f9f78Timo Sirainen}
405aa3bff8ca00739ebeaab59afb593bcfc8edccTimo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenint mbox_storage_save(Mailbox *box, MailFlags flags, const char *custom_flags[],
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen time_t internal_date, IOBuffer *data, size_t data_size)
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen{
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen IndexMailbox *ibox = (IndexMailbox *) box;
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen off_t pos;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen int fd, failed;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen if (box->readonly) {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen mail_storage_set_error(box->storage, "Mailbox is read-only");
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen return FALSE;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen }
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen if (!index_mailbox_fix_custom_flags(ibox, &flags, custom_flags))
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen return mail_storage_set_index_error(ibox);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen /* append the data into mbox file */
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen fd = open(ibox->index->mbox_path, O_RDWR | O_CREAT);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen if (fd == -1) {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen mail_storage_set_critical(box->storage, "Can't open mbox file "
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen "%s: %m", ibox->index->mbox_path);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen return FALSE;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen }
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen if (!mbox_lock(ibox->index, ibox->index->mbox_path, fd)) {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen (void)close(fd);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen return mail_storage_set_index_error(ibox);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen }
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen failed = FALSE;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainen pos = lseek(fd, 0, SEEK_END);
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainen if (pos == -1) {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen mail_storage_set_critical(box->storage,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen "lseek() failed for mbox file %s: %m",
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen ibox->index->mbox_path);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen failed = TRUE;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen } else {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen if (!write_from_line(box->storage, fd, internal_date) ||
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen !index_storage_save_into_fd(box->storage, fd,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen ibox->index->mbox_path,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen data, data_size)) {
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen /* failed, truncate file back to original size */
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen (void)ftruncate(fd, pos);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen failed = TRUE;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen }
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen }
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen (void)mbox_unlock(ibox->index, ibox->index->mbox_path, fd);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen (void)close(fd);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen return !failed;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen}
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen