# HG changeset patch # User Timo Sirainen # Date 1243305278 14400 # Node ID 36d823adb3025b7d2c92700486a1890209ec73e7 # Parent 82949209612e58964db48d7b4fddc0d81fd72616 deliver: If temp file can't be created because home dir doesn't exist, create it. diff -r 82949209612e -r 36d823adb302 src/deliver/deliver.c --- a/src/deliver/deliver.c Mon May 25 22:18:55 2009 -0400 +++ b/src/deliver/deliver.c Mon May 25 22:34:38 2009 -0400 @@ -20,6 +20,8 @@ #include "str-sanitize.h" #include "strescape.h" #include "safe-mkstemp.h" +#include "mkdir-parents.h" +#include "eacces-error.h" #include "close-keep-errno.h" #include "var-expand.h" #include "rfc822-parser.h" @@ -611,15 +613,50 @@ return ret; } +static int deliver_create_dir(struct mail_user *user, const char *dir) +{ + struct mail_namespace *ns; + mode_t mode; + gid_t gid; + + ns = mail_namespace_find_inbox(user->namespaces); + if (ns == NULL) + ns = user->namespaces; + + mailbox_list_get_dir_permissions(ns->list, NULL, &mode, &gid); + if (mkdir_parents_chown(dir, mode, (uid_t)-1, gid) == 0) { + return 0; + } else if (errno == EACCES) { + i_error("%s", eacces_error_get_creating("mkdir_parents_chown", + dir)); + return -1; + } else { + i_error("mkdir_parents_chown(%s, gid=%s) failed: %m", + dir, dec2str(gid)); + return -1; + } +} + static int seekable_fd_callback(const char **path_r, void *context) { struct mail_user *user = context; + const char *dir, *p; string_t *path; int fd; path = t_str_new(128); str_append(path, mail_user_get_temp_prefix(user)); fd = safe_mkstemp(path, 0600, (uid_t)-1, (gid_t)-1); + if (fd == -1 && errno == ENOENT) { + dir = str_c(path); + p = strrchr(dir, '/'); + if (p != NULL) { + dir = t_strdup_until(dir, p); + if (deliver_create_dir(user, dir) < 0) + return -1; + fd = safe_mkstemp(path, 0600, (uid_t)-1, (gid_t)-1); + } + } if (fd == -1) { i_error("safe_mkstemp(%s) failed: %m", str_c(path)); return -1;