static gboolean rspamd_symbols_cache_save_items (struct symbols_cache *cache, const gchar *name) { struct rspamd_symbols_cache_header hdr; ucl_object_t *top, *elt; GHashTableIter it; struct cache_item *item; struct ucl_emitter_functions *efunc; gpointer k, v; gint fd; bool ret; fd = open (name, O_CREAT | O_TRUNC | O_WRONLY, 00644); if (fd == -1) { msg_info ("cannot open file %s, error %d, %s", name, errno, strerror (errno)); return FALSE; } memset (&hdr, 0, sizeof (hdr)); memcpy (hdr.magic, rspamd_symbols_cache_magic, sizeof (rspamd_symbols_cache_magic)); if (write (fd, &hdr, sizeof (hdr)) == -1) { msg_info ("cannot write to file %s, error %d, %s", name, errno, strerror (errno)); close (fd); return FALSE; } top = ucl_object_typed_new (UCL_OBJECT); g_hash_table_iter_init (&it, cache->items_by_symbol); while (g_hash_table_iter_next (&it, &k, &v)) { item = v; elt = ucl_object_typed_new (UCL_OBJECT); ucl_object_insert_key (elt, ucl_object_fromdouble (item->weight), "weight", 0, false); ucl_object_insert_key (elt, ucl_object_fromdouble (item->avg_time), "time", 0, false); ucl_object_insert_key (elt, ucl_object_fromdouble (item->avg_counter), "count", 0, false); ucl_object_insert_key (elt, ucl_object_fromint (item->frequency), "frequency", 0, false); ucl_object_insert_key (top, elt, k, 0, false); } efunc = ucl_object_emit_fd_funcs (fd); ret = ucl_object_emit_full (top, UCL_EMIT_JSON_COMPACT, efunc); ucl_object_emit_funcs_free (efunc); close (fd); return ret; }
/** * Dump dynamic configuration to the disk * @param cfg * @return */ gboolean dump_dynamic_config (struct rspamd_config *cfg) { struct stat st; gchar *dir, pathbuf[PATH_MAX]; gint fd; if (cfg->dynamic_conf == NULL || cfg->current_dynamic_conf == NULL) { /* No dynamic conf has been specified, so do not try to dump it */ return FALSE; } dir = g_path_get_dirname (cfg->dynamic_conf); if (dir == NULL) { msg_err ("invalid path: %s", cfg->dynamic_conf); return FALSE; } if (stat (cfg->dynamic_conf, &st) == -1) { msg_debug ("%s is unavailable: %s", cfg->dynamic_conf, strerror (errno)); st.st_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; } if (access (dir, W_OK | R_OK) == -1) { msg_warn ("%s is inaccessible: %s", dir, strerror (errno)); g_free (dir); return FALSE; } rspamd_snprintf (pathbuf, sizeof (pathbuf), "%s%crconf-XXXXXX", dir, G_DIR_SEPARATOR); g_free (dir); #ifdef HAVE_MKSTEMP /* Umask is set before */ fd = mkstemp (pathbuf); #else fd = g_mkstemp_full (pathbuf, O_RDWR, S_IWUSR | S_IRUSR); #endif if (fd == -1) { msg_err ("mkstemp error: %s", strerror (errno)); return FALSE; } if (!ucl_object_emit_full (cfg->current_dynamic_conf, UCL_EMIT_JSON, ucl_object_emit_fd_funcs (fd))) { msg_err ("cannot emit ucl object: %s", strerror (errno)); close (fd); return FALSE; } (void)unlink (cfg->dynamic_conf); /* Rename old config */ if (rename (pathbuf, cfg->dynamic_conf) == -1) { msg_err ("rename error: %s", strerror (errno)); close (fd); unlink (pathbuf); return FALSE; } /* Set permissions */ if (chmod (cfg->dynamic_conf, st.st_mode) == -1) { msg_warn ("chmod failed: %s", strerror (errno)); } close (fd); return TRUE; }