Fixed compile warnings under windows
[oweals/gnunet.git] / src / util / pseudonym.c
index f529d11f8b703fcfc9b1ba6eb7e5746ce1751ae4..6693dadd2e8b5c6ce724b3ec4374321065767d9d 100644 (file)
 #include "gnunet_container_lib.h"
 #include "gnunet_disk_lib.h"
 #include "gnunet_pseudonym_lib.h"
+#include "gnunet_bio_lib.h"
+
+/** 
+ * Name of the directory which stores meta data for pseudonym
+ */
+#define PS_METADATA_DIR DIR_SEPARATOR_STR "data" DIR_SEPARATOR_STR "pseudonyms" DIR_SEPARATOR_STR "metadata" DIR_SEPARATOR_STR
+
+/** 
+ * Name of the directory which stores names for pseudonyms
+ */
+#define PS_NAMES_DIR    DIR_SEPARATOR_STR "data" DIR_SEPARATOR_STR "pseudonyms" DIR_SEPARATOR_STR "names"    DIR_SEPARATOR_STR
 
-#define PS_METADATA_DIR DIR_SEPARATOR_STR "data" DIR_SEPARATOR_STR "pseudonyms/metadata" DIR_SEPARATOR_STR
-#define PS_NAMES_DIR    DIR_SEPARATOR_STR "data" DIR_SEPARATOR_STR "pseudonyms/names"    DIR_SEPARATOR_STR
 
+/** 
+ * Registered callbacks for discovery of pseudonyms.
+ */
 struct DiscoveryCallback
 {
+  /** 
+   * This is a linked list.
+   */
   struct DiscoveryCallback *next;
+
+  /** 
+   * Function to call each time a pseudonym is discovered.
+   */
   GNUNET_PSEUDONYM_Iterator callback;
+
+  /** 
+   * Closure for callback.
+   */
   void *closure;
 };
 
+
+/** 
+ * Head of the linked list of functions to call when 
+ * new pseudonyms are added.
+ */
 static struct DiscoveryCallback *head;
 
 /**
  * Internal notification about new tracked URI.
+ * @param id a point to the hash code of pseudonym
+ * @param md meta data to be written
+ * @param rating rating of pseudonym
  */
 static void
 internal_notify (const GNUNET_HashCode * id,
@@ -62,9 +93,12 @@ internal_notify (const GNUNET_HashCode * id,
 /**
  * Register callback to be invoked whenever we discover
  * a new pseudonym.
+ * @param cfg configuration to use
+ * @param iterator iterator over pseudonym
+ * @param closure point to a closure
  */
 int
-GNUNET_PSEUDONYM_discovery_callback_register (struct
+GNUNET_PSEUDONYM_discovery_callback_register (const struct
                                               GNUNET_CONFIGURATION_Handle
                                               *cfg,
                                               GNUNET_PSEUDONYM_Iterator
@@ -83,6 +117,8 @@ GNUNET_PSEUDONYM_discovery_callback_register (struct
 
 /**
  * Unregister pseudonym discovery callback.
+ * @param iterator iterator over pseudonym
+ * @param closure point to a closure
  */
 int
 GNUNET_PSEUDONYM_discovery_callback_unregister (GNUNET_PSEUDONYM_Iterator
@@ -113,9 +149,13 @@ GNUNET_PSEUDONYM_discovery_callback_unregister (GNUNET_PSEUDONYM_Iterator
 /**
  * Get the filename (or directory name) for the given
  * pseudonym identifier and directory prefix.
+ * @param cfg configuration to use
+ * @param prefix path components to append to the private directory name
+ * @param psid hash code of pseudonym, can be NULL
+ * @return filename of the pseudonym (if psid != NULL) or directory with the data (if psid == NULL)
  */
 static char *
-get_data_filename (struct GNUNET_CONFIGURATION_Handle
+get_data_filename (const struct GNUNET_CONFIGURATION_Handle
                    *cfg, const char *prefix, const GNUNET_HashCode * psid)
 {
   struct GNUNET_CRYPTO_HashAsciiEncoded enc;
@@ -130,138 +170,102 @@ get_data_filename (struct GNUNET_CONFIGURATION_Handle
                                         NULL);
 }
 
+
+/**
+ * Write the pseudonym infomation into a file
+ * @param cfg configuration to use
+ * @param nsid hash code of a pseudonym
+ * @param meta meta data to be written into a file
+ * @param ranking ranking of a pseudonym
+ * @param ns_name name of a pseudonym
+ */
 static void
-write_pseudonym_info (struct GNUNET_CONFIGURATION_Handle *cfg,
+write_pseudonym_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
                       const GNUNET_HashCode * nsid,
                       const struct GNUNET_CONTAINER_MetaData *meta,
                       int32_t ranking, const char *ns_name)
 {
-  unsigned int size;
-  unsigned int tag;
-  unsigned int off;
-  char *buf;
   char *fn;
+  struct GNUNET_BIO_WriteHandle *fileW;
 
   fn = get_data_filename (cfg, PS_METADATA_DIR, nsid);
   GNUNET_assert (fn != NULL);
-  size = GNUNET_CONTAINER_meta_data_get_serialized_size (meta,
-                                                         GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL);
-  tag = size + sizeof (int) + 1;
-  off = 0;
-  if (ns_name != NULL)
-    {
-      off = strlen (ns_name);
-      tag += off;
-    }
-  buf = GNUNET_malloc (tag);
-  ((int *) buf)[0] = htonl (ranking);   /* ranking */
-  if (ns_name != NULL)
-    {
-      memcpy (&buf[sizeof (int)], ns_name, off + 1);
-    }
-  else
+  fileW = GNUNET_BIO_write_open(fn);
+  if (NULL != fileW) 
     {
-      buf[sizeof (int)] = '\0';
+      if ( (GNUNET_OK != GNUNET_BIO_write_int32(fileW, ranking)) ||
+          (GNUNET_OK != GNUNET_BIO_write_string(fileW, ns_name)) ||
+          (GNUNET_OK != GNUNET_BIO_write_meta_data(fileW, meta)) )
+       {
+         (void) GNUNET_BIO_write_close(fileW);
+         GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn));
+         GNUNET_free (fn);
+         return;
+       }
+      if (GNUNET_OK != GNUNET_BIO_write_close(fileW))
+       {
+         GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn));
+         GNUNET_free (fn);
+         return;
+       }
     }
-  GNUNET_assert
-    (size == GNUNET_CONTAINER_meta_data_serialize (meta,
-                                                   &buf[sizeof
-                                                        (int) +
-                                                        off + 1],
-                                                   size,
-                                                   GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL));
-  GNUNET_DISK_fn_write (fn, buf, tag, GNUNET_DISK_PERM_USER_READ
-      | GNUNET_DISK_PERM_USER_WRITE | GNUNET_DISK_PERM_GROUP_READ);
   GNUNET_free (fn);
-  GNUNET_free (buf);
   /* create entry for pseudonym name in names */
+  /* FIXME: 90% of what this call does is not needed
+     here => refactor code to only create the entry! */
   GNUNET_free_non_null (GNUNET_PSEUDONYM_id_to_name (cfg, nsid));
 }
 
+
+/**
+ * read the pseudonym infomation from a file
+ * @param cfg configuration to use
+ * @param nsid hash code of a pseudonym
+ * @param meta meta data to be read from a file
+ * @param ranking ranking of a pseudonym
+ * @param ns_name name of a pseudonym
+ */
 static int
-read_info (struct GNUNET_CONFIGURATION_Handle *cfg,
+read_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
            const GNUNET_HashCode * nsid,
            struct GNUNET_CONTAINER_MetaData **meta,
            int32_t * ranking, char **ns_name)
 {
-  unsigned long long len;
-  unsigned int size;
-  unsigned int zend;
-  struct stat sbuf;
-  char *buf;
   char *fn;
+  char *emsg;
+  struct GNUNET_BIO_ReadHandle *fileR;
 
-  if (meta != NULL)
-    *meta = NULL;
-  if (ns_name != NULL)
-    *ns_name = NULL;
   fn = get_data_filename (cfg, PS_METADATA_DIR, nsid);
   GNUNET_assert (fn != NULL);
-
-  if ((0 != STAT (fn, &sbuf))
-      || (GNUNET_OK != GNUNET_DISK_file_size (fn, &len, GNUNET_YES)))
-    {
-      GNUNET_free (fn);
-      return GNUNET_SYSERR;
-    }
-  if (len <= sizeof (int) + 1)
-    {
-      GNUNET_free (fn);
-      return GNUNET_SYSERR;
-    }
-  if (len > 16 * 1024 * 1024)
+  fileR = GNUNET_BIO_read_open(fn);
+  if (fileR == NULL)
     {
-      /* too big, must be invalid! remove! */
-      GNUNET_break (0);
-      if (0 != UNLINK (fn))
-        GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn);
       GNUNET_free (fn);
       return GNUNET_SYSERR;
     }
-  buf = GNUNET_malloc (len);
-  if (len != GNUNET_DISK_fn_read (fn, buf, len))
+  emsg = NULL;
+  if ( (GNUNET_OK != GNUNET_BIO_read_int32 (fileR, ranking)) ||
+       (GNUNET_OK != GNUNET_BIO_read_string(fileR, "Read string error!", ns_name, 200)) ||
+       (GNUNET_OK != GNUNET_BIO_read_meta_data(fileR, "Read meta data error!", meta)) )
     {
-      GNUNET_free (buf);
+      GNUNET_BIO_read_close(fileR, &emsg);
+      GNUNET_free_non_null (emsg);
+      GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn));
       GNUNET_free (fn);
       return GNUNET_SYSERR;
     }
-  if (ranking != NULL)
-    *ranking = ntohl (((int *) buf)[0]);
-  zend = sizeof (int);
-  while ((zend < len) && (buf[zend] != '\0'))
-    zend++;
-  if (zend == len)
+  if (GNUNET_OK != GNUNET_BIO_read_close(fileR, &emsg))
     {
-      GNUNET_free (buf);
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                 _("Failed to parse metadata about pseudonym from file `%s': %s\n"),
+                 fn,
+                 emsg);
+      GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn));
+      GNUNET_free_non_null (emsg);
       GNUNET_free (fn);
       return GNUNET_SYSERR;
     }
-  if (ns_name != NULL)
-    {
-      if (zend != sizeof (int))
-        *ns_name = GNUNET_strdup (&buf[sizeof (int)]);
-      else
-        *ns_name = NULL;
-    }
-  zend++;
-  size = len - zend;
-  if (meta != NULL)
-    {
-      *meta = GNUNET_CONTAINER_meta_data_deserialize (&buf[zend], size);
-      if ((*meta) == NULL)
-        {
-          /* invalid data! remove! */
-          GNUNET_break (0);
-          if (0 != UNLINK (fn))
-            GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
-                                      "unlink", fn);
-          GNUNET_free (buf);
-          GNUNET_free (fn);
-          return GNUNET_SYSERR;
-        }
-    }
   GNUNET_free (fn);
-  GNUNET_free (buf);
   return GNUNET_OK;
 }
 
@@ -270,38 +274,41 @@ read_info (struct GNUNET_CONFIGURATION_Handle *cfg,
 /**
  * Return the unique, human readable name for the given namespace.
  *
+ * @param cfg configuration 
+ * @param nsid cryptographic ID of the namespace
  * @return NULL on failure (should never happen)
  */
 char *
-GNUNET_PSEUDONYM_id_to_name (struct GNUNET_CONFIGURATION_Handle *cfg,
+GNUNET_PSEUDONYM_id_to_name (const struct GNUNET_CONFIGURATION_Handle *cfg,
                              const GNUNET_HashCode * nsid)
 {
   struct GNUNET_CONTAINER_MetaData *meta;
   char *name;
   GNUNET_HashCode nh;
   char *fn;
-  unsigned long long len;
-  struct GNUNET_IO_Handle *fh;
+  uint64_t len;
+  struct GNUNET_DISK_FileHandle *fh;
   unsigned int i;
   unsigned int idx;
   char *ret;
   struct stat sbuf;
+  int32_t temp = 0;
+  int32_t *rank = &temp;
 
   meta = NULL;
   name = NULL;
-  if (GNUNET_OK == read_info (cfg, nsid, &meta, NULL, &name))
+  if (GNUNET_OK == read_info (cfg, nsid, &meta, rank, &name))
     {
       if ((meta != NULL) && (name == NULL))
         name = GNUNET_CONTAINER_meta_data_get_first_by_types (meta,
-                                                              EXTRACTOR_TITLE,
-                                                              EXTRACTOR_FILENAME,
-                                                              EXTRACTOR_DESCRIPTION,
-                                                              EXTRACTOR_SUBJECT,
-                                                              EXTRACTOR_PUBLISHER,
-                                                              EXTRACTOR_AUTHOR,
-                                                              EXTRACTOR_COMMENT,
-                                                              EXTRACTOR_SUMMARY,
-                                                              EXTRACTOR_OWNER,
+                                                              EXTRACTOR_METATYPE_TITLE,
+                                                              EXTRACTOR_METATYPE_FILENAME,
+                                                              EXTRACTOR_METATYPE_DESCRIPTION,
+                                                              EXTRACTOR_METATYPE_SUBJECT,
+                                                              EXTRACTOR_METATYPE_PUBLISHER,
+                                                              EXTRACTOR_METATYPE_AUTHOR_NAME,
+                                                              EXTRACTOR_METATYPE_COMMENT,
+                                                              EXTRACTOR_METATYPE_SUMMARY,
                                                               -1);
       if (meta != NULL)
         {
@@ -319,8 +326,9 @@ GNUNET_PSEUDONYM_id_to_name (struct GNUNET_CONFIGURATION_Handle *cfg,
   if (0 == STAT (fn, &sbuf))
     GNUNET_DISK_file_size (fn, &len, GNUNET_YES);
   fh = GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_CREATE
-      | GNUNET_DISK_OPEN_READWRITE, GNUNET_DISK_PERM_USER_READ
-      | GNUNET_DISK_PERM_USER_WRITE);
+                              | GNUNET_DISK_OPEN_READWRITE,
+                              GNUNET_DISK_PERM_USER_READ |
+                              GNUNET_DISK_PERM_USER_WRITE);
   i = 0;
   idx = -1;
   while ((len >= sizeof (GNUNET_HashCode)) &&
@@ -342,7 +350,7 @@ GNUNET_PSEUDONYM_id_to_name (struct GNUNET_CONFIGURATION_Handle *cfg,
           GNUNET_DISK_file_write (fh, nsid, sizeof (GNUNET_HashCode)))
         GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "write", fn);
     }
-  GNUNET_DISK_file_close (&fh);
+  GNUNET_DISK_file_close (fh);
   ret = GNUNET_malloc (strlen (name) + 32);
   GNUNET_snprintf (ret, strlen (name) + 32, "%s-%u", name, idx);
   GNUNET_free (name);
@@ -353,19 +361,22 @@ GNUNET_PSEUDONYM_id_to_name (struct GNUNET_CONFIGURATION_Handle *cfg,
 /**
  * Get the namespace ID belonging to the given namespace name.
  *
+ * @param cfg configuration to use
+ * @param ns_uname human-readable name for the namespace
+ * @param nsid set to namespace ID based on 'ns_uname'
  * @return GNUNET_OK on success
  */
 int
-GNUNET_PSEUDONYM_name_to_id (struct GNUNET_CONFIGURATION_Handle *cfg,
+GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg,
                              const char *ns_uname, GNUNET_HashCode * nsid)
 {
   size_t slen;
-  unsigned long long len;
+  uint64_t len;
   unsigned int idx;
   char *name;
   GNUNET_HashCode nh;
   char *fn;
-  struct GNUNET_IO_Handle *fh;
+  struct GNUNET_DISK_FileHandle *fh;
 
   idx = -1;
   slen = strlen (ns_uname);
@@ -388,29 +399,53 @@ GNUNET_PSEUDONYM_name_to_id (struct GNUNET_CONFIGURATION_Handle *cfg,
       return GNUNET_SYSERR;
     }
   fh = GNUNET_DISK_file_open (fn, GNUNET_DISK_OPEN_CREATE
-      | GNUNET_DISK_OPEN_READWRITE, GNUNET_DISK_PERM_USER_READ
-      | GNUNET_DISK_PERM_USER_WRITE);
+                              | GNUNET_DISK_OPEN_READWRITE,
+                              GNUNET_DISK_PERM_USER_READ |
+                              GNUNET_DISK_PERM_USER_WRITE);
   GNUNET_free (fn);
-  GNUNET_DISK_file_seek (fh, idx * sizeof (GNUNET_HashCode), GNUNET_SEEK_SET);
-  if (sizeof (GNUNET_HashCode) != GNUNET_DISK_file_read (fh, nsid, sizeof (GNUNET_HashCode)))
+  GNUNET_DISK_file_seek (fh, idx * sizeof (GNUNET_HashCode),
+                         GNUNET_DISK_SEEK_SET);
+  if (sizeof (GNUNET_HashCode) !=
+      GNUNET_DISK_file_read (fh, nsid, sizeof (GNUNET_HashCode)))
     {
-      GNUNET_DISK_file_close (&fh);
+      GNUNET_DISK_file_close (fh);
       return GNUNET_SYSERR;
     }
-  GNUNET_DISK_file_close (&fh);
+  GNUNET_DISK_file_close (fh);
   return GNUNET_OK;
 }
 
 
 
-
+/**
+ * struct used to list the pseudonym
+ */
 struct ListPseudonymClosure
 {
+
+  /**
+   * iterator over pseudonym
+   */
   GNUNET_PSEUDONYM_Iterator iterator;
+
+  /**
+   * Closure for iterator.
+   */
   void *closure;
-  struct GNUNET_CONFIGURATION_Handle *cfg;
+
+  /**
+   * Configuration to use.
+   */
+  const struct GNUNET_CONFIGURATION_Handle *cfg;
 };
 
+
+
+/**
+ * the help function to list all available pseudonyms
+ * @param cls point to a struct ListPseudonymClosure
+ * @param fullname name of pseudonym
+ */
 static int
 list_pseudonym_helper (void *cls, const char *fullname)
 {
@@ -420,6 +455,7 @@ list_pseudonym_helper (void *cls, const char *fullname)
   int rating;
   struct GNUNET_CONTAINER_MetaData *meta;
   const char *fn;
+  char *str;
 
   if (strlen (fullname) < sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded))
     return GNUNET_OK;
@@ -431,19 +467,27 @@ list_pseudonym_helper (void *cls, const char *fullname)
   ret = GNUNET_OK;
   if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (fn, &id))
     return GNUNET_OK;           /* invalid name */
-  if (GNUNET_OK != read_info (c->cfg, &id, &meta, &rating, NULL))
+  str = NULL;
+  if (GNUNET_OK != read_info (c->cfg, &id, &meta, &rating, &str))
     return GNUNET_OK;           /* ignore entry */
+  GNUNET_free_non_null (str);
   if (c->iterator != NULL)
     ret = c->iterator (c->closure, &id, meta, rating);
   GNUNET_CONTAINER_meta_data_destroy (meta);
   return ret;
 }
 
+
 /**
  * List all available pseudonyms.
+ *
+ * @param cfg overall configuration 
+ * @param iterator function to call for each pseudonym
+ * @param closure closure for iterator
+ * @return number of pseudonyms found
  */
 int
-GNUNET_PSEUDONYM_list_all (struct GNUNET_CONFIGURATION_Handle *cfg,
+GNUNET_PSEUDONYM_list_all (const struct GNUNET_CONFIGURATION_Handle *cfg,
                            GNUNET_PSEUDONYM_Iterator iterator, void *closure)
 {
   struct ListPseudonymClosure cls;
@@ -461,16 +505,18 @@ GNUNET_PSEUDONYM_list_all (struct GNUNET_CONFIGURATION_Handle *cfg,
   return ret;
 }
 
+
 /**
  * Change the ranking of a pseudonym.
  *
+ * @param cfg overall configuration
  * @param nsid id of the pseudonym
  * @param delta by how much should the rating be
  *  changed?
  * @return new rating of the pseudonym
  */
 int
-GNUNET_PSEUDONYM_rank (struct GNUNET_CONFIGURATION_Handle *cfg,
+GNUNET_PSEUDONYM_rank (const struct GNUNET_CONFIGURATION_Handle *cfg,
                        const GNUNET_HashCode * nsid, int delta)
 {
   struct GNUNET_CONTAINER_MetaData *meta;
@@ -492,28 +538,18 @@ GNUNET_PSEUDONYM_rank (struct GNUNET_CONFIGURATION_Handle *cfg,
   return ranking;
 }
 
-/**
- * Insert metadata into existing MD record (passed as cls).
- */
-static int
-merge_meta_helper (EXTRACTOR_KeywordType type, const char *data, void *cls)
-{
-  struct GNUNET_CONTAINER_MetaData *meta = cls;
-  GNUNET_CONTAINER_meta_data_insert (meta, type, data);
-  return GNUNET_OK;
-}
-
-
 
 /**
  * Add a pseudonym to the set of known pseudonyms.
  * For all pseudonym advertisements that we discover
- * FSUI should automatically call this function.
+ * FS should automatically call this function.
  *
+ * @param cfg overall configuration
  * @param id the pseudonym identifier
+ * @param meta metadata for the pseudonym
  */
 void
-GNUNET_PSEUDONYM_add (struct GNUNET_CONFIGURATION_Handle *cfg,
+GNUNET_PSEUDONYM_add (const struct GNUNET_CONFIGURATION_Handle *cfg,
                       const GNUNET_HashCode * id,
                       const struct GNUNET_CONTAINER_MetaData *meta)
 {
@@ -530,7 +566,7 @@ GNUNET_PSEUDONYM_add (struct GNUNET_CONFIGURATION_Handle *cfg,
   if ((0 == STAT (fn, &sbuf)) &&
       (GNUNET_OK == read_info (cfg, id, &old, &ranking, &name)))
     {
-      GNUNET_CONTAINER_meta_data_get_contents (meta, &merge_meta_helper, old);
+      GNUNET_CONTAINER_meta_data_merge (old, meta);
       write_pseudonym_info (cfg, id, old, ranking, name);
       GNUNET_CONTAINER_meta_data_destroy (old);
       GNUNET_free_non_null (name);
@@ -544,7 +580,4 @@ GNUNET_PSEUDONYM_add (struct GNUNET_CONFIGURATION_Handle *cfg,
 }
 
 
-
-
-
 /* end of pseudonym.c */