From 5b3f77c7fbafb036d20a1577ed74f475e94ed821 Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Sat, 15 Dec 2007 01:03:17 +0000 Subject: [PATCH 1/1] Fix up dynamic loading; we export a structure of functions now from each of the backends, which means we can maintain unique namespaces. This should allow further cleanups/cunningness, but hopefully this is enough to get us operating correctly across all platforms to start with. --- Makefile.in | 3 +- add.c | 6 +- gpgwww.c | 19 ++- keyd.c | 16 +- keydb.c | 28 +-- keydb.h | 38 +++-- keydb_db4.c | 138 +++++++-------- keydb_dynamic.c | 440 +++++++++++++++++++++++------------------------- keydb_file.c | 39 +++-- keydb_fs.c | 53 ++++-- keydb_keyd.c | 41 +++-- keydb_pg.c | 45 +++-- keyindex.c | 3 +- lookup.c | 14 +- maxpath.c | 9 +- onak-conf.c | 4 + onak-conf.h | 4 + onak.c | 33 ++-- sixdegrees.c | 13 +- stats.c | 16 +- 20 files changed, 528 insertions(+), 434 deletions(-) diff --git a/Makefile.in b/Makefile.in index 4d551bc..a6c12c5 100644 --- a/Makefile.in +++ b/Makefile.in @@ -101,7 +101,8 @@ onak: onak.o cleankey.o $(CORE_OBJS) $(KEYDB_OBJ) $(CORE_OBJS) $(KEYDB_OBJ) $(LIBS) $(PROGS_LDFLAGS_EXTRA) onak-conf.o: onak-conf.c onak-conf.h - $(CC) $(CFLAGS) -DCONFIGFILE=\"@sysconfdir@/onak.conf\" -c onak-conf.c + $(CC) $(CFLAGS) -DCONFIGFILE=\"@sysconfdir@/onak.conf\" \ + -DDBFUNCS=keydb_@DBTYPE@_funcs -c onak-conf.c onak-mail.pl: onak-mail.pl.in sed 's:@CONFIG@:@sysconfdir@/onak.conf:g' < onak-mail.pl.in > onak-mail.pl diff --git a/add.c b/add.c index 167e5bd..3a9161f 100644 --- a/add.c +++ b/add.c @@ -76,13 +76,13 @@ int main(int argc, char *argv[]) fclose(stderr); } catchsignals(); - initdb(false); + config.dbbackend->initdb(false); count = cleankeys(keys); logthing(LOGTHING_INFO, "%d keys cleaned.", count); - count = update_keys(&keys, true); + count = config.dbbackend->update_keys(&keys, true); logthing(LOGTHING_NOTICE, "Got %d new keys.", count); @@ -91,7 +91,7 @@ int main(int argc, char *argv[]) keys = NULL; } - cleanupdb(); + config.dbbackend->cleanupdb(); } else { puts("No OpenPGP packets found in input."); end_html(); diff --git a/gpgwww.c b/gpgwww.c index 44c226c..984aab4 100644 --- a/gpgwww.c +++ b/gpgwww.c @@ -61,14 +61,14 @@ int getkeyspath(uint64_t have, uint64_t want, int count) int rec; int pathlen = 0; - fullhave = getfullkeyid(have); - fullwant = getfullkeyid(want); + fullhave = config.dbbackend->getfullkeyid(have); + fullwant = config.dbbackend->getfullkeyid(want); /* * Make sure the keys we have and want are in the cache. */ - cached_getkeysigs(fullhave); - cached_getkeysigs(fullwant); + config.dbbackend->cached_getkeysigs(fullhave); + config.dbbackend->cached_getkeysigs(fullwant); if ((keyinfoa = findinhash(fullhave)) == NULL) { return 1; @@ -93,9 +93,10 @@ int getkeyspath(uint64_t have, uint64_t want, int count) */ curkey = findinhash(keyinfoa->parent); while (curkey != NULL && curkey->keyid != 0) { - if (curkey->keyid != fullwant && fetch_key( + if (curkey->keyid != fullwant && + config.dbbackend->fetch_key( curkey->keyid, - &publickey, false)) { + &publickey, false)) { flatten_publickey(publickey, &packets, &list_end); @@ -114,7 +115,7 @@ int getkeyspath(uint64_t have, uint64_t want, int count) /* * Add the destination key to the list of returned keys. */ - if (fetch_key(fullwant, &publickey, false)) { + if (config.dbbackend->fetch_key(fullwant, &publickey, false)) { flatten_publickey(publickey, &packets, &list_end); @@ -168,7 +169,7 @@ int main(int argc, char *argv[]) readconfig(NULL); initlogthing("gpgwww", config.logfile); catchsignals(); - initdb(true); + config.dbbackend->initdb(true); inithash(); logthing(LOGTHING_NOTICE, "Looking for path from 0x%llX to 0x%llX.", from, @@ -179,7 +180,7 @@ int main(int argc, char *argv[]) dofindpath(from, to, true, 3); } destroyhash(); - cleanupdb(); + config.dbbackend->cleanupdb(); cleanuplogthing(); cleanupconfig(); diff --git a/keyd.c b/keyd.c index f8f5d4a..d6abd32 100644 --- a/keyd.c +++ b/keyd.c @@ -137,6 +137,7 @@ int sock_do(int fd) logthing(LOGTHING_INFO, "Fetching 0x%llX, result: %d", keyid, + config.dbbackend-> fetch_key(keyid, &key, false)); if (key != NULL) { storebuf.size = 8192; @@ -184,6 +185,7 @@ int sock_do(int fd) logthing(LOGTHING_INFO, "Fetching %s, result: %d", search, + config.dbbackend-> fetch_key_text(search, &key)); if (key != NULL) { storebuf.size = 8192; @@ -244,7 +246,7 @@ int sock_do(int fd) &packets, 0); parse_keys(packets, &key); - store_key(key, false, false); + config.dbbackend->store_key(key, false, false); free_packet_list(packets); packets = NULL; free_publickey(key); @@ -265,7 +267,8 @@ int sock_do(int fd) logthing(LOGTHING_INFO, "Deleting 0x%llX, result: %d", keyid, - delete_key(keyid, false)); + config.dbbackend->delete_key( + keyid, false)); } break; case KEYD_CMD_GETFULLKEYID: @@ -276,14 +279,15 @@ int sock_do(int fd) ret = 1; } if (ret == 0) { - keyid = getfullkeyid(keyid); + keyid = config.dbbackend->getfullkeyid(keyid); write(fd, &keyid, sizeof(keyid)); } break; case KEYD_CMD_KEYITER: cmd = KEYD_REPLY_OK; write(fd, &cmd, sizeof(cmd)); - iterate_keys(iteratefunc, (void *) fd); + config.dbbackend->iterate_keys(iteratefunc, + (void *) fd); bytes = 0; write(fd, &bytes, sizeof(bytes)); break; @@ -348,7 +352,7 @@ int main(int argc, char *argv[]) FD_ZERO(&rfds); FD_SET(fd, &rfds); - initdb(false); + config.dbbackend->initdb(false); logthing(LOGTHING_NOTICE, "Accepting connections."); while (!cleanup() && select(fd + 1, &rfds, NULL, NULL, NULL) != -1) { @@ -356,7 +360,7 @@ int main(int argc, char *argv[]) sock_accept(fd); FD_SET(fd, &rfds); } - cleanupdb(); + config.dbbackend->cleanupdb(); sock_close(fd); unlink(sockname); } diff --git a/keydb.c b/keydb.c index 7d33108..339450b 100644 --- a/keydb.c +++ b/keydb.c @@ -31,14 +31,15 @@ * keyid2uid - Takes a keyid and returns the primary UID for it. * @keyid: The keyid to lookup. */ -char *keyid2uid(uint64_t keyid) +char *generic_keyid2uid(uint64_t keyid) { struct openpgp_publickey *publickey = NULL; struct openpgp_signedpacket_list *curuid = NULL; char buf[1024]; buf[0]=0; - if (fetch_key(keyid, &publickey, false) && publickey != NULL) { + if (config.dbbackend->fetch_key(keyid, &publickey, false) && + publickey != NULL) { curuid = publickey->uids; while (curuid != NULL && buf[0] == 0) { if (curuid->packet->tag == 13) { @@ -69,13 +70,13 @@ char *keyid2uid(uint64_t keyid) * indexing and doing stats bits. If revoked is non-NULL then if the key * is revoked it's set to true. */ -struct ll *getkeysigs(uint64_t keyid, bool *revoked) +struct ll *generic_getkeysigs(uint64_t keyid, bool *revoked) { struct ll *sigs = NULL; struct openpgp_signedpacket_list *uids = NULL; struct openpgp_publickey *publickey = NULL; - fetch_key(keyid, &publickey, false); + config.dbbackend->fetch_key(keyid, &publickey, false); if (publickey != NULL) { for (uids = publickey->uids; uids != NULL; uids = uids->next) { @@ -99,7 +100,7 @@ struct ll *getkeysigs(uint64_t keyid, bool *revoked) * getkeysigs function above except we use the hash module to cache the * data so if we need it again it's already loaded. */ -struct ll *cached_getkeysigs(uint64_t keyid) +struct ll *generic_cached_getkeysigs(uint64_t keyid) { struct stats_key *key = NULL; struct stats_key *signedkey = NULL; @@ -113,7 +114,7 @@ struct ll *cached_getkeysigs(uint64_t keyid) key = createandaddtohash(keyid); if (key->gotsigs == false) { - key->sigs = getkeysigs(key->keyid, &revoked); + key->sigs = config.dbbackend->getkeysigs(key->keyid, &revoked); key->revoked = revoked; for (cursig = key->sigs; cursig != NULL; cursig = cursig->next) { @@ -134,12 +135,12 @@ struct ll *cached_getkeysigs(uint64_t keyid) * This function maps a 32bit key id to the full 64bit one. It returns the * full keyid. If the key isn't found a keyid of 0 is returned. */ -uint64_t getfullkeyid(uint64_t keyid) +uint64_t generic_getfullkeyid(uint64_t keyid) { struct openpgp_publickey *publickey = NULL; if (keyid < 0x100000000LL) { - fetch_key(keyid, &publickey, false); + config.dbbackend->fetch_key(keyid, &publickey, false); if (publickey != NULL) { keyid = get_keyid(publickey); free_publickey(publickey); @@ -165,7 +166,7 @@ uint64_t getfullkeyid(uint64_t keyid) * we had before to what we have now (ie the set of data that was added to * the DB). Returns the number of entirely new keys added. */ -int update_keys(struct openpgp_publickey **keys, bool sendsync) +int generic_update_keys(struct openpgp_publickey **keys, bool sendsync) { struct openpgp_publickey *curkey = NULL; struct openpgp_publickey *oldkey = NULL; @@ -174,11 +175,12 @@ int update_keys(struct openpgp_publickey **keys, bool sendsync) bool intrans; for (curkey = *keys; curkey != NULL; curkey = curkey->next) { - intrans = starttrans(); + intrans = config.dbbackend->starttrans(); logthing(LOGTHING_INFO, "Fetching key 0x%llX, result: %d", get_keyid(curkey), - fetch_key(get_keyid(curkey), &oldkey, intrans)); + config.dbbackend->fetch_key(get_keyid(curkey), &oldkey, + intrans)); /* * If we already have the key stored in the DB then merge it @@ -210,10 +212,10 @@ int update_keys(struct openpgp_publickey **keys, bool sendsync) } else { logthing(LOGTHING_INFO, "Storing completely new key."); - store_key(curkey, intrans, false); + config.dbbackend->store_key(curkey, intrans, false); newkeys++; } - endtrans(); + config.dbbackend->endtrans(); intrans = false; } diff --git a/keydb.h b/keydb.h index 4406223..b3be902 100644 --- a/keydb.h +++ b/keydb.h @@ -14,6 +14,10 @@ #include "keystructs.h" #include "ll.h" +/** + * struct dbfuncs - All of the functions a DB backend exports. + */ +struct dbfuncs { /** * initdb - Initialize the key database. * @readonly: If we'll only be reading the DB, not writing to it. @@ -22,7 +26,7 @@ * this file are called in order to allow the DB to be initialized ready * for access. */ -void initdb(bool readonly); + void (*initdb)(bool readonly); /** * cleanupdb - De-initialize the key database. @@ -30,7 +34,7 @@ void initdb(bool readonly); * This function should be called upon program exit to allow the DB to * cleanup after itself. */ -void cleanupdb(void); + void (*cleanupdb)(void); /** * starttrans - Start a transaction. @@ -39,14 +43,14 @@ void cleanupdb(void); * operations on the database to help speed it all up, or if we want * something to only succeed if all relevant operations are successful. */ -bool starttrans(void); + bool (*starttrans)(void); /** * endtrans - End a transaction. * * Ends a transaction. */ -void endtrans(void); + void (*endtrans)(void); /** * fetch_key - Given a keyid fetch the key from storage. @@ -59,7 +63,8 @@ void endtrans(void); * * TODO: What about keyid collisions? Should we use fingerprint instead? */ -int fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, bool intrans); + int (*fetch_key)(uint64_t keyid, struct openpgp_publickey **publickey, + bool intrans); /** * store_key - Takes a key and stores it. @@ -75,7 +80,8 @@ int fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, bool intrans * TODO: Do we store multiple keys of the same id? Or only one and replace * it? */ -int store_key(struct openpgp_publickey *publickey, bool intrans, bool update); + int (*store_key)(struct openpgp_publickey *publickey, bool intrans, + bool update); /** * delete_key - Given a keyid delete the key from storage. @@ -85,7 +91,7 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, bool update); * This function deletes a public key from whatever storage mechanism we * are using. Returns 0 if the key existed. */ -int delete_key(uint64_t keyid, bool intrans); + int (*delete_key)(uint64_t keyid, bool intrans); /** * fetch_key_text - Trys to find the keys that contain the supplied text. @@ -95,7 +101,8 @@ int delete_key(uint64_t keyid, bool intrans); * This function searches for the supplied text and returns the keys that * contain it. */ -int fetch_key_text(const char *search, struct openpgp_publickey **publickey); + int (*fetch_key_text)(const char *search, + struct openpgp_publickey **publickey); /** * update_keys - Takes a list of public keys and updates them in the DB. @@ -111,7 +118,7 @@ int fetch_key_text(const char *search, struct openpgp_publickey **publickey); * If sendsync is true then we send out a keysync mail to our sync peers * with the update. */ -int update_keys(struct openpgp_publickey **keys, bool sendsync); + int (*update_keys)(struct openpgp_publickey **keys, bool sendsync); /** * keyid2uid - Takes a keyid and returns the primary UID for it. @@ -120,7 +127,7 @@ int update_keys(struct openpgp_publickey **keys, bool sendsync); * This function returns a UID for the given key. Returns NULL if the key * isn't found. */ -char *keyid2uid(uint64_t keyid); + char * (*keyid2uid)(uint64_t keyid); /** * getkeysigs - Gets a linked list of the signatures on a key. @@ -131,7 +138,7 @@ char *keyid2uid(uint64_t keyid); * indexing and doing stats bits. If revoked is non-NULL then if the key * is revoked it's set to true. */ -struct ll *getkeysigs(uint64_t keyid, bool *revoked); + struct ll * (*getkeysigs)(uint64_t keyid, bool *revoked); /** * cached_getkeysigs - Gets the signatures on a key. @@ -140,7 +147,7 @@ struct ll *getkeysigs(uint64_t keyid, bool *revoked); * This function gets the signatures on a key. It's the same as the * getkeysigs function above except we use the hash module to cache the */ -struct ll *cached_getkeysigs(uint64_t keyid); + struct ll * (*cached_getkeysigs)(uint64_t keyid); /** * getfullkeyid - Maps a 32bit key id to a 64bit one. @@ -149,7 +156,7 @@ struct ll *cached_getkeysigs(uint64_t keyid); * This function maps a 32bit key id to the full 64bit one. It returns the * full keyid. If the key isn't found a keyid of 0 is returned. */ -uint64_t getfullkeyid(uint64_t keyid); + uint64_t (*getfullkeyid)(uint64_t keyid); /** * iterate_keys - call a function once for each key in the db. @@ -162,7 +169,8 @@ uint64_t getfullkeyid(uint64_t keyid); * * Returns the number of keys we iterated over. */ -int iterate_keys(void (*iterfunc)(void *ctx, struct openpgp_publickey *key), - void *ctx); + int (*iterate_keys)(void (*iterfunc)(void *ctx, + struct openpgp_publickey *key), void *ctx); +}; #endif /* __KEYDB_H__ */ diff --git a/keydb_db4.c b/keydb_db4.c index 80397aa..2f6033a 100644 --- a/keydb_db4.c +++ b/keydb_db4.c @@ -69,6 +69,59 @@ DB *keydb(uint64_t keyid) return(dbconns[keytrun % numdbs]); } +/** + * starttrans - Start a transaction. + * + * Start a transaction. Intended to be used if we're about to perform many + * operations on the database to help speed it all up, or if we want + * something to only succeed if all relevant operations are successful. + */ +static bool db4_starttrans(void) +{ + int ret; + + log_assert(dbenv != NULL); + log_assert(txn == NULL); + + ret = dbenv->txn_begin(dbenv, + NULL, /* No parent transaction */ + &txn, + 0); + if (ret != 0) { + logthing(LOGTHING_CRITICAL, + "Error starting transaction: %s", + db_strerror(ret)); + exit(1); + } + + return true; +} + +/** + * endtrans - End a transaction. + * + * Ends a transaction. + */ +static void db4_endtrans(void) +{ + int ret; + + log_assert(dbenv != NULL); + log_assert(txn != NULL); + + ret = txn->commit(txn, + 0); + if (ret != 0) { + logthing(LOGTHING_CRITICAL, + "Error ending transaction: %s", + db_strerror(ret)); + exit(1); + } + txn = NULL; + + return; +} + /** * initdb - Initialize the key database. * @@ -76,7 +129,7 @@ DB *keydb(uint64_t keyid) * this file are called in order to allow the DB to be initialized ready * for access. */ -void initdb(bool readonly) +static void db4_initdb(bool readonly) { char buf[1024]; FILE *numdb = NULL; @@ -150,7 +203,7 @@ void initdb(bool readonly) } if (ret == 0) { - starttrans(); + db4_starttrans(); for (i = 0; !ret && i < numdbs; i++) { ret = db_create(&dbconns[i], dbenv, 0); @@ -252,7 +305,7 @@ void initdb(bool readonly) * This function should be called upon program exit to allow the DB to * cleanup after itself. */ -void cleanupdb(void) +static void db4_cleanupdb(void) { int i = 0; @@ -279,59 +332,6 @@ void cleanupdb(void) } } -/** - * starttrans - Start a transaction. - * - * Start a transaction. Intended to be used if we're about to perform many - * operations on the database to help speed it all up, or if we want - * something to only succeed if all relevant operations are successful. - */ -bool starttrans(void) -{ - int ret; - - log_assert(dbenv != NULL); - log_assert(txn == NULL); - - ret = dbenv->txn_begin(dbenv, - NULL, /* No parent transaction */ - &txn, - 0); - if (ret != 0) { - logthing(LOGTHING_CRITICAL, - "Error starting transaction: %s", - db_strerror(ret)); - exit(1); - } - - return true; -} - -/** - * endtrans - End a transaction. - * - * Ends a transaction. - */ -void endtrans(void) -{ - int ret; - - log_assert(dbenv != NULL); - log_assert(txn != NULL); - - ret = txn->commit(txn, - 0); - if (ret != 0) { - logthing(LOGTHING_CRITICAL, - "Error ending transaction: %s", - db_strerror(ret)); - exit(1); - } - txn = NULL; - - return; -} - /** * fetch_key - Given a keyid fetch the key from storage. * @keyid: The keyid to fetch. @@ -344,7 +344,7 @@ void endtrans(void) * in and then parse_keys() to parse the packets into a publickey * structure. */ -int fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, +static int db4_fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, bool intrans) { struct openpgp_packet_list *packets = NULL; @@ -367,7 +367,7 @@ int fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, key.data = &keyid; if (!intrans) { - starttrans(); + db4_starttrans(); } ret = keydb(keyid)->get(keydb(keyid), @@ -412,7 +412,8 @@ int worddb_cmp(const void *d1, const void *d2) * This function searches for the supplied text and returns the keys that * contain it. */ -int fetch_key_text(const char *search, struct openpgp_publickey **publickey) +static int db4_fetch_key_text(const char *search, + struct openpgp_publickey **publickey) { DBC *cursor = NULL; DBT key, data; @@ -431,7 +432,7 @@ int fetch_key_text(const char *search, struct openpgp_publickey **publickey) wordlist = makewordlist(wordlist, searchtext); for (curword = wordlist; curword != NULL; curword = curword->next) { - starttrans(); + db4_starttrans(); ret = worddb->cursor(worddb, txn, @@ -485,7 +486,7 @@ int fetch_key_text(const char *search, struct openpgp_publickey **publickey) llfree(wordlist, NULL); wordlist = NULL; - starttrans(); + db4_starttrans(); for (i = 0; i < keylist.count; i++) { numkeys += fetch_key(keylist.keys[i], publickey, @@ -512,7 +513,8 @@ int fetch_key_text(const char *search, struct openpgp_publickey **publickey) * the file. If update is true then we delete the old key first, otherwise * we trust that it doesn't exist. */ -int store_key(struct openpgp_publickey *publickey, bool intrans, bool update) +static int db4_store_key(struct openpgp_publickey *publickey, bool intrans, + bool update) { struct openpgp_packet_list *packets = NULL; struct openpgp_packet_list *list_end = NULL; @@ -535,7 +537,7 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, bool update) keyid = get_keyid(publickey); if (!intrans) { - starttrans(); + db4_starttrans(); } /* @@ -739,7 +741,7 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, bool update) * This function deletes a public key from whatever storage mechanism we * are using. Returns 0 if the key existed. */ -int delete_key(uint64_t keyid, bool intrans) +static int db4_delete_key(uint64_t keyid, bool intrans) { struct openpgp_publickey *publickey = NULL; DBT key, data; @@ -756,7 +758,7 @@ int delete_key(uint64_t keyid, bool intrans) bool deadlock = false; if (!intrans) { - starttrans(); + db4_starttrans(); } fetch_key(keyid, &publickey, true); @@ -954,8 +956,8 @@ int delete_key(uint64_t keyid, bool intrans) * * Returns the number of keys we iterated over. */ -int iterate_keys(void (*iterfunc)(void *ctx, struct openpgp_publickey *key), - void *ctx) +static int db4_iterate_keys(void (*iterfunc)(void *ctx, + struct openpgp_publickey *key), void *ctx) { DBT dbkey, data; DBC *cursor = NULL; @@ -1016,7 +1018,7 @@ int iterate_keys(void (*iterfunc)(void *ctx, struct openpgp_publickey *key), * This function maps a 32bit key id to the full 64bit one. It returns the * full keyid. If the key isn't found a keyid of 0 is returned. */ -uint64_t getfullkeyid(uint64_t keyid) +static uint64_t db4_getfullkeyid(uint64_t keyid) { DBT key, data; DBC *cursor = NULL; diff --git a/keydb_dynamic.c b/keydb_dynamic.c index 49d77b8..503f1bf 100644 --- a/keydb_dynamic.c +++ b/keydb_dynamic.c @@ -6,37 +6,43 @@ * Copyright 2005 Project Purple */ +#include #include +#include #include "decodekey.h" #include "hash.h" #include "keydb.h" #include "keyid.h" #include "keystructs.h" +#include "log.h" #include "mem.h" #include "merge.h" +#include "onak-conf.h" #include "parsekey.h" #include "sendsync.h" -#include "keydb_dynamic.h" -struct dynamic_backend *get_backend(void) -{ - return &__dynamicdb_backend__; -} +static struct dbfuncs *loaded_backend = NULL; +static char *backendsoname; +static void *backend_handle; -bool backend_loaded(void) +static bool close_backend(void) { - return __dynamicdb_backend__.loaded; + loaded_backend = NULL; + dlclose(backend_handle); + backend_handle = NULL; + + return true; } -bool load_backend(void) +static bool load_backend(void) { char *soname = NULL; - void *handle; - struct dynamic_backend *backend = get_backend(); + char *funcsname = NULL; - if (backend->loaded) { + if (loaded_backend != NULL) { close_backend(); + loaded_backend = NULL; } if (!config.db_backend) { @@ -64,8 +70,8 @@ bool load_backend(void) logthing(LOGTHING_INFO, "Loading dynamic backend: %s", soname); - handle = dlopen(soname, RTLD_LAZY); - if (handle == NULL) { + backend_handle = dlopen(soname, RTLD_LAZY); + if (backend_handle == NULL) { logthing(LOGTHING_CRITICAL, "Failed to open handle to library '%s': %s", soname, dlerror()); @@ -73,83 +79,174 @@ bool load_backend(void) soname = NULL; exit(EXIT_FAILURE); } + + funcsname = malloc(strlen(config.db_backend) + + strlen("keydb_") + + strlen("_funcs") + + 1); + sprintf(funcsname, "keydb_%s_funcs", config.db_backend); + + loaded_backend = dlsym(backend_handle, funcsname); + free(funcsname); + + if (loaded_backend == NULL) { + logthing(LOGTHING_CRITICAL, + "Failed to find dbfuncs structure in library " + "'%s' : %s", soname, dlerror()); + free(soname); + soname = NULL; + exit(EXIT_FAILURE); + } free(soname); soname = NULL; - backend->initdb = (initdbfunc_t) dlsym(handle, "initdb"); - backend->cleanupdb = (cleanupdbfunc_t) dlsym(handle, "cleanupdb"); - backend->starttrans = (starttransfunc_t) dlsym(handle, "starttrans"); - backend->endtrans = (endtransfunc_t) dlsym(handle, "endtrans"); - backend->fetch_key = (fetch_keyfunc_t) dlsym(handle, "fetch_key"); - backend->store_key = (store_keyfunc_t) dlsym(handle, "store_key"); - backend->delete_key = (delete_keyfunc_t) dlsym(handle, "delete_key"); - backend->fetch_key_text = (fetch_key_textfunc_t) - dlsym (handle, "fetch_key_text"); - backend->update_keys = (update_keysfunc_t) - dlsym(handle, "update_keys"); - backend->keyid2uid = (keyid2uidfunc_t) dlsym(handle, "keyid2uid"); - backend->cached_getkeysigs = (cached_getkeysigsfunc_t) - dlsym(handle, "cached_getkeysigs"); - backend->getfullkeyid = (getfullkeyidfunc_t) - dlsym(handle, "getfullkeyid"); - backend->iterate_keys = (iterate_keysfunc_t) - dlsym(handle, "iterate_keys"); - - backend->handle = handle; - backend->loaded = true; - return true; } -bool close_backend(void) +static bool dynamic_starttrans() { struct dynamic_backend *backend; - backend = get_backend(); + + if (loaded_backend == NULL) { + load_backend(); + } - backend->initdb = NULL; - backend->cleanupdb = NULL; - backend->starttrans = NULL; - backend->endtrans = NULL; - backend->fetch_key = NULL; - backend->store_key = NULL; - backend->delete_key = NULL; - backend->fetch_key_text = NULL; - backend->update_keys = NULL; - backend->keyid2uid = NULL; - backend->cached_getkeysigs = NULL; - backend->getfullkeyid = NULL; - backend->iterate_keys = NULL; - backend->loaded = false; - dlclose(backend->handle); - backend->handle = NULL; + if (loaded_backend != NULL) { + if (loaded_backend->starttrans != NULL) { + return loaded_backend->starttrans(); + } + } - return true; + return false; +} + +static void dynamic_endtrans() +{ + struct dynamic_backend *backend; + + if (loaded_backend == NULL) { + load_backend(); + } + + if (loaded_backend != NULL) { + if (loaded_backend->endtrans != NULL) { + loaded_backend->endtrans(); + } + } +} + +static int dynamic_fetch_key(uint64_t keyid, + struct openpgp_publickey **publickey, bool intrans) +{ + struct dynamic_backend *backend; + + if (loaded_backend == NULL) { + load_backend(); + } + + if (loaded_backend != NULL) { + if (loaded_backend->fetch_key != NULL) { + return loaded_backend->fetch_key(keyid,publickey,intrans); + } + } + + return -1; +} + +static int dynamic_store_key(struct openpgp_publickey *publickey, bool intrans, + bool update) +{ + struct dynamic_backend *backend; + + if (loaded_backend == NULL) { + load_backend(); + } + + if (loaded_backend != NULL) { + if (loaded_backend->store_key != NULL) { + return loaded_backend->store_key(publickey,intrans,update); + } + } + + return -1; +} + +static int dynamic_delete_key(uint64_t keyid, bool intrans) +{ + struct dynamic_backend *backend; + + if (loaded_backend == NULL) { + load_backend(); + } + + if (loaded_backend != NULL) { + if (loaded_backend->delete_key != NULL) { + return loaded_backend->delete_key(keyid, intrans); + } + } + + return -1; +} + +static int dynamic_fetch_key_text(const char *search, + struct openpgp_publickey **publickey) +{ + struct dynamic_backend *backend; + + if (loaded_backend == NULL) { + load_backend(); + } + + if (loaded_backend != NULL) { + if (loaded_backend->fetch_key_text != NULL) { + return loaded_backend->fetch_key_text(search, publickey); + } + } + + return -1; +} + +static int dynamic_iterate_keys(void (*iterfunc)(void *ctx, + struct openpgp_publickey *key), void *ctx) +{ + struct dynamic_backend *backend; + + if (loaded_backend == NULL) { + load_backend(); + } + + if (loaded_backend != NULL) { + if (loaded_backend->iterate_keys != NULL) { + return loaded_backend->iterate_keys(iterfunc, ctx); + } + } + + return -1; } /** * keyid2uid - Takes a keyid and returns the primary UID for it. * @keyid: The keyid to lookup. */ -char *keyid2uid(uint64_t keyid) +static char *dynamic_keyid2uid(uint64_t keyid) { struct openpgp_publickey *publickey = NULL; struct openpgp_signedpacket_list *curuid = NULL; char buf[1024]; struct dynamic_backend *backend; - if (!backend_loaded()) { + if (loaded_backend == NULL) { load_backend(); } - if (backend_loaded()) { - backend = get_backend(); - if (backend->keyid2uid != NULL) { - return backend->keyid2uid(keyid); + if (loaded_backend != NULL) { + if (loaded_backend->keyid2uid != NULL) { + return loaded_backend->keyid2uid(keyid); } } buf[0]=0; - if (fetch_key(keyid, &publickey, false) && publickey != NULL) { + if (dynamic_fetch_key(keyid, &publickey, false) && publickey != NULL) { curuid = publickey->uids; while (curuid != NULL && buf[0] == 0) { if (curuid->packet->tag == 13) { @@ -178,25 +275,24 @@ char *keyid2uid(uint64_t keyid) * indexing and doing stats bits. If revoked is non-NULL then if the key * is revoked it's set to true. */ -struct ll *getkeysigs(uint64_t keyid, bool *revoked) +static struct ll *dynamic_getkeysigs(uint64_t keyid, bool *revoked) { struct ll *sigs = NULL; struct openpgp_signedpacket_list *uids = NULL; struct openpgp_publickey *publickey = NULL; struct dynamic_backend *backend; - if ( !backend_loaded() ) { + if ( loaded_backend == NULL ) { load_backend(); } - if (backend_loaded()) { - backend = get_backend(); - if (backend->getkeysigs != NULL) { - return backend->getkeysigs(keyid,revoked); + if (loaded_backend != NULL) { + if (loaded_backend->getkeysigs != NULL) { + return loaded_backend->getkeysigs(keyid,revoked); } } - fetch_key(keyid, &publickey, false); + dynamic_fetch_key(keyid, &publickey, false); if (publickey != NULL) { for (uids = publickey->uids; uids != NULL; uids = uids->next) { @@ -219,7 +315,7 @@ struct ll *getkeysigs(uint64_t keyid, bool *revoked) * getkeysigs function above except we use the hash module to cache the * data so if we need it again it's already loaded. */ -struct ll *cached_getkeysigs(uint64_t keyid) +static struct ll *dynamic_cached_getkeysigs(uint64_t keyid) { struct stats_key *key = NULL; struct stats_key *signedkey = NULL; @@ -232,21 +328,20 @@ struct ll *cached_getkeysigs(uint64_t keyid) return NULL; } - if (!backend_loaded()) { + if (loaded_backend == NULL) { load_backend(); } - if (backend_loaded()) { - backend = get_backend(); - if (backend->cached_getkeysigs != NULL) { - return backend->cached_getkeysigs(keyid); + if (loaded_backend != NULL) { + if (loaded_backend->cached_getkeysigs != NULL) { + return loaded_backend->cached_getkeysigs(keyid); } } key = createandaddtohash(keyid); if (key->gotsigs == false) { - key->sigs = getkeysigs(key->keyid, &revoked); + key->sigs = dynamic_getkeysigs(key->keyid, &revoked); key->revoked = revoked; for (cursig = key->sigs; cursig != NULL; cursig = cursig->next) { @@ -266,24 +361,23 @@ struct ll *cached_getkeysigs(uint64_t keyid) * This function maps a 32bit key id to the full 64bit one. It returns the * full keyid. If the key isn't found a keyid of 0 is returned. */ -uint64_t getfullkeyid(uint64_t keyid) +static uint64_t dynamic_getfullkeyid(uint64_t keyid) { struct openpgp_publickey *publickey = NULL; struct dynamic_backend *backend; - if (!backend_loaded()) { + if (loaded_backend == NULL) { load_backend(); } - if (backend_loaded()) { - backend = get_backend(); - if (backend->getfullkeyid != NULL) { - return backend->getfullkeyid(keyid); + if (loaded_backend != NULL) { + if (loaded_backend->getfullkeyid != NULL) { + return loaded_backend->getfullkeyid(keyid); } } if (keyid < 0x100000000LL) { - fetch_key(keyid, &publickey, false); + dynamic_fetch_key(keyid, &publickey, false); if (publickey != NULL) { keyid = get_keyid(publickey); free_publickey(publickey); @@ -307,7 +401,7 @@ uint64_t getfullkeyid(uint64_t keyid) * we had before to what we have now (ie the set of data that was added to * the DB). Returns the number of entirely new keys added. */ -int update_keys(struct openpgp_publickey **keys, bool sendsync) +static int dynamic_update_keys(struct openpgp_publickey **keys, bool sendsync) { struct openpgp_publickey *curkey = NULL; struct openpgp_publickey *oldkey = NULL; @@ -316,23 +410,22 @@ int update_keys(struct openpgp_publickey **keys, bool sendsync) int newkeys = 0; bool intrans; - if (!backend_loaded()) { + if (loaded_backend == NULL) { load_backend(); } - if (backend_loaded()) { - backend = get_backend(); - if (backend->update_keys != NULL) { - return backend->update_keys(keys, sendsync); + if (loaded_backend != NULL) { + if (loaded_backend->update_keys != NULL) { + return loaded_backend->update_keys(keys, sendsync); } } for (curkey = *keys; curkey != NULL; curkey = curkey->next) { - intrans = starttrans(); + intrans = dynamic_starttrans(); logthing(LOGTHING_INFO, "Fetching key 0x%llX, result: %d", get_keyid(curkey), - fetch_key(get_keyid(curkey), &oldkey, intrans)); + dynamic_fetch_key(get_keyid(curkey), &oldkey, intrans)); /* * If we already have the key stored in the DB then merge it @@ -357,7 +450,7 @@ int update_keys(struct openpgp_publickey **keys, bool sendsync) prev = curkey; logthing(LOGTHING_INFO, "Merged key; storing updated key."); - store_key(oldkey, intrans, true); + dynamic_store_key(oldkey, intrans, true); } free_publickey(oldkey); oldkey = NULL; @@ -365,10 +458,10 @@ int update_keys(struct openpgp_publickey **keys, bool sendsync) } else { logthing(LOGTHING_INFO, "Storing completely new key."); - store_key(curkey, intrans, false); + dynamic_store_key(curkey, intrans, false); newkeys++; } - endtrans(); + dynamic_endtrans(); intrans = false; } @@ -379,158 +472,47 @@ int update_keys(struct openpgp_publickey **keys, bool sendsync) return newkeys; } -void initdb(bool readonly) +static void dynamic_initdb(bool readonly) { struct dynamic_backend *backend; - backend = get_backend(); - if (!backend_loaded()) { + if (loaded_backend == NULL) { load_backend(); } - if (backend->loaded) { - if (backend->initdb != NULL) { - backend->initdb(readonly); + if (loaded_backend != NULL) { + if (loaded_backend->initdb != NULL) { + loaded_backend->initdb(readonly); } } } -void cleanupdb(void) +static void dynamic_cleanupdb(void) { struct dynamic_backend *backend; - backend = get_backend(); - if (backend->loaded) { - if (backend->cleanupdb != NULL) { - backend->cleanupdb(); + if (loaded_backend != NULL) { + if (loaded_backend->cleanupdb != NULL) { + loaded_backend->cleanupdb(); } } close_backend(); } -bool starttrans() -{ - struct dynamic_backend *backend; - backend = get_backend(); - - if (!backend_loaded()) { - load_backend(); - } - - if (backend->loaded) { - if (backend->starttrans != NULL) { - return backend->starttrans(); - } - } - - return false; -} - -void endtrans() -{ - struct dynamic_backend *backend; - backend = get_backend(); - - if (!backend_loaded()) { - load_backend(); - } - - if (backend->loaded) { - if (backend->endtrans != NULL) { - backend->endtrans(); - } - } -} - -int fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, - bool intrans) -{ - struct dynamic_backend *backend; - backend = get_backend(); - - if (!backend_loaded()) { - load_backend(); - } - - if (backend->loaded) { - if (backend->fetch_key != NULL) { - return backend->fetch_key(keyid,publickey,intrans); - } - } - - return -1; -} - -int store_key(struct openpgp_publickey *publickey, bool intrans, bool update) -{ - struct dynamic_backend *backend; - backend = get_backend(); - - if (!backend_loaded()) { - load_backend(); - } - - if (backend->loaded) { - if (backend->store_key != NULL) { - return backend->store_key(publickey,intrans,update); - } - } - - return -1; -} - -int delete_key(uint64_t keyid, bool intrans) -{ - struct dynamic_backend *backend; - backend = get_backend(); - - if (!backend_loaded()) { - load_backend(); - } - - if (backend->loaded) { - if (backend->delete_key != NULL) { - return backend->delete_key(keyid, intrans); - } - } - - return -1; -} - -int fetch_key_text(const char *search, struct openpgp_publickey **publickey) -{ - struct dynamic_backend *backend; - backend = get_backend(); - - if (!backend_loaded()) { - load_backend(); - } - - if (backend->loaded) { - if (backend->fetch_key_text != NULL) { - return backend->fetch_key_text(search, publickey); - } - } - - return -1; -} - -int iterate_keys(void (*iterfunc)(void *ctx, struct openpgp_publickey *key), - void *ctx) -{ - struct dynamic_backend *backend; - backend = get_backend(); - - if (!backend_loaded()) { - load_backend(); - } - - if (backend->loaded) { - if (backend->iterate_keys != NULL) { - return backend->iterate_keys(iterfunc, ctx); - } - } - - return -1; -} +struct dbfuncs keydb_dynamic_funcs = { + .initdb = dynamic_initdb, + .cleanupdb = dynamic_cleanupdb, + .starttrans = dynamic_starttrans, + .endtrans = dynamic_endtrans, + .fetch_key = dynamic_fetch_key, + .fetch_key_text = dynamic_fetch_key_text, + .store_key = dynamic_store_key, + .update_keys = dynamic_update_keys, + .delete_key = dynamic_delete_key, + .getkeysigs = dynamic_getkeysigs, + .cached_getkeysigs = dynamic_cached_getkeysigs, + .keyid2uid = dynamic_keyid2uid, + .getfullkeyid = dynamic_getfullkeyid, + .iterate_keys = dynamic_iterate_keys, +}; diff --git a/keydb_file.c b/keydb_file.c index a0c9032..88bb680 100644 --- a/keydb_file.c +++ b/keydb_file.c @@ -31,7 +31,7 @@ * * This is just a no-op for flat file access. */ -void initdb(bool readonly) +static void file_initdb(bool readonly) { } @@ -40,7 +40,7 @@ void initdb(bool readonly) * * This is just a no-op for flat file access. */ -void cleanupdb(void) +static void file_cleanupdb(void) { } @@ -49,7 +49,7 @@ void cleanupdb(void) * * This is just a no-op for flat file access. */ -bool starttrans(void) +static bool file_starttrans(void) { return true; } @@ -59,7 +59,7 @@ bool starttrans(void) * * This is just a no-op for flat file access. */ -void endtrans(void) +static void file_endtrans(void) { return; } @@ -76,7 +76,7 @@ void endtrans(void) * in and then parse_keys() to parse the packets into a publickey * structure. */ -int fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, +static int file_fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, bool intrans) { struct openpgp_packet_list *packets = NULL; @@ -109,7 +109,8 @@ int fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, * packets and then use write_openpgp_stream() to write the stream out to * the file. */ -int store_key(struct openpgp_publickey *publickey, bool intrans, bool update) +static int file_store_key(struct openpgp_publickey *publickey, bool intrans, + bool update) { struct openpgp_packet_list *packets = NULL; struct openpgp_packet_list *list_end = NULL; @@ -144,7 +145,7 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, bool update) * This function deletes a public key from whatever storage mechanism we * are using. Returns 0 if the key existed. */ -int delete_key(uint64_t keyid, bool intrans) +static int file_delete_key(uint64_t keyid, bool intrans) { char keyfile[1024]; @@ -164,7 +165,8 @@ int delete_key(uint64_t keyid, bool intrans) * * TODO: Write for flat file access. Some sort of grep? */ -int fetch_key_text(const char *search, struct openpgp_publickey **publickey) +static int file_fetch_key_text(const char *search, + struct openpgp_publickey **publickey) { return 0; } @@ -180,8 +182,8 @@ int fetch_key_text(const char *search, struct openpgp_publickey **publickey) * * Returns the number of keys we iterated over. */ -int iterate_keys(void (*iterfunc)(void *ctx, struct openpgp_publickey *key), - void *ctx) +static int file_iterate_keys(void (*iterfunc)(void *ctx, + struct openpgp_publickey *key), void *ctx) { int numkeys = 0; struct openpgp_packet_list *packets = NULL; @@ -236,3 +238,20 @@ int iterate_keys(void (*iterfunc)(void *ctx, struct openpgp_publickey *key), #define NEED_GETFULLKEYID 1 #define NEED_UPDATEKEYS 1 #include "keydb.c" + +struct dbfuncs keydb_file_funcs = { + .initdb = file_initdb, + .cleanupdb = file_cleanupdb, + .starttrans = file_starttrans, + .endtrans = file_endtrans, + .fetch_key = file_fetch_key, + .fetch_key_text = file_fetch_key_text, + .store_key = file_store_key, + .update_keys = generic_update_keys, + .delete_key = file_delete_key, + .getkeysigs = generic_getkeysigs, + .cached_getkeysigs = generic_cached_getkeysigs, + .keyid2uid = generic_keyid2uid, + .getfullkeyid = generic_getfullkeyid, + .iterate_keys = file_iterate_keys, +}; diff --git a/keydb_fs.c b/keydb_fs.c index 14220d1..bc3c890 100644 --- a/keydb_fs.c +++ b/keydb_fs.c @@ -54,7 +54,7 @@ static uint32_t calchash(uint8_t * ptr) } -void keypath(char *buffer, uint64_t _keyid) +static void keypath(char *buffer, uint64_t _keyid) { uint64_t keyid = _keyid << 32; snprintf(buffer, PATH_MAX, "%s/key/%02X/%02X/%08X/%016llX", @@ -63,7 +63,7 @@ void keypath(char *buffer, uint64_t _keyid) (uint32_t) (keyid >> 32), _keyid); } -void keydir(char *buffer, uint64_t _keyid) +static void keydir(char *buffer, uint64_t _keyid) { uint64_t keyid = _keyid << 32; snprintf(buffer, PATH_MAX, "%s/key/%02X/%02X/%08X", config.db_dir, @@ -72,7 +72,7 @@ void keydir(char *buffer, uint64_t _keyid) (uint32_t) (keyid >> 32)); } -void prove_path_to(uint64_t keyid, char *what) +static void prove_path_to(uint64_t keyid, char *what) { static char buffer[1024]; snprintf(buffer, PATH_MAX, "%s/%s", config.db_dir, what); @@ -93,21 +93,21 @@ void prove_path_to(uint64_t keyid, char *what) mkdir(buffer, 0777); } -void wordpath(char *buffer, char *word, uint32_t hash, uint64_t keyid) +static void wordpath(char *buffer, char *word, uint32_t hash, uint64_t keyid) { snprintf(buffer, PATH_MAX, "%s/words/%02X/%02X/%08X/%s/%016llX", config.db_dir, (uint8_t) ((hash >> 24) & 0xFF), (uint8_t) ((hash >> 16) & 0xFF), hash, word, keyid); } -void worddir(char *buffer, char *word, uint32_t hash) +static void worddir(char *buffer, char *word, uint32_t hash) { snprintf(buffer, PATH_MAX, "%s/words/%02X/%02X/%08X/%s", config.db_dir, (uint8_t) ((hash >> 24) & 0xFF), (uint8_t) ((hash >> 16) & 0xFF), hash, word); } -void subkeypath(char *buffer, uint64_t subkey, uint64_t keyid) +static void subkeypath(char *buffer, uint64_t subkey, uint64_t keyid) { snprintf(buffer, PATH_MAX, "%s/subkeys/%02X/%02X/%08X/%016llX", config.db_dir, @@ -117,7 +117,7 @@ void subkeypath(char *buffer, uint64_t subkey, uint64_t keyid) keyid); } -void subkeydir(char *buffer, uint64_t subkey) +static void subkeydir(char *buffer, uint64_t subkey) { snprintf(buffer, PATH_MAX, "%s/subkeys/%02X/%02X/%08X", config.db_dir, @@ -131,7 +131,7 @@ void subkeydir(char *buffer, uint64_t subkey) /** * initdb - Initialize the key database. */ -void initdb(bool readonly) +static void fs_initdb(bool readonly) { char buffer[PATH_MAX]; @@ -167,7 +167,7 @@ void initdb(bool readonly) /** * cleanupdb - De-initialize the key database. */ -void cleanupdb(void) +static void fs_cleanupdb(void) { /* Mmmm nothing to do here? */ close(keydb_lockfile_fd); @@ -176,7 +176,7 @@ void cleanupdb(void) /** * starttrans - Start a transaction. */ -bool starttrans(void) +static bool fs_starttrans(void) { struct flock lockstruct; int remaining = 20; @@ -197,7 +197,7 @@ bool starttrans(void) /** * endtrans - End a transaction. */ -void endtrans(void) +static void fs_endtrans(void) { struct flock lockstruct; @@ -214,7 +214,7 @@ void endtrans(void) * @publickey: A pointer to a structure to return the key in. * @intrans: If we're already in a transaction. */ -int fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, +static int fs_fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, bool intrans) { static char buffer[PATH_MAX]; @@ -249,7 +249,7 @@ int fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, * @intrans: If we're already in a transaction. * @update: If true the key exists and should be updated. */ -int store_key(struct openpgp_publickey *publickey, bool intrans, +static int fs_store_key(struct openpgp_publickey *publickey, bool intrans, bool update) { static char buffer[PATH_MAX]; @@ -328,7 +328,7 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, * @keyid: The keyid to delete. * @intrans: If we're already in a transaction. */ -int delete_key(uint64_t keyid, bool intrans) +static int fs_delete_key(uint64_t keyid, bool intrans) { static char buffer[PATH_MAX]; int ret; @@ -426,7 +426,7 @@ static struct ll *internal_get_key_by_word(char *word, struct ll *mct) * @search: The text to search for. * @publickey: A pointer to a structure to return the key in. */ -int fetch_key_text(const char *search, +static int fs_fetch_key_text(const char *search, struct openpgp_publickey **publickey) { struct ll *wordlist = NULL, *wl = NULL; @@ -485,7 +485,7 @@ int fetch_key_text(const char *search, return addedkeys; } -uint64_t getfullkeyid(uint64_t keyid) +static uint64_t fs_getfullkeyid(uint64_t keyid) { static char buffer[PATH_MAX]; DIR *d = NULL; @@ -534,8 +534,8 @@ uint64_t getfullkeyid(uint64_t keyid) * * Returns the number of keys we iterated over. */ -int iterate_keys(void (*iterfunc)(void *ctx, struct openpgp_publickey *key), - void *ctx) +static int fs_iterate_keys(void (*iterfunc)(void *ctx, + struct openpgp_publickey *key), void *ctx) { return 0; } @@ -547,3 +547,20 @@ int iterate_keys(void (*iterfunc)(void *ctx, struct openpgp_publickey *key), #define NEED_GETKEYSIGS 1 #define NEED_UPDATEKEYS 1 #include "keydb.c" + +struct dbfuncs keydb_fs_funcs = { + .initdb = fs_initdb, + .cleanupdb = fs_cleanupdb, + .starttrans = fs_starttrans, + .endtrans = fs_endtrans, + .fetch_key = fs_fetch_key, + .fetch_key_text = fs_fetch_key_text, + .store_key = fs_store_key, + .update_keys = generic_update_keys, + .delete_key = fs_delete_key, + .getkeysigs = generic_getkeysigs, + .cached_getkeysigs = generic_cached_getkeysigs, + .keyid2uid = generic_keyid2uid, + .getfullkeyid = fs_getfullkeyid, + .iterate_keys = fs_iterate_keys, +}; diff --git a/keydb_keyd.c b/keydb_keyd.c index 26cb326..32cf0f0 100644 --- a/keydb_keyd.c +++ b/keydb_keyd.c @@ -39,7 +39,7 @@ static int keyd_fd = -1; * this file are called in order to allow the DB to be initialized ready * for access. */ -void initdb(bool readonly) +static void keyd_initdb(bool readonly) { struct sockaddr_un sock; int cmd = KEYD_CMD_UNKNOWN; @@ -101,7 +101,7 @@ void initdb(bool readonly) * This function should be called upon program exit to allow the DB to * cleanup after itself. */ -void cleanupdb(void) +static void keyd_cleanupdb(void) { if (shutdown(keyd_fd, SHUT_RDWR) < 0) { logthing(LOGTHING_NOTICE, "Error shutting down socket: %d", @@ -120,7 +120,7 @@ void cleanupdb(void) * operations on the database to help speed it all up, or if we want * something to only succeed if all relevant operations are successful. */ -bool starttrans(void) +static bool keyd_starttrans(void) { return true; } @@ -130,7 +130,7 @@ bool starttrans(void) * * Ends a transaction. */ -void endtrans(void) +static void keyd_endtrans(void) { return; } @@ -146,7 +146,7 @@ void endtrans(void) * * TODO: What about keyid collisions? Should we use fingerprint instead? */ -int fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, +static int keyd_fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, bool intrans) { struct buffer_ctx keybuf; @@ -202,7 +202,8 @@ int fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, * TODO: Do we store multiple keys of the same id? Or only one and replace * it? */ -int store_key(struct openpgp_publickey *publickey, bool intrans, bool update) +static int keyd_store_key(struct openpgp_publickey *publickey, bool intrans, + bool update) { struct buffer_ctx keybuf; struct openpgp_packet_list *packets = NULL; @@ -254,7 +255,7 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, bool update) * This function deletes a public key from whatever storage mechanism we * are using. Returns 0 if the key existed. */ -int delete_key(uint64_t keyid, bool intrans) +static int keyd_delete_key(uint64_t keyid, bool intrans) { int cmd = KEYD_CMD_DELETE; @@ -275,7 +276,8 @@ int delete_key(uint64_t keyid, bool intrans) * This function searches for the supplied text and returns the keys that * contain it. */ -int fetch_key_text(const char *search, struct openpgp_publickey **publickey) +static int keyd_fetch_key_text(const char *search, + struct openpgp_publickey **publickey) { struct buffer_ctx keybuf; struct openpgp_packet_list *packets = NULL; @@ -327,7 +329,7 @@ int fetch_key_text(const char *search, struct openpgp_publickey **publickey) * This function maps a 32bit key id to the full 64bit one. It returns the * full keyid. If the key isn't found a keyid of 0 is returned. */ -uint64_t getfullkeyid(uint64_t keyid) +static uint64_t keyd_getfullkeyid(uint64_t keyid) { int cmd = KEYD_CMD_GETFULLKEYID; @@ -352,8 +354,8 @@ uint64_t getfullkeyid(uint64_t keyid) * * Returns the number of keys we iterated over. */ -int iterate_keys(void (*iterfunc)(void *ctx, struct openpgp_publickey *key), - void *ctx) +static int keyd_iterate_keys(void (*iterfunc)(void *ctx, + struct openpgp_publickey *key), void *ctx) { struct buffer_ctx keybuf; struct openpgp_packet_list *packets = NULL; @@ -410,3 +412,20 @@ int iterate_keys(void (*iterfunc)(void *ctx, struct openpgp_publickey *key), #define NEED_GETKEYSIGS 1 #define NEED_UPDATEKEYS 1 #include "keydb.c" + +struct dbfuncs keydb_keyd_funcs = { + .initdb = keyd_initdb, + .cleanupdb = keyd_cleanupdb, + .starttrans = keyd_starttrans, + .endtrans = keyd_endtrans, + .fetch_key = keyd_fetch_key, + .fetch_key_text = keyd_fetch_key_text, + .store_key = keyd_store_key, + .update_keys = generic_update_keys, + .delete_key = keyd_delete_key, + .getkeysigs = generic_getkeysigs, + .cached_getkeysigs = generic_cached_getkeysigs, + .keyid2uid = generic_keyid2uid, + .getfullkeyid = keyd_getfullkeyid, + .iterate_keys = keyd_iterate_keys, +}; diff --git a/keydb_pg.c b/keydb_pg.c index 5933c91..eee3bde 100644 --- a/keydb_pg.c +++ b/keydb_pg.c @@ -56,7 +56,7 @@ static int keydb_putchar(void *fd, size_t count, unsigned char *c) * this file are called in order to allow the DB to be initialized ready * for access. */ -void initdb(bool readonly) +static void pg_initdb(bool readonly) { dbconn = PQsetdbLogin(config.pg_dbhost, // host NULL, // port @@ -81,7 +81,7 @@ void initdb(bool readonly) * This function should be called upon program exit to allow the DB to * cleanup after itself. */ -void cleanupdb(void) +static void pg_cleanupdb(void) { PQfinish(dbconn); dbconn = NULL; @@ -94,7 +94,7 @@ void cleanupdb(void) * operations on the database to help speed it all up, or if we want * something to only succeed if all relevant operations are successful. */ -bool starttrans(void) +static bool pg_starttrans(void) { PGresult *result = NULL; @@ -109,7 +109,7 @@ bool starttrans(void) * * Ends a transaction. */ -void endtrans(void) +static void pg_endtrans(void) { PGresult *result = NULL; @@ -131,7 +131,7 @@ void endtrans(void) * in and then parse_keys() to parse the packets into a publickey * structure. */ -int fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, +static int pg_fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, bool intrans) { struct openpgp_packet_list *packets = NULL; @@ -200,7 +200,8 @@ int fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, * This function searches for the supplied text and returns the keys that * contain it. */ -int fetch_key_text(const char *search, struct openpgp_publickey **publickey) +static int pg_fetch_key_text(const char *search, + struct openpgp_publickey **publickey) { struct openpgp_packet_list *packets = NULL; PGresult *result = NULL; @@ -270,7 +271,8 @@ int fetch_key_text(const char *search, struct openpgp_publickey **publickey) * the file. If update is true then we delete the old key first, otherwise * we trust that it doesn't exist. */ -int store_key(struct openpgp_publickey *publickey, bool intrans, bool update) +static int pg_store_key(struct openpgp_publickey *publickey, bool intrans, + bool update) { struct openpgp_packet_list *packets = NULL; struct openpgp_packet_list *list_end = NULL; @@ -299,7 +301,7 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, bool update) * it definitely needs updated. */ if (update) { - delete_key(get_keyid(publickey), true); + pg_delete_key(get_keyid(publickey), true); } next = publickey->next; @@ -401,7 +403,7 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, bool update) * This function deletes a public key from whatever storage mechanism we * are using. Returns 0 if the key existed. */ -int delete_key(uint64_t keyid, bool intrans) +static int pg_delete_key(uint64_t keyid, bool intrans) { PGresult *result = NULL; char *oids = NULL; @@ -466,7 +468,7 @@ int delete_key(uint64_t keyid, bool intrans) * keyid2uid - Takes a keyid and returns the primary UID for it. * @keyid: The keyid to lookup. */ -char *keyid2uid(uint64_t keyid) +static char *pg_keyid2uid(uint64_t keyid) { PGresult *result = NULL; char statement[1024]; @@ -506,7 +508,7 @@ char *keyid2uid(uint64_t keyid) * This function gets the list of signatures on a key. Used for key * indexing and doing stats bits. */ -struct ll *getkeysigs(uint64_t keyid, bool *revoked) +static struct ll *pg_getkeysigs(uint64_t keyid, bool *revoked) { struct ll *sigs = NULL; PGresult *result = NULL; @@ -578,8 +580,8 @@ struct ll *getkeysigs(uint64_t keyid, bool *revoked) * * Returns the number of keys we iterated over. */ -int iterate_keys(void (*iterfunc)(void *ctx, struct openpgp_publickey *key), - void *ctx) +static int pg_iterate_keys(void (*iterfunc)(void *ctx, + struct openpgp_publickey *key), void *ctx) { struct openpgp_packet_list *packets = NULL; struct openpgp_publickey *key = NULL; @@ -632,3 +634,20 @@ int iterate_keys(void (*iterfunc)(void *ctx, struct openpgp_publickey *key), #define NEED_GETFULLKEYID 1 #define NEED_UPDATEKEYS 1 #include "keydb.c" + +struct dbfuncs keydb_pg_funcs = { + .initdb = pg_initdb, + .cleanupdb = pg_cleanupdb, + .starttrans = pg_starttrans, + .endtrans = pg_endtrans, + .fetch_key = pg_fetch_key, + .fetch_key_text = pg_fetch_key_text, + .store_key = pg_store_key, + .update_keys = generic_update_keys, + .delete_key = pg_delete_key, + .getkeysigs = pg_getkeysigs, + .cached_getkeysigs = generic_cached_getkeysigs, + .keyid2uid = pg_keyid2uid, + .getfullkeyid = generic_getfullkeyid, + .iterate_keys = pg_iterate_keys, +}; diff --git a/keyindex.c b/keyindex.c index 64c99a3..a4cc90b 100644 --- a/keyindex.c +++ b/keyindex.c @@ -21,6 +21,7 @@ #include "keyindex.h" #include "keystructs.h" #include "log.h" +#include "onak-conf.h" int list_sigs(struct openpgp_packet_list *sigs, bool html) { @@ -30,7 +31,7 @@ int list_sigs(struct openpgp_packet_list *sigs, bool html) while (sigs != NULL) { sigid = sig_keyid(sigs->packet); - uid = keyid2uid(sigid); + uid = config.dbbackend->keyid2uid(sigid); if (sigs->packet->data[0] == 4 && sigs->packet->data[1] == 0x30) { /* It's a Type 4 sig revocation */ diff --git a/lookup.c b/lookup.c index e5cd1ae..d48bc3f 100644 --- a/lookup.c +++ b/lookup.c @@ -40,9 +40,9 @@ void find_keys(char *search, uint64_t keyid, bool ishex, int count = 0; if (ishex) { - count = fetch_key(keyid, &publickey, false); + count = config.dbbackend->fetch_key(keyid, &publickey, false); } else { - count = fetch_key_text(search, &publickey); + count = config.dbbackend->fetch_key_text(search, &publickey); } if (publickey != NULL) { if (mrhkp) { @@ -159,12 +159,13 @@ int main(int argc, char *argv[]) readconfig(NULL); initlogthing("lookup", config.logfile); catchsignals(); - initdb(true); + config.dbbackend->initdb(true); switch (op) { case OP_GET: logthing(LOGTHING_NOTICE, "Getting keyid 0x%llX", keyid); - if (fetch_key(keyid, &publickey, false)) { + if (config.dbbackend->fetch_key(keyid, &publickey, + false)) { puts("
");
 				cleankeys(publickey);
 				flatten_publickey(publickey,
@@ -189,7 +190,8 @@ int main(int argc, char *argv[])
 					true, mrhkp);
 			break;
 		case OP_PHOTO:
-			if (fetch_key(keyid, &publickey, false)) {
+			if (config.dbbackend->fetch_key(keyid, &publickey,
+					false)) {
 				unsigned char *photo = NULL;
 				size_t         length = 0;
 
@@ -206,7 +208,7 @@ int main(int argc, char *argv[])
 		default:
 			puts("Unknown operation!");
 		}
-		cleanupdb();
+		config.dbbackend->cleanupdb();
 		cleanuplogthing();
 		cleanupconfig();
 	}
diff --git a/maxpath.c b/maxpath.c
index 191ce8a..b9ba53a 100644
--- a/maxpath.c
+++ b/maxpath.c
@@ -31,7 +31,7 @@ void findmaxpath(unsigned long max)
 	 * My (noodles@earth.li, DSA) key is in the strongly connected set of
 	 * keys, so we use it as a suitable starting seed.
 	 */
-	cached_getkeysigs(0xF1BD4BE45B430367);
+	config.dbbackend->cached_getkeysigs(0xF1BD4BE45B430367);
 
 	/*
 	 * Loop through the hash examining each key present and finding the
@@ -42,7 +42,8 @@ void findmaxpath(unsigned long max)
 	for (loop = 0; (loop < HASHSIZE) && (distance < max); loop++) {
 		curkey = gethashtableentry(loop);
 		while (curkey != NULL && distance < max) {
-			cached_getkeysigs(((struct stats_key *)
+			config.dbbackend->cached_getkeysigs(
+					((struct stats_key *)
 					curkey->object)->keyid);
 			initcolour(false);
 			tmp = furthestkey((struct stats_key *)
@@ -72,13 +73,13 @@ int main(int argc, char *argv[])
 {
 	readconfig(NULL);
 	initlogthing("maxpath", config.logfile);
-	initdb(true);
+	config.dbbackend->initdb(true);
 	inithash();
 	findmaxpath(30);
 	printf("--------\n");
 	findmaxpath(30);
 	destroyhash();
-	cleanupdb();
+	config.dbbackend->cleanupdb();
 	cleanuplogthing();
 	cleanupconfig();
 	
diff --git a/onak-conf.c b/onak-conf.c
index 0958502..70990f8 100644
--- a/onak-conf.c
+++ b/onak-conf.c
@@ -17,6 +17,8 @@
 #include "log.h"
 #include "onak-conf.h"
 
+extern struct dbfuncs DBFUNCS;
+
 /*
  *	config - Runtime configuration for onak.
  *
@@ -49,6 +51,8 @@ struct onak_config config = {
 	 */
 	NULL,			/* db_backend */
 	NULL,			/* backends_dir */
+
+	&DBFUNCS,		/* Default dbfuncs struct */
 };
 
 void readconfig(const char *configfile) {
diff --git a/onak-conf.h b/onak-conf.h
index 0a36c9a..11bdbdb 100644
--- a/onak-conf.h
+++ b/onak-conf.h
@@ -9,6 +9,8 @@
 #ifndef __ONAK_CONF_H_
 #define __ONAK_CONF_H_
 
+#include "keydb.h"
+
 /*
  *	struct onak_config - Runtime configuration for onak.
  *	@maxkeys: The maximum number of keys a query should return.
@@ -57,6 +59,8 @@ struct onak_config {
 	 */
 	char *db_backend;
 	char *backends_dir;
+
+	struct dbfuncs *dbbackend;
 };
 
 /*
diff --git a/onak.c b/onak.c
index 4e63720..3a6f62f 100644
--- a/onak.c
+++ b/onak.c
@@ -40,9 +40,9 @@ void find_keys(char *search, uint64_t keyid, bool ishex,
 	int count = 0;
 
 	if (ishex) {
-		count = fetch_key(keyid, &publickey, false);
+		count = config.dbbackend->fetch_key(keyid, &publickey, false);
 	} else {
-		count = fetch_key_text(search, &publickey);
+		count = config.dbbackend->fetch_key_text(search, &publickey);
 	}
 	if (publickey != NULL) {
 		key_index(publickey, verbose, fingerprint, false);
@@ -99,7 +99,7 @@ void usage(void) {
 	puts("\tCommands:\n");
 	puts("\tadd      - read armored OpenPGP keys from stdin and add to the"
 		" keyserver");
-	puts("\tclean    - read armored OpenPGP keys from stdin, run the "
+	puts("\tclean    - read armored OpenPGP keys from stdin, run the"
 		" cleaning\n\t       	   routines against them and dump to"
 		" stdout");
 	puts("\tdelete   - delete a given key from the keyserver");
@@ -159,17 +159,17 @@ int main(int argc, char *argv[])
 	if ((argc - optind) < 1) {
 		usage();
 	} else if (!strcmp("dump", argv[optind])) {
-		initdb(true);
+		config.dbbackend->initdb(true);
 		dumpstate.count = dumpstate.filenum = 0;
 		dumpstate.maxcount = 1000000;
 		dumpstate.fd = -1;
 		dumpstate.filebase = "keydump.%d.pgp";
-		iterate_keys(dump_func, &dumpstate);
+		config.dbbackend->iterate_keys(dump_func, &dumpstate);
 		if (dumpstate.fd != -1) {
 			close(dumpstate.fd);
 			dumpstate.fd = -1;
 		}
-		cleanupdb();
+		config.dbbackend->cleanupdb();
 	} else if (!strcmp("add", argv[optind])) {
 		if (binary) {
 			result = read_openpgp_stream(stdin_getchar, NULL,
@@ -190,9 +190,10 @@ int main(int argc, char *argv[])
 			logthing(LOGTHING_INFO, "%d keys cleaned.",
 					result);
 
-			initdb(false);
+			config.dbbackend->initdb(false);
 			logthing(LOGTHING_NOTICE, "Got %d new keys.",
-					update_keys(&keys, false));
+					config.dbbackend->update_keys(&keys,
+					false));
 			if (keys != NULL && update) {
 				flatten_publickey(keys,
 					&packets,
@@ -209,7 +210,7 @@ int main(int argc, char *argv[])
 				free_packet_list(packets);
 				packets = NULL;
 			}
-			cleanupdb();
+			config.dbbackend->cleanupdb();
 		} else {
 			rc = 1;
 			logthing(LOGTHING_NOTICE, "No keys read.");
@@ -279,7 +280,7 @@ int main(int argc, char *argv[])
 				ishex = true;
 			}
 		}
-		initdb(false);
+		config.dbbackend->initdb(false);
 		if (!strcmp("index", argv[optind])) {
 			find_keys(search, keyid, ishex, fingerprint,
 					false, false);
@@ -290,7 +291,8 @@ int main(int argc, char *argv[])
 			if (!ishex) {
 				puts("Can't get a key on uid text."
 					" You must supply a keyid.");
-			} else if (fetch_key(keyid, &keys, false)) {
+			} else if (config.dbbackend->fetch_key(keyid, &keys,
+					false)) {
 				unsigned char *photo = NULL;
 				size_t         length = 0;
 
@@ -306,12 +308,15 @@ int main(int argc, char *argv[])
 				puts("Key not found");
 			}
 		} else if (!strcmp("delete", argv[optind])) {
-			delete_key(getfullkeyid(keyid), false);
+			config.dbbackend->delete_key(
+					config.dbbackend->getfullkeyid(keyid),
+					false);
 		} else if (!strcmp("get", argv[optind])) {
 			if (!ishex) {
 				puts("Can't get a key on uid text."
 					" You must supply a keyid.");
-			} else if (fetch_key(keyid, &keys, false)) {
+			} else if (config.dbbackend->fetch_key(keyid, &keys,
+					false)) {
 				logthing(LOGTHING_INFO, "Got key.");
 				flatten_publickey(keys,
 						&packets,
@@ -326,7 +331,7 @@ int main(int argc, char *argv[])
 				puts("Key not found");
 			}
 		}
-		cleanupdb();
+		config.dbbackend->cleanupdb();
 	} else {
 		usage();
 	}
diff --git a/sixdegrees.c b/sixdegrees.c
index d7d650f..d4e55c1 100644
--- a/sixdegrees.c
+++ b/sixdegrees.c
@@ -30,7 +30,8 @@ unsigned long countdegree(struct stats_key *have, bool sigs, int maxdegree)
 
 	while (curll != NULL && curdegree <= maxdegree) {
 		if (sigs) {
-			sigll = cached_getkeysigs(((struct stats_key *)
+			sigll = config.dbbackend->cached_getkeysigs(
+				((struct stats_key *)
 				curll->object)->keyid);
 		} else {
 			sigll = NULL;
@@ -82,14 +83,14 @@ void sixdegrees(uint64_t keyid)
 	long degree;
 	char *uid;
 
-	cached_getkeysigs(keyid);
+	config.dbbackend->cached_getkeysigs(keyid);
 
 	if ((keyinfo = findinhash(keyid)) == NULL) {
 		printf("Couldn't find key 0x%llX.\n", keyid);
 		return;
 	}
 
-	uid = keyid2uid(keyinfo->keyid);
+	uid = config.dbbackend->keyid2uid(keyinfo->keyid);
 	printf("Six degrees for 0x%llX (%s):\n", keyinfo->keyid, uid);
 	free(uid);
 	uid = NULL;
@@ -127,11 +128,11 @@ int main(int argc, char *argv[])
 
 	readconfig(NULL);
 	initlogthing("sixdegrees", config.logfile);
-	initdb(true);
+	config.dbbackend->initdb(true);
 	inithash();
-	sixdegrees(getfullkeyid(keyid));
+	sixdegrees(config.dbbackend->getfullkeyid(keyid));
 	destroyhash();
-	cleanupdb();
+	config.dbbackend->cleanupdb();
 	cleanuplogthing();
 	cleanupconfig();
 
diff --git a/stats.c b/stats.c
index da1f13c..ca7c929 100644
--- a/stats.c
+++ b/stats.c
@@ -14,6 +14,7 @@
 #include "hash.h"
 #include "keydb.h"
 #include "ll.h"
+#include "onak-conf.h"
 #include "stats.h"
 
 /**
@@ -68,7 +69,7 @@ unsigned long findpath(struct stats_key *have, struct stats_key *want)
 	oldkeys = keys;
 
 	while ((!cleanup()) && keys != NULL && have->colour == 0) {
-		sigs = cached_getkeysigs(((struct stats_key *)
+		sigs = config.dbbackend->cached_getkeysigs(((struct stats_key *)
 					keys->object)->keyid);
 		while ((!cleanup()) && sigs != NULL && have->colour == 0) {
 			/*
@@ -128,14 +129,14 @@ void dofindpath(uint64_t have, uint64_t want, bool html, int count)
 	int pathnum;
 	char *uid;
 
-	fullhave = getfullkeyid(have);
-	fullwant = getfullkeyid(want);
+	fullhave = config.dbbackend->getfullkeyid(have);
+	fullwant = config.dbbackend->getfullkeyid(want);
 
 	/*
 	 * Make sure the keys we have and want are in the cache.
 	 */
-	(void) cached_getkeysigs(fullhave);
-	(void) cached_getkeysigs(fullwant);
+	(void) config.dbbackend->cached_getkeysigs(fullhave);
+	(void) config.dbbackend->cached_getkeysigs(fullwant);
 
 	if ((keyinfoa = findinhash(fullhave)) == NULL) {
 		printf("Couldn't find key 0x%llX.\n", have);
@@ -180,7 +181,8 @@ void dofindpath(uint64_t have, uint64_t want, bool html, int count)
 				html ? "
" : ""); curkey = keyinfoa; while (curkey != NULL && curkey->keyid != 0) { - uid = keyid2uid(curkey->keyid); + uid = config.dbbackend->keyid2uid( + curkey->keyid); if (html && uid == NULL) { printf("0x%08llX ([" @@ -256,7 +258,7 @@ struct stats_key *furthestkey(struct stats_key *have) curll = lladd(NULL, have); while (curll != NULL) { - sigs = cached_getkeysigs(((struct stats_key *) + sigs = config.dbbackend->cached_getkeysigs(((struct stats_key *) curll->object)->keyid); while (sigs != NULL) { if (((struct stats_key *) sigs->object)->colour == 0) { -- 2.39.5