]> git.sommitrealweird.co.uk Git - onak.git/blobdiff - keydb_pg.c
Fix PostgreSQL backend key iteration
[onak.git] / keydb_pg.c
index 5933c91381647f4fb837c3de4ea859aafb9d59f9..85ea50060b5b12a58cad35badabb066d9d9043a8 100644 (file)
@@ -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.
  */
  *     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
 {
        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.
  */
  *     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;
 {
        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.
  */
  *     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;
        
 {
        PGresult *result = NULL;
        
@@ -109,7 +109,7 @@ bool starttrans(void)
  *
  *     Ends a transaction.
  */
  *
  *     Ends a transaction.
  */
-void endtrans(void)
+static void pg_endtrans(void)
 {
        PGresult *result = NULL;
 
 {
        PGresult *result = NULL;
 
@@ -131,7 +131,7 @@ void endtrans(void)
  *     in and then parse_keys() to parse the packets into a publickey
  *     structure.
  */
  *     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;
                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.
  */
  *     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;
 {
        struct openpgp_packet_list *packets = NULL;
        PGresult *result = NULL;
@@ -217,7 +218,7 @@ int fetch_key_text(const char *search, struct openpgp_publickey **publickey)
 
        newsearch = malloc(strlen(search) * 2 + 1);
        memset(newsearch, 0, strlen(search) * 2 + 1);
 
        newsearch = malloc(strlen(search) * 2 + 1);
        memset(newsearch, 0, strlen(search) * 2 + 1);
-       PQescapeString(newsearch, search, strlen(search));
+       PQescapeStringConn(dbconn, newsearch, search, strlen(search), NULL);
        snprintf(statement, 1023,
                        "SELECT DISTINCT onak_keys.keydata FROM onak_keys, "
                        "onak_uids WHERE onak_keys.keyid = onak_uids.keyid "
        snprintf(statement, 1023,
                        "SELECT DISTINCT onak_keys.keydata FROM onak_keys, "
                        "onak_uids WHERE onak_keys.keyid = onak_uids.keyid "
@@ -258,6 +259,75 @@ int fetch_key_text(const char *search, struct openpgp_publickey **publickey)
        return (numkeys);
 }
 
        return (numkeys);
 }
 
+/**
+ *     delete_key - Given a keyid delete the key from storage.
+ *     @keyid: The keyid to delete.
+ *     @intrans: If we're already in a transaction.
+ *
+ *     This function deletes a public key from whatever storage mechanism we
+ *     are using. Returns 0 if the key existed.
+ */
+static int pg_delete_key(uint64_t keyid, bool intrans)
+{
+       PGresult *result = NULL;
+       char *oids = NULL;
+       char statement[1024];
+       int found = 1;
+       int i;
+       Oid key_oid;
+
+       if (!intrans) {
+               result = PQexec(dbconn, "BEGIN");
+               PQclear(result);
+       }
+       
+       snprintf(statement, 1023,
+                       "SELECT keydata FROM onak_keys WHERE keyid = '%llX'",
+                       keyid);
+       result = PQexec(dbconn, statement);
+
+       if (PQresultStatus(result) == PGRES_TUPLES_OK) {
+               found = 0;
+               i = PQntuples(result);
+               while (i > 0) {
+                       oids = PQgetvalue(result, i-1, 0);
+                       key_oid = (Oid) atoi(oids);
+                       lo_unlink(dbconn, key_oid);
+                       i--;
+               }
+               PQclear(result);
+
+               snprintf(statement, 1023,
+                       "DELETE FROM onak_keys WHERE keyid = '%llX'",
+                       keyid);
+               result = PQexec(dbconn, statement);
+               PQclear(result);
+
+               snprintf(statement, 1023,
+                       "DELETE FROM onak_sigs WHERE signee = '%llX'",
+                       keyid);
+               result = PQexec(dbconn, statement);
+               PQclear(result);
+
+               snprintf(statement, 1023,
+                       "DELETE FROM onak_uids WHERE keyid = '%llX'",
+                       keyid);
+               result = PQexec(dbconn, statement);
+       } else if (PQresultStatus(result) != PGRES_TUPLES_OK) {
+               logthing(LOGTHING_ERROR,
+                               "Problem retrieving key (%llX) from DB.",
+                               keyid);
+       }
+
+       PQclear(result);
+
+       if (!intrans) {
+               result = PQexec(dbconn, "COMMIT");
+               PQclear(result);
+       }
+       return (found);
+}
+
 /**
  *     store_key - Takes a key and stores it.
  *     @publickey: A pointer to the public key to store.
 /**
  *     store_key - Takes a key and stores it.
  *     @publickey: A pointer to the public key to store.
@@ -270,7 +340,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.
  */
  *     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;
 {
        struct openpgp_packet_list *packets = NULL;
        struct openpgp_packet_list *list_end = NULL;
@@ -299,7 +370,7 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, bool update)
         * it definitely needs updated.
         */
        if (update) {
         * it definitely needs updated.
         */
        if (update) {
-               delete_key(get_keyid(publickey), true);
+               pg_delete_key(get_keyid(publickey), true);
        }
 
        next = publickey->next;
        }
 
        next = publickey->next;
@@ -337,8 +408,8 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, bool update)
                        safeuid = malloc(strlen(uids[i]) * 2 + 1);
                        if (safeuid != NULL) {
                                memset(safeuid, 0, strlen(uids[i]) * 2 + 1);
                        safeuid = malloc(strlen(uids[i]) * 2 + 1);
                        if (safeuid != NULL) {
                                memset(safeuid, 0, strlen(uids[i]) * 2 + 1);
-                               PQescapeString(safeuid, uids[i],
-                                               strlen(uids[i]));
+                               PQescapeStringConn(dbconn, safeuid, uids[i],
+                                               strlen(uids[i]), NULL);
 
                                snprintf(statement, 1023,
                                        "INSERT INTO onak_uids "
 
                                snprintf(statement, 1023,
                                        "INSERT INTO onak_uids "
@@ -393,80 +464,11 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, bool update)
        return 0;
 }
 
        return 0;
 }
 
-/**
- *     delete_key - Given a keyid delete the key from storage.
- *     @keyid: The keyid to delete.
- *     @intrans: If we're already in a transaction.
- *
- *     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)
-{
-       PGresult *result = NULL;
-       char *oids = NULL;
-       char statement[1024];
-       int found = 1;
-       int i;
-       Oid key_oid;
-
-       if (!intrans) {
-               result = PQexec(dbconn, "BEGIN");
-               PQclear(result);
-       }
-       
-       snprintf(statement, 1023,
-                       "SELECT keydata FROM onak_keys WHERE keyid = '%llX'",
-                       keyid);
-       result = PQexec(dbconn, statement);
-
-       if (PQresultStatus(result) == PGRES_TUPLES_OK) {
-               found = 0;
-               i = PQntuples(result);
-               while (i > 0) {
-                       oids = PQgetvalue(result, i-1, 0);
-                       key_oid = (Oid) atoi(oids);
-                       lo_unlink(dbconn, key_oid);
-                       i--;
-               }
-               PQclear(result);
-
-               snprintf(statement, 1023,
-                       "DELETE FROM onak_keys WHERE keyid = '%llX'",
-                       keyid);
-               result = PQexec(dbconn, statement);
-               PQclear(result);
-
-               snprintf(statement, 1023,
-                       "DELETE FROM onak_sigs WHERE signee = '%llX'",
-                       keyid);
-               result = PQexec(dbconn, statement);
-               PQclear(result);
-
-               snprintf(statement, 1023,
-                       "DELETE FROM onak_uids WHERE keyid = '%llX'",
-                       keyid);
-               result = PQexec(dbconn, statement);
-       } else if (PQresultStatus(result) != PGRES_TUPLES_OK) {
-               logthing(LOGTHING_ERROR,
-                               "Problem retrieving key (%llX) from DB.",
-                               keyid);
-       }
-
-       PQclear(result);
-
-       if (!intrans) {
-               result = PQexec(dbconn, "COMMIT");
-               PQclear(result);
-       }
-       return (found);
-}
-
 /**
  *     keyid2uid - Takes a keyid and returns the primary UID for it.
  *     @keyid: The keyid to lookup.
  */
 /**
  *     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];
 {
        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.
  */
  *     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;
 {
        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.
  */
  *
  *     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;
 {
        struct openpgp_packet_list *packets = NULL;
        struct openpgp_publickey *key = NULL;
@@ -606,7 +608,7 @@ int iterate_keys(void (*iterfunc)(void *ctx, struct openpgp_publickey *key),
                        } else {
                                read_openpgp_stream(keydb_fetchchar, &fd,
                                                &packets, 0);
                        } else {
                                read_openpgp_stream(keydb_fetchchar, &fd,
                                                &packets, 0);
-                               parse_keys(packets, key);
+                               parse_keys(packets, &key);
                                lo_close(dbconn, fd);
 
                                iterfunc(ctx, key);
                                lo_close(dbconn, fd);
 
                                iterfunc(ctx, key);
@@ -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"
 #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,
+};