static int cmd_sieve_activate_run(struct doveadm_sieve_cmd_context *_ctx) { struct doveadm_sieve_activate_cmd_context *ctx = (struct doveadm_sieve_activate_cmd_context *)_ctx; struct sieve_storage *storage = _ctx->storage; struct sieve_script *script; enum sieve_error error; int ret = 0; script = sieve_storage_open_script (storage, ctx->scriptname, NULL); if ( script == NULL ) { i_error("Failed to activate Sieve script: %s", sieve_storage_get_last_error(storage, &error)); doveadm_sieve_cmd_failed_error(_ctx, error); return -1; } if ( sieve_script_is_active(script) <= 0 ) { /* Script is first being activated; compile it again without the UPLOAD * flag. */ struct sieve_error_handler *ehandler; enum sieve_compile_flags cpflags = SIEVE_COMPILE_FLAG_NOGLOBAL | SIEVE_COMPILE_FLAG_ACTIVATED; struct sieve_binary *sbin; enum sieve_error error; /* Compile */ ehandler = sieve_master_ehandler_create(ctx->ctx.svinst, NULL, 0); if ( (sbin=sieve_compile_script (script, ehandler, cpflags, &error)) == NULL ) { doveadm_sieve_cmd_failed_error(_ctx, error); ret = -1; } else { sieve_close(&sbin); } sieve_error_handler_unref(&ehandler); } /* Activate only when script is valid (or already active) */ if ( ret == 0 ) { /* Refresh activation no matter what; this can also resolve some erroneous * situations. */ ret = sieve_script_activate(script, (time_t)-1); if ( ret < 0 ) { i_error("Failed to activate Sieve script: %s", sieve_storage_get_last_error(storage, &error)); doveadm_sieve_cmd_failed_error(_ctx, error); ret = -1; } } sieve_script_unref(&script); return ret; }
static int sieve_attribute_set_active(struct mail_storage *storage, struct sieve_storage *svstorage, const struct mail_attribute_value *value) { const char *scriptname; struct sieve_script *script; int ret; if (mailbox_attribute_value_to_string(storage, value, &scriptname) < 0) return -1; if (scriptname == NULL) { /* don't affect non-link active script */ if ((ret=sieve_storage_is_singular(svstorage)) != 0) { if (ret < 0) { mail_storage_set_internal_error(storage); return -1; } return 0; } /* deactivate current script */ if (sieve_storage_deactivate(svstorage, value->last_change) < 0) { mail_storage_set_critical(storage, "Failed to deactivate Sieve: %s", sieve_storage_get_last_error(svstorage, NULL)); return -1; } return 0; } i_assert(scriptname[0] == MAILBOX_ATTRIBUTE_SIEVE_DEFAULT_LINK); scriptname++; /* activate specified script */ script = sieve_storage_open_script(svstorage, scriptname, NULL); ret = script == NULL ? -1 : sieve_script_activate(script, value->last_change); if (ret < 0) { mail_storage_set_critical(storage, "Failed to activate Sieve script '%s': %s", scriptname, sieve_storage_get_last_error(svstorage, NULL)); } if (script != NULL) sieve_script_unref(&script); sieve_storage_set_modified(svstorage, value->last_change); return ret; }
static int sieve_attribute_set_active_script(struct mail_storage *storage, struct sieve_storage *svstorage, const struct mail_attribute_value *value) { struct istream *input; if (value->value != NULL) { input = i_stream_create_from_data(value->value, strlen(value->value)); } else if (value->value_stream != NULL) { input = value->value_stream; i_stream_ref(input); } else { return sieve_attribute_unset_active_script(storage, svstorage, value->last_change); } /* skip over the 'S' type */ i_stream_skip(input, 1); if (sieve_storage_save_as_active (svstorage, input, value->last_change) < 0) { mail_storage_set_critical(storage, "Failed to save active sieve script: %s", sieve_storage_get_last_error(svstorage, NULL)); i_stream_unref(&input); return -1; } sieve_storage_set_modified(svstorage, value->last_change); i_stream_unref(&input); return 0; }
static int sieve_attribute_unset_script(struct mail_storage *storage, struct sieve_storage *svstorage, const char *scriptname) { struct sieve_script *script; const char *errstr; enum sieve_error error; int ret = 0; script = sieve_storage_open_script(svstorage, scriptname, NULL); if (script == NULL) { ret = -1; } else { ret = sieve_script_delete(script, TRUE); sieve_script_unref(&script); } if (ret < 0) { errstr = sieve_storage_get_last_error(svstorage, &error); if (error == SIEVE_ERROR_NOT_FOUND) { /* already deleted, ignore */ return 0; } mail_storage_set_critical(storage, "Failed to delete Sieve script '%s': %s", scriptname, errstr); return -1; } return 0; }
void doveadm_sieve_cmd_failed_storage (struct doveadm_sieve_cmd_context *ctx, struct sieve_storage *storage) { enum sieve_error error; (void)sieve_storage_get_last_error(storage, &error); doveadm_sieve_cmd_failed_error(ctx, error); }
static const char * sieve_attribute_iter_next_script(struct sieve_mailbox_attribute_iter *siter) { struct mail_user *user = siter->iter.box->storage->user; struct sieve_mail_user *suser = SIEVE_USER_CONTEXT(user); struct sieve_storage *svstorage = suser->sieve_storage; const char *scriptname; bool active; int ret; if (siter->sieve_list == NULL) return NULL; /* Iterate through all scripts in sieve_dir */ while ((scriptname = sieve_storage_list_next(siter->sieve_list, &active)) != NULL) { if (active) siter->have_active = TRUE; str_truncate(siter->name, strlen(MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES)); str_append(siter->name, scriptname); return str_c(siter->name); } if (sieve_storage_list_deinit(&siter->sieve_list) < 0) { mail_storage_set_critical(siter->iter.box->storage, "Failed to iterate sieve scripts: %s", sieve_storage_get_last_error(svstorage, NULL)); siter->failed = TRUE; return NULL; } /* Check whether active script is a proper symlink or a regular file */ if ((ret=sieve_storage_is_singular(svstorage)) < 0) { mail_storage_set_critical(siter->iter.box->storage, "Failed to iterate sieve scripts: %s", sieve_storage_get_last_error(svstorage, NULL)); return NULL; } /* Regular file */ if (ret > 0) return MAILBOX_ATTRIBUTE_SIEVE_DEFAULT; /* Symlink or none active */ return siter->have_active ? MAILBOX_ATTRIBUTE_SIEVE_DEFAULT : NULL; }
static int sieve_attribute_retrieve_script(struct mail_storage *storage, struct sieve_storage *svstorage, struct sieve_script *script, bool add_type_prefix, struct mail_attribute_value *value_r, const char **errorstr_r) { static char type = MAILBOX_ATTRIBUTE_SIEVE_DEFAULT_SCRIPT; struct istream *input, *inputs[3]; const struct stat *st; enum sieve_error error; if (script == NULL) *errorstr_r = sieve_storage_get_last_error(svstorage, &error); else if (sieve_script_get_stream(script, &input, &error) < 0) sieve_script_unref(&script); if (script == NULL) { if (error == SIEVE_ERROR_NOT_FOUND) { /* already deleted, but return the last_change */ (void)sieve_storage_get_last_change(svstorage, &value_r->last_change); return 0; } *errorstr_r = sieve_storage_get_last_error(svstorage, &error); return -1; } if (i_stream_stat(input, FALSE, &st) < 0) { mail_storage_set_critical(storage, "stat(%s) failed: %m", i_stream_get_name(input)); } else { value_r->last_change = st->st_mtime; } if (!add_type_prefix) { i_stream_ref(input); value_r->value_stream = input; } else { inputs[0] = i_stream_create_from_data(&type, 1); inputs[1] = input; inputs[2] = NULL; value_r->value_stream = i_stream_create_concat(inputs); i_stream_unref(&inputs[0]); } sieve_script_unref(&script); return 1; }
static int cmd_sieve_deactivate_run (struct doveadm_sieve_cmd_context *_ctx) { struct sieve_storage *storage = _ctx->storage; enum sieve_error error; if (sieve_storage_deactivate(storage, (time_t)-1) < 0) { i_error("Failed to deactivate Sieve script: %s", sieve_storage_get_last_error(storage, &error)); doveadm_sieve_cmd_failed_error(_ctx, error); return -1; } return 0; }
static int cmd_sieve_delete_run(struct doveadm_sieve_cmd_context *_ctx) { struct doveadm_sieve_delete_cmd_context *ctx = (struct doveadm_sieve_delete_cmd_context *)_ctx; struct sieve_storage *storage = _ctx->storage; const ARRAY_TYPE(const_string) *scriptnames = &ctx->scriptnames; const char *const *namep; struct sieve_script *script; enum sieve_error error; int ret = 0; array_foreach(scriptnames, namep) { const char *scriptname = *namep; int sret = 0; script = sieve_storage_open_script (storage, scriptname, NULL); if (script == NULL) { sret = -1; } else { if (sieve_script_delete(script, ctx->ignore_active) < 0) { (void)sieve_storage_get_last_error(storage, &error); sret = -1; } sieve_script_unref(&script); } if (sret < 0) { i_error("Failed to delete Sieve script: %s", sieve_storage_get_last_error(storage, &error)); doveadm_sieve_cmd_failed_error(_ctx, error); ret = -1; } } return ret; }
static int sieve_attribute_unset_active_script(struct mail_storage *storage, struct sieve_storage *svstorage, time_t last_change) { int ret; if ((ret=sieve_storage_is_singular(svstorage)) != 0) { if (ret < 0) mail_storage_set_internal_error(storage); return ret; } if (sieve_storage_deactivate(svstorage, last_change) < 0) { mail_storage_set_critical(storage, "Failed to deactivate sieve: %s", sieve_storage_get_last_error(svstorage, NULL)); return -1; } return 0; }
static int cmd_sieve_get_run(struct doveadm_sieve_cmd_context *_ctx) { struct doveadm_sieve_get_cmd_context *ctx = (struct doveadm_sieve_get_cmd_context *)_ctx; struct sieve_script *script; struct istream *input; enum sieve_error error; script = sieve_storage_open_script (_ctx->storage, ctx->scriptname, &error); if ( script == NULL || sieve_script_get_stream (script, &input, &error) < 0 ) { i_error("Failed to open Sieve script: %s", sieve_storage_get_last_error(_ctx->storage, &error)); doveadm_sieve_cmd_failed_error(_ctx, error); if (script != NULL) sieve_script_unref(&script); return -1; } return doveadm_print_istream(input); }
static int sieve_attribute_iter_script_init(struct sieve_mailbox_attribute_iter *siter) { struct mail_user *user = siter->iter.box->storage->user; struct sieve_storage *svstorage; int ret; if (user->mail_debug) i_debug("doveadm-sieve: Iterating Sieve mailbox attributes"); if ((ret = mail_sieve_user_init(user, &svstorage)) <= 0) return ret; siter->sieve_list = sieve_storage_list_init(svstorage); if (siter->sieve_list == NULL) { mail_storage_set_critical(siter->iter.box->storage, "Failed to iterate sieve scripts: %s", sieve_storage_get_last_error(svstorage, NULL)); return -1; } siter->name = str_new(default_pool, 128); str_append(siter->name, MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES); return 0; }
static int sieve_attribute_set_sieve(struct mail_storage *storage, const char *key, const struct mail_attribute_value *value) { struct sieve_storage *svstorage; struct sieve_storage_save_context *save_ctx; struct istream *input; const char *scriptname; int ret; if ((ret = mail_sieve_user_init(storage->user, &svstorage)) <= 0) { if (ret == 0) { mail_storage_set_error(storage, MAIL_ERROR_NOTFOUND, "Sieve not enabled for user"); } return -1; } if (strcmp(key, MAILBOX_ATTRIBUTE_SIEVE_DEFAULT) == 0) return sieve_attribute_set_default(storage, svstorage, value); if (strncmp(key, MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES, strlen(MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES)) != 0) { mail_storage_set_error(storage, MAIL_ERROR_NOTFOUND, "Nonexistent sieve attribute"); return -1; } scriptname = key + strlen(MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES); if (value->value != NULL) { input = i_stream_create_from_data(value->value, strlen(value->value)); save_ctx = sieve_storage_save_init(svstorage, scriptname, input); i_stream_unref(&input); } else if (value->value_stream != NULL) { input = value->value_stream; save_ctx = sieve_storage_save_init(svstorage, scriptname, input); } else { return sieve_attribute_unset_script(storage, svstorage, scriptname); } if (save_ctx == NULL) { /* save initialization failed */ mail_storage_set_critical(storage, "Failed to save sieve script '%s': %s", scriptname, sieve_storage_get_last_error(svstorage, NULL)); return -1; } sieve_storage_save_set_mtime(save_ctx, value->last_change); ret = 0; while (i_stream_read(input) > 0) { if (sieve_storage_save_continue(save_ctx) < 0) { mail_storage_set_critical(storage, "Failed to save sieve script '%s': %s", scriptname, sieve_storage_get_last_error(svstorage, NULL)); ret = -1; break; } } i_assert(input->eof || ret < 0); if (input->stream_errno != 0) { errno = input->stream_errno; mail_storage_set_critical(storage, "Saving sieve script: read(%s) failed: %m", i_stream_get_name(input)); ret = -1; } if (ret == 0 && sieve_storage_save_finish(save_ctx) < 0) { mail_storage_set_critical(storage, "Failed to save sieve script '%s': %s", scriptname, sieve_storage_get_last_error(svstorage, NULL)); ret = -1; } if (ret < 0) sieve_storage_save_cancel(&save_ctx); else if (sieve_storage_save_commit(&save_ctx) < 0) { mail_storage_set_critical(storage, "Failed to save sieve script '%s': %s", scriptname, sieve_storage_get_last_error(svstorage, NULL)); ret = -1; } return ret; }