static gboolean _load(PersistState *self, gboolean all_errors_are_fatal, gboolean load_all_entries) { FILE *persist_file; gboolean success = FALSE; persist_file = fopen(self->commited_filename, "r"); if (persist_file) { SerializeArchive *sa; gchar magic[4]; gint version; sa = serialize_file_archive_new(persist_file); serialize_read_blob(sa, magic, 4); if (memcmp(magic, "SLP", 3) != 0) { msg_error("Persistent configuration file is in invalid format, ignoring", NULL); success = all_errors_are_fatal ? FALSE : TRUE; goto close_and_exit; } version = magic[3] - '0'; if (version >= 2 && version <= 3) { success = _load_v23(self, version, sa); } else if (version == 4) { success = _load_v4(self, load_all_entries); } else { msg_error("Persistent configuration file has an unsupported major version, ignoring", evt_tag_int("version", version), NULL); success = TRUE; } close_and_exit: fclose(persist_file); serialize_archive_free(sa); } else { if (all_errors_are_fatal) { msg_error("Failed to open persist file!", evt_tag_str("filename", self->commited_filename), evt_tag_str("error", strerror(errno)), NULL); success = FALSE; } else success = TRUE; } return success; }
static gboolean _deserialize_ipv4(SerializeArchive *sa, GSockAddr **addr) { struct sockaddr_in sin; sin.sin_family = AF_INET; if (!serialize_read_blob(sa, (gchar *) &sin.sin_addr, sizeof(sin.sin_addr)) || !serialize_read_uint16(sa, &sin.sin_port)) return FALSE; *addr = g_sockaddr_inet_new2(&sin); return TRUE; }
static gboolean _deserialize_ipv6(SerializeArchive *sa, GSockAddr **addr) { gboolean result = FALSE; struct sockaddr_in6 sin6; sin6.sin6_family = AF_INET6; if (serialize_read_blob(sa, (gchar *) &sin6.sin6_addr, sizeof(sin6.sin6_addr)) && serialize_read_uint16(sa, &sin6.sin6_port)) { *addr = g_sockaddr_inet6_new2(&sin6); result = TRUE; } return result; }
static gboolean _deserialize_blob_v22(SerializeArchive *sa, NVTable *self, gchar *table_top, gboolean different_endianness) { GString *old_nvtable_payload; gchar *current_payload_pointer = table_top; int i; NVIndexEntry *dyn_entries; if (!self->used) return TRUE; old_nvtable_payload = g_string_sized_new(self->used); old_nvtable_payload->len = self->used; if (!serialize_read_blob(sa, old_nvtable_payload->str, self->used)) { g_string_free(old_nvtable_payload, TRUE); return FALSE; } /* * Iterate through all NVEntries and convert them. We should update * their offset, too. We do not need to iterate them in order, we * will simply copy them to the new place linearly. The only problem * is that the indirect/direct use-case should be resolved * correctly. */ for (i = 0; i < self->num_static_entries; i++) { guint32 old_entry_offset = self->static_entries[i]; if (old_entry_offset != 0) { NVEntry *new_entry = _deserialize_old_entry(old_nvtable_payload, old_entry_offset, current_payload_pointer, different_endianness); self->static_entries[i] = (guint32)(table_top - (gchar *)new_entry); current_payload_pointer = current_payload_pointer - new_entry->alloc_len; } } dyn_entries = nv_table_get_index(self); for (i = 0; i < self->index_size; i++) { NVIndexEntry *dynvalue = &dyn_entries[i]; guint32 old_entry_offset = dynvalue->ofs; NVEntry *new_entry = _deserialize_old_entry(old_nvtable_payload, old_entry_offset, current_payload_pointer, different_endianness); dynvalue->ofs = (guint32) (table_top - (gchar *) new_entry); current_payload_pointer = current_payload_pointer - new_entry->alloc_len; } self->used = table_top - current_payload_pointer; g_string_free(old_nvtable_payload, TRUE); return TRUE; }
static inline gboolean _read_payload(SerializeArchive *sa, NVTable *res) { return serialize_read_blob(sa, NV_TABLE_ADDR(res, res->size - res->used), res->used); }