gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnunet] branch master updated: early draft for libgnunetpq event notifi


From: gnunet
Subject: [gnunet] branch master updated: early draft for libgnunetpq event notification support
Date: Sat, 24 Jul 2021 22:09:19 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository gnunet.

The following commit(s) were added to refs/heads/master by this push:
     new 31eae6bbe early draft for libgnunetpq event notification support
31eae6bbe is described below

commit 31eae6bbe16302d2593b806ef3d2ac2ca9c2d8de
Author: Christian Grothoff <grothoff@gnunet.org>
AuthorDate: Sat Jul 24 22:05:46 2021 +0200

    early draft for libgnunetpq event notification support
---
 src/include/gnunet_common.h      |  11 +-
 src/include/gnunet_pq_lib.h      | 168 +++++++++++++-
 src/include/gnunet_strings_lib.h |  55 +++--
 src/json/json_helper.c           |  28 +--
 src/pq/Makefile.am               |   2 +
 src/pq/pq.h                      |  20 ++
 src/pq/pq_connect.c              |   2 +-
 src/pq/pq_event.c                | 396 +++++++++++++++++++++++++++++++++
 src/util/strings.c               | 467 +++++++--------------------------------
 9 files changed, 714 insertions(+), 435 deletions(-)

diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h
index 1126deaf4..df1ccff26 100644
--- a/src/include/gnunet_common.h
+++ b/src/include/gnunet_common.h
@@ -435,11 +435,12 @@ enum GNUNET_ErrorType
  * @param date when was the message logged?
  * @param message what is the message
  */
-typedef void (*GNUNET_Logger) (void *cls,
-                               enum GNUNET_ErrorType kind,
-                               const char *component,
-                               const char *date,
-                               const char *message);
+typedef void
+(*GNUNET_Logger) (void *cls,
+                  enum GNUNET_ErrorType kind,
+                  const char *component,
+                  const char *date,
+                  const char *message);
 
 
 /**
diff --git a/src/include/gnunet_pq_lib.h b/src/include/gnunet_pq_lib.h
index 2cecb9885..1f2915165 100644
--- a/src/include/gnunet_pq_lib.h
+++ b/src/include/gnunet_pq_lib.h
@@ -1,6 +1,6 @@
 /*
    This file is part of GNUnet
-   Copyright (C) 2016, 2017, 2020 GNUnet e.V.
+   Copyright (C) 2016, 2017, 2020, 2021 GNUnet e.V.
 
    GNUnet is free software: you can redistribute it and/or modify it
    under the terms of the GNU Affero General Public License as published
@@ -852,6 +852,170 @@ void
 GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db);
 
 
+/**
+ * Function called whenever the socket needed for 
+ * notifications from postgres changes.
+ *
+ * @param cls closure
+ * @param fd socket to listen on, -1 for none
+ */
+typedef void
+(*GNUNET_PQ_SocketCallback)(void *cls,
+                            int fd);
+
+
+/**
+ * Obtain the file descriptor to poll on for notifications.
+ * Useful if the GNUnet scheduler is NOT to be used for
+ * such notifications.
+ * 
+ * @param db database handle
+ * @param sc function to call with the socket
+ * @param sc_cls closure for @a sc
+ */
+void
+GNUNET_PQ_event_set_socket_callback (struct GNUNET_PQ_Context *db,
+                                     GNUNET_PQ_SocketCallback sc,
+                                     void *sc_cls);
+
+
+/**
+ * Poll for database events now.  Used if the event FD
+ * is ready and the application wants to trigger applicable
+ * events.
+ * Useful if the GNUnet scheduler is NOT to be used for
+ * such notifications.
+ *
+ * @param db database handle
+ */
+void
+GNUNET_PQ_event_do_poll (struct GNUNET_PQ_Context *db);
+
+
+/**
+ * Run poll event loop using the GNUnet scheduler.
+ *
+ * @param db database handle
+ */
+void
+GNUNET_PQ_event_scheduler_start (struct GNUNET_PQ_Context *db);
+
+
+/**
+ * Stop running poll event loop using the GNUnet scheduler.
+ *
+ * @param db database handle
+ */
+void
+GNUNET_PQ_event_scheduler_stop (struct GNUNET_PQ_Context *db);
+
+
+/**
+ * Handle for an active LISTENer to the database.
+ */ 
+struct GNUNET_PQ_EventHandler;
+
+/**
+ * Function called on events received from Postgres.
+ *
+ * @param cls closure
+ * @param extra additional event data provided
+ * @param extra_size number of bytes in @a extra
+ */
+typedef void
+(*GNUNET_PQ_EventCallback)(void *cls,
+                           const void *extra,
+                           size_t extra_size);
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
+
+/**
+ * Header of a structure that describes an
+ * event channel we may subscribe to or notify on.
+ */
+struct GNUNET_PQ_EventHeaderP
+{
+  /**
+   * The length of the struct (in bytes, including the length field itself),
+   * in big-endian format.
+   */
+  uint16_t size GNUNET_PACKED;
+
+  /**
+   * The type of the message (GNUNET_PQ_EVENT_TYPE_XXXX), in big-endian format.
+   */
+  uint16_t type GNUNET_PACKED;
+
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
+/**
+ * Handle for an active LISTENer to the database.
+ */ 
+struct GNUNET_PQ_EventHandler;
+
+/**
+ * Register callback to be invoked on events of type @a es.
+ * 
+ * Unlike many other calls, this function is thread-safe
+ * and may be called from threads that are different
+ * from the one that setup @a db. However, the @a cb
+ * will always be called from the thread that runs
+ * #GNUNET_PQ_event_do_poll() or the GNUnet scheduler.
+ *
+ * @param db database context to use
+ * @param es specification of the event to listen for
+ * @param cb function to call when the event happens, possibly
+ *         multiple times (until #GNUNET_PQ_event_listen_cancel() is invoked)
+ * @param cb_cls closure for @a cb
+ * @return handle useful to cancel the listener
+ */
+struct GNUNET_PQ_EventHandler *
+GNUNET_PQ_event_listen (struct GNUNET_PQ_Context *db,
+                        const struct GNUNET_PQ_EventHeaderP *es,
+                        GNUNET_PQ_EventCallback cb,
+                        void *cb_cls);
+
+
+/**
+ * Stop notifications.
+ * 
+ * Unlike many other calls, this function is thread-safe
+ * and may be called from threads that are different
+ * from the one that setup @a db. However, the @a cb
+ * will always be called from the thread that runs
+ * #GNUNET_PQ_event_do_poll() or the GNUnet scheduler.
+ *
+ * @param eh handle to unregister.
+ */
+void
+GNUNET_PQ_event_listen_cancel (struct GNUNET_PQ_EventHandler *eh);
+
+
+/**
+ * Notify all that listen on @a es of an event.
+ * 
+ * Unlike many other calls, this function is thread-safe
+ * and may be called from threads that are different
+ * from the one that setup @a db. However, the @a cb
+ * will always be called from the thread that runs
+ * #GNUNET_PQ_event_do_poll() or the GNUnet scheduler.
+ *
+ * @param db database context to use
+ * @param es specification of the event to generate
+ * @param extra additional event data provided
+ * @param extra_size number of bytes in @a extra
+ */
+void
+GNUNET_PQ_event_notify (struct GNUNET_PQ_Context *db,
+                        const struct GNUNET_PQ_EventHeaderP *es,
+                        const void *extra,
+                        size_t extra_size);
+
+
 /**
  * Within the @a db context, run all the SQL files
  * from the @a load_path from 0000-9999.sql (as long
@@ -861,7 +1025,7 @@ GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db);
  * @param load_path where to find the XXXX.sql files
  * @return #GNUNET_OK on success
  */
-int
+enum GNUNET_GenericReturnValue
 GNUNET_PQ_run_sql (struct GNUNET_PQ_Context *db,
                    const char *load_path);
 
diff --git a/src/include/gnunet_strings_lib.h b/src/include/gnunet_strings_lib.h
index 955a3afca..977c2ead7 100644
--- a/src/include/gnunet_strings_lib.h
+++ b/src/include/gnunet_strings_lib.h
@@ -327,13 +327,31 @@ GNUNET_STRINGS_data_to_string_alloc (const void *buf,
  * @param out_size size of the output buffer @a out
  * @return #GNUNET_OK on success, #GNUNET_SYSERR if result has the wrong 
encoding
  */
-int
+enum GNUNET_GenericReturnValue
 GNUNET_STRINGS_string_to_data (const char *enc,
                                size_t enclen,
                                void *out,
                                size_t out_size);
 
 
+/**
+ * Convert CrockfordBase32 encoding back to data.
+ * @a out_size will be determined from @a enc and
+ * @a out will be allocated to be large enough.
+ *
+ * @param enc the encoding
+ * @param enclen number of characters in @a enc (without 0-terminator, which 
can be missing)
+ * @param[out] out location where to allocate and store the decoded data
+ * @param[out] out_size set to the size of the output buffer @a out
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR if result has the wrong 
encoding
+ */
+enum GNUNET_GenericReturnValue
+GNUNET_STRINGS_string_to_data_alloc (const char *enc,
+                                     size_t enclen,
+                                     void **out,
+                                     size_t *out_size);
+
+
 /**
  * Encode into Base64.
  *
@@ -359,7 +377,10 @@ GNUNET_STRINGS_base64_encode (const void *in,
  * @return the size of the output
  */
 size_t
-GNUNET_STRINGS_urlencode (const char *data, size_t len, char **out);
+GNUNET_STRINGS_urlencode (const char *data,
+                          size_t len,
+                          char **out);
+
 
 /**
  * Encode into Base64url. RFC7515
@@ -371,7 +392,9 @@ GNUNET_STRINGS_urlencode (const char *data, size_t len, 
char **out);
  * @return the size of the output
  */
 size_t
-GNUNET_STRINGS_base64url_encode (const void *in, size_t len, char **output);
+GNUNET_STRINGS_base64url_encode (const void *in,
+                                 size_t len,
+                                 char **output);
 
 
 /**
@@ -399,7 +422,9 @@ GNUNET_STRINGS_base64_decode (const char *data,
  * @return the size of the output
  */
 size_t
-GNUNET_STRINGS_base64url_decode (const char *data, size_t len, void **out);
+GNUNET_STRINGS_base64url_decode (const char *data,
+                                 size_t len,
+                                 void **out);
 
 /**
  * url/percent encode (RFC3986).
@@ -411,7 +436,9 @@ GNUNET_STRINGS_base64url_decode (const char *data, size_t 
len, void **out);
  * @return the size of the output
  */
 size_t
-GNUNET_STRINGS_urldecode (const char *data, size_t len, char **out);
+GNUNET_STRINGS_urldecode (const char *data,
+                          size_t len,
+                          char **out);
 
 
 /**
@@ -442,7 +469,7 @@ GNUNET_STRINGS_pp2s (const struct GNUNET_PeerIdentity *pids,
  *         an URI, '* scheme_part' and '*path_part' will remain unchanged
  *         (if they weren't NULL).
  */
-int
+enum GNUNET_GenericReturnValue
 GNUNET_STRINGS_parse_uri (const char *path,
                           char **scheme_part,
                           const char **path_part);
@@ -462,7 +489,7 @@ GNUNET_STRINGS_parse_uri (const char *path,
  *        GNUNET_free (). Can be NULL.
  * @return #GNUNET_YES if 'filename' is absolute, #GNUNET_NO otherwise.
  */
-int
+enum GNUNET_GenericReturnValue
 GNUNET_STRINGS_path_is_absolute (const char *filename,
                                  int can_be_uri,
                                  int *r_is_uri,
@@ -505,7 +532,7 @@ enum GNUNET_STRINGS_FilenameCheck
  * @return #GNUNET_YES if all checks pass, #GNUNET_NO if at least one of them
  *         fails, #GNUNET_SYSERR when a check can't be performed
  */
-int
+enum GNUNET_GenericReturnValue
 GNUNET_STRINGS_check_filename (const char *filename,
                                enum GNUNET_STRINGS_FilenameCheck checks);
 
@@ -521,7 +548,7 @@ GNUNET_STRINGS_check_filename (const char *filename,
  * @return #GNUNET_OK if conversion succeeded. #GNUNET_SYSERR otherwise, in 
which
  *         case the contents of r_buf are undefined.
  */
-int
+enum GNUNET_GenericReturnValue
 GNUNET_STRINGS_to_address_ipv6 (const char *zt_addr,
                                 uint16_t addrlen,
                                 struct sockaddr_in6 *r_buf);
@@ -537,7 +564,7 @@ GNUNET_STRINGS_to_address_ipv6 (const char *zt_addr,
  * @return #GNUNET_OK if conversion succeeded. #GNUNET_SYSERR otherwise, in 
which case
  *         the contents of r_buf are undefined.
  */
-int
+enum GNUNET_GenericReturnValue
 GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr,
                                 uint16_t addrlen,
                                 struct sockaddr_in *r_buf);
@@ -569,7 +596,7 @@ GNUNET_STRINGS_parse_socket_addr (const char *addr,
  * @return #GNUNET_OK if conversion succeeded. #GNUNET_SYSERR otherwise, in 
which
  *         case the contents of r_buf are undefined.
  */
-int
+enum GNUNET_GenericReturnValue
 GNUNET_STRINGS_to_address_ip (const char *addr,
                               uint16_t addrlen,
                               struct sockaddr_storage *r_buf);
@@ -587,7 +614,7 @@ GNUNET_STRINGS_to_address_ip (const char *addr,
  * @param u8argv a location to store new argv in
  * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
  */
-int
+enum GNUNET_GenericReturnValue
 GNUNET_STRINGS_get_utf8_args (int argc,
                               char *const *argv,
                               int *u8argc,
@@ -610,7 +637,9 @@ GNUNET_STRINGS_get_utf8_args (int argc,
  *         null byte
  */
 size_t
-GNUNET_strlcpy (char *dst, const char *src, size_t n);
+GNUNET_strlcpy (char *dst,
+                const char *src,
+                size_t n);
 
 
 /* ***************** IPv4/IPv6 parsing ****************** */
diff --git a/src/json/json_helper.c b/src/json/json_helper.c
index 03db9ec80..55435ea19 100644
--- a/src/json/json_helper.c
+++ b/src/json/json_helper.c
@@ -116,7 +116,6 @@ parse_variable_data (void *cls,
   const char *str;
   size_t size;
   void *data;
-  int res;
 
   str = json_string_value (root);
   if (NULL == str)
@@ -124,30 +123,13 @@ parse_variable_data (void *cls,
     GNUNET_break_op (0);
     return GNUNET_SYSERR;
   }
-  size = (strlen (str) * 5) / 8;
-  if (size >= GNUNET_MAX_MALLOC_CHECKED)
-  {
-    GNUNET_break_op (0);
-    return GNUNET_SYSERR;
-  }
-  data = GNUNET_malloc (size);
-  res = GNUNET_STRINGS_string_to_data (str,
-                                       strlen (str),
-                                       data,
-                                       size);
-  if ( (0 < size) &&
-       (GNUNET_OK != res) )
-  {
-    size--;
-    res = GNUNET_STRINGS_string_to_data (str,
-                                         strlen (str),
-                                         data,
-                                         size);
-  }
-  if (GNUNET_OK != res)
+  if (GNUNET_OK !=
+      GNUNET_STRINGS_string_to_data_alloc (str,
+                                           strlen (str),
+                                           &data,
+                                           &size))
   {
     GNUNET_break_op (0);
-    GNUNET_free (data);
     return GNUNET_SYSERR;
   }
   *(void **) spec->ptr = data;
diff --git a/src/pq/Makefile.am b/src/pq/Makefile.am
index fcc30f6ff..0febac4ac 100644
--- a/src/pq/Makefile.am
+++ b/src/pq/Makefile.am
@@ -14,6 +14,7 @@ libgnunetpq_la_SOURCES = \
   pq.h \
   pq_connect.c \
   pq_eval.c \
+  pq_event.c \
   pq_exec.c \
   pq_prepare.c \
   pq_query_helper.c \
@@ -23,6 +24,7 @@ libgnunetpq_la_LIBADD = -lpq \
 libgnunetpq_la_LDFLAGS = \
  $(POSTGRESQL_LDFLAGS) \
  $(GN_LIB_LDFLAGS) \
+  -lpthread \
   -version-info 1:0:0
 
 if ENABLE_TEST_RUN
diff --git a/src/pq/pq.h b/src/pq/pq.h
index 91a890bcb..3c89626a9 100644
--- a/src/pq/pq.h
+++ b/src/pq/pq.h
@@ -57,6 +57,26 @@ struct GNUNET_PQ_Context
    * Path to load SQL files from.
    */
   char *load_path;
+
+  /**
+   * Function to call on Postgres FDs.
+   */
+  GNUNET_PQ_SocketCallback sc;
+
+  /**
+   * Closure for @e sc.
+   */
+  void *sc_cls;
+
+  /**
+   * Map managing event subscriptions.
+   */
+  struct GNUNET_CONTAINER_MultiShortmap *channel_map;
+
+  /**
+   * Lock to access @e channel_map.
+   */
+  pthread_mutex_t notify_lock;
 };
 
 #endif
diff --git a/src/pq/pq_connect.c b/src/pq/pq_connect.c
index cd52c2728..00664dcd0 100644
--- a/src/pq/pq_connect.c
+++ b/src/pq/pq_connect.c
@@ -209,7 +209,7 @@ apply_patch (struct GNUNET_PQ_Context *db,
  * @param load_path where to find the XXXX.sql files
  * @return #GNUNET_OK on success
  */
-int
+enum GNUNET_GenericReturnValue
 GNUNET_PQ_run_sql (struct GNUNET_PQ_Context *db,
                    const char *load_path)
 {
diff --git a/src/pq/pq_event.c b/src/pq/pq_event.c
new file mode 100644
index 000000000..ecb942230
--- /dev/null
+++ b/src/pq/pq_event.c
@@ -0,0 +1,396 @@
+/*
+   This file is part of GNUnet
+   Copyright (C) 2021 GNUnet e.V.
+
+   GNUnet is free software: you can redistribute it and/or modify it
+   under the terms of the GNU Affero General Public License as published
+   by the Free Software Foundation, either version 3 of the License,
+   or (at your option) any later version.
+
+   GNUnet is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Affero General Public License for more details.
+
+   You should have received a copy of the GNU Affero General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
+ */
+/**
+ * @file pq/pq_event.c
+ * @brief event notifications via Postgres
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "pq.h"
+#include <pthread.h>
+
+
+/**
+ * Handle for an active LISTENer to the database.
+ */ 
+struct GNUNET_PQ_EventHandler
+{
+  /**
+   * Channel name.
+   */
+  struct GNUNET_ShortHashCode sh;
+
+  /**
+   * Function to call on events.
+   */
+  GNUNET_PQ_EventCallback cb;
+
+  /**
+   * Closure for @e cb.
+   */
+  void *cb_cls;
+
+  /**
+   * Database context this event handler is with.
+   */
+  struct GNUNET_PQ_Context *db;
+};
+
+
+
+
+/**
+ * Convert @a es to a short hash.
+ *
+ * @param es spec to hash to an identifier
+ * @param[out] sh short hash to set
+ */
+static void
+es_to_sh (const struct GNUNET_PQ_EventHeaderP *es,
+          struct GNUNET_ShortHashCode *sh)
+{
+  struct GNUNET_HashCode h_channel;
+
+  GNUNET_CRYPTO_hash (es,
+                      ntohs (es->size),
+                      &h_channel);
+  GNUNET_static_assert (sizeof (*sh) <= sizeof (h_channel));
+  memcpy (sh,
+          &h_channel,
+          sizeof (*sh));
+}
+
+
+/**
+ * Convert @a sh to a Postgres identifier.
+ *
+ * @param sh short hash to convert to an identifier
+ * @param[out] identifier by default, Postgres supports
+ *     NAMEDATALEN=64 character identifiers
+ * @return end position of the identifier
+ */
+static char *
+sh_to_channel (struct GNUNET_ShortHashCode *sh,
+               char identifier[64])
+{
+  char *end;
+
+  end = GNUNET_STRINGS_data_to_string (sh,
+                                       sizeof (*sh),
+                                       identifier,
+                                       63);
+  GNUNET_assert (NULL != end);
+  *end = '\0';
+  return end;
+}
+
+
+/**
+ * Convert @a es to a Postgres identifier.
+ *
+ * @param es spec to hash to an identifier
+ * @param[out] identifier by default, Postgres supports
+ *     NAMEDATALEN=64 character identifiers
+ * @return end position of the identifier
+ */
+static char *
+es_to_channel (const struct GNUNET_PQ_EventHeaderP *es,
+               char identifier[64])
+{
+  struct GNUNET_ShortHashCode sh;
+
+  es_to_sh (es,
+            &sh);
+  return sh_to_channel (&sh,
+                        identifier);
+}
+
+
+/**
+ * Closure for #do_notify().
+ */
+struct NotifyContext
+{
+  /**
+   * Extra argument of the notification, or NULL.
+   */
+  void *extra;
+
+  /**
+   * Number of bytes in @e extra.
+   */
+  size_t extra_size;
+};
+
+
+/**
+ * Function called on every event handler that 
+ * needs to be triggered.
+ *
+ * @param cls a `struct NotifyContext`
+ * @param sh channel name
+ * @param value a `struct GNUNET_PQ_EventHandler`
+ * @return #GNUNET_OK continue to iterate
+ */
+static int
+do_notify (void *cls,
+           const struct GNUNET_ShortHashCode *sh,
+           void *value)
+{
+  struct NotifyContext *ctx = cls;
+  struct GNUNET_PQ_EventHandler *eh = value;
+
+  eh->cb (eh->cb_cls,
+          ctx->extra,
+          ctx->extra_size);
+  return GNUNET_OK;
+} 
+
+
+void
+GNUNET_PQ_event_set_socket_callback (struct GNUNET_PQ_Context *db,
+                                     GNUNET_PQ_SocketCallback sc,
+                                     void *sc_cls)
+{
+  int fd;
+
+  db->sc = sc;
+  db->sc_cls = sc_cls;
+  if (NULL == sc)
+    return;
+  GNUNET_assert (0 ==
+                 pthread_mutex_lock (&db->notify_lock));
+  fd = PQsocket (db->conn);
+  if ( (-1 != fd) &&
+       (0 != GNUNET_CONTAINER_multishortmap_size (db->channel_map)) )
+    sc (sc_cls,
+        fd);
+  GNUNET_assert (0 ==
+                 pthread_mutex_unlock (&db->notify_lock));
+}
+
+
+void
+GNUNET_PQ_event_do_poll (struct GNUNET_PQ_Context *db)
+{
+  PGnotify *n;
+
+  GNUNET_assert (0 ==
+                 pthread_mutex_lock (&db->notify_lock));
+  while (NULL != (n = PQnotifies (db->conn)))
+  {
+    struct GNUNET_ShortHashCode sh;
+    struct NotifyContext ctx = {
+      .extra = NULL
+    };
+
+    if (GNUNET_OK !=
+        GNUNET_STRINGS_string_to_data (n->relname,
+                                       strlen (n->relname),
+                                       &sh,
+                                       sizeof (sh)))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  "Ignoring notification for unsupported channel identifier 
`%s'\n",
+                  n->relname);
+      continue;
+    }
+    if ( (NULL != n->extra) &&
+         (GNUNET_OK !=
+          GNUNET_STRINGS_string_to_data_alloc (n->extra,
+                                               strlen (n->extra),
+                                               &ctx.extra,
+                                               &ctx.extra_size)))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  "Ignoring notification for unsupported extra data `%s' on 
channel `%s'\n",
+                  n->extra,
+                  n->relname);
+      continue;
+    }
+    GNUNET_CONTAINER_multishortmap_iterate (db->channel_map,
+                                            &do_notify,
+                                            &ctx);
+    GNUNET_free (ctx.extra);
+  }
+  GNUNET_assert (0 ==
+                 pthread_mutex_unlock (&db->notify_lock));
+}
+
+
+void
+GNUNET_PQ_event_scheduler_start (struct GNUNET_PQ_Context *db)
+{
+  GNUNET_break (0); // FIXME: not implemented
+}
+
+
+void
+GNUNET_PQ_event_scheduler_stop (struct GNUNET_PQ_Context *db)
+{
+  GNUNET_break (0); // FIXME: not implemented
+}
+
+
+static void
+manage_subscribe (struct GNUNET_PQ_Context *db,
+                  const char *cmd,
+                  struct GNUNET_PQ_EventHandler *eh)
+{
+  char sql[16 + 64];
+  char *end;
+  PGresult *result;
+
+  end = stpcpy (sql,
+                cmd);
+  end = sh_to_channel (&eh->sh,
+                       end);
+  result = PQexec (db->conn,
+                   sql);
+  if (PGRES_COMMAND_OK != PQresultStatus (result))
+  {
+    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
+                     "pq",
+                     "Failed to execute `%s': %s/%s/%s/%s/%s",
+                     sql,
+                     PQresultErrorField (result,
+                                         PG_DIAG_MESSAGE_PRIMARY),
+                     PQresultErrorField (result,
+                                         PG_DIAG_MESSAGE_DETAIL),
+                     PQresultErrorMessage (result),
+                     PQresStatus (PQresultStatus (result)),
+                     PQerrorMessage (db->conn));
+  }
+  PQclear (result);
+}
+
+
+struct GNUNET_PQ_EventHandler *
+GNUNET_PQ_event_listen (struct GNUNET_PQ_Context *db,
+                        const struct GNUNET_PQ_EventHeaderP *es,
+                        GNUNET_PQ_EventCallback cb,
+                        void *cb_cls)
+{
+  struct GNUNET_PQ_EventHandler *eh;
+  bool was_zero;
+
+  eh = GNUNET_new (struct GNUNET_PQ_EventHandler);
+  eh->db = db;
+  es_to_sh (es,
+            &eh->sh);
+  eh->cb = cb;
+  eh->cb_cls = cb_cls;
+  GNUNET_assert (0 ==
+                 pthread_mutex_lock (&db->notify_lock));
+  was_zero = (0 == GNUNET_CONTAINER_multishortmap_size (db->channel_map));
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_CONTAINER_multishortmap_put (db->channel_map,
+                                                         &eh->sh,
+                                                         eh,
+                                                         
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
+  if ( (NULL != db->sc) &&
+       was_zero)
+  {
+    int fd = PQsocket (db->conn);
+    
+    if (-1 != fd)
+      db->sc (db->sc_cls,
+              fd);
+  }
+  manage_subscribe (db,
+                    "LISTEN ",
+                    eh);
+  GNUNET_assert (0 ==
+                 pthread_mutex_unlock (&db->notify_lock));
+  return eh;
+}
+
+
+void
+GNUNET_PQ_event_listen_cancel (struct GNUNET_PQ_EventHandler *eh)
+{
+  struct GNUNET_PQ_Context *db = eh->db;
+
+  GNUNET_assert (0 ==
+                 pthread_mutex_lock (&db->notify_lock));
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_CONTAINER_multishortmap_remove (db->channel_map,
+                                                    &eh->sh,
+                                                    eh));
+    
+  manage_subscribe (db,
+                    "UNLISTEN ",
+                    eh);
+  if ( (NULL != db->sc) &&
+       (0 == GNUNET_CONTAINER_multishortmap_size (db->channel_map)) )
+  {
+    db->sc (db->sc_cls,
+            -1);
+  }
+  GNUNET_assert (0 ==
+                 pthread_mutex_unlock (&db->notify_lock));
+}
+
+
+void
+GNUNET_PQ_event_notify (struct GNUNET_PQ_Context *db,
+                        const struct GNUNET_PQ_EventHeaderP *es,
+                        const void *extra,
+                        size_t extra_size)
+{
+  char sql[16 + 64 + extra_size * 8 / 5 + 8];
+  char *end;
+  PGresult *result;
+
+  end = stpcpy (sql,
+                "NOTIFY ");
+  end = es_to_channel (es,
+                       end);
+  end = stpcpy (end,
+                "'");
+  end = GNUNET_STRINGS_data_to_string (extra,
+                                       extra_size,
+                                       end,
+                                       sizeof (sql) - (end - sql) - 1);
+  GNUNET_assert (NULL != end);
+  *end = '\0';
+  end = stpcpy (end,
+                "'");
+  result = PQexec (db->conn,
+                   sql);
+  if (PGRES_COMMAND_OK != PQresultStatus (result))
+  {
+    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
+                     "pq",
+                     "Failed to execute `%s': %s/%s/%s/%s/%s",
+                     sql,
+                     PQresultErrorField (result,
+                                         PG_DIAG_MESSAGE_PRIMARY),
+                     PQresultErrorField (result,
+                                         PG_DIAG_MESSAGE_DETAIL),
+                     PQresultErrorMessage (result),
+                     PQresStatus (PQresultStatus (result)),
+                     PQerrorMessage (db->conn));
+  }
+  PQclear (result);
+}
+
+/* end of pq_event.c */
+
diff --git a/src/util/strings.c b/src/util/strings.c
index b62d5f547..24335e444 100644
--- a/src/util/strings.c
+++ b/src/util/strings.c
@@ -41,27 +41,6 @@
   GNUNET_log_from_strerror (kind, "util-strings", syscall)
 
 
-/**
- * Fill a buffer of the given size with
- * count 0-terminated strings (given as varargs).
- * If "buffer" is NULL, only compute the amount of
- * space required (sum of "strlen(arg)+1").
- *
- * Unlike using "snprintf" with "%s", this function
- * will add 0-terminators after each string.  The
- * #GNUNET_string_buffer_tokenize() function can be
- * used to parse the buffer back into individual
- * strings.
- *
- * @param buffer the buffer to fill with strings, can
- *               be NULL in which case only the necessary
- *               amount of space will be calculated
- * @param size number of bytes available in buffer
- * @param count number of strings that follow
- * @param ... count 0-terminated strings to copy to buffer
- * @return number of bytes written to the buffer
- *         (or number of bytes that would have been written)
- */
 size_t
 GNUNET_STRINGS_buffer_fill (char *buffer,
                             size_t size,
@@ -90,13 +69,6 @@ GNUNET_STRINGS_buffer_fill (char *buffer,
 }
 
 
-/**
- * Convert a peer path to a human-readable string.
- *
- * @param pids array of PIDs to convert to a string
- * @param num_pids length of the @a pids array
- * @return string representing the array of @a pids
- */
 char *
 GNUNET_STRINGS_pp2s (const struct GNUNET_PeerIdentity *pids,
                      unsigned int num_pids)
@@ -120,19 +92,6 @@ GNUNET_STRINGS_pp2s (const struct GNUNET_PeerIdentity *pids,
 }
 
 
-/**
- * Given a buffer of a given size, find "count"
- * 0-terminated strings in the buffer and assign
- * the count (varargs) of type "const char**" to the
- * locations of the respective strings in the
- * buffer.
- *
- * @param buffer the buffer to parse
- * @param size size of the buffer
- * @param count number of strings to locate
- * @return offset of the character after the last 0-termination
- *         in the buffer, or 0 on error.
- */
 unsigned int
 GNUNET_STRINGS_buffer_tokenize (const char *buffer,
                                 size_t size,
@@ -167,12 +126,6 @@ GNUNET_STRINGS_buffer_tokenize (const char *buffer,
 }
 
 
-/**
- * Convert a given filesize into a fancy human-readable format.
- *
- * @param size number of bytes
- * @return fancy representation of the size (possibly rounded) for humans
- */
 char *
 GNUNET_STRINGS_byte_size_fancy (unsigned long long size)
 {
@@ -205,20 +158,10 @@ GNUNET_STRINGS_byte_size_fancy (unsigned long long size)
 }
 
 
-/**
- * Like strlcpy but portable. The given string @a src is copied until its null
- * byte or until @a n - 1 bytes have been read. The destination buffer is
- * guaranteed to be null-terminated.
- *
- * @param dst destination of the copy (must be @a n bytes long)
- * @param src source of the copy (at most @a n - 1 bytes will be read)
- * @param n the length of the string to copy, including its terminating null
- *          byte
- * @return the length of the string that was copied, excluding the terminating
- *         null byte
- */
 size_t
-GNUNET_strlcpy (char *dst, const char *src, size_t n)
+GNUNET_strlcpy (char *dst,
+                const char *src,
+                size_t n)
 {
   size_t slen;
 
@@ -313,13 +256,6 @@ convert_with_table (const char *input,
 }
 
 
-/**
- * Convert a given fancy human-readable size to bytes.
- *
- * @param fancy_size human readable string (e.g. 1 MB)
- * @param size set to the size in bytes
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
- */
 int
 GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size,
                                     unsigned long long *size)
@@ -344,14 +280,6 @@ GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size,
 }
 
 
-/**
- * Convert a given fancy human-readable time to our internal
- * representation.
- *
- * @param fancy_time human readable string (e.g. 1 minute)
- * @param rtime set to the relative time
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
- */
 int
 GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_time,
                                        struct GNUNET_TIME_Relative *rtime)
@@ -394,15 +322,6 @@ GNUNET_STRINGS_fancy_time_to_relative (const char 
*fancy_time,
 }
 
 
-/**
- * Convert a given fancy human-readable time to our internal
- * representation. The human-readable time is expected to be
- * in local time, whereas the returned value will be in UTC.
- *
- * @param fancy_time human readable string (e.g. %Y-%m-%d %H:%M:%S)
- * @param atime set to the absolute time
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
- */
 int
 GNUNET_STRINGS_fancy_time_to_absolute (const char *fancy_time,
                                        struct GNUNET_TIME_Absolute *atime)
@@ -435,19 +354,6 @@ GNUNET_STRINGS_fancy_time_to_absolute (const char 
*fancy_time,
 }
 
 
-/**
- * Convert the len characters long character sequence
- * given in input that is in the given input charset
- * to a string in given output charset.
- *
- * @param input input string
- * @param len number of bytes in @a input
- * @param input_charset character set used for @a input
- * @param output_charset desired character set for the return value
- * @return the converted string (0-terminated),
- *  if conversion fails, a copy of the original
- *  string is returned.
- */
 char *
 GNUNET_STRINGS_conv (const char *input,
                      size_t len,
@@ -510,18 +416,6 @@ fail:
 }
 
 
-/**
- * Convert the len characters long character sequence
- * given in input that is in the given charset
- * to UTF-8.
- *
- * @param input the input string (not necessarily 0-terminated)
- * @param len the number of bytes in the @a input
- * @param charset character set to convert from
- * @return the converted string (0-terminated),
- *  if conversion fails, a copy of the original
- *  string is returned.
- */
 char *
 GNUNET_STRINGS_to_utf8 (const char *input,
                         size_t len,
@@ -534,17 +428,6 @@ GNUNET_STRINGS_to_utf8 (const char *input,
 }
 
 
-/**
- * Convert the len bytes-long UTF-8 string
- * given in input to the given charset.
- *
- * @param input the input string (not necessarily 0-terminated)
- * @param len the number of bytes in the @a input
- * @param charset character set to convert to
- * @return the converted string (0-terminated),
- *  if conversion fails, a copy of the original
- *  string is returned.
- */
 char *
 GNUNET_STRINGS_from_utf8 (const char *input,
                           size_t len,
@@ -557,15 +440,9 @@ GNUNET_STRINGS_from_utf8 (const char *input,
 }
 
 
-/**
- * Convert the utf-8 input string to lowercase.
- * Output needs to be allocated appropriately.
- *
- * @param input input string
- * @param output output buffer
- */
 void
-GNUNET_STRINGS_utf8_tolower (const char *input, char *output)
+GNUNET_STRINGS_utf8_tolower (const char *input,
+                             char *output)
 {
   uint8_t *tmp_in;
   size_t len;
@@ -582,15 +459,9 @@ GNUNET_STRINGS_utf8_tolower (const char *input, char 
*output)
 }
 
 
-/**
- * Convert the utf-8 input string to uppercase.
- * Output needs to be allocated appropriately.
- *
- * @param input input string
- * @param output output buffer
- */
 void
-GNUNET_STRINGS_utf8_toupper (const char *input, char *output)
+GNUNET_STRINGS_utf8_toupper (const char *input,
+                             char *output)
 {
   uint8_t *tmp_in;
   size_t len;
@@ -607,13 +478,6 @@ GNUNET_STRINGS_utf8_toupper (const char *input, char 
*output)
 }
 
 
-/**
- * Complete filename (a la shell) from abbrevition.
- * @param fil the name of the file, may contain ~/ or
- *        be relative to the current directory
- * @returns the full file name,
- *          NULL is returned on error
- */
 char *
 GNUNET_STRINGS_filename_expand (const char *fil)
 {
@@ -689,15 +553,6 @@ GNUNET_STRINGS_filename_expand (const char *fil)
 }
 
 
-/**
- * Give relative time in human-readable fancy format.
- * This is one of the very few calls in the entire API that is
- * NOT reentrant!
- *
- * @param delta time in milli seconds
- * @param do_round are we allowed to round a bit?
- * @return time as human-readable string
- */
 const char *
 GNUNET_STRINGS_relative_time_to_string (struct GNUNET_TIME_Relative delta,
                                         int do_round)
@@ -745,15 +600,6 @@ GNUNET_STRINGS_relative_time_to_string (struct 
GNUNET_TIME_Relative delta,
 }
 
 
-/**
- * "asctime", except for GNUnet time.  Converts a GNUnet internal
- * absolute time (which is in UTC) to a string in local time.
- * Note that the returned value will be overwritten if this function
- * is called again.
- *
- * @param t the absolute time to convert
- * @return timestamp in human-readable form in local time
- */
 const char *
 GNUNET_STRINGS_absolute_time_to_string (struct GNUNET_TIME_Absolute t)
 {
@@ -776,17 +622,6 @@ GNUNET_STRINGS_absolute_time_to_string (struct 
GNUNET_TIME_Absolute t)
 }
 
 
-/**
- * "man basename"
- * Returns a pointer to a part of filename (allocates nothing)!
- *
- * @param filename filename to extract basename from
- * @return short (base) name of the file (that is, everything following the
- *         last directory separator in filename. If filename ends with a
- *         directory separator, the result will be a zero-length string.
- *         If filename has no directory separators, the result is filename
- *         itself.
- */
 const char *
 GNUNET_STRINGS_get_short_name (const char *filename)
 {
@@ -856,18 +691,6 @@ getValue__ (unsigned char a)
 }
 
 
-/**
- * Convert binary data to ASCII encoding using Crockford Base32 encoding.
- * Returns a pointer to the byte after the last byte in the string, that
- * is where the 0-terminator was placed if there was room.
- *
- * @param data data to encode
- * @param size size of data (in bytes)
- * @param out buffer to fill
- * @param out_size size of the buffer. Must be large enough to hold
- * (size * 8 + 4) / 5 bytes
- * @return pointer to the next byte in @a out or NULL on error.
- */
 char *
 GNUNET_STRINGS_data_to_string (const void *data,
                                size_t size,
@@ -923,16 +746,6 @@ GNUNET_STRINGS_data_to_string (const void *data,
 }
 
 
-/**
- * Return the base32crockford encoding of the given buffer.
- *
- * The returned string will be freshly allocated, and must be free'd
- * with GNUNET_free().
- *
- * @param buffer with data
- * @param size size of the buffer
- * @return freshly allocated, null-terminated string
- */
 char *
 GNUNET_STRINGS_data_to_string_alloc (const void *buf, size_t size)
 {
@@ -958,17 +771,7 @@ GNUNET_STRINGS_data_to_string_alloc (const void *buf, 
size_t size)
 }
 
 
-/**
- * Convert Crockford Base32hex encoding back to data.
- * @a out_size must match exactly the size of the data before it was encoded.
- *
- * @param enc the encoding
- * @param enclen number of characters in @a enc (without 0-terminator, which 
can be missing)
- * @param out location where to store the decoded data
- * @param out_size size of the output buffer @a out
- * @return #GNUNET_OK on success, #GNUNET_SYSERR if result has the wrong 
encoding
- */
-int
+enum GNUNET_GenericReturnValue
 GNUNET_STRINGS_string_to_data (const char *enc,
                                size_t enclen,
                                void *out,
@@ -1034,23 +837,49 @@ GNUNET_STRINGS_string_to_data (const char *enc,
 }
 
 
-/**
- * Parse a path that might be an URI.
- *
- * @param path path to parse. Must be NULL-terminated.
- * @param scheme_part a pointer to 'char *' where a pointer to a string that
- *        represents the URI scheme will be stored. Can be NULL. The string is
- *        allocated by the function, and should be freed by GNUNET_free() when
- *        it is no longer needed.
- * @param path_part a pointer to 'const char *' where a pointer to the path
- *        part of the URI will be stored. Can be NULL. Points to the same block
- *        of memory as 'path', and thus must not be freed. Might point to '\0',
- *        if path part is zero-length.
- * @return GNUNET_YES if it's an URI, GNUNET_NO otherwise. If 'path' is not
- *         an URI, '* scheme_part' and '*path_part' will remain unchanged
- *         (if they weren't NULL).
- */
-int
+enum GNUNET_GenericReturnValue
+GNUNET_STRINGS_string_to_data_alloc (const char *enc,
+                                     size_t enclen,
+                                     void **out,
+                                     size_t *out_size)
+{
+  size_t size;
+  void *data;
+  int res;
+
+  size = (enclen * 5) / 8;
+  if (size >= GNUNET_MAX_MALLOC_CHECKED)
+  {
+    GNUNET_break_op (0);
+    return GNUNET_SYSERR;
+  }
+  data = GNUNET_malloc (size);
+  res = GNUNET_STRINGS_string_to_data (enc,
+                                       enclen,
+                                       data,
+                                       size);
+  if ( (0 < size) &&
+       (GNUNET_OK != res) )
+  {
+    size--;
+    res = GNUNET_STRINGS_string_to_data (enc,
+                                         enclen,
+                                         data,
+                                         size);
+  }
+  if (GNUNET_OK != res)
+  {
+    GNUNET_break_op (0);
+    GNUNET_free (data);
+    return GNUNET_SYSERR;
+  }
+  *out = data;
+  *out_size = size;
+  return GNUNET_OK;
+}
+
+
+enum GNUNET_GenericReturnValue
 GNUNET_STRINGS_parse_uri (const char *path,
                           char **scheme_part,
                           const char **path_part)
@@ -1112,21 +941,7 @@ GNUNET_STRINGS_parse_uri (const char *path,
 }
 
 
-/**
- * Check whether @a filename is absolute or not, and if it's an URI
- *
- * @param filename filename to check
- * @param can_be_uri #GNUNET_YES to check for being URI, #GNUNET_NO - to
- *        assume it's not URI
- * @param r_is_uri a pointer to an int that is set to #GNUNET_YES if @a 
filename
- *        is URI and to #GNUNET_NO otherwise. Can be NULL. If @a can_be_uri is
- *        not #GNUNET_YES, `* r_is_uri` is set to #GNUNET_NO.
- * @param r_uri_scheme a pointer to a char * that is set to a pointer to URI 
scheme.
- *        The string is allocated by the function, and should be freed with
- *        GNUNET_free(). Can be NULL.
- * @return #GNUNET_YES if @a filename is absolute, #GNUNET_NO otherwise.
- */
-int
+enum GNUNET_GenericReturnValue
 GNUNET_STRINGS_path_is_absolute (const char *filename,
                                  int can_be_uri,
                                  int *r_is_uri,
@@ -1168,15 +983,7 @@ GNUNET_STRINGS_path_is_absolute (const char *filename,
 }
 
 
-/**
- * Perform @a checks on @a filename.
- *
- * @param filename file to check
- * @param checks checks to perform
- * @return #GNUNET_YES if all checks pass, #GNUNET_NO if at least one of them
- *         fails, #GNUNET_SYSERR when a check can't be performed
- */
-int
+enum GNUNET_GenericReturnValue
 GNUNET_STRINGS_check_filename (const char *filename,
                                enum GNUNET_STRINGS_FilenameCheck checks)
 {
@@ -1209,19 +1016,7 @@ GNUNET_STRINGS_check_filename (const char *filename,
 }
 
 
-/**
- * Tries to convert @a zt_addr string to an IPv6 address.
- * The string is expected to have the format "[ABCD::01]:80".
- *
- * @param zt_addr 0-terminated string. May be mangled by the function.
- * @param addrlen length of @a zt_addr (not counting 0-terminator).
- * @param r_buf a buffer to fill. Initially gets filled with zeroes,
- *        then its sin6_port, sin6_family and sin6_addr are set appropriately.
- * @return #GNUNET_OK if conversion succeeded.
- *         #GNUNET_SYSERR otherwise, in which
- *         case the contents of @a r_buf are undefined.
- */
-int
+enum GNUNET_GenericReturnValue
 GNUNET_STRINGS_to_address_ipv6 (const char *zt_addr,
                                 uint16_t addrlen,
                                 struct sockaddr_in6 *r_buf)
@@ -1284,18 +1079,7 @@ GNUNET_STRINGS_to_address_ipv6 (const char *zt_addr,
 }
 
 
-/**
- * Tries to convert 'zt_addr' string to an IPv4 address.
- * The string is expected to have the format "1.2.3.4:80".
- *
- * @param zt_addr 0-terminated string. May be mangled by the function.
- * @param addrlen length of @a zt_addr (not counting 0-terminator).
- * @param r_buf a buffer to fill.
- * @return #GNUNET_OK if conversion succeeded.
- *         #GNUNET_SYSERR otherwise, in which case
- *         the contents of @a r_buf are undefined.
- */
-int
+enum GNUNET_GenericReturnValue
 GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr,
                                 uint16_t addrlen,
                                 struct sockaddr_in *r_buf)
@@ -1333,18 +1117,7 @@ GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr,
 }
 
 
-/**
- * Tries to convert @a addr string to an IP (v4 or v6) address.
- * Will automatically decide whether to treat 'addr' as v4 or v6 address.
- *
- * @param addr a string, may not be 0-terminated.
- * @param addrlen number of bytes in @a addr (if addr is 0-terminated,
- *        0-terminator should not be counted towards addrlen).
- * @param r_buf a buffer to fill.
- * @return #GNUNET_OK if conversion succeeded. #GNUNET_SYSERR otherwise, in 
which
- *         case the contents of @a r_buf are undefined.
- */
-int
+enum GNUNET_GenericReturnValue
 GNUNET_STRINGS_to_address_ip (const char *addr,
                               uint16_t addrlen,
                               struct sockaddr_storage *r_buf)
@@ -1359,15 +1132,6 @@ GNUNET_STRINGS_to_address_ip (const char *addr,
 }
 
 
-/**
- * Parse an address given as a string into a
- * `struct sockaddr`.
- *
- * @param addr the address
- * @param[out] af set to the parsed address family (e.g. AF_INET)
- * @param[out] sa set to the parsed address
- * @return 0 on error, otherwise number of bytes in @a sa
- */
 size_t
 GNUNET_STRINGS_parse_socket_addr (const char *addr,
                                   uint8_t *af,
@@ -1441,21 +1205,7 @@ _make_continuous_arg_copy (int argc, char *const *argv)
 }
 
 
-/**
- * Returns utf-8 encoded arguments.
- * Does nothing (returns a copy of argc and argv) on any platform
- * other than W32.
- * Returned argv has u8argv[u8argc] == NULL.
- * Returned argv is a single memory block, and can be freed with a single
- *   GNUNET_free() call.
- *
- * @param argc argc (as given by main())
- * @param argv argv (as given by main())
- * @param u8argc a location to store new argc in (though it's th same as argc)
- * @param u8argv a location to store new argv in
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
- */
-int
+enum GNUNET_GenericReturnValue
 GNUNET_STRINGS_get_utf8_args (int argc,
                               char *const *argv,
                               int *u8argc,
@@ -1478,7 +1228,7 @@ GNUNET_STRINGS_get_utf8_args (int argc,
  * @return #GNUNET_OK on success, #GNUNET_SYSERR if the
  *         @a port_policy is malformed
  */
-static int
+static enum GNUNET_GenericReturnValue
 parse_port_policy (const char *port_policy,
                    struct GNUNET_STRINGS_PortPolicy *pp)
 {
@@ -1523,18 +1273,6 @@ parse_port_policy (const char *port_policy,
 }
 
 
-/**
- * Parse an IPv4 network policy. The argument specifies a list of
- * subnets. The format is
- * <tt>(network[/netmask][:SPORT[-DPORT]];)*</tt> (no whitespace, must
- * be terminated with a semicolon). The network must be given in
- * dotted-decimal notation. The netmask can be given in CIDR notation
- * (/16) or in dotted-decimal (/255.255.0.0).
- *
- * @param routeListX a string specifying the IPv4 subnets
- * @return the converted list, terminated with all zeros;
- *         NULL if the synatx is flawed
- */
 struct GNUNET_STRINGS_IPv4NetworkPolicy *
 GNUNET_STRINGS_parse_ipv4_policy (const char *routeListX)
 {
@@ -1716,17 +1454,6 @@ GNUNET_STRINGS_parse_ipv4_policy (const char *routeListX)
 }
 
 
-/**
- * Parse an IPv6 network policy. The argument specifies a list of
- * subnets. The format is <tt>(network[/netmask[:SPORT[-DPORT]]];)*</tt>
- * (no whitespace, must be terminated with a semicolon). The network
- * must be given in colon-hex notation.  The netmask must be given in
- * CIDR notation (/16) or can be omitted to specify a single host.
- * Note that the netmask is mandatory if ports are specified.
- *
- * @param routeListX a string specifying the policy
- * @return the converted list, 0-terminated, NULL if the synatx is flawed
- */
 struct GNUNET_STRINGS_IPv6NetworkPolicy *
 GNUNET_STRINGS_parse_ipv6_policy (const char *routeListX)
 {
@@ -1863,17 +1590,10 @@ static char *cvt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                    "0123456789+/";
 
 
-/**
- * Encode into Base64.
- *
- * @param in the data to encode
- * @param len the length of the input
- * @param output where to write the output (*output should be NULL,
- *   is allocated)
- * @return the size of the output
- */
 size_t
-GNUNET_STRINGS_base64_encode (const void *in, size_t len, char **output)
+GNUNET_STRINGS_base64_encode (const void *in,
+                              size_t len,
+                              char **output)
 {
   const char *data = in;
   size_t ret;
@@ -1919,17 +1639,10 @@ GNUNET_STRINGS_base64_encode (const void *in, size_t 
len, char **output)
 }
 
 
-/**
- * Encode into Base64url. RFC7515
- *
- * @param in the data to encode
- * @param len the length of the input
- * @param output where to write the output (*output should be NULL,
- *   is allocated)
- * @return the size of the output
- */
 size_t
-GNUNET_STRINGS_base64url_encode (const void *in, size_t len, char **output)
+GNUNET_STRINGS_base64url_encode (const void *in,
+                                 size_t len,
+                                 char **output)
 {
   char *enc;
   size_t pos;
@@ -1965,17 +1678,10 @@ GNUNET_STRINGS_base64url_encode (const void *in, size_t 
len, char **output)
    : ((a) == '+') ? 62 : ((a) == '/') ? 63 : -1)
 
 
-/**
- * Decode from Base64.
- *
- * @param data the data to encode
- * @param len the length of the input
- * @param output where to write the output (*output should be NULL,
- *   is allocated)
- * @return the size of the output
- */
 size_t
-GNUNET_STRINGS_base64_decode (const char *data, size_t len, void **out)
+GNUNET_STRINGS_base64_decode (const char *data,
+                              size_t len,
+                              void **out)
 {
   char *output;
   size_t ret = 0;
@@ -2037,17 +1743,10 @@ END:
 }
 
 
-/**
- * Decode from Base64url. RFC7515
- *
- * @param data the data to decode
- * @param len the length of the input
- * @param output where to write the output (*output should be NULL,
- *   is allocated)
- * @return the size of the output
- */
 size_t
-GNUNET_STRINGS_base64url_decode (const char *data, size_t len, void **out)
+GNUNET_STRINGS_base64url_decode (const char *data,
+                                 size_t len,
+                                 void **out)
 {
   char *s;
   int padding;
@@ -2090,17 +1789,10 @@ GNUNET_STRINGS_base64url_decode (const char *data, 
size_t len, void **out)
 }
 
 
-/**
- * url/percent encode (RFC3986).
- *
- * @param data the data to encode
- * @param len the length of the input
- * @param output where to write the output (*output should be NULL,
- *   is allocated)
- * @return the size of the output
- */
 size_t
-GNUNET_STRINGS_urldecode (const char *data, size_t len, char **out)
+GNUNET_STRINGS_urldecode (const char *data,
+                          size_t len,
+                          char **out)
 {
   const char *rpos = data;
   *out = GNUNET_malloc (len + 1); /* output should always fit into input */
@@ -2134,17 +1826,10 @@ GNUNET_STRINGS_urldecode (const char *data, size_t len, 
char **out)
 }
 
 
-/**
- * url/percent encode (RFC3986).
- *
- * @param data the data to decode
- * @param len the length of the input
- * @param output where to write the output (*output should be NULL,
- *   is allocated)
- * @return the size of the output
- */
 size_t
-GNUNET_STRINGS_urlencode (const char *data, size_t len, char **out)
+GNUNET_STRINGS_urlencode (const char *data,
+                          size_t len,
+                          char **out)
 {
   struct GNUNET_Buffer buf = { 0 };
   const uint8_t *i8 = (uint8_t *) data;

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]