Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions pop/init_journal.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/xattr.h>
#include <unistd.h>
Expand Down Expand Up @@ -37,8 +38,9 @@ static void write_with_retry(int fd, void *data, size_t size)
while(off < size);
}

static void load_emails(int journal_fd, char *path)
static off_t load_emails(int journal_fd, char *path)
{
off_t f_pos = 0;
int mail_dir = openat(AT_FDCWD, path, O_RDONLY | O_DIRECTORY);
if(0 > mail_dir)
err(1, "unable to open mail directory \"%s\"", path);
Expand Down Expand Up @@ -70,10 +72,24 @@ static void load_emails(int journal_fd, char *path)
errx(1, "filename of email %s is too long", ptr->d_name);
memcpy(email.name, ptr->d_name, size + 1);
write_with_retry(journal_fd, &email, sizeof email);
f_pos += sizeof email;
}
if(errno)
err(1, "Unable to read from directory");
closedir(dir);
return f_pos;
}

static int compar_email(const void *e1, const void *e2)
{
return strcmp(((const struct email *)e1)->name, ((const struct email *)e2)->name);
}

static void sort_mail(int journal_fd, size_t journal_size)
{
void *data = mmap(NULL, journal_size, PROT_READ | PROT_WRITE, MAP_SHARED, journal_fd, 0);
qsort(data, sizeof(struct email), journal_size / sizeof(struct email), compar_email);
munmap(data, journal_size);
}

static void replicate_xattrs(int targetfd, char *srcpath)
Expand Down Expand Up @@ -119,12 +135,13 @@ int main(int argc, char **argv)
int new_fd = openat(AT_FDCWD, new_file, O_CREAT | O_EXCL | O_WRONLY, 0600);
if(0 > new_fd)
err(1, "Unable to create file \"%s\"", new_file);
off_t f_pos = 0;
if(email_folder)
{
load_emails(new_fd, email_folder);
f_pos = load_emails(new_fd, email_folder);
sort_mail(new_fd, (size_t)f_pos);
replicate_xattrs(new_fd, journal_file);
}
off_t f_pos = lseek(new_fd, 0, SEEK_CUR);
if(fsetxattr(new_fd, "user.data_end", &f_pos, sizeof f_pos, 0))
err(1, "unable to write journal file size to journal file");
if(fdatasync(new_fd))
Expand Down