From: Aki Tuomi Date: Thu, 29 Aug 2024 11:05:06 +0000 (+0300) Subject: lib: Drop old var_expand X-Git-Tag: 2.4.0~306 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=741dedd8bf1b23ce34be8d99b9bd5d374a831f5c;p=thirdparty%2Fdovecot%2Fcore.git lib: Drop old var_expand --- diff --git a/src/auth/auth-cache.c b/src/auth/auth-cache.c index 156d4fc5c8..360ad8b3f6 100644 --- a/src/auth/auth-cache.c +++ b/src/auth/auth-cache.c @@ -6,7 +6,7 @@ #include "hash.h" #include "str.h" #include "strescape.h" -#include "var-expand-new.h" +#include "var-expand.h" #include "auth-request.h" #include "auth-cache.h" diff --git a/src/auth/auth-common.h b/src/auth/auth-common.h index a895ecb3cd..f6b6aa9446 100644 --- a/src/auth/auth-common.h +++ b/src/auth/auth-common.h @@ -2,7 +2,6 @@ #define AUTH_COMMON_H #include "lib.h" -#include "var-expand-new.h" #include "auth.h" #include "connection.h" diff --git a/src/auth/auth-request-var-expand.c b/src/auth/auth-request-var-expand.c index f794066144..e101c8d1b2 100644 --- a/src/auth/auth-request-var-expand.c +++ b/src/auth/auth-request-var-expand.c @@ -248,7 +248,7 @@ int auth_request_var_expand_with_table(string_t *dest, const char *str, .event = auth_request->event, }; - return var_expand_new(dest, str, ¶ms, error_r); + return var_expand(dest, str, ¶ms, error_r); } int t_auth_request_var_expand(const char *str, diff --git a/src/auth/auth-request.h b/src/auth/auth-request.h index 32b2195ba7..e02682008f 100644 --- a/src/auth/auth-request.h +++ b/src/auth/auth-request.h @@ -7,7 +7,7 @@ #include "array.h" #include "net.h" -#include "var-expand-new.h" +#include "var-expand.h" #include "mech.h" #include "userdb.h" #include "passdb.h" diff --git a/src/auth/db-ldap.h b/src/auth/db-ldap.h index ca69740ffe..7b2f60f65f 100644 --- a/src/auth/db-ldap.h +++ b/src/auth/db-ldap.h @@ -20,7 +20,7 @@ #define DB_LDAP_IDLE_RECONNECT_SECS 60 #include -#include "var-expand-new.h" +#include "var-expand.h" #include "db-ldap-settings.h" #define DB_LDAP_ATTR_MULTI_PREFIX "+" diff --git a/src/auth/db-oauth2.c b/src/auth/db-oauth2.c index c041db2b31..bca6ace6f1 100644 --- a/src/auth/db-oauth2.c +++ b/src/auth/db-oauth2.c @@ -493,8 +493,8 @@ db_oauth2_validate_username(struct db_oauth2_request *req, .event = req->auth_request->event, }; - if (var_expand_new(username_val, req->db->set->username_validation_format, - ¶ms, &error) < 0) { + if (var_expand(username_val, req->db->set->username_validation_format, + ¶ms, &error) < 0) { *error_r = t_strdup_printf("var_expand(%s) failed: %s", req->db->set->username_validation_format, error); *result_r = PASSDB_RESULT_INTERNAL_FAILURE; diff --git a/src/auth/test-auth-cache.c b/src/auth/test-auth-cache.c index f7bb5a7d1f..1d7c5ec48f 100644 --- a/src/auth/test-auth-cache.c +++ b/src/auth/test-auth-cache.c @@ -62,7 +62,7 @@ int auth_request_var_expand_with_table(string_t *dest, const char *str, VAR_EXPAND_TABLE_END }, }; - return var_expand_new(dest, str, ¶ms, error_r); + return var_expand(dest, str, ¶ms, error_r); } static void test_auth_cache_parse_key(void) diff --git a/src/auth/test-auth-request-var-expand.c b/src/auth/test-auth-request-var-expand.c index c49bb7eee9..851e365e29 100644 --- a/src/auth/test-auth-request-var-expand.c +++ b/src/auth/test-auth-request-var-expand.c @@ -78,7 +78,7 @@ static bool test_empty_request(string_t *str, const char *input) const char *error; str_truncate(str, 0); - test_assert(var_expand_new(str, input, ¶ms, &error) == 0); + test_assert(var_expand(str, input, ¶ms, &error) == 0); return strspn(str_c(str), "\n0") == str_len(str); } @@ -106,7 +106,7 @@ static void test_auth_request_var_expand_keys(void) .escape_context = &test_request, }; - test_assert(var_expand_new(str, test_input_long, ¶ms, &error) == 0); + test_assert(var_expand(str, test_input_long, ¶ms, &error) == 0); test_assert_strcmp(str_c(str), test_output); /* test with empty input that it won't crash */ @@ -132,7 +132,7 @@ static void test_auth_request_var_expand_flags(void) .escape_func = (var_expand_escape_func_t *)test_escape, .escape_context = &test_request }; - test_assert(var_expand_new(str, test_input, ¶ms, &error) == 0); + test_assert(var_expand(str, test_input, ¶ms, &error) == 0); test_assert_strcmp(str_c(str), "40\n\n\n"); test_request.userdb_lookup = TRUE; @@ -141,7 +141,7 @@ static void test_auth_request_var_expand_flags(void) params.table = auth_request_get_var_expand_table(&test_request); str_truncate(str, 0); - test_assert(var_expand_new(str, test_input, ¶ms, &error) == 0); + test_assert(var_expand(str, test_input, ¶ms, &error) == 0); test_assert_strcmp(str_c(str), "41\nsecured\nvalid\n"); test_assert(test_empty_request(str, test_input)); @@ -173,7 +173,7 @@ static void test_auth_request_var_expand_long(void) .escape_context = &test_request, }; - test_assert(var_expand_new(str, test_input, ¶ms, &error) == 0); + test_assert(var_expand(str, test_input, ¶ms, &error) == 0); test_assert_strcmp(str_c(str), test_output); test_assert(test_empty_request(str, test_input)); @@ -204,7 +204,7 @@ static void test_auth_request_var_expand_usernames(void) .escape_context = &test_request, }; str_truncate(str, 0); - test_assert(var_expand_new(str, test_input, ¶ms, &error) == 0); + test_assert(var_expand(str, test_input, ¶ms, &error) == 0); test_assert_idx(strcmp(str_c(str), tests[i].output) == 0, i); } test_request.fields.user = default_test_request.fields.user; diff --git a/src/config/settings-get.pl b/src/config/settings-get.pl index 96482cf277..0946bd621a 100755 --- a/src/config/settings-get.pl +++ b/src/config/settings-get.pl @@ -14,7 +14,7 @@ print '#include "lib.h"'."\n"; print '#include "array.h"'."\n"; print '#include "str.h"'."\n"; print '#include "ipwd.h"'."\n"; -print '#include "var-expand-new.h"'."\n"; +print '#include "var-expand.h"'."\n"; print '#include "file-lock.h"'."\n"; print '#include "fsync-mode.h"'."\n"; print '#include "hash-format.h"'."\n"; diff --git a/src/doveadm/doveadm-auth-server.c b/src/doveadm/doveadm-auth-server.c index 7bca76fbd3..81d012490f 100644 --- a/src/doveadm/doveadm-auth-server.c +++ b/src/doveadm/doveadm-auth-server.c @@ -4,7 +4,7 @@ #include "ioloop.h" #include "array.h" #include "str.h" -#include "var-expand-new.h" +#include "var-expand.h" #include "wildcard-match.h" #include "settings-parser.h" #include "master-service.h" @@ -297,7 +297,7 @@ cmd_user_mail_input(struct mail_storage_service_ctx *storage_service, string_t *str = t_str_new(128); const struct var_expand_params *params = mail_user_var_expand_params(user); - if (var_expand_new(str, expand_field, params, &error) < 0) { + if (var_expand(str, expand_field, params, &error) < 0) { json_ostream_nwritef_string(json_output, "error", "Failed to expand field: %s", error); } else { diff --git a/src/doveadm/doveadm-auth.c b/src/doveadm/doveadm-auth.c index 59a68409e6..fa8c18a258 100644 --- a/src/doveadm/doveadm-auth.c +++ b/src/doveadm/doveadm-auth.c @@ -8,7 +8,7 @@ #include "hex-binary.h" #include "str.h" #include "strescape.h" -#include "var-expand-new.h" +#include "var-expand.h" #include "wildcard-match.h" #include "dsasl-client.h" #include "settings-parser.h" @@ -726,7 +726,7 @@ cmd_user_mail_input(struct mail_storage_service_ctx *storage_service, string_t *str = t_str_new(128); const struct var_expand_params *params = mail_user_var_expand_params(user); - if (var_expand_new(str, expand_field, params, &error) < 0) { + if (var_expand(str, expand_field, params, &error) < 0) { e_error(event, "Failed to expand %s: %s", expand_field, error); } else { printf("%s\n", str_c(str)); diff --git a/src/doveadm/doveadm-dsync.c b/src/doveadm/doveadm-dsync.c index 58413ce9a8..63f374b809 100644 --- a/src/doveadm/doveadm-dsync.c +++ b/src/doveadm/doveadm-dsync.c @@ -15,7 +15,7 @@ #include "strescape.h" #include "str-parse.h" #include "env-util.h" -#include "var-expand-new.h" +#include "var-expand.h" #include "process-title.h" #include "settings.h" #include "imap-util.h" @@ -305,8 +305,8 @@ get_ssh_cmd_args(const char *host, const char *login, const char *mail_user, text in the parameter, skip it. */ str_truncate(str, 0); str_truncate(str2, 0); - if (var_expand_new(str, *args, ¶ms, &error) < 0 || - var_expand_new(str2, *args, &static_params, &error) < 0) { + if (var_expand(str, *args, ¶ms, &error) < 0 || + var_expand(str2, *args, &static_params, &error) < 0) { e_error(event, "Failed to expand dsync_remote_cmd=%s: %s", *args, error); diff --git a/src/doveadm/doveadm-print-formatted.c b/src/doveadm/doveadm-print-formatted.c index 3ef9d3b5a6..adb66106b5 100644 --- a/src/doveadm/doveadm-print-formatted.c +++ b/src/doveadm/doveadm-print-formatted.c @@ -8,7 +8,7 @@ #include "doveadm-print.h" #include "doveadm-print-private.h" #include "client-connection.h" -#include "var-expand-new.h" +#include "var-expand.h" struct doveadm_print_formatted_context { pool_t pool; @@ -65,7 +65,7 @@ static void doveadm_print_formatted_print(const char *value) const struct var_expand_params params = { .table = array_front(&ctx.headers), }; - if (var_expand_new(ctx.buf, ctx.format, ¶ms, &error) < 0) { + if (var_expand(ctx.buf, ctx.format, ¶ms, &error) < 0) { i_error("Failed to expand print format '%s': %s", ctx.format, error); } diff --git a/src/imap-hibernate/imap-client.c b/src/imap-hibernate/imap-client.c index 99771bc985..46261dba3c 100644 --- a/src/imap-hibernate/imap-client.c +++ b/src/imap-hibernate/imap-client.c @@ -16,7 +16,7 @@ #include "str.h" #include "strescape.h" #include "time-util.h" -#include "var-expand-new.h" +#include "var-expand.h" #include "master-service.h" #include "master-service-settings.h" #include "imap-keepalive.h" @@ -663,7 +663,7 @@ imap_client_create(int fd, const struct imap_client_state *state) string_t *str; str = t_str_new(256); - if (var_expand_new(str, state->mail_log_prefix, ¶ms, &error) < 0) { + if (var_expand(str, state->mail_log_prefix, ¶ms, &error) < 0) { e_error(client->event, "Failed to expand mail_log_prefix=%s: %s", state->mail_log_prefix, error); diff --git a/src/imap/imap-client.c b/src/imap/imap-client.c index 3870fa7ca9..81694d6134 100644 --- a/src/imap/imap-client.c +++ b/src/imap/imap-client.c @@ -14,7 +14,6 @@ #include "ostream-multiplex.h" #include "time-util.h" #include "settings.h" -#include "var-expand-new.h" #include "master-service.h" #include "imap-resp-code.h" #include "imap-util.h" @@ -341,7 +340,7 @@ const char *client_stats(struct client *client) event_add_int(client->event, "net_out_bytes", client->output->offset); str = t_str_new(128); - if (var_expand_new(str, client->set->imap_logout_format, + if (var_expand(str, client->set->imap_logout_format, ¶ms, &error) < 0) { e_error(client->event, "Failed to expand imap_logout_format=%s: %s", diff --git a/src/lib-dict-backend/dict-ldap.c b/src/lib-dict-backend/dict-ldap.c index aa1cfe8063..bca4b3295e 100644 --- a/src/lib-dict-backend/dict-ldap.c +++ b/src/lib-dict-backend/dict-ldap.c @@ -9,7 +9,7 @@ #include "str.h" #include "istream.h" #include "ostream.h" -#include "var-expand-new.h" +#include "var-expand.h" #include "connection.h" #include "llist.h" #include "ldap-client.h" @@ -230,7 +230,7 @@ ldap_dict_build_query(const struct dict_op_settings *set, .table = array_front(&exp), }; - if (var_expand_new(query_r, template, ¶ms, &error) < 0) { + if (var_expand(query_r, template, ¶ms, &error) < 0) { *error_r = t_strdup_printf("Failed to expand %s: %s", template, error); return FALSE; } diff --git a/src/lib-lda/lda-settings.c b/src/lib-lda/lda-settings.c index 719de94262..6438e92089 100644 --- a/src/lib-lda/lda-settings.c +++ b/src/lib-lda/lda-settings.c @@ -6,7 +6,7 @@ #include "mail-storage-settings.h" #include "smtp-submit-settings.h" #include "lda-settings.h" -#include "var-expand-new.h" +#include "var-expand.h" static bool lda_settings_check(void *_set, pool_t pool, const char **error_r); diff --git a/src/lib-lda/mail-deliver.c b/src/lib-lda/mail-deliver.c index 1f45c3aba4..7980a64d74 100644 --- a/src/lib-lda/mail-deliver.c +++ b/src/lib-lda/mail-deliver.c @@ -7,7 +7,7 @@ #include "str-sanitize.h" #include "time-util.h" #include "unichar.h" -#include "var-expand-new.h" +#include "var-expand.h" #include "message-address.h" #include "smtp-address.h" #include "lda-settings.h" @@ -197,7 +197,7 @@ void mail_deliver_log(struct mail_deliver_context *ctx, const char *fmt, ...) .table = mail_deliver_ctx_get_log_var_expand_table(ctx, msg), .event = ctx->event, }; - if (var_expand_new(str, ctx->set->deliver_log_format, + if (var_expand(str, ctx->set->deliver_log_format, ¶ms, &error) < 0) { e_error(ctx->event, "Failed to expand deliver_log_format=%s: %s", diff --git a/src/lib-lda/mail-send.c b/src/lib-lda/mail-send.c index b9c59346db..a069c90d0c 100644 --- a/src/lib-lda/mail-send.c +++ b/src/lib-lda/mail-send.c @@ -7,7 +7,7 @@ #include "ostream.h" #include "str.h" #include "str-sanitize.h" -#include "var-expand-new.h" +#include "var-expand.h" #include "message-date.h" #include "message-size.h" #include "message-address.h" @@ -120,8 +120,8 @@ int mail_send_rejection(struct mail_deliver_context *ctx, ctx->dsn ? "delivery-status" : "disposition-notification", boundary); str_append(str, "Subject: "); - if (var_expand_new(str, ctx->set->rejection_subject, - ¶ms, &error) < 0) { + if (var_expand(str, ctx->set->rejection_subject, + ¶ms, &error) < 0) { e_error(ctx->event, "Failed to expand rejection_subject=%s: %s", ctx->set->rejection_subject, error); @@ -138,8 +138,8 @@ int mail_send_rejection(struct mail_deliver_context *ctx, str_append(str, "Content-Disposition: inline\r\n"); str_append(str, "Content-Transfer-Encoding: 8bit\r\n\r\n"); - if (var_expand_new(str, ctx->set->rejection_reason, - ¶ms, &error) < 0) { + if (var_expand(str, ctx->set->rejection_reason, + ¶ms, &error) < 0) { e_error(ctx->event, "Failed to expand rejection_reason=%s: %s", ctx->set->rejection_reason, error); diff --git a/src/lib-master/master-service.c b/src/lib-master/master-service.c index b815861350..6a1555053a 100644 --- a/src/lib-master/master-service.c +++ b/src/lib-master/master-service.c @@ -26,7 +26,6 @@ #include "master-service-ssl.h" #include "master-service-settings.h" #include "iostream-ssl.h" -#include "var-expand-new.h" #include #include @@ -1044,7 +1043,7 @@ static void master_service_import_environment_real(const char *import_environmen key = *envs; else { key = t_strdup_until(*envs, value++); - if (var_expand_new(expanded, value, NULL, &error) < 0) + if (var_expand(expanded, value, NULL, &error) < 0) i_fatal("Cannot expand variable %s", value); if (str_len(expanded) > 0) { value = str_c(expanded); diff --git a/src/lib-settings/settings.c b/src/lib-settings/settings.c index f8c61008a4..db92f213fe 100644 --- a/src/lib-settings/settings.c +++ b/src/lib-settings/settings.c @@ -10,7 +10,7 @@ #include "wildcard-match.h" #include "mmap-util.h" #include "settings.h" -#include "var-expand-new.h" +#include "var-expand.h" enum set_seen_type { /* Setting has not been changed */ @@ -580,7 +580,7 @@ settings_mmap_apply_key(struct settings_apply_ctx *ctx, unsigned int key_idx, /* Make sure only the file path is var-expanded. */ value = file.path; } - if (var_expand_new(ctx->str, value, &ctx->var_params, &error) < 0 && + if (var_expand(ctx->str, value, &ctx->var_params, &error) < 0 && (ctx->flags & SETTINGS_GET_FLAG_FAKE_EXPAND) == 0) { *error_r = t_strdup_printf( "Failed to expand %s setting variables: %s", @@ -646,7 +646,7 @@ settings_mmap_apply_defaults(struct settings_apply_ctx *ctx, if ((ctx->flags & SETTINGS_GET_FLAG_NO_EXPAND) == 0) { const char *error; str_truncate(ctx->str, 0); - if (var_expand_new(ctx->str, value, &ctx->var_params, &error) < 0 && + if (var_expand(ctx->str, value, &ctx->var_params, &error) < 0 && (ctx->flags & SETTINGS_GET_FLAG_FAKE_EXPAND) == 0) { *error_r = t_strdup_printf( "Failed to expand default setting %s=%s variables: %s", @@ -1895,7 +1895,7 @@ settings_instance_override(struct settings_apply_ctx *ctx, or with SETTINGS_OVERRIDE_TYPE_2ND_DEFAULT. */ const char *error; str_truncate(ctx->str, 0); - if (var_expand_new(ctx->str, value, &ctx->var_params, &error) < 0 && + if (var_expand(ctx->str, value, &ctx->var_params, &error) < 0 && (ctx->flags & SETTINGS_GET_FLAG_FAKE_EXPAND) == 0) { *error_r = t_strdup_printf( "Failed to expand default setting %s=%s variables: %s", diff --git a/src/lib-settings/settings.h b/src/lib-settings/settings.h index 5edd2c6898..8d27ed6a1f 100644 --- a/src/lib-settings/settings.h +++ b/src/lib-settings/settings.h @@ -1,14 +1,13 @@ #ifndef SETTINGS_H #define SETTINGS_H +#include "var-expand.h" #include "settings-parser.h" -typedef const char *var_expand_escape_func_t(const char *str, void *context); - struct settings_root; struct settings_mmap; struct settings_instance; -struct var_expand_params_new; +struct var_expand_params; enum settings_override_type { /* Setting is a built-in default. This is used only when the defaults @@ -121,7 +120,7 @@ struct settings_get_params { "settings_var_expand_callback_context" /* Callback function used with SETTINGS_EVENT_VAR_EXPAND_CALLBACK. */ typedef void -settings_var_expand_t(void *context, struct var_expand_params_new *params_r); +settings_var_expand_t(void *context, struct var_expand_params *params_r); /* Get the wanted settings and check that the settings are valid. The settings struct must have pool_t (info->pool_offset1), which the caller diff --git a/src/lib-settings/test-settings-parser.c b/src/lib-settings/test-settings-parser.c index 45cd6b6585..2be78b9727 100644 --- a/src/lib-settings/test-settings-parser.c +++ b/src/lib-settings/test-settings-parser.c @@ -3,7 +3,7 @@ #include "lib.h" #include "array.h" #include "net.h" -#include "var-expand-new.h" +#include "var-expand.h" #include "settings-parser.h" #include "test-common.h" diff --git a/src/lib-sql/driver-cassandra.c b/src/lib-sql/driver-cassandra.c index a6f7577c9e..5469557653 100644 --- a/src/lib-sql/driver-cassandra.c +++ b/src/lib-sql/driver-cassandra.c @@ -13,7 +13,6 @@ #include "time-util.h" #include "safe-memset.h" #include "settings.h" -#include "var-expand-new.h" #include "ssl-settings.h" #include "sql-api-private.h" @@ -1193,7 +1192,7 @@ static void driver_cassandra_metrics_write(struct cassandra_db *db) .event = db->api.event, }; - if (var_expand_new(path, db->set->metrics_path, ¶ms, &error) < 0) { + if (var_expand(path, db->set->metrics_path, ¶ms, &error) < 0) { e_error(db->api.event, "Failed to expand metrics_path=%s: %s", db->set->metrics_path, error); return; diff --git a/src/lib-storage/index/shared/shared-storage.c b/src/lib-storage/index/shared/shared-storage.c index 8b1d7b271d..33eaf245b1 100644 --- a/src/lib-storage/index/shared/shared-storage.c +++ b/src/lib-storage/index/shared/shared-storage.c @@ -5,7 +5,6 @@ #include "str.h" #include "ioloop.h" #include "settings.h" -#include "var-expand-new.h" #include "index-storage.h" #include "mail-storage-service.h" #include "mailbox-list-private.h" diff --git a/src/lib-storage/mail-storage-service.c b/src/lib-storage/mail-storage-service.c index 243968bab9..12020ac3ea 100644 --- a/src/lib-storage/mail-storage-service.c +++ b/src/lib-storage/mail-storage-service.c @@ -14,7 +14,6 @@ #include "sleep.h" #include "dict.h" #include "settings.h" -#include "var-expand-new.h" #include "auth-master.h" #include "master-service-private.h" #include "mail-user.h" diff --git a/src/lib-storage/mail-storage-settings.c b/src/lib-storage/mail-storage-settings.c index 18c9dff2ea..a7c2b7e7e5 100644 --- a/src/lib-storage/mail-storage-settings.c +++ b/src/lib-storage/mail-storage-settings.c @@ -6,7 +6,6 @@ #include "unichar.h" #include "hostpid.h" #include "settings.h" -#include "var-expand-new.h" #include "message-address.h" #include "message-header-parser.h" #include "smtp-address.h" diff --git a/src/lib-storage/mail-storage.c b/src/lib-storage/mail-storage.c index 248492eef3..99bae4536a 100644 --- a/src/lib-storage/mail-storage.c +++ b/src/lib-storage/mail-storage.c @@ -18,7 +18,6 @@ #include "mkdir-parents.h" #include "time-util.h" #include "settings.h" -#include "var-expand-new.h" #include "dsasl-client.h" #include "imap-date.h" #include "mail-index-private.h" diff --git a/src/lib-storage/mail-user-lua.c b/src/lib-storage/mail-user-lua.c index 175ed011ce..dcb9ed8881 100644 --- a/src/lib-storage/mail-user-lua.c +++ b/src/lib-storage/mail-user-lua.c @@ -4,7 +4,7 @@ #include "str.h" #include "istream.h" #include "array.h" -#include "var-expand-new.h" +#include "var-expand.h" #include "dlua-script.h" #include "dlua-script-private.h" #include "mail-storage.h" @@ -133,7 +133,7 @@ static int lua_storage_mail_user_var_expand(lua_State *L) const char *format = luaL_checkstring(L, 2); const struct var_expand_params *params = mail_user_var_expand_params(user); string_t *str = t_str_new(128); - if (var_expand_new(str, format, params, &error) < 0) { + if (var_expand(str, format, params, &error) < 0) { return luaL_error(L, "var_expand(%s) failed: %s", format, error); } diff --git a/src/lib-storage/mail-user.c b/src/lib-storage/mail-user.c index 6f1c6e489a..430573117f 100644 --- a/src/lib-storage/mail-user.c +++ b/src/lib-storage/mail-user.c @@ -14,7 +14,6 @@ #include "strescape.h" #include "strfuncs.h" #include "settings.h" -#include "var-expand-new.h" #include "fs-api.h" #include "auth-master.h" #include "master-service.h" @@ -125,7 +124,7 @@ mail_user_expand_plugins_envs(struct mail_user *user, for (i = 0; i < count; i += 2) { str_truncate(str, 0); - if (var_expand_new(str, envs[i+1], params, &error) < 0) { + if (var_expand(str, envs[i+1], params, &error) < 0) { user->error = p_strdup_printf(user->pool, "Failed to expand plugin setting %s = '%s': %s", envs[i], envs[i+1], error); diff --git a/src/lib-storage/mail-user.h b/src/lib-storage/mail-user.h index 3f804b2a33..0085ed5a27 100644 --- a/src/lib-storage/mail-user.h +++ b/src/lib-storage/mail-user.h @@ -57,7 +57,7 @@ struct mail_user { this stays the same after IMAP client is hibernated and restored. */ time_t session_create_time; - const struct var_expand_params_new *var_expand_params; + const struct var_expand_params *var_expand_params; /* If non-NULL, fail the user initialization with this error. This could be set by plugins that need to fail the initialization. */ const char *error; @@ -146,7 +146,7 @@ struct mail_user *mail_user_find(struct mail_user *user, const char *name); void mail_user_set_vars(struct mail_user *user, const char *service, const struct mail_user_connection_data *conn); /* Return %variable expansion table for the user. */ -const struct var_expand_params_new * +const struct var_expand_params * mail_user_var_expand_params(struct mail_user *user); /* Specify the user's home directory. This should be called also with home=NULL diff --git a/src/lib-var-expand/Makefile.am b/src/lib-var-expand/Makefile.am index 3dbfaeb413..cb78496a72 100644 --- a/src/lib-var-expand/Makefile.am +++ b/src/lib-var-expand/Makefile.am @@ -45,7 +45,7 @@ noinst_HEADERS = \ expansion.h headers = \ - var-expand-new.h \ + var-expand.h \ var-expand-private.h pkginc_libdir=$(pkgincludedir) diff --git a/src/lib-var-expand/test-var-expand.c b/src/lib-var-expand/test-var-expand.c index 671731f65b..0bd9431e24 100644 --- a/src/lib-var-expand/test-var-expand.c +++ b/src/lib-var-expand/test-var-expand.c @@ -26,14 +26,14 @@ static void run_var_expand_tests(const struct var_expand_params *params, const struct var_expand_test tests[], size_t test_count) { - string_t *dest = str_new(default_pool, 128); + string_t *dest= str_new(default_pool, 128); for (size_t i = 0; i < test_count; i++) { const struct var_expand_test *test = &tests[i]; const char *error = NULL; str_truncate(dest, 0); - int ret = var_expand_new(dest, test->in, params, &error); + int ret = var_expand(dest, test->in, params, &error); test_assert_cmp_idx(test->ret, ==, ret, i); if (ret < 0) { @@ -69,7 +69,7 @@ static void run_var_expand_tests(const struct var_expand_params *params, } -static void test_var_expand_new_builtin_filters(void) { +static void test_var_expand_builtin_filters(void) { test_begin("var_expand(buildin filters)"); const struct var_expand_table table[] = { @@ -249,7 +249,7 @@ static void test_var_expand_new_builtin_filters(void) { test_end(); } -static void test_var_expand_new_math(void) { +static void test_var_expand_math(void) { test_begin("var_expand(math)"); const struct var_expand_table table[] = { @@ -284,7 +284,7 @@ static void test_var_expand_new_math(void) { test_end(); } -static void test_var_expand_new_if(void) +static void test_var_expand_if(void) { test_begin("var_expand(if)"); @@ -391,7 +391,7 @@ static int test_custom_provider(const char *key, const char **value_r, void *con return 0; } -static void test_var_expand_new_providers(void) { +static void test_var_expand_providers(void) { test_begin("var_expand(providers)"); int ncpus; const char *error ATTR_UNUSED; @@ -468,11 +468,11 @@ static void test_var_expand_new_providers(void) { if (uname(&utsname_result) == 0) { string_t *dest = t_str_new(32); str_truncate(dest, 0); - test_assert(var_expand_new(dest, "%{system:os}", ¶ms, &error) == 0); + test_assert(var_expand(dest, "%{system:os}", ¶ms, &error) == 0); test_assert_strcmp(utsname_result.sysname, str_c(dest)); str_truncate(dest, 0); - test_assert(var_expand_new(dest, "%{system:os-version}", ¶ms, &error) == 0); + test_assert(var_expand(dest, "%{system:os-version}", ¶ms, &error) == 0); test_assert_strcmp(utsname_result.release, str_c(dest)); } @@ -504,7 +504,7 @@ static void test_var_expand_new_providers(void) { test_end(); } -static void test_var_expand_new_provider_arr(void) +static void test_var_expand_provider_arr(void) { test_begin("var_expand(provider arr)"); const struct var_expand_test tests[] = { @@ -539,7 +539,7 @@ static void test_var_expand_new_provider_arr(void) test_end(); } -static void test_var_expand_new_tables_arr(void) +static void test_var_expand_tables_arr(void) { test_begin("var_expand(tables_arr)"); @@ -565,7 +565,7 @@ static void test_var_expand_new_tables_arr(void) string_t *dest = t_str_new(32); const char *error; - int ret = var_expand_new(dest, "I am %{name} and %{age} years old", + int ret = var_expand(dest, "I am %{name} and %{age} years old", ¶ms, &error); test_assert(ret == 0); @@ -592,7 +592,7 @@ static const char *test_escape(const char *str, void *context) return str_c(dest); } -static void test_var_expand_new_escape(void) +static void test_var_expand_escape(void) { const struct var_expand_table table[] = { { .key = "clean", .value = "hello world", }, @@ -647,7 +647,7 @@ static void test_var_expand_new_escape(void) .escape_context = "'", }; - test_begin("var_expand_new(escape)"); + test_begin("var_expand(escape)"); run_var_expand_tests(¶ms, tests, N_ELEMENTS(tests)); @@ -692,7 +692,7 @@ static int test_value2(const char *key, const char **value_r, void *context, return 0; } -static void test_var_expand_new_value_func(void) +static void test_var_expand_value_func(void) { const struct var_expand_table table[] = { { .key = "first", .value = "hello", }, @@ -713,14 +713,14 @@ static void test_var_expand_new_value_func(void) .context = "test", }; - test_begin("var_expand_new(value func)"); + test_begin("var_expand(value func)"); run_var_expand_tests(¶ms, tests, N_ELEMENTS(tests)); test_end(); } -static void test_var_expand_new_value_func_arr(void) +static void test_var_expand_value_func_arr(void) { const struct var_expand_table table[] = { { .key = "first", .value = "hello", }, @@ -777,10 +777,10 @@ static void test_var_expand_merge_tables(void) test_begin("var_expand_merge_tables"); - merged = var_expand_merge_tables_new(pool_datastack_create(), one, two); + merged = var_expand_merge_tables(pool_datastack_create(), one, two); - test_assert(var_expand_table_size_new(merged) == 4); - for (unsigned int i = 0; i < var_expand_table_size_new(merged); i++) { + test_assert(var_expand_table_size(merged) == 4); + for (unsigned int i = 0; i < var_expand_table_size(merged); i++) { if (i < 2) { test_assert_idx(merged[i].value == one[i].value || strcmp(merged[i].value, one[i].value) == 0, i); test_assert_idx(merged[i].key == one[i].key || strcmp(merged[i].key, one[i].key) == 0, i); @@ -794,7 +794,7 @@ static void test_var_expand_merge_tables(void) test_end(); } -static void test_var_expand_new_variables(void) +static void test_var_expand_variables(void) { test_begin("var_expand(variables)"); @@ -849,7 +849,7 @@ static int test_filter(const struct var_expand_statement *stmt, } -static void test_var_expand_new_parameter_sorted(void) +static void test_var_expand_parameter_sorted(void) { const struct var_expand_test tests[] = { { .in = "%{test_filter}", .out ="done", .ret = 0 }, @@ -874,7 +874,7 @@ static void test_var_expand_new_parameter_sorted(void) test_end(); } -static void test_var_expand_new_perc(void) +static void test_var_expand_perc(void) { test_begin("var_expand(percentage handling)"); @@ -901,7 +901,7 @@ static void test_var_expand_new_perc(void) test_end(); } -static void test_var_expand_new_set_copy(void) +static void test_var_expand_set_copy(void) { test_begin("var_expand(set, copy)"); struct var_expand_table tab[] = { @@ -928,19 +928,19 @@ int main(void) { void (*const tests[])(void) = { test_var_expand_merge_tables, - test_var_expand_new_builtin_filters, - test_var_expand_new_math, - test_var_expand_new_if, - test_var_expand_new_providers, - test_var_expand_new_provider_arr, - test_var_expand_new_tables_arr, - test_var_expand_new_escape, - test_var_expand_new_value_func, - test_var_expand_new_value_func_arr, - test_var_expand_new_variables, - test_var_expand_new_parameter_sorted, - test_var_expand_new_perc, - test_var_expand_new_set_copy, + test_var_expand_builtin_filters, + test_var_expand_math, + test_var_expand_if, + test_var_expand_providers, + test_var_expand_provider_arr, + test_var_expand_tables_arr, + test_var_expand_escape, + test_var_expand_value_func, + test_var_expand_value_func_arr, + test_var_expand_variables, + test_var_expand_parameter_sorted, + test_var_expand_perc, + test_var_expand_set_copy, NULL }; diff --git a/src/lib-var-expand/var-expand-private.h b/src/lib-var-expand/var-expand-private.h index 6897f6de4e..26d30c60bc 100644 --- a/src/lib-var-expand/var-expand-private.h +++ b/src/lib-var-expand/var-expand-private.h @@ -1,7 +1,7 @@ #ifndef VAR_EXPAND_PRIVATE_H #define VAR_EXPAND_PRIVATE_H 1 -#include "var-expand-new.h" +#include "var-expand.h" /* Macro for filters to error our with unsupported key */ #define ERROR_UNSUPPORTED_KEY(key) STMT_START { \ diff --git a/src/lib-var-expand/var-expand.c b/src/lib-var-expand/var-expand.c index a9c1e1bbc8..efe9684c10 100644 --- a/src/lib-var-expand/var-expand.c +++ b/src/lib-var-expand/var-expand.c @@ -243,12 +243,12 @@ static int var_expand_table_key_cmp(const char *key, } struct var_expand_table * -var_expand_merge_tables_new(pool_t pool, const struct var_expand_table *a, +var_expand_merge_tables(pool_t pool, const struct var_expand_table *a, const struct var_expand_table *b) { ARRAY(struct var_expand_table) table; - size_t a_size = var_expand_table_size_new(a); - size_t b_size = var_expand_table_size_new(b); + size_t a_size = var_expand_table_size(a); + size_t b_size = var_expand_table_size(b); p_array_init(&table, pool, a_size + b_size + 1); for (size_t i = 0; i < a_size; i++) { struct var_expand_table *entry = @@ -437,9 +437,9 @@ int var_expand_state_lookup_variable(const struct var_expand_state *state, } } -int var_expand_new(string_t *dest, const char *str, - const struct var_expand_params *params, - const char **error_r) +int var_expand(string_t *dest, const char *str, + const struct var_expand_params *params, + const char **error_r) { struct var_expand_program *program = NULL; if (var_expand_program_create(str, &program, error_r) != 0) diff --git a/src/lib-var-expand/var-expand-new.h b/src/lib-var-expand/var-expand.h similarity index 92% rename from src/lib-var-expand/var-expand-new.h rename to src/lib-var-expand/var-expand.h index eb05bbd293..30eb60936b 100644 --- a/src/lib-var-expand/var-expand-new.h +++ b/src/lib-var-expand/var-expand.h @@ -21,7 +21,7 @@ struct var_expand_program; #define VAR_EXPAND_TABLE_END { .key = NULL } #define VAR_EXPAND_CONTEXTS_END (void*)var_expand_contexts_end -struct var_expand_table_new { +struct var_expand_table { /* Key name, as in %{key} */ const char *key; /* Value to expand into */ @@ -29,7 +29,6 @@ struct var_expand_table_new { /* Or function that provides the value */ value_provider_func_t *func; }; -#define var_expand_table var_expand_table_new struct var_expand_provider { /* key as in %{key:name} */ @@ -40,7 +39,7 @@ struct var_expand_provider { extern const void *const var_expand_contexts_end; -struct var_expand_params_new { +struct var_expand_params { /* Variables to use, must end with VAR_EXPAND_TABLE_END, asserts that tables_arr is non-NULL. */ const struct var_expand_table *table; @@ -68,7 +67,6 @@ struct var_expand_params_new { will be attempted if this is NULL. */ struct event *event; }; -#define var_expand_params var_expand_params_new /* Creates a new expansion program for reusing */ int var_expand_program_create(const char *str, struct var_expand_program **program_r, @@ -87,8 +85,8 @@ void var_expand_program_free(struct var_expand_program **_program); /* Creates a new program, executes it and frees it. Params can be left NULL, in which case empty parameters are used. */ -int var_expand_new(string_t *dest, const char *str, const struct var_expand_params *params, - const char **error_r) ATTR_NULL(3); +int var_expand(string_t *dest, const char *str, const struct var_expand_params *params, + const char **error_r) ATTR_NULL(3); /* Wrapper for var_expand(), places the result into result_r. */ int t_var_expand(const char *str, const struct var_expand_params *params, @@ -97,15 +95,15 @@ int t_var_expand(const char *str, const struct var_expand_params *params, /* Merge two tables together, keys in table a will be overwritten with keys * from table b in collision. */ struct var_expand_table * -var_expand_merge_tables_new(pool_t pool, const struct var_expand_table *a, - const struct var_expand_table *b); +var_expand_merge_tables(pool_t pool, const struct var_expand_table *a, + const struct var_expand_table *b); /* Returns true if provider is a built-in provider */ bool var_expand_provider_is_builtin(const char *prefix); /* Provides size of a table */ static inline size_t ATTR_PURE -var_expand_table_size_new(const struct var_expand_table *table) +var_expand_table_size(const struct var_expand_table *table) { size_t n = 0; while (table != NULL && table[n].key != NULL) diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 85e71aa800..4dbacee207 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -196,8 +196,6 @@ liblib_la_SOURCES = \ uri-util.c \ utc-offset.c \ utc-mktime.c \ - var-expand.c \ - var-expand-if.c \ wildcard-match.c \ write-full.c @@ -357,8 +355,6 @@ headers = \ uri-util.h \ utc-offset.h \ utc-mktime.h \ - var-expand.h \ - var-expand-private.h \ wildcard-match.h \ write-full.h @@ -465,7 +461,6 @@ test_lib_SOURCES = \ test-unichar.c \ test-utc-mktime.c \ test-uri.c \ - test-var-expand.c \ test-wildcard-match.c test_headers = \ diff --git a/src/lib/lib.c b/src/lib/lib.c index 5a8671fed9..4df939b7a1 100644 --- a/src/lib/lib.c +++ b/src/lib/lib.c @@ -9,7 +9,6 @@ #include "ipwd.h" #include "process-title.h" #include "restrict-access.h" -#include "var-expand-private.h" #include "randgen.h" #include @@ -190,7 +189,6 @@ void lib_init(void) lib_open_non_stdio_dev_null(); lib_event_init(); event_filter_init(); - var_expand_extensions_init(); /* Default to clean exit. Otherwise there would be too many accidents with e.g. command line parsing errors that try to return instead @@ -214,7 +212,6 @@ void lib_deinit(void) lib_atexit_run(); ipwd_deinit(); hostpid_deinit(); - var_expand_extensions_deinit(); event_filter_deinit(); data_stack_deinit_event(); lib_event_deinit(); diff --git a/src/lib/test-lib.inc b/src/lib/test-lib.inc index c65cfbc6a5..2fceca2f9b 100644 --- a/src/lib/test-lib.inc +++ b/src/lib/test-lib.inc @@ -109,5 +109,4 @@ TEST(test_time_util) TEST(test_unichar) TEST(test_uri) TEST(test_utc_mktime) -TEST(test_var_expand) TEST(test_wildcard_match) diff --git a/src/lib/test-var-expand.c b/src/lib/test-var-expand.c deleted file mode 100644 index f9b17192d9..0000000000 --- a/src/lib/test-var-expand.c +++ /dev/null @@ -1,639 +0,0 @@ -/* Copyright (c) 2009-2018 Dovecot authors, see the included COPYING file */ - -#include "test-lib.h" -#include "cpu-count.h" -#include "str.h" -#include "env-util.h" -#include "hostpid.h" -#include "var-expand.h" -#include "var-expand-private.h" -#include "dovecot-version.h" - -#include -#ifdef HAVE_SYS_UTSNAME_H -# include -#endif - -struct var_expand_test { - const char *in; - const char *out; - int ret; -}; - -struct var_get_key_range_test { - const char *in; - unsigned int idx, size; -}; - -static void test_var_expand_ranges(void) -{ - static const struct var_expand_test tests[] = { - { "%v", "value1234", 1 }, - { "%3v", "val", 1 }, - { "%3.2v", "ue", 1 }, - { "%3.-2v", "ue12", 1 }, - { "%-3.2v", "23", 1 }, - { "%0.-1v", "value123", 1 }, - { "%-4.-1v", "123", 1 } - }; - static const struct var_expand_table table[] = { - { 'v', "value1234", NULL }, - { '\0', NULL, NULL } - }; - string_t *str = t_str_new(128); - const char *error; - unsigned int i; - - test_begin("var_expand - ranges"); - for (i = 0; i < N_ELEMENTS(tests); i++) { - str_truncate(str, 0); - test_assert(var_expand_with_table(str, tests[i].in, table, &error) == tests[i].ret); - test_assert(strcmp(tests[i].out, str_c(str)) == 0); - } - test_end(); -} - -static void test_var_expand_builtin(void) -{ - static struct var_expand_test tests[] = { - { "%{system:hostname}", NULL, 1 }, - { "%{process:pid}", NULL, 1 }, - { "%{process:uid}", NULL, 1 }, - { "%{process:gid}", NULL, 1 }, - { "a%{env:FOO}b", "abaRb", 1 }, - { "%50Hv", "1f", 1 }, - { "%50Hw", "2e", 1 }, - { "%50Nv", "25", 1 }, - { "%50Nw", "e", 1 }, - - { "%{nonexistent}", "UNSUPPORTED_VARIABLE_nonexistent", 0 }, - { "%1.2M{nonexistent:default}", "UNSUPPORTED_VARIABLE_nonexistent", 0 }, - { "%x", "UNSUPPORTED_VARIABLE_x", 0 }, - { "%5Mm", "UNSUPPORTED_VARIABLE_m", 0 }, - - { "%", "", -1 }, - }; - static const struct var_expand_table table[] = { - { 'v', "value", NULL }, - { 'w', "value2", NULL }, - { '\0', NULL, NULL } - }; - string_t *str = t_str_new(128); - const char *error; - unsigned int i; - - tests[0].out = my_hostname; - tests[1].out = my_pid; - tests[2].out = dec2str(geteuid()); - tests[3].out = dec2str(getegid()); - env_put("FOO", "baR"); - - test_begin("var_expand - builtin"); - for (i = 0; i < N_ELEMENTS(tests); i++) { - str_truncate(str, 0); - test_assert_idx(var_expand_with_table(str, tests[i].in, table, &error) == tests[i].ret, i); - test_assert_strcmp_idx(tests[i].out, str_c(str), i); - } - test_end(); -} - -static void test_var_get_key_range(void) -{ - static const struct var_get_key_range_test tests[] = { - { "", 0, 0 }, - { "{", 1, 0 }, - { "k", 0, 1 }, - { "{key}", 1, 3 }, - { "5.5Rk", 4, 1 }, - { "5.5R{key}", 5, 3 }, - { "{key", 1, 3 }, - { "{if;%{if;%{value};eq;value;t;f};eq;t;t;f}", 1, 39 }, - }; - unsigned int i, idx, size; - - test_begin("var_get_key_range"); - for (i = 0; i < N_ELEMENTS(tests); i++) { - var_get_key_range(tests[i].in, &idx, &size); - test_assert_idx(tests[i].idx == idx, i); - test_assert_idx(tests[i].size == size, i); - - if (tests[i].size == 1) - test_assert_idx(tests[i].in[idx] == var_get_key(tests[i].in), i); - } - test_end(); -} - -static int test_var_expand_func0(const char *data ATTR_UNUSED, - void *context ATTR_UNUSED, - const char **value_r, - const char **error_r ATTR_UNUSED) -{ - *value_r = "0"; - return 1; -} - -static int test_var_expand_func1(const char *data, void *context, - const char **value_r, - const char **error_r ATTR_UNUSED) -{ - test_assert(*(int *)context == 0xabcdef); - *value_r = t_strdup_printf("<%s>", data); - return 1; -} - -static int test_var_expand_func2(const char *data ATTR_UNUSED, - void *context ATTR_UNUSED, - const char **value_r, - const char **error_r ATTR_UNUSED) -{ - *value_r = ""; - return 1; -} - -static int test_var_expand_func3(const char *data ATTR_UNUSED, - void *context ATTR_UNUSED, - const char **value_r, - const char **error_r ATTR_UNUSED) -{ - *value_r = NULL; - return 1; -} - -static int test_var_expand_func4(const char *data, - void *context ATTR_UNUSED, - const char **value_r ATTR_UNUSED, - const char **error_r) -{ - *error_r = t_strdup_printf("Unknown data %s", data == NULL ? "" : data); - return 0; -} - -static int test_var_expand_func5(const char *data ATTR_UNUSED, - void *context ATTR_UNUSED, - const char **value_r ATTR_UNUSED, - const char **error_r) -{ - *error_r = "Internal error"; - return -1; -} - -static void test_var_expand_with_funcs(void) -{ - static const struct var_expand_test tests[] = { - { "%f", "0", 1 }, - { "%{func1}", "<>", 1 }, - { "%{func1:foo}", "", 1 }, - { "%{func2}", "", 1 }, - { "%{func3}", "", 1 }, - { "%{func4}", "", 0 }, - { "%{func5}", "", -1 }, - { "%{func4}%{func5}", "", -1 }, - { "%{func5}%{func4}%{func3}", "", -1 }, - }; - static const struct var_expand_table table[] = { - { '\0', NULL, NULL } - }; - static const struct var_expand_func_table func_table[] = { - { "f", test_var_expand_func0 }, - { "func1", test_var_expand_func1 }, - { "func2", test_var_expand_func2 }, - { "func3", test_var_expand_func3 }, - { "func4", test_var_expand_func4 }, - { "func5", test_var_expand_func5 }, - { NULL, NULL } - }; - string_t *str = t_str_new(128); - const char *error; - unsigned int i; - int ctx = 0xabcdef; - - test_begin("var_expand_with_funcs"); - for (i = 0; i < N_ELEMENTS(tests); i++) { - str_truncate(str, 0); - test_assert_idx(var_expand_with_funcs(str, tests[i].in, table, func_table, &ctx, &error) == tests[i].ret, i); - test_assert_idx(strcmp(tests[i].out, str_c(str)) == 0, i); - } - test_end(); -} - -static int -test_var_expand_arrays_func1(const char *data ATTR_UNUSED, void *context, - const char **value_r, - const char **error_r ATTR_UNUSED) -{ - test_assert(strcmp(context, "context1") == 0); - *value_r = context; - return 1; -} - -static int -test_var_expand_arrays_func2(const char *data ATTR_UNUSED, void *context, - const char **value_r, - const char **error_r ATTR_UNUSED) -{ - test_assert(strcmp(context, "context2") == 0); - *value_r = context; - return 1; -} - -static void test_var_expand_with_arrays(void) -{ - static const struct var_expand_table table1[] = { - { 'f', "firstvalue", "first" }, - { '\0', NULL, NULL } - }; - static const struct var_expand_table table2[] = { - { 's', "secondvalue", "second" }, - { '\0', NULL, NULL } - }; - static const struct var_expand_func_table func_table1[] = { - { "func1", test_var_expand_arrays_func1 }, - { NULL, NULL } - }; - static const struct var_expand_func_table func_table2[] = { - { "func2", test_var_expand_arrays_func2 }, - { NULL, NULL } - }; - - static const struct var_expand_table *tables[] = { - table1, table2, NULL - }; - static const struct var_expand_params_func funcs[] = { - { func_table1, "context1", }, - { func_table2, "context2", }, - { NULL, NULL } - }; - const char *input = "%f, %s, %{first}, %{second}, %{func1}, %{func2}"; - const char *output = "firstvalue, secondvalue, firstvalue, secondvalue, context1, context2"; - string_t *str = t_str_new(128); - const char *error; - - test_begin("var_expand_with_arrays"); - test_assert(var_expand_with_arrays(str, input, tables, funcs, &error) == 1); - test_assert_strcmp(str_c(str), output); - test_end(); -} - -static void test_var_get_key(void) -{ - static const struct { - const char *str; - char key; - } tests[] = { - { "x", 'x' }, - { "2.5Mx", 'x' }, - { "200MDx", 'x' }, - { "200MD{foo}", '{' }, - { "{foo}", '{' }, - { "", '\0' }, - }; - - test_begin("var_get_key"); - for (unsigned int i = 0; i < N_ELEMENTS(tests); i++) - test_assert_idx(var_get_key(tests[i].str) == tests[i].key, i); - test_end(); -} - -static void test_var_has_key(void) -{ - static const struct { - const char *str; - char key; - const char *long_key; - bool result; - } tests[] = { - { "%x%y", 'x', NULL, TRUE }, - { "%x%y", 'y', NULL, TRUE }, - { "%x%y", 'z', NULL, FALSE }, - { "%{foo}", 'f', NULL, FALSE }, - { "%{foo}", 'o', NULL, FALSE }, - { "%{foo}", '\0', "foo", TRUE }, - { "%{foo}", 'o', "foo", TRUE }, - { "%2.5Mx%y", 'x', NULL, TRUE }, - { "%2.5M{foo}", '\0', "foo", TRUE }, - }; - - test_begin("var_has_key"); - for (unsigned int i = 0; i < N_ELEMENTS(tests); i++) - test_assert_idx(var_has_key(tests[i].str, tests[i].key, tests[i].long_key) == tests[i].result, i); - test_end(); -} - -static int test_var_expand_hashing_func1(const char *data, - void *context ATTR_UNUSED, - const char **value_r, - const char **error_r ATTR_UNUSED) -{ - *value_r = data; - return 1; -} - -static int test_var_expand_bad_func(struct var_expand_context *ctx ATTR_UNUSED, - const char *key, - const char *field ATTR_UNUSED, - const char **result_r ATTR_UNUSED, - const char **error_r) -{ - if (strcmp(key, "notfound") == 0) { - *error_r = "Invalid field"; - return 0; - } - *error_r = "Bad parameters"; - return -1; -} - -static const struct var_expand_extension_func_table test_extension_funcs[] = { - { "notfound", test_var_expand_bad_func }, - { "badparam", test_var_expand_bad_func }, - { NULL, NULL } -}; - -static void test_var_expand_extensions(void) -{ - const char *error; - test_begin("var_expand_extensions"); - - var_expand_register_func_array(test_extension_funcs); - - static const struct var_expand_table table[] = { - {'\0', "example", "value" }, - {'\0', "other-example", "other-value" }, - {'\0', NULL, NULL} - }; - - static const struct { - const char *in; - const char *out; - } tests[] = { - { "md5: %M{value} %{md5:value}", "md5: 1a79a4d60de6718e8e5b326e338ae533 1a79a4d60de6718e8e5b326e338ae533" }, - { "sha1: %{sha1:value}", "sha1: c3499c2729730a7f807efb8676a92dcb6f8a3f8f" }, - { "sha1: %{sha1:func1:example}", "sha1: c3499c2729730a7f807efb8676a92dcb6f8a3f8f" }, - { "truncate: %{sha1;truncate=12:value}", "truncate: 0c34" }, - { "truncate: %{sha1;truncate=16:value}", "truncate: c349" }, - { "rounds,salt: %{sha1;rounds=1000,salt=seawater:value}", "rounds,salt: b515c85884f6b82dc7588279f3643a73e55d2289" }, - { "rounds,salt,expand: %{sha1;rounds=1000,salt=%{other-value}:value} %{other-value}", "rounds,salt,expand: 49a598ee110af615e175f2e4511cc5d7ccff96ab other-example" }, - { "format: %4.8{sha1:value}", "format: 9c272973" }, - { "base64: %{sha1;format=base64:value}", "base64: w0mcJylzCn+AfvuGdqkty2+KP48=" }, - { "base64url: %{sha1;format=base64url:value}", "base64url: w0mcJylzCn-AfvuGdqkty2-KP48" }, - }; - - static const struct var_expand_func_table func_table[] = { - { "func1", test_var_expand_hashing_func1 }, - { NULL, NULL } - }; - - string_t *str = t_str_new(128); - - for (unsigned int i = 0; i < N_ELEMENTS(tests); i++) { - str_truncate(str, 0); - error = NULL; - test_assert(var_expand_with_funcs(str, tests[i].in, table, - func_table, NULL, &error) == 1); - test_assert_idx(strcmp(str_c(str), tests[i].out) == 0, i); - if (error != NULL) { - i_debug("Error: %s", error); - } - } - - test_assert(var_expand_with_funcs(str, "notfound: %{notfound:field}", - table, func_table, NULL, &error) == 0); - error = NULL; - test_assert(var_expand_with_funcs(str, "notfound: %{badparam:field}", - table, func_table, NULL, &error) == -1); - test_assert(error != NULL); - - var_expand_unregister_func_array(test_extension_funcs); - - test_end(); -} - -static void test_var_expand_if(void) -{ - static const struct var_expand_table table[] = { - { 'a', "alpha", "alpha" }, - { 'b', "beta", "beta" }, - { 'o', "1", "one" }, - { 't', "2", "two" }, - { '\0', ";:", "evil1" }, - { '\0', ";test;", "evil2" }, - { '\0', NULL, NULL } - }; - const char *error; - string_t *dest = t_str_new(64); - test_begin("var_expand_if"); - - static const struct var_expand_test tests[] = { - /* basic numeric operand test */ - { "%{if;1;==;1;yes;no}", "yes", 1 }, - { "%{if;1;==;2;yes;no}", "no", 1 }, - { "%{if;1;<;1;yes;no}", "no", 1 }, - { "%{if;1;<;2;yes;no}", "yes", 1 }, - { "%{if;1;<=;1;yes;no}", "yes", 1 }, - { "%{if;1;<=;2;yes;no}", "yes", 1 }, - { "%{if;1;>;1;yes;no}", "no", 1 }, - { "%{if;1;>;2;yes;no}", "no", 1 }, - { "%{if;1;>=;1;yes;no}", "yes", 1 }, - { "%{if;1;>=;2;yes;no}", "no", 1 }, - { "%{if;1;!=;1;yes;no}", "no", 1 }, - { "%{if;1;!=;2;yes;no}", "yes", 1 }, - /* basic string operand test */ - { "%{if;a;eq;a;yes;no}", "yes", 1 }, - { "%{if;a;eq;b;yes;no}", "no", 1 }, - { "%{if;a;lt;a;yes;no}", "no", 1 }, - { "%{if;a;lt;b;yes;no}", "yes", 1 }, - { "%{if;a;le;a;yes;no}", "yes", 1 }, - { "%{if;a;le;b;yes;no}", "yes", 1 }, - { "%{if;a;gt;a;yes;no}", "no", 1 }, - { "%{if;a;gt;b;yes;no}", "no", 1 }, - { "%{if;a;ge;a;yes;no}", "yes", 1 }, - { "%{if;a;ge;b;yes;no}", "no", 1 }, - { "%{if;a;ne;a;yes;no}", "no", 1 }, - { "%{if;a;ne;b;yes;no}", "yes", 1 }, - { "%{if;a;*;a;yes;no}", "yes", 1 }, - { "%{if;a;*;b;yes;no}", "no", 1 }, - { "%{if;a;*;*a*;yes;no}", "yes", 1 }, - { "%{if;a;*;*b*;yes;no}", "no", 1 }, - { "%{if;a;*;*;yes;no}", "yes", 1 }, - { "%{if;a;!*;a;yes;no}", "no", 1 }, - { "%{if;a;!*;b;yes;no}", "yes", 1 }, - { "%{if;a;!*;*a*;yes;no}", "no", 1 }, - { "%{if;a;!*;*b*;yes;no}", "yes", 1 }, - { "%{if;a;!*;*;yes;no}", "no", 1 }, - { "%{if;a;~;a;yes;no}", "yes", 1 }, - { "%{if;a;~;b;yes;no}", "no", 1 }, - { "%{if;a;~;.*a.*;yes;no}", "yes", 1 }, - { "%{if;a;~;.*b.*;yes;no}", "no", 1 }, - { "%{if;a;~;.*;yes;no}", "yes", 1 }, - { "%{if;a;!~;a;yes;no}", "no", 1 }, - { "%{if;a;!~;b;yes;no}", "yes", 1 }, - { "%{if;a;!~;.*a.*;yes;no}", "no", 1 }, - { "%{if;a;!~;.*b.*;yes;no}", "yes", 1 }, - { "%{if;a;!~;.*;yes;no}", "no", 1 }, - { "%{if;this is test;~;^test;yes;no}", "no", 1 }, - { "%{if;this is test;~;.*test;yes;no}", "yes", 1 }, - /* variable expansion */ - { "%{if;%a;eq;%a;yes;no}", "yes", 1 }, - { "%{if;%a;eq;%b;yes;no}", "no", 1 }, - { "%{if;%{alpha};eq;%{alpha};yes;no}", "yes", 1 }, - { "%{if;%{alpha};eq;%{beta};yes;no}", "no", 1 }, - { "%{if;%o;eq;%o;yes;no}", "yes", 1 }, - { "%{if;%o;eq;%t;yes;no}", "no", 1 }, - { "%{if;%{one};eq;%{one};yes;no}", "yes", 1 }, - { "%{if;%{one};eq;%{two};yes;no}", "no", 1 }, - { "%{if;%{one};eq;%{one};%{one};%{two}}", "1", 1 }, - { "%{if;%{one};gt;%{two};%{one};%{two}}", "2", 1 }, - { "%{if;%{evil1};eq;\\;\\:;%{evil2};no}", ";test;", 1 }, - /* inner if */ - { "%{if;%{if;%{one};eq;1;1;0};eq;%{if;%{two};eq;2;2;3};yes;no}", "no", 1 }, - /* no false */ - { "%{if;1;==;1;yes}", "yes", 1 }, - { "%{if;1;==;2;yes}", "", 1 }, - /* invalid input */ - { "%{if;}", "", -1 }, - { "%{if;1;}", "", -1 }, - { "%{if;1;==;}", "", -1 }, - { "%{if;1;==;2;}", "", -1 }, - { "%{if;1;fu;2;yes;no}", "", -1 }, - /* missing variables */ - { "%{if;%{missing1};==;%{missing2};yes;no}", "", 0 }, - }; - - for(size_t i = 0; i < N_ELEMENTS(tests); i++) { - int ret; - error = NULL; - str_truncate(dest, 0); - ret = var_expand_with_table(dest, tests[i].in, table, &error); - test_assert_idx(tests[i].ret == ret, i); - test_assert_idx(strcmp(tests[i].out, str_c(dest)) == 0, i); - } - - test_end(); -} - -static void test_var_expand_merge_tables(void) -{ - const struct var_expand_table one[] = { - { 'a', "1", "alpha" }, - { '\0', "2", "beta" }, - { '\0', NULL, NULL } - }, - two[] = { - { 't', "3", "theta" }, - { '\0', "4", "phi" }, - { '\0', NULL, NULL } - }, - *merged = NULL; - - - test_begin("var_expand_merge_tables"); - - merged = t_var_expand_merge_tables(one, two); - - test_assert(var_expand_table_size(merged) == 4); - for(unsigned int i = 0; i < var_expand_table_size(merged); i++) { - if (i < 2) { - test_assert_idx(merged[i].key == one[i].key, i); - test_assert_idx(merged[i].value == one[i].value || strcmp(merged[i].value, one[i].value) == 0, i); - test_assert_idx(merged[i].long_key == one[i].long_key || strcmp(merged[i].long_key, one[i].long_key) == 0, i); - } else if (i < 4) { - test_assert_idx(merged[i].key == two[i-2].key, i); - test_assert_idx(merged[i].value == two[i-2].value || strcmp(merged[i].value, two[i-2].value) == 0, i); - test_assert_idx(merged[i].long_key == two[i-2].long_key || strcmp(merged[i].long_key, two[i-2].long_key) == 0, i); - } else { - break; - } - } - test_end(); -} - -static void test_var_expand_system() -{ - test_begin("var_expand_system"); - int ncpus; - const char *error ATTR_UNUSED; - int ret = cpu_count_get(&ncpus, &error) == 0 ? 1 : -1; - const struct var_expand_test tests[] = { - { "%{system:cpu_count}", dec2str(ncpus), ret }, - }; - - const struct var_expand_table table[] = { - { '\0', NULL, NULL } - }; - string_t *dest = t_str_new(64); - for (size_t i = 0; i < N_ELEMENTS(tests); i++) { - const struct var_expand_test *test = &tests[i]; - const char *error ATTR_UNUSED; - str_truncate(dest, 0); - int ret = var_expand_with_table(dest, test->in, table, &error); - test_assert_cmp_idx(ret, ==, test->ret, i); - test_assert_strcmp_idx(str_c(dest), test->out, i); - } - - /* Check the expansion of os/os-version depending on whether uname() - succeeds. */ - struct utsname utsname_result; - if (uname(&utsname_result) == 0) { - str_truncate(dest, 0); - test_assert(var_expand_with_table(dest, "%{system:os}", table, &error) == 1); - test_assert(strcmp(utsname_result.sysname, str_c(dest)) == 0); - - str_truncate(dest, 0); - test_assert(var_expand_with_table(dest, "%{system:os-version}", table, &error) == 1); - test_assert(strcmp(utsname_result.release, str_c(dest)) == 0); - } - - test_end(); -} - -static void -test_var_expand_dovecot(void) -{ - static const struct var_expand_table table[] = { - { '\0', NULL, NULL } - }; - - int ret; - const char *error; - string_t *dest = t_str_new(64); - test_begin("var_expand_dovecot"); - - /* Available keys should be correctly expanded. */ - static const struct var_expand_test tests[] = { - { "%{dovecot:name}", PACKAGE_NAME, 1 }, - { "%{dovecot:version}", PACKAGE_VERSION, 1 }, - { "%{dovecot:support-url}", PACKAGE_WEBPAGE, 1 }, - { "%{dovecot:support-email}", PACKAGE_BUGREPORT, 1 }, - { "%{dovecot:revision}", DOVECOT_REVISION, 1 }, - }; - - for (size_t i = 0; i < N_ELEMENTS(tests); i++) { - str_truncate(dest, 0); - - ret = var_expand_with_table(dest, tests[i].in, table, &error); - test_assert_idx(tests[i].ret == ret, i); - test_assert_idx(strcmp(tests[i].out, str_c(dest)) == 0, i); - } - - /* Make sure invalid keys are rejected. */ - str_truncate(dest, 0); - test_assert(var_expand_with_table(dest, "%{dovecot:invalid}", table, &error) == 0); - test_assert(strcmp(error, "Unsupported dovecot key 'invalid'") == 0); - - test_end(); -} - -void test_var_expand(void) -{ - test_var_expand_ranges(); - test_var_expand_builtin(); - test_var_get_key_range(); - test_var_expand_with_funcs(); - test_var_expand_with_arrays(); - test_var_get_key(); - test_var_has_key(); - test_var_expand_extensions(); - test_var_expand_if(); - test_var_expand_merge_tables(); - test_var_expand_system(); - test_var_expand_dovecot(); -} diff --git a/src/lib/var-expand-if.c b/src/lib/var-expand-if.c deleted file mode 100644 index 3050130399..0000000000 --- a/src/lib/var-expand-if.c +++ /dev/null @@ -1,269 +0,0 @@ -/* Copyright (c) 2003-2018 Dovecot authors, see the included COPYING file */ - -#include "lib.h" -#include "array.h" -#include "str.h" -#include "var-expand.h" -#include "var-expand-private.h" -#include "wildcard-match.h" - -#include - -enum var_expand_if_op { - OP_UNKNOWN, - OP_NUM_EQ, - OP_NUM_LT, - OP_NUM_LE, - OP_NUM_GT, - OP_NUM_GE, - OP_NUM_NE, -/* put all numeric comparisons before this line */ - OP_STR_EQ, - OP_STR_LT, - OP_STR_LE, - OP_STR_GT, - OP_STR_GE, - OP_STR_NE, - OP_STR_LIKE, - OP_STR_NOT_LIKE, - OP_STR_REGEXP, - OP_STR_NOT_REGEXP, -/* keep this as last */ - OP_COUNT -}; - -static enum var_expand_if_op var_expand_if_str_to_comp(const char *op) -{ - const char *ops[] = { - NULL, - "==", - "<", - "<=", - ">", - ">=", - "!=", - "eq", - "lt", - "le", - "gt", - "ge", - "ne", - "*", - "!*", - "~", - "!~", - }; - static_assert_array_size(ops, OP_COUNT); - for(enum var_expand_if_op i = 1; i < OP_COUNT; i++) { - i_assert(ops[i] != NULL); - if (strcmp(op, ops[i]) == 0) - return i; - } - return OP_UNKNOWN; -} - -static int var_expand_if_comp(const char *lhs, const char *_op, const char *rhs, - bool *result_r, const char **error_r) -{ - bool neg = FALSE; - enum var_expand_if_op op = var_expand_if_str_to_comp(_op); - - *result_r = FALSE; - if (op == OP_UNKNOWN) { - *error_r = t_strdup_printf("if: Unsupported comparator '%s'", _op); - return -1; - } - - if (op < OP_STR_EQ) { - intmax_t a; - intmax_t b; - if (str_to_intmax(lhs, &a) < 0) { - *error_r = t_strdup_printf("if: %s (lhs) is not a number", lhs); - return -1; - } - if (str_to_intmax(rhs, &b) < 0) { - *error_r = t_strdup_printf("if: %s (rhs) is not a number", rhs); - return -1; - } - switch(op) { - case OP_NUM_EQ: - *result_r = a==b; - return 0; - case OP_NUM_LT: - *result_r = ab; - return 0; - case OP_NUM_GE: - *result_r = a>=b; - return 0; - case OP_NUM_NE: - *result_r = a!=b; - return 0; - default: - i_panic("Missing numeric comparator %u", op); - } - } - - switch(op) { - case OP_STR_EQ: - *result_r = strcmp(lhs,rhs)==0; - return 0; - case OP_STR_LT: - *result_r = strcmp(lhs,rhs)<0; - return 0; - case OP_STR_LE: - *result_r = strcmp(lhs,rhs)<=0; - return 0; - case OP_STR_GT: - *result_r = strcmp(lhs,rhs)>0; - return 0; - case OP_STR_GE: - *result_r = strcmp(lhs,rhs)>=0; - return 0; - case OP_STR_NE: - *result_r = strcmp(lhs,rhs)!=0; - return 0; - case OP_STR_LIKE: - *result_r = wildcard_match(lhs, rhs); - return 0; - case OP_STR_NOT_LIKE: - *result_r = !wildcard_match(lhs, rhs); - return 0; - case OP_STR_NOT_REGEXP: - neg = TRUE; - /* fall through */ - case OP_STR_REGEXP: { - int ec; - bool res; - regex_t reg; - if ((ec = regcomp(®, rhs, REG_EXTENDED)) != 0) { - size_t siz; - char *errbuf; - siz = regerror(ec, ®, NULL, 0); - errbuf = t_malloc_no0(siz); - (void)regerror(ec, ®, errbuf, siz); - *error_r = t_strdup_printf("if: regex failed: %s", - errbuf); - return -1; - } - if ((ec = regexec(®, lhs, 0, 0, 0)) != 0) { - i_assert(ec == REG_NOMATCH); - res = FALSE; - } else { - res = TRUE; - } - regfree(®); - /* this should be same as neg. - if NOT_REGEXP, neg == TRUE and res should be FALSE - if REGEXP, ned == FALSE, and res should be TRUE - */ - *result_r = res != neg; - return 0; - } - default: - i_panic("Missing generic comparator %u", op); - } -} - -int var_expand_if(struct var_expand_context *ctx, - const char *key, const char *field, - const char **result_r, const char **error_r) -{ - /* in case the original input had :, we need to fix that - by concatenating the key and field together. */ - const char *input = t_strconcat(key, ":", field, NULL); - const char *p = strchr(input, ';'); - const char *par_end; - string_t *parbuf; - const char *const *parms; - unsigned int depth = 0; - int ret; - bool result, escape = FALSE, maybe_var = FALSE; - - if (p == NULL) { - *error_r = "if: missing parameter(s)"; - return -1; - } - ARRAY_TYPE(const_string) params; - t_array_init(¶ms, 6); - - parbuf = t_str_new(64); - /* we need to skip any %{} parameters here, so we can split the string - correctly from , without breaking any inner expansions */ - for(par_end = p+1; *par_end != '\0'; par_end++) { - if (*par_end == '\\') { - escape = TRUE; - continue; - } else if (escape) { - str_append_c(parbuf, *par_end); - escape = FALSE; - continue; - } - if (*par_end == '%') { - maybe_var = TRUE; - } else if (maybe_var && *par_end == '{') { - depth++; - maybe_var = FALSE; - } else if (depth > 0 && *par_end == '}') { - depth--; - } else if (depth == 0 && *par_end == ';') { - const char *par = str_c(parbuf); - array_push_back(¶ms, &par); - parbuf = t_str_new(64); - continue; - /* if there is a unescaped : at top level it means - that the key + arguments end here. it's probably - a by-product of the t_strconcat at top of function, - which is best handled here. */ - } else if (depth == 0 && *par_end == ':') { - break; - } - str_append_c(parbuf, *par_end); - } - - if (str_len(parbuf) > 0) { - const char *par = str_c(parbuf); - array_push_back(¶ms, &par); - } - - if (array_count(¶ms) != 5) { - if (array_count(¶ms) == 4) { - const char *empty = ""; - array_push_back(¶ms, &empty); - } else { - *error_r = t_strdup_printf("if: requires four or five parameters, got %u", - array_count(¶ms)); - return -1; - } - } - - array_append_zero(¶ms); - parms = array_front(¶ms); - t_array_init(¶ms, 6); - - for(;*parms != NULL; parms++) { - /* expand the parameters */ - string_t *param = t_str_new(64); - ret = var_expand_with_arrays(param, *parms, ctx->tables, - ctx->funcs, error_r); - if (ret <= 0) - return ret; - const char *p = str_c(param); - array_push_back(¶ms, &p); - } - - i_assert(array_count(¶ms) == 5); - - /* execute comparison */ - const char *const *args = array_front(¶ms); - if (var_expand_if_comp(args[0], args[1], args[2], &result, error_r)<0) - return -1; - *result_r = result ? args[3] : args[4]; - return 1; -} - diff --git a/src/lib/var-expand-private.h b/src/lib/var-expand-private.h deleted file mode 100644 index 868fca7a76..0000000000 --- a/src/lib/var-expand-private.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef VAR_EXPAND_PRIVATE_H -#define VAR_EXPAND_PRIVATE_H 1 - -struct var_expand_context { - /* NULL-terminated array of variable tables */ - const struct var_expand_table *const *tables; - /* table=NULL-terminated array of function tables */ - const struct var_expand_params_func *funcs; - - /* last offset, negative counts from end*/ - int offset; - /* last width, negative counts from end */ - int width; - /* last zero padding */ - bool zero_padding:1; -}; - -/* this can be used to register a *global* function that is - prepended to function table. These can be used to register some - special handling for keys. - - you can call var_expand_with_funcs if you need to - expand something inside here. - - return -1 on error, 0 on unknown variable, 1 on success -*/ -typedef int -var_expand_extension_func_t(struct var_expand_context *ctx, - const char *key, const char *field, - const char **result_r, const char **error_r); - -struct var_expand_extension_func_table { - const char *key; - var_expand_extension_func_t *func; -}; - -int var_expand_long(struct var_expand_context *ctx, - const void *key_start, size_t key_len, - const char **var_r, const char **error_r); - -void var_expand_extensions_init(void); -void var_expand_extensions_deinit(void); - -/* Functions registered here are placed before in-built functions, - so you can include your own implementation of something. - Be careful. Use NULL terminated list. -*/ -void var_expand_register_func_array(const struct var_expand_extension_func_table *funcs); -void var_expand_unregister_func_array(const struct var_expand_extension_func_table *funcs); - -int var_expand_if(struct var_expand_context *ctx, - const char *key, const char *field, - const char **result_r, const char **error_r); - -#endif diff --git a/src/lib/var-expand.c b/src/lib/var-expand.c deleted file mode 100644 index 51d7938f91..0000000000 --- a/src/lib/var-expand.c +++ /dev/null @@ -1,1034 +0,0 @@ -/* Copyright (c) 2003-2018 Dovecot authors, see the included COPYING file */ - -#include "lib.h" -#include "array.h" -#include "cpu-count.h" -#include "md5.h" -#include "hash.h" -#include "hex-binary.h" -#include "base64.h" -#include "hostpid.h" -#include "hmac.h" -#include "pkcs5.h" -#include "hash-method.h" -#include "str.h" -#include "strescape.h" -#include "var-expand.h" -#include "var-expand-private.h" -#include "dovecot-version.h" - -#include -#include - -#ifdef HAVE_SYS_UTSNAME_H -# include -#endif - -#define ENV_CPU_COUNT "NCPU" - -#define TABLE_LAST(t) \ - ((t)->key == '\0' && (t)->long_key == NULL) - -struct var_expand_modifier { - char key; - const char *(*func)(const char *, struct var_expand_context *); -}; - -static ARRAY(struct var_expand_extension_func_table) var_expand_extensions; - -enum os_default_type { - OS_DEFAULT_TYPE_SYSNAME, - OS_DEFAULT_TYPE_RELEASE, -}; - -static const char * -m_str_lcase(const char *str, struct var_expand_context *ctx ATTR_UNUSED) -{ - return t_str_lcase(str); -} - -static const char * -m_str_ucase(const char *str, struct var_expand_context *ctx ATTR_UNUSED) -{ - return t_str_ucase(str); -} - -static const char * -m_str_escape(const char *str, struct var_expand_context *ctx ATTR_UNUSED) -{ - return str_escape(str); -} - -static const char * -m_str_hex(const char *str, struct var_expand_context *ctx ATTR_UNUSED) -{ - unsigned long long l; - - if (str_to_ullong(str, &l) < 0) - l = 0; - return t_strdup_printf("%llx", l); -} - -static const char * -m_str_reverse(const char *str, struct var_expand_context *ctx ATTR_UNUSED) -{ - size_t len = strlen(str); - char *p, *rev; - - rev = t_malloc_no0(len + 1); - rev[len] = '\0'; - - for (p = rev + len - 1; *str != '\0'; str++) - *p-- = *str; - return rev; -} - -static const char *m_str_hash(const char *str, struct var_expand_context *ctx) -{ - unsigned int value = str_hash(str); - string_t *hash = t_str_new(20); - - if (ctx->width != 0) { - value %= ctx->width; - ctx->width = 0; - } - - str_printfa(hash, "%x", value); - while ((int)str_len(hash) < ctx->offset) - str_insert(hash, 0, "0"); - ctx->offset = 0; - - return str_c(hash); -} - -static const char * -m_str_newhash(const char *str, struct var_expand_context *ctx) -{ - string_t *hash = t_str_new(20); - unsigned char result[MD5_RESULTLEN]; - unsigned int i; - uint64_t value = 0; - - md5_get_digest(str, strlen(str), result); - for (i = 0; i < sizeof(value); i++) { - value <<= 8; - value |= result[i]; - } - - if (ctx->width != 0) { - value %= ctx->width; - ctx->width = 0; - } - - str_printfa(hash, "%x", (unsigned int)value); - while ((int)str_len(hash) < ctx->offset) - str_insert(hash, 0, "0"); - ctx->offset = 0; - - return str_c(hash); -} - -static const char * -m_str_md5(const char *str, struct var_expand_context *ctx ATTR_UNUSED) -{ - unsigned char digest[16]; - - md5_get_digest(str, strlen(str), digest); - - return binary_to_hex(digest, sizeof(digest)); -} - -static const char * -m_str_ldap_dn(const char *str, struct var_expand_context *ctx ATTR_UNUSED) -{ - string_t *ret = t_str_new(256); - - while (*str != '\0') { - if (*str == '.') - str_append(ret, ",dc="); - else - str_append_c(ret, *str); - str++; - } - - return str_free_without_data(&ret); -} - -static const char * -m_str_trim(const char *str, struct var_expand_context *ctx ATTR_UNUSED) -{ - size_t len; - - len = strlen(str); - while (len > 0 && i_isspace(str[len-1])) - len--; - return t_strndup(str, len); -} - -#define MAX_MODIFIER_COUNT 10 -static const struct var_expand_modifier modifiers[] = { - { 'L', m_str_lcase }, - { 'U', m_str_ucase }, - { 'E', m_str_escape }, - { 'X', m_str_hex }, - { 'R', m_str_reverse }, - { 'H', m_str_hash }, - { 'N', m_str_newhash }, - { 'M', m_str_md5 }, - { 'D', m_str_ldap_dn }, - { 'T', m_str_trim }, - { '\0', NULL } -}; - -static int -var_expand_short(const struct var_expand_context *ctx, char key, - const char **var_r, const char **error_r) -{ - const struct var_expand_table *t; - - for (unsigned int i = 0; ctx->tables[i] != NULL; i++) { - for (t = ctx->tables[i]; !TABLE_LAST(t); t++) { - if (t->key == key) { - *var_r = t->value != NULL ? t->value : ""; - return 1; - } - } - } - - for (unsigned int j = 0; ctx->funcs[j].table != NULL; j++) { - const struct var_expand_func_table *func_table = ctx->funcs[j].table; - for (unsigned int i = 0; func_table[i].key != NULL; i++) { - if (func_table[i].key[0] == key && - func_table[i].key[1] == '\0') { - const char *value; - int ret = func_table->func( - "", ctx->funcs[j].context, &value, error_r); - *var_r = value != NULL ? value : ""; - return ret; - } - } - } - - /* not found */ - if (key == '%') { - *var_r = "%"; - return 1; - } - if (*error_r == NULL) - *error_r = t_strdup_printf("Unknown variable '%%%c'", key); - *var_r = t_strdup_printf("UNSUPPORTED_VARIABLE_%c", key); - return 0; -} - -static int -var_expand_hash(struct var_expand_context *ctx, - const char *key, const char *field, - const char **result_r, const char **error_r) -{ - enum { - FORMAT_HEX, - FORMAT_HEX_UC, - FORMAT_BASE64, - FORMAT_BASE64_URL, - } format = FORMAT_HEX; - - const char *p = strchr(key, ';'); - const char *const *args = NULL; - const char *algo = key; - const char *value; - int ret; - - if (p != NULL) { - algo = t_strcut(key, ';'); - args = t_strsplit(p+1, ","); - } - - const struct hash_method *method; - if (strcmp(algo, "pkcs5") == 0) { - method = hash_method_lookup("sha256"); - } else { - method = hash_method_lookup(algo); - } - - /* since this can get called only by registered algorithms - it's not really possible for them to be suddenly missing */ - i_assert(method != NULL); - - string_t *field_value = t_str_new(64); - string_t *salt = t_str_new(64); - string_t *tmp = t_str_new(method->digest_size); - - if ((ret = var_expand_long(ctx, field, strlen(field), - &value, error_r)) <= 0) { - return ret; - } - - str_append(field_value, value); - - /* default values */ - unsigned int rounds = 1; - unsigned int truncbits = 0; - - if (strcmp(algo, "pkcs5") == 0) { - rounds = 2048; - str_append(salt, field); - } - - while(args != NULL && *args != NULL) { - const char *k = t_strcut(*args, '='); - const char *value = strchr(*args, '='); - if (value == NULL) { - args++; - continue; - } else { - value++; - } - if (strcmp(k, "rounds") == 0) { - if (str_to_uint(value, &rounds)<0) { - *error_r = t_strdup_printf( - "Cannot parse hash arguments:" - "'%s' is not number for rounds", - value); - return -1; - } - if (rounds < 1) { - *error_r = t_strdup_printf( - "Cannot parse hash arguments:" - "rounds must be at least 1"); - return -1; - } - } else if (strcmp(k, "truncate") == 0) { - if (str_to_uint(value, &truncbits)<0) { - *error_r = t_strdup_printf( - "Cannot parse hash arguments:" - "'%s' is not number for truncbits", - value); - return -1; - } - truncbits = I_MIN(truncbits, method->digest_size*8); - } else if (strcmp(k, "salt") == 0) { - str_truncate(salt, 0); - ret = var_expand_with_arrays(salt, value, ctx->tables, - ctx->funcs, error_r); - if (ret <= 0) - return ret; - break; - } else if (strcmp(k, "format") == 0) { - if (strcmp(value, "hex") == 0) { - format = FORMAT_HEX; - } else if (strcmp(value, "hexuc") == 0){ - format = FORMAT_HEX_UC; - } else if (strcmp(value, "base64") == 0) { - format = FORMAT_BASE64; - } else if (strcmp(value, "base64url") == 0) { - format = FORMAT_BASE64_URL; - } else { - *error_r = t_strdup_printf( - "Cannot parse hash arguments:" - "'%s' is not supported format", - value); - return -1; - } - } - args++; - } - - str_truncate(tmp, 0); - - if (strcmp(algo, "pkcs5") == 0) { - if (pkcs5_pbkdf(PKCS5_PBKDF2, method, - field_value->data, field_value->used, - salt->data, salt->used, - rounds, HMAC_MAX_CONTEXT_SIZE, tmp) != 0) { - *error_r = "Cannot hash: PKCS5_PBKDF2 failed"; - return -1; - } - } else { - void *context = t_malloc_no0(method->context_size); - - str_append_str(tmp, field_value); - - for(;rounds>0;rounds--) { - method->init(context); - if (salt->used > 0) - method->loop(context, salt->data, salt->used); - method->loop(context, tmp->data, tmp->used); - unsigned char *digest = - buffer_get_modifiable_data(tmp, NULL); - method->result(context, digest); - if (tmp->used != method->digest_size) - buffer_set_used_size(tmp, method->digest_size); - } - } - - if (truncbits > 0) - buffer_truncate_rshift_bits(tmp, truncbits); - - switch(format) { - case FORMAT_HEX: - *result_r = binary_to_hex(tmp->data, tmp->used); - return 1; - case FORMAT_HEX_UC: - *result_r = binary_to_hex(tmp->data, tmp->used); - return 1; - case FORMAT_BASE64: { - string_t *dest = t_str_new(64); - base64_encode(tmp->data, tmp->used, dest); - *result_r = str_c(dest); - return 1; - } - case FORMAT_BASE64_URL: { - string_t *dest = t_str_new(64); - base64url_encode(BASE64_ENCODE_FLAG_NO_PADDING, 0, - tmp->data, tmp->used, dest); - *result_r = str_c(dest); - return 1; - } - } - - i_unreached(); -} - -static int -var_expand_process(struct var_expand_context *ctx ATTR_UNUSED, - const char *key, const char *field, - const char **result_r, const char **error_r) -{ - i_assert(strcmp(key, "process") == 0); - if (strcmp(field, "pid") == 0) - *result_r = my_pid; - else if (strcmp(field, "uid") == 0) - *result_r = dec2str(geteuid()); - else if (strcmp(field, "gid") == 0) - *result_r = dec2str(getegid()); - else { - *error_r = t_strdup_printf("Unsupported process field '%s'", - field); - return 0; - } - return 1; -} - -static struct utsname utsname_result; -static bool utsname_set = FALSE; - -static int -var_expand_system_os(enum os_default_type type, - const char **value_r, const char **error_r) -{ - if (!utsname_set) { - utsname_set = TRUE; - - if (uname(&utsname_result) < 0) { - *error_r = t_strdup_printf("uname() failed: %m"); - i_zero(&utsname_result); - return -1; - } - } - - switch (type) { - case OS_DEFAULT_TYPE_SYSNAME: - *value_r = utsname_result.sysname; - return 1; - case OS_DEFAULT_TYPE_RELEASE: - *value_r = utsname_result.release; - return 1; - default: - break; - } - - i_unreached(); -} - -static int -var_expand_system(struct var_expand_context *ctx ATTR_UNUSED, - const char *key, const char *field, - const char **result_r, const char **error_r) -{ - i_assert(strcmp(key, "system") == 0); - if (strcmp(field, "cpu_count") == 0) { - int ncpus; - const char *cpuenv = getenv(ENV_CPU_COUNT); - if (cpuenv != NULL) { - *result_r = cpuenv; - return 1; - } - if (cpu_count_get(&ncpus, error_r) < 0) - return -1; - *result_r = dec2str(ncpus); - return 1; - } else if (strcmp(field, "hostname") == 0) { - *result_r = my_hostname; - return 1; - } else if (strcmp(field, "os") == 0) - return var_expand_system_os(OS_DEFAULT_TYPE_SYSNAME, result_r, - error_r); - else if (strcmp(field, "os-version") == 0) - return var_expand_system_os(OS_DEFAULT_TYPE_RELEASE, result_r, - error_r); - *error_r = t_strdup_printf("Unsupported system key '%s'", field); - return 0; -} - -static int -var_expand_dovecot(struct var_expand_context *ctx ATTR_UNUSED, - const char *key, const char *field, - const char **result_r, const char **error_r) -{ - i_assert(strcmp(key, "dovecot") == 0); - - if (strcmp(field, "name") == 0) { - *result_r = PACKAGE_NAME; - return 1; - } else if (strcmp(field, "version") == 0) { - *result_r = PACKAGE_VERSION; - return 1; - } else if (strcmp(field, "support-url") == 0) { - *result_r = PACKAGE_WEBPAGE; - return 1; - } else if (strcmp(field, "support-email") == 0) { - *result_r = PACKAGE_BUGREPORT; - return 1; - } else if (strcmp(field, "revision") == 0) { - *result_r = DOVECOT_REVISION; - return 1; - } - - *error_r = t_strdup_printf("Unsupported dovecot key '%s'", field); - return 0; -} - -static int -var_expand_func(const struct var_expand_params_func *funcs, - const char *key, const char *data, - const char **var_r, const char **error_r) -{ - const char *value = NULL; - int ret; - - if (strcmp(key, "env") == 0) { - value = getenv(data); - *var_r = value != NULL ? value : ""; - return 1; - } - for (unsigned int i = 0; funcs[i].table != NULL; i++) { - const struct var_expand_func_table *func_table = funcs[i].table; - for (; func_table->key != NULL; func_table++) { - if (strcmp(func_table->key, key) == 0) { - ret = func_table->func(data, funcs[i].context, &value, error_r); - if (*error_r == NULL) - *error_r = t_strdup_printf("Unknown variables in function %%%s", key); - *var_r = value != NULL ? value : ""; - return ret; - } - } - } - if (*error_r == NULL) - *error_r = t_strdup_printf("Unknown variable '%%%s'", key); - *var_r = t_strdup_printf("UNSUPPORTED_VARIABLE_%s", key); - return 0; -} - -static int -var_expand_try_extension(struct var_expand_context *ctx, - const char *key, const char *data, - const char **var_r, const char **error_r) -{ - int ret; - const char *sep = strchr(key, ';'); - - if (sep == NULL) sep = key + strlen(key); - - /* try with extensions */ - const struct var_expand_extension_func_table *f; - array_foreach(&var_expand_extensions, f) { - /* ensure we won't match abbreviations */ - size_t len = sep-key; - if (strncasecmp(key, f->key, len) == 0 && f->key[len] == '\0') { - ret = f->func(ctx, key, data, var_r, error_r); - i_assert(ret == 1 || *error_r != NULL); - return ret; - } - } - return var_expand_func(ctx->funcs, key, data, var_r, error_r); -} - - -int -var_expand_long(struct var_expand_context *ctx, - const void *key_start, size_t key_len, - const char **var_r, const char **error_r) -{ - const struct var_expand_table *t; - const char *key, *value = NULL; - int ret = 1; - - for (unsigned int i = 0; ctx->tables[i] != NULL; i++) { - for (t = ctx->tables[i]; !TABLE_LAST(t); t++) { - if (t->long_key != NULL && - strncmp(t->long_key, key_start, key_len) == 0 && - t->long_key[key_len] == '\0') { - *var_r = t->value != NULL ? t->value : ""; - return 1; - } - } - } - key = t_strndup(key_start, key_len); - - const char *data = strchr(key, ':'); - - if (data != NULL) - key = t_strdup_until(key, data++); - else - data = ""; - - ret = var_expand_try_extension(ctx, key, data, &value, error_r); - - if (ret <= 0 && value == NULL) - value = ""; - - *var_r = value; - return ret; -} - -int var_expand_with_funcs(string_t *dest, const char *str, - const struct var_expand_table *table, - const struct var_expand_func_table *func_table, - void *context, const char **error_r) -{ - const struct var_expand_params params = { - .table = table, - .func_table = func_table, - .func_context = context, - }; - return var_expand(dest, str, ¶ms, error_r); -} - -int var_expand_with_arrays(string_t *dest, const char *str, - const struct var_expand_table *const *tables, - const struct var_expand_params_func *funcs, - const char **error_r) -{ - const struct var_expand_params params = { - .tables_arr = tables, - .funcs_arr = funcs, - }; - return var_expand(dest, str, ¶ms, error_r); -} - -int var_expand(string_t *dest, const char *str, - const struct var_expand_params *params, const char **error_r) -{ - static const struct var_expand_table *empty_table = NULL; - static const struct var_expand_params_func empty_funcs = { NULL, NULL }; - const struct var_expand_table *tables[2] = { NULL, NULL }; - struct var_expand_params_func funcs[2] = { - { NULL, NULL }, { NULL, NULL } }; - const struct var_expand_modifier *m; - const char *var; - struct var_expand_context ctx; - const char *(*modifier[MAX_MODIFIER_COUNT]) - (const char *, struct var_expand_context *); - const char *end; - unsigned int i, modifier_count; - size_t len; - int ret, final_ret = 1; - - *error_r = NULL; - - i_zero(&ctx); - if (params->table != NULL) { - i_assert(params->tables_arr == NULL); - tables[0] = params->table; - ctx.tables = tables; - } else if (params->tables_arr != NULL) - ctx.tables = params->tables_arr; - else - ctx.tables = &empty_table; - - if (params->func_table != NULL) { - i_assert(params->funcs_arr == NULL); - funcs[0].table = params->func_table; - funcs[0].context = params->func_context; - ctx.funcs = funcs; - } else if (params->funcs_arr != NULL) - ctx.funcs = params->funcs_arr; - else - ctx.funcs = &empty_funcs; - - for (; *str != '\0'; str++) { - if (*str != '%') - str_append_c(dest, *str); - else { - int sign = 1; - - str++; - - /* reset per-field modifiers */ - ctx.offset = 0; - ctx.width = 0; - ctx.zero_padding = FALSE; - - /* [.][] */ - if (*str == '-') { - sign = -1; - str++; - } - if (*str == '0') { - ctx.zero_padding = TRUE; - str++; - } - while (*str >= '0' && *str <= '9') { - ctx.width = ctx.width*10 + (*str - '0'); - str++; - } - - if (*str == '.') { - ctx.offset = sign * ctx.width; - sign = 1; - ctx.width = 0; - str++; - - /* if offset was prefixed with zero (or it was - plain zero), just ignore that. zero padding - is done with the width. */ - ctx.zero_padding = FALSE; - if (*str == '0') { - ctx.zero_padding = TRUE; - str++; - } - if (*str == '-') { - sign = -1; - str++; - } - - while (*str >= '0' && *str <= '9') { - ctx.width = ctx.width*10 + (*str - '0'); - str++; - } - ctx.width = sign * ctx.width; - } - - modifier_count = 0; - while (modifier_count < MAX_MODIFIER_COUNT) { - modifier[modifier_count] = NULL; - for (m = modifiers; m->key != '\0'; m++) { - if (m->key == *str) { - /* @UNSAFE */ - modifier[modifier_count] = - m->func; - str++; - break; - } - } - if (modifier[modifier_count] == NULL) - break; - modifier_count++; - } - - var = ""; - if (*str == '{' && strchr(str, '}') != NULL) { - /* %{long_key} */ - unsigned int ctr = 1; - bool escape = FALSE; - end = str; - while(*++end != '\0' && ctr > 0) { - if (!escape && *end == '\\') { - escape = TRUE; - continue; - } - if (escape) { - escape = FALSE; - continue; - } - if (*end == '{') ctr++; - if (*end == '}') ctr--; - } - if (ctr == 0) - /* it needs to come back a bit */ - end--; - /* if there is no } it will consume rest of the - string */ - len = end - (str + 1); - ret = var_expand_long(&ctx, str+1, len, - &var, error_r); - str = end; - } else { - ret = var_expand_short(&ctx, *str, - &var, error_r); - } - i_assert(var != NULL); - - if (*str == '\0') { - *error_r = "%variable ends unexpectedly"; - return -1; - } - if (final_ret > ret) - final_ret = ret; - - if (params->escape_func != NULL) { - var = params->escape_func(var, - params->escape_context); - } - - if (ret <= 0) - str_append(dest, var); - else { - for (i = 0; i < modifier_count; i++) - var = modifier[i](var, &ctx); - - if (ctx.offset < 0) { - /* if offset is < 0 then we want to - start at the end */ - size_t len = strlen(var); - size_t offset_from_end = -ctx.offset; - - if (len > offset_from_end) - var += len - offset_from_end; - } else { - while (*var != '\0' && ctx.offset > 0) { - ctx.offset--; - var++; - } - } - if (ctx.width == 0) - str_append(dest, var); - else if (!ctx.zero_padding) { - if (ctx.width < 0) - ctx.width = strlen(var) - (-ctx.width); - str_append_max(dest, var, ctx.width); - } else { - /* %05d -like padding. no truncation. */ - ssize_t len = strlen(var); - while (len < ctx.width) { - str_append_c(dest, '0'); - ctx.width--; - } - str_append(dest, var); - } - } - } - } - return final_ret; -} - -int var_expand_with_table(string_t *dest, const char *str, - const struct var_expand_table *table, - const char **error_r) -{ - const struct var_expand_params params = { - .table = table, - }; - return var_expand(dest, str, ¶ms, error_r); -} - -static bool -var_get_key_range_full(const char *str, unsigned int *idx_r, - unsigned int *size_r) -{ - const struct var_expand_modifier *m; - unsigned int i = 0; - - /* [.][] */ - while ((str[i] >= '0' && str[i] <= '9') || str[i] == '-') - i++; - - if (str[i] == '.') { - i++; - while ((str[i] >= '0' && str[i] <= '9') || str[i] == '-') - i++; - } - - do { - for (m = modifiers; m->key != '\0'; m++) { - if (m->key == str[i]) { - i++; - break; - } - } - } while (m->key != '\0'); - - if (str[i] != '{') { - /* short key */ - *idx_r = i; - *size_r = str[i] == '\0' ? 0 : 1; - return FALSE; - } else { - unsigned int depth = 1; - bool escape = FALSE; - /* long key */ - *idx_r = ++i; - for (; str[i] != '\0'; i++) { - if (!escape && str[i] == '\\') { - escape = TRUE; - continue; - } - if (escape) { - escape = FALSE; - continue; - } - if (str[i] == '{') - depth++; - if (str[i] == '}') { - if (--depth==0) - break; - } - } - *size_r = i - *idx_r; - return TRUE; - } -} - -char var_get_key(const char *str) -{ - unsigned int idx, size; - - if (var_get_key_range_full(str, &idx, &size)) - return '{'; - return str[idx]; -} - -void var_get_key_range(const char *str, unsigned int *idx_r, - unsigned int *size_r) -{ - (void)var_get_key_range_full(str, idx_r, size_r); -} - -static bool var_has_long_key(const char **str, const char *long_key) -{ - const char *start, *end; - - start = strchr(*str, '{'); - i_assert(start != NULL); - - end = strchr(++start, '}'); - if (end == NULL) - return FALSE; - - if (strncmp(start, long_key, end-start) == 0 && - long_key[end-start] == '\0') - return TRUE; - - *str = end; - return FALSE; -} - -bool var_has_key(const char *str, char key, const char *long_key) -{ - char c; - - for (; *str != '\0'; str++) { - if (*str == '%' && str[1] != '\0') { - str++; - c = var_get_key(str); - if (c == key && key != '\0') - return TRUE; - - if (c == '{' && long_key != NULL) { - if (var_has_long_key(&str, long_key)) - return TRUE; - } - } - } - return FALSE; -} - -void var_expand_extensions_deinit(void) -{ - array_free(&var_expand_extensions); -} - -void var_expand_extensions_init(void) -{ - i_array_init(&var_expand_extensions, 32); - - /* put all hash methods there */ - for(const struct hash_method **meth = hash_methods; - *meth != NULL; - meth++) { - struct var_expand_extension_func_table *func = - array_append_space(&var_expand_extensions); - func->key = (*meth)->name; - func->func = var_expand_hash; - } - - /* pkcs5 */ - struct var_expand_extension_func_table *func = - array_append_space(&var_expand_extensions); - func->key = "pkcs5"; - func->func = var_expand_hash; - - /* if */ - func = array_append_space(&var_expand_extensions); - func->key = "if"; - func->func = var_expand_if; - - /* system */ - func = array_append_space(&var_expand_extensions); - func->key = "system"; - func->func = var_expand_system; - - /* process */ - func = array_append_space(&var_expand_extensions); - func->key = "process"; - func->func = var_expand_process; - - /* dovecot */ - func = array_append_space(&var_expand_extensions); - func->key = "dovecot"; - func->func = var_expand_dovecot; -} - -void -var_expand_register_func_array(const struct var_expand_extension_func_table *funcs) -{ - for(const struct var_expand_extension_func_table *ptr = funcs; - ptr->key != NULL; - ptr++) { - i_assert(*ptr->key != '\0'); - array_push_front(&var_expand_extensions, ptr); - } -} - -void -var_expand_unregister_func_array(const struct var_expand_extension_func_table *funcs) -{ - for(const struct var_expand_extension_func_table *ptr = funcs; - ptr->key != NULL; - ptr++) { - i_assert(ptr->func != NULL); - for(unsigned int i = 0; i < array_count(&var_expand_extensions); i++) { - const struct var_expand_extension_func_table *func = - array_idx(&var_expand_extensions, i); - if (strcasecmp(func->key, ptr->key) == 0) { - array_delete(&var_expand_extensions, i, 1); - } - } - } -} - -struct var_expand_table * -var_expand_merge_tables(pool_t pool, const struct var_expand_table *a, - const struct var_expand_table *b) -{ - ARRAY(struct var_expand_table) table; - size_t a_size = var_expand_table_size(a); - size_t b_size = var_expand_table_size(b); - p_array_init(&table, pool, a_size + b_size + 1); - for(size_t i=0; ikey = a[i].key; - entry->value = p_strdup(pool, a[i].value); - entry->long_key = p_strdup(pool, a[i].long_key); - } - for(size_t i=0; ikey = b[i].key; - entry->value = p_strdup(pool, b[i].value); - entry->long_key = p_strdup(pool, b[i].long_key); - } - array_append_zero(&table); - return array_front_modifiable(&table); -} diff --git a/src/lib/var-expand.h b/src/lib/var-expand.h deleted file mode 100644 index d5c1e88781..0000000000 --- a/src/lib/var-expand.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef VAR_EXPAND_H -#define VAR_EXPAND_H - -typedef const char *var_expand_escape_t(const char *str, void *context); - -struct var_expand_table { - char key; - const char *value; - const char *long_key; -}; - -struct var_expand_func_table { - const char *key; - /* %{key:data}, or data is "" with %{key}. - Returns 1 on success, 0 if data is invalid, -1 on temporary error. */ - int (*func)(const char *data, void *context, - const char **value_r, const char **error_r); -}; - -struct var_expand_params_func { - const struct var_expand_func_table *table; - void *context; -}; - -struct var_expand_params { - /* If non-NULL, all variables are escaped with this function. */ - var_expand_escape_t *escape_func; - void *escape_context; - - /* Single table: */ - const struct var_expand_table *table; - const struct var_expand_func_table *func_table; - void *func_context; - - /* Alternatively, multiple tables: */ - const struct var_expand_table *const *tables_arr; - const struct var_expand_params_func *funcs_arr; -}; - -/* Expand % variables in src and append the string in dest. Returns 1 on - success, 0 if the format string contained invalid/unknown %variables, -1 if - one of the functions returned temporary error. Even in case of errors the - dest string is still written as fully as possible. */ -int var_expand(string_t *dest, const char *str, - const struct var_expand_params *params, const char **error_r); -/* Expand % variables in src and append the string in dest. - table must end with key = 0. Returns 1 on success, 0 if the format string - contained invalid/unknown %variables, -1 if one of the functions returned - temporary error. Even in case of errors the dest string is still written as - fully as possible. */ -int var_expand_with_table(string_t *dest, const char *str, - const struct var_expand_table *table, - const char **error_r); -/* Like var_expand_with_table(), but support also callback functions for - variable expansion. */ -int var_expand_with_funcs(string_t *dest, const char *str, - const struct var_expand_table *table, - const struct var_expand_func_table *func_table, - void *func_context, const char **error_r) ATTR_NULL(3, 4, 5); -/* Like var_expand_with_funcs(), but multiple separate tables can be given. - Each func_table[n] has a matching func_context[n] */ -int var_expand_with_arrays(string_t *dest, const char *str, - const struct var_expand_table *const *tables, - const struct var_expand_params_func *funcs, - const char **error_r); - -/* Returns the actual key character for given string, ie. skip any modifiers - that are before it. The string should be the data after the '%' character. - For %{long_variable}, '{' is returned. */ -char var_get_key(const char *str) ATTR_PURE; -/* Similar to var_get_key(), but works for long keys as well. For single char - keys size=1, while for e.g. %{key} size=3 and idx points to 'k'. */ -void var_get_key_range(const char *str, unsigned int *idx_r, - unsigned int *size_r); -/* Returns TRUE if key variable is used in the string. - If key is '\0', it's ignored. If long_key is NULL, it's ignored. */ -bool var_has_key(const char *str, char key, const char *long_key) ATTR_PURE; - -static inline size_t ATTR_PURE -var_expand_table_size(const struct var_expand_table *table) -{ - size_t n = 0; - while(table != NULL && (table[n].key != '\0' || - table[n].long_key != NULL)) - n++; - return n; -} - -struct var_expand_table * -var_expand_merge_tables(pool_t pool, const struct var_expand_table *a, - const struct var_expand_table *b); -#define t_var_expand_merge_tables(a, b) \ - (const struct var_expand_table *)var_expand_merge_tables(pool_datastack_create(), (a), (b)) -#endif diff --git a/src/login-common/client-common.c b/src/login-common/client-common.c index 86a308d9db..1ad17e15d0 100644 --- a/src/login-common/client-common.c +++ b/src/login-common/client-common.c @@ -22,7 +22,6 @@ #include "safe-memset.h" #include "time-util.h" #include "settings.h" -#include "var-expand-new.h" #include "master-interface.h" #include "master-service.h" #include "login-client.h" @@ -1203,7 +1202,7 @@ client_get_log_str(struct client *client, const char *msg) }; str_truncate(str, 0); - if (var_expand_new(str, client->set->login_log_format, ¶ms2, + if (var_expand(str, client->set->login_log_format, ¶ms2, &error) < 0) { /* NOTE: Don't log via client->event - it would cause recursion */ diff --git a/src/master/service-process.c b/src/master/service-process.c index 83c2937840..dd36978749 100644 --- a/src/master/service-process.c +++ b/src/master/service-process.c @@ -17,7 +17,7 @@ #include "restrict-access.h" #include "restrict-process-size.h" #include "eacces-error.h" -#include "var-expand-new.h" +#include "var-expand.h" #include "master-service.h" #include "master-service-settings.h" #include "dup2-array.h" @@ -64,7 +64,7 @@ service_unix_pid_listener_get_path(struct service_listener *l, pid_t pid, }; str_truncate(path, 0); - return var_expand_new(path, l->set.fileset.set->path, ¶ms, error_r); + return var_expand(path, l->set.fileset.set->path, ¶ms, error_r); } static void diff --git a/src/plugins/notify-status/notify-status-plugin.c b/src/plugins/notify-status/notify-status-plugin.c index b908586457..5a955db39c 100644 --- a/src/plugins/notify-status/notify-status-plugin.c +++ b/src/plugins/notify-status/notify-status-plugin.c @@ -4,7 +4,7 @@ #include "array.h" #include "json-generator.h" #include "str.h" -#include "var-expand-new.h" +#include "var-expand.h" #include "mail-user.h" #include "mail-storage.h" #include "mail-storage-private.h" @@ -150,7 +150,7 @@ static void notify_update_mailbox_status(struct mailbox *box) json_append_escaped(username, user->username); json_append_escaped(mboxname, mailbox_get_vname(box)); - const struct var_expand_table_new values[] = { + const struct var_expand_table values[] = { { .key = "username", .value = str_c(username) }, { .key = "mailbox", .value = str_c(mboxname) }, { .key = "messages", .value = dec2str(status.messages) }, @@ -171,7 +171,7 @@ static void notify_update_mailbox_status(struct mailbox *box) const char *key = t_strdup_printf(NOTIFY_STATUS_KEY, mailbox_get_vname(box)); string_t *dest = t_str_new(64); - if (var_expand_new(dest, nuser->set->notify_status_value, + if (var_expand(dest, nuser->set->notify_status_value, ¶ms, &error) < 0) { e_error(box->event, "notify-status: var_expand(%s) failed: %s", nuser->set->notify_status_value, error); diff --git a/src/plugins/var-expand-crypt/test-var-expand-crypt.c b/src/plugins/var-expand-crypt/test-var-expand-crypt.c index 5564cfacde..4ec4b472ba 100644 --- a/src/plugins/var-expand-crypt/test-var-expand-crypt.c +++ b/src/plugins/var-expand-crypt/test-var-expand-crypt.c @@ -3,7 +3,7 @@ #include "lib.h" #include "test-common.h" #include "str.h" -#include "var-expand-new.h" +#include "var-expand.h" #include "randgen.h" #include "dcrypt.h" @@ -48,7 +48,7 @@ static void test_var_expand_crypt(void) for(i=0; i < N_ELEMENTS(test_cases); i++) T_BEGIN { const char *error; string_t *dest = t_str_new(32); - int ret = var_expand_new(dest, test_cases[i].input, ¶ms, &error); + int ret = var_expand(dest, test_cases[i].input, ¶ms, &error); if (ret < 0) { if (test_cases[i].expect_ret == -1) i_info("Expected: var_expand(%s): %s", test_cases[i].input, error); @@ -71,9 +71,9 @@ static void test_var_expand_crypt(void) str_truncate(input, 0); str_truncate(output, 0); - test_assert_idx(var_expand_new(input, "%{decrypted|encrypt(algorithm='aes-128-cbc',key=key)}", ¶ms, &error) == 0, i); + test_assert_idx(var_expand(input, "%{decrypted|encrypt(algorithm='aes-128-cbc',key=key)}", ¶ms, &error) == 0, i); table[5].value = str_c(input); - test_assert_idx(var_expand_new(output, "%{encrypted2|decrypt(algorithm='aes-128-cbc',key=key)}", ¶ms, &error) == 0, i); + test_assert_idx(var_expand(output, "%{encrypted2|decrypt(algorithm='aes-128-cbc',key=key)}", ¶ms, &error) == 0, i); test_assert_strcmp_idx(str_c(output), table[4].value, i); }; diff --git a/src/pop3/pop3-client.c b/src/pop3/pop3-client.c index d2539ad322..6a639d1b49 100644 --- a/src/pop3/pop3-client.c +++ b/src/pop3/pop3-client.c @@ -15,7 +15,6 @@ #include "hostpid.h" #include "file-dotlock.h" #include "settings.h" -#include "var-expand-new.h" #include "master-service.h" #include "mail-storage.h" #include "mail-storage-service.h" @@ -572,7 +571,7 @@ static const char *client_stats(struct client *client) event_add_int(client->event, "net_out_bytes", client->output->offset); str = t_str_new(128); - if (var_expand_new(str, client->set->pop3_logout_format, + if (var_expand(str, client->set->pop3_logout_format, ¶ms, &error) < 0) { e_error(client->event, "Failed to expand pop3_logout_format=%s: %s", diff --git a/src/pop3/pop3-commands.c b/src/pop3/pop3-commands.c index 8c6d9b3b98..09adba747d 100644 --- a/src/pop3/pop3-commands.c +++ b/src/pop3/pop3-commands.c @@ -7,7 +7,7 @@ #include "hash.h" #include "str.h" #include "strfuncs.h" -#include "var-expand-new.h" +#include "var-expand.h" #include "message-size.h" #include "mail-storage.h" #include "mail-storage-settings.h" @@ -680,7 +680,7 @@ pop3_get_uid(struct client *client, struct mail *mail, string_t *str, }; const char *error; - if (var_expand_new(str, client->mail_set->pop3_uidl_format, + if (var_expand(str, client->mail_set->pop3_uidl_format, ¶ms, &error) < 0) { e_error(client->event, "UIDL: Failed to expand pop3_uidl_format=%s: %s", diff --git a/src/pop3/pop3-settings.c b/src/pop3/pop3-settings.c index a2cf9b9978..70f2de6ba8 100644 --- a/src/pop3/pop3-settings.c +++ b/src/pop3/pop3-settings.c @@ -6,7 +6,7 @@ #include "service-settings.h" #include "mail-storage-settings.h" #include "pop3-settings.h" -#include "var-expand-new.h" +#include "var-expand.h" #include diff --git a/src/stats/stats-metrics.c b/src/stats/stats-metrics.c index 6cd13076e0..f9a50ca1eb 100644 --- a/src/stats/stats-metrics.c +++ b/src/stats/stats-metrics.c @@ -6,7 +6,7 @@ #include "str-sanitize.h" #include "stats-dist.h" #include "time-util.h" -#include "var-expand-new.h" +#include "var-expand.h" #include "event-filter.h" #include "event-exporter.h" #include "settings.h" @@ -603,7 +603,7 @@ label_by_mod_str(const struct stats_metric_settings_group_by *group_by, }, }; string_t *str = t_str_new(128); - if (var_expand_new(str, group_by->discrete_modifier, ¶ms, &error) < 0) { + if (var_expand(str, group_by->discrete_modifier, ¶ms, &error) < 0) { i_error("Failed to expand discrete modifier for %s: %s", group_by->field, error); } diff --git a/src/stats/stats-settings.c b/src/stats/stats-settings.c index b1a62e3923..66f8b223a4 100644 --- a/src/stats/stats-settings.c +++ b/src/stats/stats-settings.c @@ -8,7 +8,7 @@ #include "event-exporter.h" #include "array.h" #include "str.h" -#include "var-expand-new.h" +#include "var-expand.h" /* */ #include "event-filter.h" @@ -474,7 +474,7 @@ parse_metric_group_by_mod(pool_t pool, }; const char *error; string_t *str = t_str_new(128); - if (var_expand_new(str, group_by->discrete_modifier, &vparams, &error) < 0) { + if (var_expand(str, group_by->discrete_modifier, &vparams, &error) < 0) { *error_r = t_strdup_printf( "Failed to expand discrete modifier for %s: %s", group_by->field, error); diff --git a/src/submission/submission-client.c b/src/submission/submission-client.c index cf190c9130..9a7506c210 100644 --- a/src/submission/submission-client.c +++ b/src/submission/submission-client.c @@ -430,7 +430,7 @@ static const char *client_stats(struct client *client) event_add_int(client->event, "net_out_bytes", stats->output); str = t_str_new(128); - if (var_expand_new(str, client->set->submission_logout_format, + if (var_expand(str, client->set->submission_logout_format, ¶ms, &error) < 0) { e_error(client->event, "Failed to expand submission_logout_format=%s: %s",