You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

lua_cfg_file.c 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*-
  2. * Copyright 2016 Vsevolod Stakhov
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "lua_common.h"
  17. #include "expression.h"
  18. #include "src/libserver/composites/composites.h"
  19. /*
  20. * This is implementation of lua routines to handle config file params
  21. */
  22. /* Process a single item in 'metrics' table */
  23. static void
  24. lua_process_metric (lua_State *L, const gchar *name, struct rspamd_config *cfg)
  25. {
  26. gchar *symbol;
  27. const gchar *desc = NULL;
  28. gdouble *score;
  29. struct rspamd_symbol *s;
  30. /* Now iterate through module table */
  31. for (lua_pushnil (L); lua_next (L, -2); lua_pop (L, 1)) {
  32. /* key - -2, value - -1 */
  33. symbol = rspamd_mempool_strdup (cfg->cfg_pool, luaL_checkstring (L, -2));
  34. if (symbol != NULL) {
  35. if (lua_istable (L, -1)) {
  36. /* We got a table, so extract individual attributes */
  37. lua_pushstring (L, "weight");
  38. lua_gettable (L, -2);
  39. if (lua_isnumber (L, -1)) {
  40. score = rspamd_mempool_alloc (cfg->cfg_pool, sizeof (double));
  41. *score = lua_tonumber (L, -1);
  42. }
  43. else {
  44. msg_warn_config("cannot get weight of symbol: %s", symbol);
  45. continue;
  46. }
  47. lua_pop (L, 1);
  48. lua_pushstring (L, "description");
  49. lua_gettable (L, -2);
  50. if (lua_isstring (L, -1)) {
  51. desc = lua_tostring (L, -1);
  52. }
  53. lua_pop (L, 1);
  54. }
  55. else if (lua_isnumber (L, -1)) {
  56. /* Just got weight */
  57. score = rspamd_mempool_alloc (cfg->cfg_pool, sizeof (double));
  58. *score = lua_tonumber (L, -1);
  59. }
  60. else {
  61. msg_warn_config("cannot get weight of symbol: %s", symbol);
  62. continue;
  63. }
  64. /* Insert symbol */
  65. if ((s =
  66. g_hash_table_lookup (cfg->symbols, symbol)) != NULL) {
  67. msg_info_config("replacing weight for symbol %s: %.2f -> %.2f",
  68. symbol,
  69. *s->weight_ptr,
  70. *score);
  71. s->weight_ptr = score;
  72. }
  73. else {
  74. s = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (*s));
  75. s->name = symbol;
  76. s->weight_ptr = score;
  77. g_hash_table_insert (cfg->symbols, symbol, s);
  78. }
  79. if (desc) {
  80. s->description = rspamd_mempool_strdup (cfg->cfg_pool, desc);
  81. }
  82. }
  83. }
  84. }
  85. /* Do post load initialization based on lua */
  86. void
  87. rspamd_lua_post_load_config (struct rspamd_config *cfg)
  88. {
  89. lua_State *L = cfg->lua_state;
  90. const gchar *name;
  91. ucl_object_t *obj;
  92. gsize keylen, i;
  93. /* First check all module options that may be overridden in 'config' global */
  94. lua_getglobal (L, "config");
  95. if (lua_istable (L, -1)) {
  96. /* Iterate to get all keys */
  97. GPtrArray *names = g_ptr_array_new_full (rspamd_lua_table_size (L, -1),
  98. g_free);
  99. for (lua_pushnil (L); lua_next (L, -2); lua_pop (L, 2)) {
  100. gchar *tmp;
  101. lua_pushvalue (L, -2);
  102. name = luaL_checklstring (L, -1, &keylen);
  103. if (name && lua_istable (L, -2)) {
  104. tmp = g_malloc (keylen + 1);
  105. rspamd_strlcpy (tmp, name, keylen + 1);
  106. g_ptr_array_add (names, tmp);
  107. }
  108. }
  109. PTR_ARRAY_FOREACH (names, i, name) {
  110. lua_getfield (L, -1, name);
  111. if (lua_istable (L, -1)) {
  112. obj = ucl_object_lua_import (L, lua_gettop (L));
  113. if (obj != NULL) {
  114. ucl_object_sort_keys (obj, UCL_SORT_KEYS_DEFAULT);
  115. ucl_object_insert_key_merged (cfg->rcl_obj,
  116. obj,
  117. name,
  118. strlen (name),
  119. true);
  120. }
  121. }
  122. }
  123. g_ptr_array_free (names, TRUE);
  124. }
  125. /* Check metrics settings */
  126. lua_getglobal (L, "metrics");
  127. if (lua_istable (L, -1)) {
  128. /* Iterate */
  129. for (lua_pushnil (L); lua_next (L, -2); lua_pop (L, 1)) {
  130. /* 'key' is at index -2 and 'value' is at index -1 */
  131. /* Key must be a string and value must be a table */
  132. name = luaL_checkstring (L, -2);
  133. if (name != NULL && lua_istable (L, -1)) {
  134. lua_process_metric (L, name, cfg);
  135. }
  136. }
  137. }
  138. lua_settop (L, 0);
  139. rspamd_lua_start_gc (cfg);
  140. }