diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/fuzzy_storage.h | 3 | ||||
-rw-r--r-- | src/libserver/fuzzy_backend.c | 64 |
2 files changed, 64 insertions, 3 deletions
diff --git a/src/fuzzy_storage.h b/src/fuzzy_storage.h index 037f21a79..783280fc0 100644 --- a/src/fuzzy_storage.h +++ b/src/fuzzy_storage.h @@ -24,7 +24,8 @@ struct legacy_fuzzy_cmd { struct rspamd_fuzzy_cmd { guint8 version; guint8 cmd; - guint16 shingles_count; + guint8 shingles_count; + guint8 flag; gchar digest[64]; }; diff --git a/src/libserver/fuzzy_backend.c b/src/libserver/fuzzy_backend.c index 9bdf9fc1c..9ea44f56d 100644 --- a/src/libserver/fuzzy_backend.c +++ b/src/libserver/fuzzy_backend.c @@ -31,6 +31,13 @@ /* Magic sequence for hashes file */ #define FUZZY_FILE_MAGIC "rsh" +struct rspamd_legacy_fuzzy_node { + gint32 value; + gint32 flag; + guint64 time; + rspamd_fuzzy_t h; +}; + struct rspamd_fuzzy_backend { sqlite3 *db; const char *path; @@ -42,6 +49,59 @@ rspamd_fuzzy_backend_quark(void) return g_quark_from_static_string ("fuzzy-storage-backend"); } +/* + * Convert old database to the new format + */ +static gboolean +rspamd_fuzzy_backend_convert (const gchar *path, int fd, GError **err) +{ + gchar tmpdb[PATH_MAX]; + struct rspamd_fuzzy_backend *nbackend; + struct stat st; + gint off; + guint8 *map, *p, *end; + struct rspamd_legacy_fuzzy_node *n; + + rspamd_snprintf (tmpdb, sizeof (tmpdb), "%s.converted", path); + (void)unlink (tmpdb); + nbackend = rspamd_fuzzy_backend_create_db (tmpdb, FALSE, err); + + if (nbackend == NULL) { + return FALSE; + } + + (void)fstat (fd, &st); + (void)lseek (fd, 0, SEEK_SET); + + off = sizeof (FUZZY_FILE_MAGIC) - 1; + if ((map = mmap (NULL, st.st_size - off, PROT_READ, MAP_SHARED, fd, + off)) == MAP_FAILED) { + g_set_error (err, rspamd_fuzzy_backend_quark (), + errno, "Cannot mmap file %s: %s", + path, strerror (errno)); + + return FALSE; + } + + end = map + st.st_size - off; + p = map; + + while (p < end) { + n = (struct rspamd_legacy_fuzzy_node *)p; + /* Convert node */ + + p += sizeof (struct rspamd_legacy_fuzzy_node); + } + + munmap (map, st.st_size - off); + rspamd_fuzzy_backend_create_index (nbackend); + rspamd_fuzzy_backend_close (nbackend); + + rename (tmpdb, path); + + return TRUE; +} + struct rspamd_fuzzy_backend* rspamd_fuzzy_backend_open (const gchar *path, GError **err) { @@ -80,7 +140,7 @@ rspamd_fuzzy_backend_open (const gchar *path, GError **err) if ((r = read (fd, header, sizeof (header))) == sizeof (header)) { if (memcmp (header, FUZZY_FILE_MAGIC, sizeof (header) - 1) == 0) { msg_info ("Trying to convert old fuzzy database"); - if (!rspamd_fuzzy_backend_convert (fd, err)) { + if (!rspamd_fuzzy_backend_convert (path, fd, err)) { close (fd); return NULL; } @@ -92,7 +152,7 @@ rspamd_fuzzy_backend_open (const gchar *path, GError **err) if ((res = rspamd_fuzzy_backend_open_db (path, err)) == NULL) { GError *tmp = NULL; - if ((res = rspamd_fuzzy_backend_create_db (path, tmp)) == NULL) { + if ((res = rspamd_fuzzy_backend_create_db (path, TRUE, &tmp)) == NULL) { g_clear_error (err); g_propagate_error (err, tmp); return NULL; |