#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
+#include <time.h>
#include <unistd.h>
#include <loc/libloc.h>
FILE* file;
unsigned int version;
+ time_t created_at;
off_t vendor;
off_t description;
db->ctx = loc_ref(ctx);
db->refcount = 1;
+ // Save creation time
+ db->created_at = time(NULL);
+
DEBUG(db->ctx, "Database allocated at %p\n", db);
// Create string pool
return NULL;
}
+LOC_EXPORT time_t loc_database_created_at(struct loc_database* db) {
+ return db->created_at;
+}
+
LOC_EXPORT const char* loc_database_get_vendor(struct loc_database* db) {
return loc_stringpool_get(db->pool, db->vendor);
}
}
// Copy over data
+ db->created_at = be64toh(header.created_at);
db->vendor = ntohl(header.vendor);
db->description = ntohl(header.description);
magic->version = htons(LOC_DATABASE_VERSION);
}
+static void loc_database_align_page_boundary(off_t* offset, FILE* f) {
+ // Move to next page boundary
+ while (*offset % LOC_DATABASE_PAGE_SIZE > 0)
+ *offset += fwrite("", 1, 1, f);
+}
+
+static int loc_database_write_pool(struct loc_database* db, struct loc_database_header_v0* header, off_t* offset, FILE* f) {
+ // Save the offset of the pool section
+ DEBUG(db->ctx, "Pool starts at %jd bytes\n", *offset);
+ header->pool_offset = htonl(*offset);
+
+ // Write the pool
+ size_t pool_length = loc_stringpool_write(db->pool, f);
+ *offset += pool_length;
+
+ DEBUG(db->ctx, "Pool has a length of %zu bytes\n", pool_length);
+ header->pool_length = htonl(pool_length);
+
+ return 0;
+}
+
+static int loc_database_write_as_section(struct loc_database* db,
+ struct loc_database_header_v0* header, off_t* offset, FILE* f) {
+ DEBUG(db->ctx, "AS section starts at %jd bytes\n", *offset);
+ header->as_offset = htonl(*offset);
+
+ size_t as_length = 0;
+
+ struct loc_database_as_v0 dbas;
+ for (unsigned int i = 0; i < db->as_count; i++) {
+ // Convert AS into database format
+ loc_as_to_database_v0(db->as[i], &dbas);
+
+ // Write to disk
+ offset += fwrite(&dbas, 1, sizeof(dbas), f);
+ as_length += sizeof(dbas);
+ }
+
+ DEBUG(db->ctx, "AS section has a length of %zu bytes\n", as_length);
+ header->as_length = htonl(as_length);
+
+ return 0;
+}
+
LOC_EXPORT int loc_database_write(struct loc_database* db, FILE* f) {
struct loc_database_magic magic;
loc_database_make_magic(db, &magic);
// Make the header
struct loc_database_header_v0 header;
+ header.created_at = htobe64(db->created_at);
header.vendor = htonl(db->vendor);
header.description = htonl(db->description);
}
offset += sizeof(header);
- // Write all ASes
- header.as_offset = htonl(offset);
-
- struct loc_database_as_v0 dbas;
- for (unsigned int i = 0; i < db->as_count; i++) {
- // Convert AS into database format
- loc_as_to_database_v0(db->as[i], &dbas);
-
- // Write to disk
- offset += fwrite(&dbas, 1, sizeof(dbas), f);
- }
- header.as_length = htonl(db->as_count * sizeof(dbas));
+ loc_database_align_page_boundary(&offset, f);
- // Move to next page boundary
- while (offset % LOC_DATABASE_PAGE_SIZE > 0)
- offset += fwrite("", 1, 1, f);
+ // Write all ASes
+ r = loc_database_write_as_section(db, &header, &offset, f);
+ if (r)
+ return r;
- // Save the offset of the pool section
- DEBUG(db->ctx, "Pool starts at %jd bytes\n", offset);
- header.pool_offset = htonl(offset);
+ loc_database_align_page_boundary(&offset, f);
- // Size of the pool
- size_t pool_length = loc_stringpool_write(db->pool, f);
- DEBUG(db->ctx, "Pool has a length of %zu bytes\n", pool_length);
- header.pool_length = htonl(pool_length);
+ // Write pool
+ r = loc_database_write_pool(db, &header, &offset, f);
+ if (r)
+ return r;
// Write the header
r = fseek(f, sizeof(magic), SEEK_SET);