Ejemplo n.º 1
0
/**
 * Function called to (recursively) add all of the files in the
 * directory to the tree.  Called by the directory scanner to initiate
 * the scan.  Does NOT yet add any metadata.
 *
 * @param filename file or directory to scan
 * @param dst where to store the resulting share tree item;
 *         NULL is stored in @a dst upon recoverable errors (#GNUNET_OK is returned)
 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
 */
static int
preprocess_file (const char *filename,
		 struct ScanTreeNode **dst)
{
  struct ScanTreeNode *item;
  struct stat sbuf;
  uint64_t fsize = 0;

  if ((0 != STAT (filename, &sbuf)) ||
      ((!S_ISDIR (sbuf.st_mode)) && (GNUNET_OK != GNUNET_DISK_file_size (
      filename, &fsize, GNUNET_NO, GNUNET_YES))))
  {
    /* If the file doesn't exist (or is not stat-able for any other reason)
       skip it (but report it), but do continue. */
    if (GNUNET_OK !=
	write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_SKIP_FILE,
		       filename, strlen (filename) + 1))
      return GNUNET_SYSERR;
    /* recoverable error, store 'NULL' in *dst */
    *dst = NULL;
    return GNUNET_OK;
  }

  /* Report the progress */
  if (GNUNET_OK !=
      write_message (S_ISDIR (sbuf.st_mode)
		     ? GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_PROGRESS_DIRECTORY
		     : GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_PROGRESS_FILE,
		     filename, strlen (filename) + 1))
    return GNUNET_SYSERR;
  item = GNUNET_new (struct ScanTreeNode);
  item->filename = GNUNET_strdup (filename);
  item->is_directory = (S_ISDIR (sbuf.st_mode)) ? GNUNET_YES : GNUNET_NO;
  item->file_size = fsize;
  if (GNUNET_YES == item->is_directory)
  {
    struct RecursionContext rc;

    rc.parent = item;
    rc.stop = GNUNET_NO;
    GNUNET_DISK_directory_scan (filename,
				&scan_callback,
				&rc);
    if ( (GNUNET_YES == rc.stop) ||
	 (GNUNET_OK !=
	  write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_PROGRESS_DIRECTORY,
			 "..", 3)) )
    {
      free_tree (item);
      return GNUNET_SYSERR;
    }
  }
  *dst = item;
  return GNUNET_OK;
}
Ejemplo n.º 2
0
/**
 * Get the namespace ID belonging to the given namespace name.
 *
 * @param cfg configuration to use
 * @param ns_uname unique (!) human-readable name for the namespace
 * @param nsid set to namespace ID based on 'ns_uname'
 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
 */
int
GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg,
    const char *ns_uname, struct GNUNET_HashCode * nsid)
{
  size_t slen;
  uint64_t len;
  unsigned int idx;
  char *name;
  struct GNUNET_HashCode nh;
  char *fn;
  struct GNUNET_DISK_FileHandle *fh;

  idx = -1;
  slen = strlen (ns_uname);
  while ((slen > 0) && (1 != SSCANF (&ns_uname[slen - 1], "-%u", &idx)))
    slen--;
  if (slen == 0)
    return GNUNET_SYSERR;
  name = GNUNET_strdup (ns_uname);
  name[slen - 1] = '\0';

  GNUNET_CRYPTO_hash (name, strlen (name), &nh);
  GNUNET_free (name);
  fn = get_data_filename (cfg, PS_NAMES_DIR, &nh);
  GNUNET_assert (fn != NULL);

  if ((GNUNET_OK != GNUNET_DISK_file_test (fn) ||
       (GNUNET_OK != GNUNET_DISK_file_size (fn, &len, GNUNET_YES, GNUNET_YES))) ||
      ((idx + 1) * sizeof (struct GNUNET_HashCode) > len))
  {
    GNUNET_free (fn);
    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_free (fn);
  if (GNUNET_SYSERR ==
      GNUNET_DISK_file_seek (fh, idx * sizeof (struct GNUNET_HashCode),
			     GNUNET_DISK_SEEK_SET))
  {
    GNUNET_DISK_file_close (fh);
    return GNUNET_SYSERR;
  }
  if (sizeof (struct GNUNET_HashCode) !=
      GNUNET_DISK_file_read (fh, nsid, sizeof (struct GNUNET_HashCode)))
  {
    GNUNET_DISK_file_close (fh);
    return GNUNET_SYSERR;
  }
  GNUNET_DISK_file_close (fh);
  return GNUNET_OK;
}
Ejemplo n.º 3
0
/**
 * Return unique variant of the namespace name.
 * Use it after GNUNET_PSEUDONYM_get_info() to make sure
 * that name is unique.
 *
 * @param cfg configuration
 * @param nsid cryptographic ID of the namespace
 * @param name name to uniquify
 * @param suffix if not NULL, filled with the suffix value
 * @return NULL on failure (should never happen), name on success.
 *         Free the name with GNUNET_free().
 */
char *
GNUNET_PSEUDONYM_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg,
    const struct GNUNET_HashCode * nsid, const char *name, unsigned int *suffix)
{
  struct GNUNET_HashCode nh;
  uint64_t len;
  char *fn;
  struct GNUNET_DISK_FileHandle *fh;
  unsigned int i;
  unsigned int idx;
  char *ret;
  struct stat sbuf;

  GNUNET_CRYPTO_hash (name, strlen (name), &nh);
  fn = get_data_filename (cfg, PS_NAMES_DIR, &nh);
  GNUNET_assert (fn != NULL);

  len = 0;
  if (0 == STAT (fn, &sbuf))
    GNUNET_break (GNUNET_OK == GNUNET_DISK_file_size (fn, &len, GNUNET_YES, 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);
  i = 0;
  idx = -1;
  while ((len >= sizeof (struct GNUNET_HashCode)) &&
         (sizeof (struct GNUNET_HashCode) ==
          GNUNET_DISK_file_read (fh, &nh, sizeof (struct GNUNET_HashCode))))
  {
    if (0 == memcmp (&nh, nsid, sizeof (struct GNUNET_HashCode)))
    {
      idx = i;
      break;
    }
    i++;
    len -= sizeof (struct GNUNET_HashCode);
  }
  if (idx == -1)
  {
    idx = i;
    if (sizeof (struct GNUNET_HashCode) !=
        GNUNET_DISK_file_write (fh, nsid, sizeof (struct GNUNET_HashCode)))
      LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "write", fn);
  }
  GNUNET_DISK_file_close (fh);
  ret = GNUNET_malloc (strlen (name) + 32);
  GNUNET_snprintf (ret, strlen (name) + 32, "%s-%u", name, idx);
  if (suffix != NULL)
    *suffix = idx;
  GNUNET_free (fn);
  return ret;
}
/**
 * Function to load keys
 */
static int
load_keys (const struct GNUNET_CONFIGURATION_Handle *c)
{
    char *data_dir;
    char *idfile;
    uint64_t fsize;

    data_dir = NULL;
    idfile = NULL;
    fsize = 0;
    data_dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR);
    GNUNET_asprintf (&idfile, "%s/testing_hostkeys.ecc", data_dir);
    GNUNET_free (data_dir);
    data_dir = NULL;
    if (GNUNET_OK !=
            GNUNET_DISK_file_size (idfile, &fsize, GNUNET_YES, GNUNET_YES))
    {
        GNUNET_free (idfile);
        return GNUNET_SYSERR;
    }
    if (0 != (fsize % GNUNET_TESTING_HOSTKEYFILESIZE))
    {
        LOG (GNUNET_ERROR_TYPE_ERROR,
             _("Incorrect hostkey file format: %s\n"), idfile);
        GNUNET_free (idfile);
        return GNUNET_SYSERR;
    }
    hostkeys_fd = GNUNET_DISK_file_open (idfile, GNUNET_DISK_OPEN_READ,
                                         GNUNET_DISK_PERM_NONE);
    if (NULL == hostkeys_fd)
    {
        GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", idfile);
        GNUNET_free (idfile);
        return GNUNET_SYSERR;
    }
    GNUNET_free (idfile);
    idfile = NULL;
    hostkeys_data = GNUNET_DISK_file_map (hostkeys_fd,
                                          &hostkeys_map,
                                          GNUNET_DISK_MAP_TYPE_READ,
                                          fsize);
    if (NULL == hostkeys_data)
    {

        GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "mmap");
        return GNUNET_SYSERR;
    }
    num_hostkeys = fsize / GNUNET_TESTING_HOSTKEYFILESIZE;
    return GNUNET_OK;
}
Ejemplo n.º 5
0
/**
 * Main function that will be run by the scheduler.
 *
 * @param cls closure
 * @param args remaining command-line arguments
 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
 * @param cfg configuration
 */
static void
run (void *cls, char *const *args, const char *cfgfile,
     const struct GNUNET_CONFIGURATION_Handle *cfg)
{
  struct GNUNET_DISK_MapHandle *map;
  struct GNUNET_DISK_FileHandle *h;
  void *data;
  size_t len;
  uint64_t size;
  const char *filename;
  int i;

  if (NULL == args[0])
  {
    FPRINTF (stderr, "%s",  _("You must specify a filename to inspect.\n"));
    ret = 1;
    return;
  }
  i = 0;
  while (NULL != (filename = args[i++]))
  {
    if ((GNUNET_OK != GNUNET_DISK_file_size (filename, &size, GNUNET_YES, GNUNET_YES)) ||
        (NULL ==
         (h =
          GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ,
                                 GNUNET_DISK_PERM_NONE))))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to read directory `%s'\n"),
                  filename);
      ret = 1;
      continue;
    }
    len = (size_t) size;
    data = GNUNET_DISK_file_map (h, &map, GNUNET_DISK_MAP_TYPE_READ, len);
    GNUNET_assert (NULL != data);
    if (GNUNET_OK != GNUNET_FS_directory_list_contents (len, data, 0, &print_entry, NULL))
      fprintf (stdout, _("`%s' is not a GNUnet directory\n"),
	       filename);
    else
      printf ("\n");
    GNUNET_DISK_file_unmap (map);
    GNUNET_DISK_file_close (h);
  }
}
Ejemplo n.º 6
0
/**
 * Compute the hash of an entire file.
 *
 * @param priority scheduling priority to use
 * @param filename name of file to hash
 * @param blocksize number of bytes to process in one task
 * @param callback function to call upon completion
 * @param callback_cls closure for callback
 * @return NULL on (immediate) errror
 */
struct GNUNET_CRYPTO_FileHashContext *
GNUNET_CRYPTO_hash_file (enum GNUNET_SCHEDULER_Priority priority,
                         const char *filename, size_t blocksize,
                         GNUNET_CRYPTO_HashCompletedCallback callback,
                         void *callback_cls)
{
    struct GNUNET_CRYPTO_FileHashContext *fhc;

    GNUNET_assert (blocksize > 0);
    fhc =
        GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_FileHashContext) + blocksize);
    fhc->callback = callback;
    fhc->callback_cls = callback_cls;
    fhc->buffer = (unsigned char *) &fhc[1];
    fhc->filename = GNUNET_strdup (filename);
    if (GPG_ERR_NO_ERROR != gcry_md_open (&fhc->md, GCRY_MD_SHA512, 0))
    {
        GNUNET_break (0);
        GNUNET_free (fhc);
        return NULL;
    }
    fhc->bsize = blocksize;
    if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fhc->fsize, GNUNET_NO, GNUNET_YES))
    {
        GNUNET_free (fhc->filename);
        GNUNET_free (fhc);
        return NULL;
    }
    fhc->fh =
        GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ,
                               GNUNET_DISK_PERM_NONE);
    if (!fhc->fh)
    {
        GNUNET_free (fhc->filename);
        GNUNET_free (fhc);
        return NULL;
    }
    fhc->priority = priority;
    fhc->task =
        GNUNET_SCHEDULER_add_with_priority (priority, &file_hash_task, fhc);
    return fhc;
}
Ejemplo n.º 7
0
static int
testOpenClose ()
{
  struct GNUNET_DISK_FileHandle *fh;
  uint64_t size;

  fh = GNUNET_DISK_file_open (".testfile",
                              GNUNET_DISK_OPEN_READWRITE |
                              GNUNET_DISK_OPEN_CREATE,
                              GNUNET_DISK_PERM_USER_READ |
                              GNUNET_DISK_PERM_USER_WRITE);
  GNUNET_assert (GNUNET_NO == GNUNET_DISK_handle_invalid (fh));
  GNUNET_break (5 == GNUNET_DISK_file_write (fh, "Hello", 5));
  GNUNET_DISK_file_close (fh);
  GNUNET_break (GNUNET_OK ==
                GNUNET_DISK_file_size (".testfile", &size, GNUNET_NO, GNUNET_YES));
  if (size != 5)
    return 1;
  GNUNET_break (0 == UNLINK (".testfile"));

  return 0;
}
Ejemplo n.º 8
0
/**
 * Unindex a file.
 *
 * @param h handle to the file sharing subsystem
 * @param filename file to unindex
 * @param cctx initial value for the client context
 * @return NULL on error, otherwise handle
 */
struct GNUNET_FS_UnindexContext *
GNUNET_FS_unindex_start (struct GNUNET_FS_Handle *h,
			 const char *filename,
                         void *cctx)
{
  struct GNUNET_FS_UnindexContext *uc;
  struct GNUNET_FS_ProgressInfo pi;
  uint64_t size;

  if (GNUNET_OK !=
      GNUNET_DISK_file_size (filename,
                             &size,
                             GNUNET_YES,
                             GNUNET_YES))
    return NULL;
  uc = GNUNET_new (struct GNUNET_FS_UnindexContext);
  uc->h = h;
  uc->filename = GNUNET_strdup (filename);
  uc->start_time = GNUNET_TIME_absolute_get ();
  uc->file_size = size;
  uc->client_info = cctx;
  uc->seen_dh = GNUNET_CONTAINER_multihashmap_create (4,
                                                       GNUNET_NO);
  GNUNET_FS_unindex_sync_ (uc);
  pi.status = GNUNET_FS_STATUS_UNINDEX_START;
  pi.value.unindex.eta = GNUNET_TIME_UNIT_FOREVER_REL;
  GNUNET_FS_unindex_make_status_ (&pi, uc, 0);
  uc->fhc =
      GNUNET_CRYPTO_hash_file (GNUNET_SCHEDULER_PRIORITY_IDLE,
                               filename,
                               HASHING_BLOCKSIZE,
                               &GNUNET_FS_unindex_process_hash_, uc);
  uc->top = GNUNET_FS_make_top (h,
                                &GNUNET_FS_unindex_signal_suspend_,
                                uc);
  return uc;
}
/**
 * Create a message with full information about sensor
 *
 * @param sensorname Name of sensor requested
 * @return Message ready to be sent to client or NULL on error
 */
static struct GNUNET_SENSOR_SensorFullMessage *
create_full_sensor_msg (char *sensorname)
{
  struct GNUNET_HashCode key;
  struct GNUNET_SENSOR_SensorInfo *sensor;
  struct GNUNET_SENSOR_SensorFullMessage *msg;
  char *sensor_path;
  char *sensorscript_path;
  uint64_t sensorname_size;
  uint64_t sensorfile_size;
  uint64_t sensorscriptname_size;
  uint64_t sensorscript_size;
  uint64_t total_size;
  void *dummy;

  GNUNET_CRYPTO_hash (sensorname, strlen (sensorname) + 1, &key);
  sensor = GNUNET_CONTAINER_multihashmap_get (sensors, &key);
  if (NULL == sensor)
    return NULL;
  GNUNET_asprintf (&sensor_path,
                   "%s%s",
                   sensor_dir,
                   sensorname);
  if (GNUNET_OK !=
      GNUNET_DISK_file_size (sensor_path,
                             &sensorfile_size,
                             GNUNET_NO,
                             GNUNET_YES))
  {
    GNUNET_free (sensor_dir);
    GNUNET_free (sensor_path);
    return NULL;
  }
  sensorname_size = strlen (sensorname) + 1;
  sensorscript_path = NULL;
  sensorscript_size = 0;
  sensorscriptname_size = 0;
  /* Test if there is an associated script */
  if (NULL != sensor->ext_process)
  {
    GNUNET_asprintf (&sensorscript_path,
                     "%s%s-files%s%s",
                     sensor_dir,
                     sensor->name,
                     DIR_SEPARATOR_STR,
                     sensor->ext_process);
    if (GNUNET_OK ==
        GNUNET_DISK_file_size (sensorscript_path,
                               &sensorscript_size,
                               GNUNET_NO,
                               GNUNET_YES))
      sensorscriptname_size = strlen (sensor->ext_process) + 1;
  }
  /* Construct the msg */
  total_size =
      sizeof (struct GNUNET_SENSOR_SensorFullMessage) + sensorname_size +
      sensorfile_size + sensorscriptname_size + sensorscript_size;
  msg = GNUNET_malloc (total_size);
  msg->header.size = htons (total_size);
  msg->header.type = htons (GNUNET_MESSAGE_TYPE_SENSOR_FULL);
  msg->sensorname_size = htons (sensorname_size);
  msg->sensorfile_size = htons (sensorfile_size);
  msg->scriptname_size = htons (sensorscriptname_size);
  msg->scriptfile_size = htons (sensorscript_size);
  dummy = &msg[1];
  memcpy (dummy, sensorname, sensorname_size);
  dummy += sensorname_size;
  GNUNET_DISK_fn_read (sensor_path, dummy, sensorfile_size);
  dummy += sensorfile_size;
  if (sensorscriptname_size > 0)
  {
    memcpy (dummy, sensor->ext_process, sensorscriptname_size);
    dummy += sensorscriptname_size;
    GNUNET_DISK_fn_read (sensorscript_path, dummy, sensorscript_size);
  }
  GNUNET_free_non_null (sensorscript_path);
  GNUNET_free (sensor_path);
  return msg;
}
Ejemplo n.º 10
0
/**
 * Load a set of hosts from a configuration file.
 *
 * @param filename file with the host specification
 * @param cfg the configuration to use as a template while starting a controller
 *          on any of the loaded hosts.  Operation queue sizes specific to a host
 *          are also read from this configuration handle
 * @param hosts set to the hosts found in the file; caller must free this if
 *          number of hosts returned is greater than 0
 * @return number of hosts returned in 'hosts', 0 on error
 */
unsigned int
GNUNET_TESTBED_hosts_load_from_file (const char *filename,
                                     const struct GNUNET_CONFIGURATION_Handle
                                     *cfg,
                                     struct GNUNET_TESTBED_Host ***hosts)
{
  //struct GNUNET_TESTBED_Host **host_array;
  struct GNUNET_TESTBED_Host *starting_host;
  char *data;
  char *buf;
  char *username;
  char *hostname;
  regex_t rex;
  regmatch_t pmatch[6];
  uint64_t fs;
  short int port;
  unsigned int offset;
  unsigned int count;


  GNUNET_assert (NULL != filename);
  if (GNUNET_YES != GNUNET_DISK_file_test (filename))
  {
    LOG (GNUNET_ERROR_TYPE_WARNING, _("Hosts file %s not found\n"), filename);
    return 0;
  }
  if (GNUNET_OK !=
      GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES))
    fs = 0;
  if (0 == fs)
  {
    LOG (GNUNET_ERROR_TYPE_WARNING, _("Hosts file %s has no data\n"), filename);
    return 0;
  }
  data = GNUNET_malloc (fs);
  if (fs != GNUNET_DISK_fn_read (filename, data, fs))
  {
    GNUNET_free (data);
    LOG (GNUNET_ERROR_TYPE_WARNING, _("Hosts file %s cannot be read\n"),
         filename);
    return 0;
  }
  buf = data;
  offset = 0;
  starting_host = NULL;
  count = 0;
  /* refer RFC 952 and RFC 1123 for valid hostnames */
  GNUNET_assert (0 == regcomp (&rex,
                               "^(([[:alnum:]]+)@)?" /* username */
                               "([[:alnum:]]+[-[:alnum:]_\\.]+)" /* hostname */
                               "(:([[:digit:]]{1,5}))?", /* port */
                               REG_EXTENDED | REG_ICASE));
  while (offset < (fs - 1))
  {
    offset++;
    if (((data[offset] == '\n')) && (buf != &data[offset]))
    {
      unsigned int size;

      data[offset] = '\0';
      username = NULL;
      hostname = NULL;
      port = 0;
      if ((REG_NOMATCH == regexec (&rex, buf, 6, pmatch, 0))
          || (-1 == pmatch[3].rm_so))
      {
        GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                    "Error reading line `%s' in hostfile\n", buf);
        buf = &data[offset + 1];
        continue;
      }
      if (-1 != pmatch[2].rm_so)
      {
        size = pmatch[2].rm_eo - pmatch[2].rm_so;
        username = GNUNET_malloc (size + 1);
        username[size] = '\0';
        GNUNET_assert (NULL != strncpy (username, buf + pmatch[2].rm_so, size));
      }
      if (-1 != pmatch[5].rm_so)
      {
        (void) SSCANF (buf + pmatch[5].rm_so, "%5hd", &port);
      }
      size = pmatch[3].rm_eo - pmatch[3].rm_so;
      hostname = GNUNET_malloc (size + 1);
      hostname[size] = '\0';
      GNUNET_assert (NULL != strncpy (hostname, buf + pmatch[3].rm_so, size));
      LOG (GNUNET_ERROR_TYPE_DEBUG,
           "Successfully read host %s, port %d and user %s from file\n",
           (NULL == hostname) ? "NULL" : hostname,
           port,
           (NULL == username) ? "NULL" : username);
      /* We store hosts in a static list; hence we only require the starting
       * host pointer in that list to access the newly created list of hosts */
      if (NULL == starting_host)
        starting_host = GNUNET_TESTBED_host_create (hostname, username, cfg,
                                                    port);
      else
        (void) GNUNET_TESTBED_host_create (hostname, username, cfg, port);
      count++;
      GNUNET_free_non_null (username);
      GNUNET_free (hostname);
      buf = &data[offset + 1];
    }
    else if ((data[offset] == '\n') || (data[offset] == '\0'))
      buf = &data[offset + 1];
  }
  regfree (&rex);
  GNUNET_free (data);
  if (NULL == starting_host)
    return 0;
  *hosts = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Host *) * count);
  memcpy (*hosts, &host_list[GNUNET_TESTBED_host_get_id_ (starting_host)],
          sizeof (struct GNUNET_TESTBED_Host *) * count);
  return count;
}
Ejemplo n.º 11
0
int
main (int argc, char *argv[])
{
  struct GNUNET_DISK_FileHandle *fh;
  struct GNUNET_HELLO_Message *orig;
  struct GNUNET_HELLO_Message *result;
  struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pk;
  uint64_t fsize;

  GNUNET_log_setup ("gnunet-hello", "INFO", NULL);
  if (argc != 2)
  {
    FPRINTF (stderr,
	     "%s",
	     _("Call with name of HELLO file to modify.\n"));
    return 1;
  }
  if (GNUNET_OK != GNUNET_DISK_file_size (argv[1], &fsize, GNUNET_YES, GNUNET_YES))
  {
    FPRINTF (stderr,
	     _("Error accessing file `%s': %s\n"),
	     argv[1],
	     STRERROR (errno));
    return 1;
  }
  if (fsize > 65536)
  {
    FPRINTF (stderr,
	     _("File `%s' is too big to be a HELLO\n"),
	     argv[1]);
    return 1;
  }
  if (fsize < sizeof (struct GNUNET_MessageHeader))
  {
    FPRINTF (stderr,
	     _("File `%s' is too small to be a HELLO\n"),
	     argv[1]);
    return 1;
  }
  fh = GNUNET_DISK_file_open (argv[1], 
			      GNUNET_DISK_OPEN_READ,
			      GNUNET_DISK_PERM_USER_READ);
  if (NULL == fh)
  {
    FPRINTF (stderr,
	     _("Error opening file `%s': %s\n"),
	     argv[1],
	     STRERROR (errno));
    return 1;
  }
  {
    char buf[fsize] GNUNET_ALIGN;
    
    GNUNET_assert (fsize == 
		   GNUNET_DISK_file_read (fh, buf, fsize));
    GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh));
    orig = (struct GNUNET_HELLO_Message *) buf;
    if ( (fsize != GNUNET_HELLO_size (orig)) ||
	 (GNUNET_OK != GNUNET_HELLO_get_key (orig, &pk)) )
    {
      FPRINTF (stderr,
	       _("Did not find well-formed HELLO in file `%s'\n"),
	       argv[1]);
      return 1;
    }
    result = GNUNET_HELLO_create (&pk, &add_from_hello, &orig);
    GNUNET_assert (NULL != result);
     fh = GNUNET_DISK_file_open (argv[1], 
				 GNUNET_DISK_OPEN_WRITE,
				 GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE);
     if (NULL == fh)
     {
       FPRINTF (stderr,
		_("Error opening file `%s': %s\n"),
		argv[1],
		STRERROR (errno));
       GNUNET_free (result);
       return 1;
     }
     fsize = GNUNET_HELLO_size (result);
     if (fsize != GNUNET_DISK_file_write (fh,
					  result,
					  fsize))
     {
       FPRINTF (stderr,
		_("Error writing HELLO to file `%s': %s\n"),
		argv[1],
		STRERROR (errno));
       (void) GNUNET_DISK_file_close (fh);
       return 1;
     }
    GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh));
  }
  return 0;
}
Ejemplo n.º 12
0
/**
 * Create an entry for a file in a publish-structure.
 *
 * @param h handle to the file sharing subsystem
 * @param client_info initial value for the client-info value for this entry
 * @param filename name of the file or directory to publish
 * @param keywords under which keywords should this file be available
 *         directly; can be NULL
 * @param meta metadata for the file
 * @param do_index GNUNET_YES for index, GNUNET_NO for insertion,
 *                GNUNET_SYSERR for simulation
 * @param bo block options
 * @return publish structure entry for the file
 */
struct GNUNET_FS_FileInformation *
GNUNET_FS_file_information_create_from_file (struct GNUNET_FS_Handle *h,
                                             void *client_info,
                                             const char *filename,
                                             const struct GNUNET_FS_Uri
                                             *keywords,
                                             const struct
                                             GNUNET_CONTAINER_MetaData *meta,
                                             int do_index,
                                             const struct GNUNET_FS_BlockOptions
                                             *bo)
{
  struct FileInfo *fi;
  uint64_t fsize;
  struct GNUNET_FS_FileInformation *ret;
  const char *fn;
  const char *ss;

#if WINDOWS
  char fn_conv[MAX_PATH];
#endif

  /* FIXME: should includeSymLinks be GNUNET_NO or GNUNET_YES here? */
  if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fsize, GNUNET_NO, GNUNET_YES))
  {
    GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "stat", filename);
    return NULL;
  }
  fi = GNUNET_FS_make_file_reader_context_ (filename);
  if (fi == NULL)
  {
    GNUNET_break (0);
    return NULL;
  }
  ret =
      GNUNET_FS_file_information_create_from_reader (h, client_info,
                                                     fsize,
                                                     &GNUNET_FS_data_reader_file_,
                                                     fi, keywords, meta,
                                                     do_index, bo);
  if (ret == NULL)
    return NULL;
  ret->h = h;
  ret->filename = GNUNET_strdup (filename);
#if !WINDOWS
  fn = filename;
#else
  plibc_conv_to_win_path (filename, fn_conv);
  fn = fn_conv;
#endif
  while (NULL != (ss = strstr (fn, DIR_SEPARATOR_STR)))
    fn = ss + 1;
/* FIXME: If we assume that on other platforms CRT is UTF-8-aware, then
 * this should be changed to EXTRACTOR_METAFORMAT_UTF8
 */
#if !WINDOWS
  GNUNET_CONTAINER_meta_data_insert (ret->meta, "<gnunet>",
                                     EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME,
                                     EXTRACTOR_METAFORMAT_C_STRING,
                                     "text/plain", fn, strlen (fn) + 1);
#else
  GNUNET_CONTAINER_meta_data_insert (ret->meta, "<gnunet>",
                                     EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME,
                                     EXTRACTOR_METAFORMAT_UTF8,
                                     "text/plain", fn, strlen (fn) + 1);
#endif
  return ret;
}
Ejemplo n.º 13
0
/**
 * Create a new private key by reading it from a file.  If the
 * files does not exist, create a new key and write it to the
 * file.  Caller must free return value.  Note that this function
 * can not guarantee that another process might not be trying
 * the same operation on the same file at the same time.
 * If the contents of the file
 * are invalid the old file is deleted and a fresh key is
 * created.
 *
 * @param filename name of file to use to store the key
 * @return new private key, NULL on error (for example,
 *   permission denied)
 */
struct GNUNET_CRYPTO_EddsaPrivateKey *
GNUNET_CRYPTO_eddsa_key_create_from_file (const char *filename)
{
  struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
  struct GNUNET_DISK_FileHandle *fd;
  unsigned int cnt;
  int ec;
  uint64_t fs;

  if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (filename))
    return NULL;
  while (GNUNET_YES != GNUNET_DISK_file_test (filename))
  {
    fd = GNUNET_DISK_file_open (filename,
                                GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE
                                | GNUNET_DISK_OPEN_FAILIFEXISTS,
                                GNUNET_DISK_PERM_USER_READ |
                                GNUNET_DISK_PERM_USER_WRITE);
    if (NULL == fd)
    {
      if (EEXIST == errno)
      {
        if (GNUNET_YES != GNUNET_DISK_file_test (filename))
        {
          /* must exist but not be accessible, fail for good! */
          if (0 != ACCESS (filename, R_OK))
            LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", filename);
          else
            GNUNET_break (0);   /* what is going on!? */
          return NULL;
        }
        continue;
      }
      LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename);
      return NULL;
    }
    cnt = 0;
    while (GNUNET_YES !=
           GNUNET_DISK_file_lock (fd, 0,
                                  sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey),
                                  GNUNET_YES))
    {
      short_wait ();
      if (0 == ++cnt % 10)
      {
        ec = errno;
        LOG (GNUNET_ERROR_TYPE_ERROR,
             _("Could not acquire lock on file `%s': %s...\n"), filename,
             STRERROR (ec));
      }
    }
    LOG (GNUNET_ERROR_TYPE_INFO,
         _("Creating a new private key.  This may take a while.\n"));
    priv = GNUNET_CRYPTO_eddsa_key_create ();
    GNUNET_assert (NULL != priv);
    GNUNET_assert (sizeof (*priv) ==
                   GNUNET_DISK_file_write (fd, priv, sizeof (*priv)));
    GNUNET_DISK_file_sync (fd);
    if (GNUNET_YES !=
        GNUNET_DISK_file_unlock (fd, 0,
                                 sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)))
      LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
    GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
    return priv;
  }
  /* key file exists already, read it! */
  fd = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ,
                              GNUNET_DISK_PERM_NONE);
  if (NULL == fd)
  {
    LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename);
    return NULL;
  }
  cnt = 0;
  while (1)
  {
    if (GNUNET_YES !=
        GNUNET_DISK_file_lock (fd, 0,
                               sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey),
                               GNUNET_NO))
    {
      if (0 == ++cnt % 60)
      {
        ec = errno;
        LOG (GNUNET_ERROR_TYPE_ERROR,
             _("Could not acquire lock on file `%s': %s...\n"), filename,
             STRERROR (ec));
        LOG (GNUNET_ERROR_TYPE_ERROR,
             _
             ("This may be ok if someone is currently generating a private key.\n"));
      }
      short_wait ();
      continue;
    }
    if (GNUNET_YES != GNUNET_DISK_file_test (filename))
    {
      /* eh, what!? File we opened is now gone!? */
      LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", filename);
      if (GNUNET_YES !=
          GNUNET_DISK_file_unlock (fd, 0,
                                   sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)))
        LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
      GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd));

      return NULL;
    }
    if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES))
      fs = 0;
    if (fs < sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey))
    {
      /* maybe we got the read lock before the key generating
       * process had a chance to get the write lock; give it up! */
      if (GNUNET_YES !=
          GNUNET_DISK_file_unlock (fd, 0,
                                   sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)))
        LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
      if (0 == ++cnt % 10)
      {
        LOG (GNUNET_ERROR_TYPE_ERROR,
             _("When trying to read key file `%s' I found %u bytes but I need at least %u.\n"),
             filename, (unsigned int) fs,
             (unsigned int) sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey));
        LOG (GNUNET_ERROR_TYPE_ERROR,
             _("This may be ok if someone is currently generating a key.\n"));
      }
      short_wait ();                /* wait a bit longer! */
      continue;
    }
    break;
  }
  fs = sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey);
  priv = GNUNET_malloc (fs);
  GNUNET_assert (fs == GNUNET_DISK_file_read (fd, priv, fs));
  if (GNUNET_YES !=
      GNUNET_DISK_file_unlock (fd, 0,
                               sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)))
    LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
  GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
  return priv;
}
Ejemplo n.º 14
0
/**
 * Read the friends file.
 */
static void
read_friends_file (const struct GNUNET_CONFIGURATION_Handle *cfg)
{
  char *fn;
  char *data;
  size_t pos;
  struct GNUNET_PeerIdentity pid;
  uint64_t fsize;
  struct GNUNET_CRYPTO_HashAsciiEncoded enc;
  unsigned int entries_found;
  struct Peer *fl;

  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (cfg, "TOPOLOGY", "FRIENDS", &fn))
  {
    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
			       "topology", "FRIENDS");
    return;
  }
  if (GNUNET_OK != GNUNET_DISK_file_test (fn))
    GNUNET_DISK_fn_write (fn, NULL, 0,
                          GNUNET_DISK_PERM_USER_READ |
                          GNUNET_DISK_PERM_USER_WRITE);
  if (GNUNET_OK != GNUNET_DISK_file_size (fn,
      &fsize, GNUNET_NO, GNUNET_YES))
  {
    if ((friends_only) || (minimum_friend_count > 0))
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  _("Could not read friends list `%s'\n"), fn);
    GNUNET_free (fn);
    return;
  }
  if (fsize == 0)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Friends file `%s' is empty.\n"),
                fn);
    GNUNET_free (fn);
    return;
  }
  data = GNUNET_malloc_large (fsize);
  if (data == NULL)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Failed to read friends list from `%s': out of memory\n"),
                fn);
    GNUNET_free (fn);
    return;
  }
  if (fsize != GNUNET_DISK_fn_read (fn, data, fsize))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Failed to read friends list from `%s'\n"), fn);
    GNUNET_free (fn);
    GNUNET_free (data);
    return;
  }
  entries_found = 0;
  pos = 0;
  while ((pos < fsize) && isspace ((unsigned char) data[pos]))
    pos++;
  while ((fsize >= sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) &&
         (pos <=
          fsize - sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)))
  {
    memcpy (&enc, &data[pos], sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded));
    if (!isspace
        ((unsigned char)
         enc.encoding[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1]))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                  _
                  ("Syntax error in topology specification at offset %llu, skipping bytes.\n"),
                  (unsigned long long) pos);
      pos++;
      while ((pos < fsize) && (!isspace ((unsigned char) data[pos])))
        pos++;
      continue;
    }
    enc.encoding[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0';
    if (GNUNET_OK !=
        GNUNET_CRYPTO_hash_from_string ((char *) &enc, &pid.hashPubKey))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                  _
                  ("Syntax error in topology specification at offset %llu, skipping bytes `%s'.\n"),
                  (unsigned long long) pos, &enc);
    }
    else
    {
      if (0 != memcmp (&pid, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
      {
        entries_found++;
        fl = make_peer (&pid, NULL, GNUNET_YES);
        GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                    _("Found friend `%s' in configuration\n"),
                    GNUNET_i2s (&fl->pid));
      }
      else
      {
        GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                    _("Found myself `%s' in friend list (useless, ignored)\n"),
                    GNUNET_i2s (&pid));
      }
    }
    pos = pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded);
    while ((pos < fsize) && isspace ((unsigned char) data[pos]))
      pos++;
  }
  GNUNET_free (data);
  GNUNET_free (fn);
  GNUNET_STATISTICS_update (stats, gettext_noop ("# friends in configuration"),
                            entries_found, GNUNET_NO);
  if ((minimum_friend_count > entries_found) && (friends_only == GNUNET_NO))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                _
                ("Fewer friends specified than required by minimum friend count. Will only connect to friends.\n"));
  }
  if ((minimum_friend_count > target_connection_count) &&
      (friends_only == GNUNET_NO))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                _
                ("More friendly connections required than target total number of connections.\n"));
  }
}
Ejemplo n.º 15
0
/**
 * Initialize the database connections and associated
 * data structures (create tables and indices
 * as needed as well).
 *
 * @param plugin the plugin context (state for this module)
 * @return GNUNET_OK on success
 */
static int
database_setup (struct Plugin *plugin)
{
  char *afsdir;
  char *key;
  char *sub_system;
  const char *peer_id;
  char *peer;
  char *value;
  char *expiry;
  struct GNUNET_DISK_FileHandle *fh;
  struct GNUNET_PEERSTORE_Record *entry;
  struct GNUNET_HashCode hkey;
  size_t size;
  char *buffer;
  char *line;

  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, "peerstore-flat",
                                               "FILENAME", &afsdir))
  {
    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "peerstore-flat",
                               "FILENAME");
    return GNUNET_SYSERR;
  }
  if (GNUNET_OK != GNUNET_DISK_file_test (afsdir))
  {
    if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (afsdir))
    {
      GNUNET_break (0);
      GNUNET_free (afsdir);
      return GNUNET_SYSERR;
    }
  }
  /* afsdir should be UTF-8-encoded. If it isn't, it's a bug */
  plugin->fn = afsdir;

  fh = GNUNET_DISK_file_open (afsdir,
                              GNUNET_DISK_OPEN_CREATE |
                              GNUNET_DISK_OPEN_READWRITE,
                              GNUNET_DISK_PERM_USER_WRITE |
                              GNUNET_DISK_PERM_USER_READ);
  if (NULL == fh)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Unable to initialize file: %s.\n"),
                afsdir);
    return GNUNET_SYSERR;
  }

  /* Load data from file into hashmap */
  plugin->hm = GNUNET_CONTAINER_multihashmap_create (10,
                                                     GNUNET_NO);

  if (GNUNET_SYSERR == GNUNET_DISK_file_size (afsdir,
                                              &size,
                                              GNUNET_YES,
                                              GNUNET_YES))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Unable to get filesize: %s.\n"),
                afsdir);
    return GNUNET_SYSERR;
  }

  buffer = GNUNET_malloc (size + 1);

  if (GNUNET_SYSERR == GNUNET_DISK_file_read (fh,
                                              buffer,
                                              size))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Unable to read file: %s.\n"),
                afsdir);
    GNUNET_DISK_file_close (fh);
    GNUNET_free (buffer);
    return GNUNET_SYSERR;
  }
  
  buffer[size] = '\0';
  GNUNET_DISK_file_close (fh);
  if (0 < size) {
    line = strtok (buffer, "\n");
    while (line != NULL) {
      sub_system = strtok (line, ",");
      if (NULL == sub_system)
        break;
      peer = strtok (NULL, ",");
      if (NULL == peer)
        break;
      key = strtok (NULL, ",");
      if (NULL == key)
        break;
      value = strtok (NULL, ",");
      if (NULL == value)
        break;
      expiry = strtok (NULL, ",");
      if (NULL == expiry)
        break;
      entry = GNUNET_new (struct GNUNET_PEERSTORE_Record);
      entry->sub_system = GNUNET_strdup (sub_system);
      entry->key = GNUNET_strdup (key);
      GNUNET_STRINGS_base64_decode (peer,
                                    strlen (peer),
                                    (char**)&entry->peer);
      entry->value_size = GNUNET_STRINGS_base64_decode (value,
                                                        strlen (value),
                                                        (char**)&entry->value);
      if (GNUNET_SYSERR == GNUNET_STRINGS_fancy_time_to_absolute (expiry,
                                             entry->expiry))
      {
        GNUNET_free (entry->sub_system);
        GNUNET_free (entry->key);
        GNUNET_free (entry->peer);
        GNUNET_free (entry);
        break;
      }
      peer_id = GNUNET_i2s (entry->peer);
      GNUNET_CRYPTO_hash (peer_id,
                          strlen (peer_id),
                          &hkey);

      GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (plugin->hm,
                                         &hkey,
                                         entry,
                                         GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));

    }
  }
Ejemplo n.º 16
0
/**
 * Initialize the database connections and associated
 * data structures (create tables and indices
 * as needed as well).
 *
 * @param plugin the plugin context (state for this module)
 * @return #GNUNET_OK on success
 */
static int
database_setup (struct Plugin *plugin)
{
  char *afsdir;
  char* block_buffer;
  char* buffer;
  char* line;
  char* query;
  char* block;
  size_t size;
  struct FlatFileEntry *entry;
  struct GNUNET_DISK_FileHandle *fh;

  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, "namecache-flat",
                                               "FILENAME", &afsdir))
  {
    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
                               "namecache-flat", "FILENAME");
    return GNUNET_SYSERR;
  }
  if (GNUNET_OK != GNUNET_DISK_file_test (afsdir))
  {
    if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (afsdir))
    {
      GNUNET_break (0);
      GNUNET_free (afsdir);
      return GNUNET_SYSERR;
    }
  }
  /* afsdir should be UTF-8-encoded. If it isn't, it's a bug */
  plugin->fn = afsdir;

  /* Load data from file into hashmap */
  plugin->hm = GNUNET_CONTAINER_multihashmap_create (10,
                                                     GNUNET_NO);
  fh = GNUNET_DISK_file_open (afsdir,
                              GNUNET_DISK_OPEN_CREATE |
                              GNUNET_DISK_OPEN_READWRITE,
                              GNUNET_DISK_PERM_USER_WRITE |
                              GNUNET_DISK_PERM_USER_READ);
  if (NULL == fh)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Unable to initialize file: %s.\n"),
                afsdir);
    return GNUNET_SYSERR;
  }

  if (GNUNET_SYSERR == GNUNET_DISK_file_size (afsdir,
                                              &size,
                                              GNUNET_YES,
                                              GNUNET_YES))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Unable to get filesize: %s.\n"),
                afsdir);
    return GNUNET_SYSERR;
  }

  if (0 == size)
    return GNUNET_OK;

  buffer = GNUNET_malloc (size);

  if (GNUNET_SYSERR == GNUNET_DISK_file_read (fh,
                                              buffer,
                                              size))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Unable to read file: %s.\n"),
                afsdir);
    return GNUNET_SYSERR;
  }

  GNUNET_DISK_file_close (fh);
  if (0 < size) {
    line = strtok (buffer, "\n");
    while (line != NULL) {
      query = strtok (line, ",");
      if (NULL == query)
        break;
      block = strtok (NULL, ",");
      if (NULL == block)
        break;
      line = strtok (NULL, "\n");
      entry = GNUNET_malloc (sizeof (struct FlatFileEntry));
      GNUNET_CRYPTO_hash_from_string (query,
                                      &entry->query);
      GNUNET_STRINGS_base64_decode (block,
                                    strlen (block),
                                    &block_buffer);
      entry->block = (struct GNUNET_GNSRECORD_Block *) block_buffer;
      if (GNUNET_OK != 
          GNUNET_CONTAINER_multihashmap_put (plugin->hm,
                                             &entry->query,
                                             entry,
                                             GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
      {
        GNUNET_free (entry);
        GNUNET_break (0);
      }
    }
  }
  GNUNET_free (buffer);
  return GNUNET_OK;
}