#include "lib.h"
#include "ioloop.h"
-#include "file-create-locked.h"
#include "mailbox-list-iter.h"
#include "mail-storage-private.h"
#include "mail-namespace.h"
static bool
mailbox_autoexpunge_lock(struct mail_user *user, struct file_lock **lock)
{
- struct file_create_settings lock_set;
- bool created;
- const char *home, *path, *error;
+ const char *error;
int ret;
if (*lock != NULL)
so that multiple processes won't do the same work unnecessarily,
and 2) it helps to avoid duplicate mails being added with
lazy_expunge. */
- if ((ret = mail_user_get_home(user, &home)) < 0) {
- /* home lookup failed - shouldn't really happen */
- return TRUE;
- }
- if (ret == 0) {
- i_warning("autoexpunge: User has no home directory, can't lock");
- return TRUE;
- }
-
- const struct mail_storage_settings *mail_set =
- mail_user_set_get_storage_set(user);
- i_zero(&lock_set);
- lock_set.lock_method = mail_set->parsed_lock_method;
- path = t_strdup_printf("%s/"AUTOEXPUNGE_LOCK_FNAME, home);
- if (file_create_locked(path, &lock_set, lock, &created, &error) == -1) {
- if (errno == EAGAIN) {
- /* another process is autoexpunging, so we don't
- need to. */
- return FALSE;
- }
- i_error("autoexpunge: Couldn't lock %s: %s", path, error);
+ ret = mail_user_lock_file_create(user, AUTOEXPUNGE_LOCK_FNAME,
+ 0, lock, &error);
+ if (ret < 0) {
+ i_error("autoexpunge: Couldn't create %s lock: %s",
+ AUTOEXPUNGE_LOCK_FNAME, error);
/* do autoexpunging anyway */
return TRUE;
+ } else if (ret == 0) {
+ /* another process is autoexpunging, so we don't need to. */
+ return FALSE;
+ } else {
+ return TRUE;
}
- file_lock_set_unlink_on_free(*lock, TRUE);
- file_lock_set_close_on_free(*lock, TRUE);
- return TRUE;
}
static int
#include "net.h"
#include "module-dir.h"
#include "home-expand.h"
+#include "file-create-locked.h"
#include "safe-mkstemp.h"
#include "str.h"
#include "strescape.h"
str_append_c(dest, '.');
}
+int mail_user_lock_file_create(struct mail_user *user, const char *lock_fname,
+ unsigned int lock_secs,
+ struct file_lock **lock_r, const char **error_r)
+{
+ bool created;
+ const char *home, *path, *error;
+ int ret;
+
+ if ((ret = mail_user_get_home(user, &home)) < 0) {
+ /* home lookup failed - shouldn't really happen */
+ *error_r = "Failed to lookup home directory";
+ errno = EINVAL;
+ return -1;
+ }
+ if (ret == 0) {
+ *error_r = "User has no home directory";
+ errno = EINVAL;
+ return -1;
+ }
+
+ const struct mail_storage_settings *mail_set =
+ mail_user_set_get_storage_set(user);
+ struct file_create_settings lock_set = {
+ .lock_timeout_secs = lock_secs,
+ .lock_method = mail_set->parsed_lock_method,
+ };
+ path = t_strdup_printf("%s/%s", home, lock_fname);
+ if (file_create_locked(path, &lock_set, lock_r, &created, &error) == -1) {
+ *error_r = t_strdup_printf("file_create_locked(%s) failed: %s", path, error);
+ return errno == EAGAIN ? 0 : -1;
+ }
+ file_lock_set_unlink_on_free(*lock_r, TRUE);
+ file_lock_set_close_on_free(*lock_r, TRUE);
+ return 1;
+}
+
const char *mail_user_get_anvil_userip_ident(struct mail_user *user)
{
if (user->remote_ip == NULL)
The file prefix doesn't contain any uniqueness. */
void mail_user_set_get_temp_prefix(string_t *dest,
const struct mail_user_settings *set);
+/* Returns 1 on success, 0 if lock_secs is reached, -1 on error */
+int mail_user_lock_file_create(struct mail_user *user, const char *lock_fname,
+ unsigned int lock_secs,
+ struct file_lock **lock_r, const char **error_r);
/* Returns TRUE if plugin is loaded for the user. */
bool mail_user_is_plugin_loaded(struct mail_user *user, struct module *module);