GNUnet  0.11.x
Data Structures | Macros | Functions
fs_uri.c File Reference

Parses and produces uri strings. More...

#include "platform.h"
#include "gnunet_fs_service.h"
#include "gnunet_signatures.h"
#include "fs_api.h"
#include <unitypes.h>
#include <unicase.h>
#include <uniconv.h>
#include <unistr.h>
#include <unistdio.h>
Include dependency graph for fs_uri.c:

Go to the source code of this file.

Data Structures

struct  LocUriAssembly
 Structure that defines how the contents of a location URI must be assembled in memory to create or verify the signature of a location URI. More...
 

Macros

#define GNUNET_FS_URI_KSK_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_KSK_INFIX
 
#define GNUNET_FS_URI_SKS_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_SKS_INFIX
 
#define GNUNET_FS_URI_CHK_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_CHK_INFIX
 
#define GNUNET_FS_URI_LOC_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_LOC_INFIX
 
#define SIGNATURE_ASCII_LENGTH   103
 
#define TOKENS   "_. /-!?#&+@\"\'\\;:,()[]{}$<>|"
 Where to break up keywords. More...
 

Functions

int GNUNET_FS_uri_to_key (const struct GNUNET_FS_Uri *uri, struct GNUNET_HashCode *key)
 Get a unique key from a URI. More...
 
char * GNUNET_FS_uri_ksk_to_string_fancy (const struct GNUNET_FS_Uri *uri)
 Convert keyword URI to a human readable format (i.e. More...
 
static char * percent_decode_keyword (const char *in, char **emsg)
 Given a keyword with %-encoding (and possibly quotes to protect spaces), return a copy of the keyword without %-encoding and without double-quotes (%22). More...
 
static struct GNUNET_FS_Uriuri_ksk_parse (const char *s, char **emsg)
 Parse a KSK URI. More...
 
static struct GNUNET_FS_Uriuri_sks_parse (const char *s, char **emsg)
 Parse an SKS URI. More...
 
static struct GNUNET_FS_Uriuri_chk_parse (const char *s, char **emsg)
 Parse a CHK URI. More...
 
static struct GNUNET_FS_Uriuri_loc_parse (const char *s, char **emsg)
 Parse a LOC URI. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_parse (const char *uri, char **emsg)
 Convert a UTF-8 String to a URI. More...
 
void GNUNET_FS_uri_destroy (struct GNUNET_FS_Uri *uri)
 Free URI. More...
 
unsigned int GNUNET_FS_uri_ksk_get_keyword_count (const struct GNUNET_FS_Uri *uri)
 How many keywords are ANDed in this keyword URI? More...
 
int GNUNET_FS_uri_ksk_get_keywords (const struct GNUNET_FS_Uri *uri, GNUNET_FS_KeywordIterator iterator, void *iterator_cls)
 Iterate over all keywords in this keyword URI. More...
 
void GNUNET_FS_uri_ksk_add_keyword (struct GNUNET_FS_Uri *uri, const char *keyword, int is_mandatory)
 Add the given keyword to the set of keywords represented by the URI. More...
 
void GNUNET_FS_uri_ksk_remove_keyword (struct GNUNET_FS_Uri *uri, const char *keyword)
 Remove the given keyword from the set of keywords represented by the URI. More...
 
int GNUNET_FS_uri_loc_get_peer_identity (const struct GNUNET_FS_Uri *uri, struct GNUNET_PeerIdentity *peer)
 Obtain the identity of the peer offering the data. More...
 
struct GNUNET_TIME_Absolute GNUNET_FS_uri_loc_get_expiration (const struct GNUNET_FS_Uri *uri)
 Obtain the expiration of the LOC URI. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_loc_get_uri (const struct GNUNET_FS_Uri *uri)
 Obtain the URI of the content itself. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_loc_create (const struct GNUNET_FS_Uri *base_uri, const struct GNUNET_CRYPTO_EddsaPrivateKey *sign_key, struct GNUNET_TIME_Absolute expiration_time)
 Construct a location URI (this peer will be used for the location). More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_sks_create (const struct GNUNET_CRYPTO_EcdsaPublicKey *ns, const char *id)
 Create an SKS URI from a namespace ID and an identifier. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_ksk_merge (const struct GNUNET_FS_Uri *u1, const struct GNUNET_FS_Uri *u2)
 Merge the sets of keywords from two KSK URIs. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_dup (const struct GNUNET_FS_Uri *uri)
 Duplicate URI. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_ksk_create (const char *keywords, char **emsg)
 Create an FS URI from a single user-supplied string of keywords. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_ksk_create_from_args (unsigned int argc, const char **argv)
 Create an FS URI from a user-supplied command line of keywords. More...
 
int GNUNET_FS_uri_test_equal (const struct GNUNET_FS_Uri *u1, const struct GNUNET_FS_Uri *u2)
 Test if two URIs are equal. More...
 
int GNUNET_FS_uri_test_sks (const struct GNUNET_FS_Uri *uri)
 Is this a namespace URI? More...
 
int GNUNET_FS_uri_sks_get_namespace (const struct GNUNET_FS_Uri *uri, struct GNUNET_CRYPTO_EcdsaPublicKey *pseudonym)
 Get the ID of a namespace from the given namespace URI. More...
 
char * GNUNET_FS_uri_sks_get_content_id (const struct GNUNET_FS_Uri *uri)
 Get the content identifier of an SKS URI. More...
 
int GNUNET_FS_uri_test_ksk (const struct GNUNET_FS_Uri *uri)
 Is this a keyword URI? More...
 
int GNUNET_FS_uri_test_chk (const struct GNUNET_FS_Uri *uri)
 Is this a file (or directory) URI? More...
 
uint64_t GNUNET_FS_uri_chk_get_file_size (const struct GNUNET_FS_Uri *uri)
 What is the size of the file that this URI refers to? More...
 
int GNUNET_FS_uri_test_loc (const struct GNUNET_FS_Uri *uri)
 Is this a location URI? More...
 
static void insert_non_mandatory_keyword (const char *s, char **array, int index)
 Add a keyword as non-mandatory (with ' '-prefix) to the given keyword list at offset 'index'. More...
 
static int find_duplicate (const char *s, const char **array, int array_length)
 Test if the given keyword s is already present in the given array, ignoring the '+'-mandatory prefix in the array. More...
 
static char * normalize_metadata (enum EXTRACTOR_MetaFormat format, const char *data, size_t data_len)
 FIXME: comment. More...
 
static size_t u8_strcount (const uint8_t *s)
 Counts the number of UTF-8 characters (not bytes) in the string, returns that count. More...
 
static int get_keywords_from_parens (const char *s, char **array, int index)
 Break the filename up by matching [], () and {} pairs to make keywords. More...
 
static int get_keywords_from_tokens (const char *s, char **array, int index)
 Break the filename up by TOKENS to make keywords. More...
 
static int gather_uri_data (void *cls, const char *plugin_name, enum EXTRACTOR_MetaType type, enum EXTRACTOR_MetaFormat format, const char *data_mime_type, const char *data, size_t data_len)
 Function called on each value in the meta data. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_ksk_create_from_meta_data (const struct GNUNET_CONTAINER_MetaData *md)
 Construct a keyword-URI from meta-data (take all entries in the meta-data and construct one large keyword URI that lists all keywords that can be found in the meta-data). More...
 
static int needs_percent (char c)
 In URI-encoding, does the given character need to be encoded using %-encoding? More...
 
static char * uri_ksk_to_string (const struct GNUNET_FS_Uri *uri)
 Convert a KSK URI to a string. More...
 
static char * uri_sks_to_string (const struct GNUNET_FS_Uri *uri)
 Convert SKS URI to a string. More...
 
static char * uri_chk_to_string (const struct GNUNET_FS_Uri *uri)
 Convert a CHK URI to a string. More...
 
static char * uri_loc_to_string (const struct GNUNET_FS_Uri *uri)
 Convert a LOC URI to a string. More...
 
char * GNUNET_FS_uri_to_string (const struct GNUNET_FS_Uri *uri)
 Convert a URI to a UTF-8 String. More...
 

Detailed Description

Parses and produces uri strings.

Author
Igor Wronsky, Christian Grothoff

GNUnet URIs are of the general form "gnunet://MODULE/IDENTIFIER". The specific structure of "IDENTIFIER" depends on the module and maybe differenciated into additional subcategories if applicable. This module only deals with fs identifiers (MODULE = "fs").

This module only parses URIs for the AFS module. The FS URIs fall into four categories, "chk", "sks", "ksk" and "loc". The first three categories were named in analogy (!) to Freenet, but they do NOT work in exactly the same way. They are very similar from the user's point of view (unique file identifier, subspace, keyword), but the implementation is rather different in pretty much every detail. The concrete URI formats are:

The encoding for hexadecimal values is defined in the hashing.c module in the gnunetutil library and discussed there.

Definition in file fs_uri.c.

Macro Definition Documentation

◆ GNUNET_FS_URI_KSK_PREFIX

#define GNUNET_FS_URI_KSK_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_KSK_INFIX

Definition at line 269 of file fs_uri.c.

Referenced by uri_ksk_parse().

◆ GNUNET_FS_URI_SKS_PREFIX

#define GNUNET_FS_URI_SKS_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_SKS_INFIX

Definition at line 363 of file fs_uri.c.

Referenced by uri_sks_parse().

◆ GNUNET_FS_URI_CHK_PREFIX

#define GNUNET_FS_URI_CHK_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_CHK_INFIX

Definition at line 402 of file fs_uri.c.

Referenced by uri_chk_parse().

◆ GNUNET_FS_URI_LOC_PREFIX

#define GNUNET_FS_URI_LOC_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_LOC_INFIX

Definition at line 490 of file fs_uri.c.

Referenced by uri_loc_parse().

◆ SIGNATURE_ASCII_LENGTH

#define SIGNATURE_ASCII_LENGTH   103

Definition at line 492 of file fs_uri.c.

Referenced by uri_loc_parse(), and uri_loc_to_string().

◆ TOKENS

#define TOKENS   "_. /-!?#&+@\"\'\\;:,()[]{}$<>|"

Where to break up keywords.

Definition at line 1624 of file fs_uri.c.

Referenced by get_keywords_from_tokens().

Function Documentation

◆ percent_decode_keyword()

static char* percent_decode_keyword ( const char *  in,
char **  emsg 
)
static

Given a keyword with %-encoding (and possibly quotes to protect spaces), return a copy of the keyword without %-encoding and without double-quotes (%22).

Also, add a space at the beginning if there is not a '+'.

Parameters
instring with %-encoding
emsgwhere to store the parser error message (if any)
Returns
decodded string with leading space (or preserved plus)

Definition at line 219 of file fs_uri.c.

References _, GNUNET_free, GNUNET_malloc, GNUNET_strdup, and ret.

Referenced by uri_ksk_parse().

220 {
221  char *out;
222  char *ret;
223  unsigned int rpos;
224  unsigned int wpos;
225  unsigned int hx;
226 
227  out = GNUNET_strdup (in);
228  rpos = 0;
229  wpos = 0;
230  while (out[rpos] != '\0')
231  {
232  if (out[rpos] == '%')
233  {
234  if (1 != sscanf (&out[rpos + 1], "%2X", &hx))
235  {
236  GNUNET_free (out);
237  *emsg = GNUNET_strdup (
238  _ ( /* xgettext:no-c-format */
239  "Malformed KSK URI (`%' must be followed by HEX number)"));
240  return NULL;
241  }
242  rpos += 3;
243  if (hx == '"')
244  continue; /* skip double quote */
245  out[wpos++] = (char) hx;
246  }
247  else
248  {
249  out[wpos++] = out[rpos++];
250  }
251  }
252  out[wpos] = '\0';
253  if (out[0] == '+')
254  {
255  ret = GNUNET_strdup (out);
256  }
257  else
258  {
259  /* need to prefix with space */
260  ret = GNUNET_malloc (strlen (out) + 2);
261  strcpy (ret, " ");
262  strcat (ret, out);
263  }
264  GNUNET_free (out);
265  return ret;
266 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define _(String)
GNU gettext support macro.
Definition: platform.h:184
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the caller graph for this function:

◆ uri_ksk_parse()

static struct GNUNET_FS_Uri* uri_ksk_parse ( const char *  s,
char **  emsg 
)
static

Parse a KSK URI.

Parameters
san uri string
emsgwhere to store the parser error message (if any)
Returns
NULL on error, otherwise the KSK URI

Definition at line 279 of file fs_uri.c.

References _, GNUNET_FS_Uri::data, GNUNET_assert, GNUNET_free, GNUNET_FS_URI_KSK, GNUNET_FS_URI_KSK_PREFIX, GNUNET_new, GNUNET_new_array, GNUNET_strdup, GNUNET_FS_Uri::keywords, GNUNET_FS_Uri::ksk, percent_decode_keyword(), ret, and GNUNET_FS_Uri::type.

Referenced by GNUNET_FS_uri_parse().

280 {
281  struct GNUNET_FS_Uri *ret;
282  char **keywords;
283  unsigned int pos;
284  int max;
285  int iret;
286  int i;
287  size_t slen;
288  char *dup;
289  int saw_quote;
290 
291  slen = strlen (s);
292  pos = strlen (GNUNET_FS_URI_KSK_PREFIX);
293  if ((slen <= pos) || (0 != strncmp (s, GNUNET_FS_URI_KSK_PREFIX, pos)))
294  return NULL; /* not KSK URI */
295  if ((s[slen - 1] == '+') || (s[pos] == '+'))
296  {
297  *emsg =
298  GNUNET_strdup (_ ("Malformed KSK URI (must not begin or end with `+')"));
299  return NULL;
300  }
301  max = 1;
302  saw_quote = 0;
303  for (i = pos; i < slen; i++)
304  {
305  if ((s[i] == '%') && (&s[i] == strstr (&s[i], "%22")))
306  {
307  saw_quote = (saw_quote + 1) % 2;
308  i += 3;
309  continue;
310  }
311  if ((s[i] == '+') && (saw_quote == 0))
312  {
313  max++;
314  if (s[i - 1] == '+')
315  {
316  *emsg = GNUNET_strdup (_ ("Malformed KSK URI (`++' not allowed)"));
317  return NULL;
318  }
319  }
320  }
321  if (saw_quote == 1)
322  {
323  *emsg = GNUNET_strdup (_ ("Malformed KSK URI (quotes not balanced)"));
324  return NULL;
325  }
326  iret = max;
327  dup = GNUNET_strdup (s);
328  keywords = GNUNET_new_array (max, char *);
329  for (i = slen - 1; i >= (int) pos; i--)
330  {
331  if ((s[i] == '%') && (&s[i] == strstr (&s[i], "%22")))
332  {
333  saw_quote = (saw_quote + 1) % 2;
334  continue;
335  }
336  if ((dup[i] == '+') && (saw_quote == 0))
337  {
338  keywords[--max] = percent_decode_keyword (&dup[i + 1], emsg);
339  if (NULL == keywords[max])
340  goto CLEANUP;
341  dup[i] = '\0';
342  }
343  }
344  keywords[--max] = percent_decode_keyword (&dup[pos], emsg);
345  if (NULL == keywords[max])
346  goto CLEANUP;
347  GNUNET_assert (0 == max);
348  GNUNET_free (dup);
349  ret = GNUNET_new (struct GNUNET_FS_Uri);
350  ret->type = GNUNET_FS_URI_KSK;
351  ret->data.ksk.keywordCount = iret;
352  ret->data.ksk.keywords = keywords;
353  return ret;
354 CLEANUP:
355  for (i = 0; i < max; i++)
356  GNUNET_free (keywords[i]);
357  GNUNET_free (keywords);
358  GNUNET_free (dup);
359  return NULL;
360 }
#define GNUNET_FS_URI_KSK_PREFIX
Definition: fs_uri.c:269
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Keyword search key (query with keywords).
Definition: fs_api.h:153
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static char * percent_decode_keyword(const char *in, char **emsg)
Given a keyword with %-encoding (and possibly quotes to protect spaces), return a copy of the keyword...
Definition: fs_uri.c:219
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define _(String)
GNU gettext support macro.
Definition: platform.h:184
char ** keywords
Keywords start with a &#39;+&#39; if they are mandatory (in which case the &#39;+&#39; is NOT part of the keyword) an...
Definition: fs_api.h:185
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
enum GNUNET_FS_UriType type
Type of the URI.
Definition: fs_api.h:170
union GNUNET_FS_Uri::@13 data
A Universal Resource Identifier (URI), opaque.
Definition: fs_api.h:165
struct GNUNET_FS_Uri::@13::@14 ksk
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uri_sks_parse()

static struct GNUNET_FS_Uri* uri_sks_parse ( const char *  s,
char **  emsg 
)
static

Parse an SKS URI.

Parameters
san uri string
emsgwhere to store the parser error message (if any)
Returns
NULL on error, SKS URI otherwise

Definition at line 373 of file fs_uri.c.

References _, GNUNET_FS_Uri::data, end, GNUNET_FS_URI_SKS, GNUNET_FS_URI_SKS_PREFIX, GNUNET_new, GNUNET_OK, GNUNET_strdup, GNUNET_STRINGS_string_to_data(), ns, ret, GNUNET_FS_Uri::sks, and GNUNET_FS_Uri::type.

Referenced by GNUNET_FS_uri_parse().

374 {
375  struct GNUNET_FS_Uri *ret;
377  size_t pos;
378  char *end;
379 
380  pos = strlen (GNUNET_FS_URI_SKS_PREFIX);
381  if ((strlen (s) <= pos) || (0 != strncmp (s, GNUNET_FS_URI_SKS_PREFIX, pos)))
382  return NULL; /* not an SKS URI */
383  end = strchr (&s[pos], '/');
384  if ((NULL == end) ||
386  end - &s[pos],
387  &ns,
388  sizeof(ns))))
389  {
390  *emsg = GNUNET_strdup (_ ("Malformed SKS URI (wrong syntax)"));
391  return NULL; /* malformed */
392  }
393  end++; /* skip over '/' */
394  ret = GNUNET_new (struct GNUNET_FS_Uri);
395  ret->type = GNUNET_FS_URI_SKS;
396  ret->data.sks.ns = ns;
397  ret->data.sks.identifier = GNUNET_strdup (end);
398  return ret;
399 }
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
struct GNUNET_FS_Uri::@13::@15 sks
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define _(String)
GNU gettext support macro.
Definition: platform.h:184
static struct GNUNET_NAMESTORE_Handle * ns
Handle to the namestore.
Definition: gnunet-abd.c:41
#define GNUNET_FS_URI_SKS_PREFIX
Definition: fs_uri.c:363
enum GNUNET_FS_UriType type
Type of the URI.
Definition: fs_api.h:170
union GNUNET_FS_Uri::@13 data
Signed key space (file in namespace).
Definition: fs_api.h:148
A Universal Resource Identifier (URI), opaque.
Definition: fs_api.h:165
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
int GNUNET_STRINGS_string_to_data(const char *enc, size_t enclen, void *out, size_t out_size)
Convert CrockfordBase32 encoding back to data.
Definition: strings.c:970
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uri_chk_parse()

static struct GNUNET_FS_Uri* uri_chk_parse ( const char *  s,
char **  emsg 
)
static

Parse a CHK URI.

Parameters
san uri string
emsgwhere to store the parser error message (if any)
Returns
NULL on error, CHK URI otherwise

Definition at line 413 of file fs_uri.c.

References _, FileIdentifier::chk, GNUNET_FS_Uri::chk, GNUNET_FS_Uri::data, FileIdentifier::file_length, GNUNET_CRYPTO_hash_from_string, GNUNET_FS_URI_CHK, GNUNET_FS_URI_CHK_PREFIX, GNUNET_htonll(), GNUNET_memcpy, GNUNET_NETWORK_STRUCT_BEGIN, GNUNET_new, GNUNET_OK, GNUNET_strdup, ContentHashKey::key, ContentHashKey::query, ret, and GNUNET_FS_Uri::type.

Referenced by GNUNET_FS_uri_parse().

414 {
415  struct GNUNET_FS_Uri *ret;
416  struct FileIdentifier fi;
417  unsigned int pos;
418  unsigned long long flen;
419  size_t slen;
420  char h1[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)];
421  char h2[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)];
422 
423  slen = strlen (s);
424  pos = strlen (GNUNET_FS_URI_CHK_PREFIX);
425  if ((slen < pos + 2 * sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) + 1) ||
426  (0 != strncmp (s, GNUNET_FS_URI_CHK_PREFIX, pos)))
427  return NULL; /* not a CHK URI */
428  if ((s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] != '.') ||
429  (s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) * 2 - 1] != '.'))
430  {
431  *emsg = GNUNET_strdup (_ ("Malformed CHK URI (wrong syntax)"));
432  return NULL;
433  }
434  GNUNET_memcpy (h1, &s[pos], sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded));
435  h1[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0';
436  GNUNET_memcpy (h2,
437  &s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)],
438  sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded));
439  h2[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0';
440 
441  if ((GNUNET_OK != GNUNET_CRYPTO_hash_from_string (h1, &fi.chk.key)) ||
442  (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (h2, &fi.chk.query)) ||
443  (1 !=
444  sscanf (&s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) * 2],
445  "%llu",
446  &flen)))
447  {
448  *emsg = GNUNET_strdup (_ ("Malformed CHK URI (failed to decode CHK)"));
449  return NULL;
450  }
451  fi.file_length = GNUNET_htonll (flen);
452  ret = GNUNET_new (struct GNUNET_FS_Uri);
453  ret->type = GNUNET_FS_URI_CHK;
454  ret->data.chk = fi;
455  return ret;
456 }
struct FileIdentifier chk
Information needed to retrieve a file (content-hash-key plus file size).
Definition: fs_api.h:211
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define _(String)
GNU gettext support macro.
Definition: platform.h:184
complete information needed to download a file.
Definition: fs_api.h:93
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:36
Content-hash-key (simple file).
Definition: fs_api.h:143
enum GNUNET_FS_UriType type
Type of the URI.
Definition: fs_api.h:170
union GNUNET_FS_Uri::@13 data
0-terminated ASCII encoding of a struct GNUNET_HashCode.
A Universal Resource Identifier (URI), opaque.
Definition: fs_api.h:165
#define GNUNET_FS_URI_CHK_PREFIX
Definition: fs_uri.c:402
#define GNUNET_CRYPTO_hash_from_string(enc, result)
Convert ASCII encoding back to struct GNUNET_HashCode
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uri_loc_parse()

static struct GNUNET_FS_Uri* uri_loc_parse ( const char *  s,
char **  emsg 
)
static

Parse a LOC URI.

Also verifies validity of the location URI.

Parameters
san uri string
emsgwhere to store the parser error message (if any)
Returns
NULL on error, valid LOC URI otherwise

Definition at line 503 of file fs_uri.c.

References _, GNUNET_TIME_Absolute::abs_value_us, FileIdentifier::chk, Location::contentSignature, GNUNET_FS_Uri::data, Location::expirationTime, LocUriAssembly::exptime, Location::fi, LocUriAssembly::fi, FileIdentifier::file_length, GNUNET_CRYPTO_eddsa_public_key_from_string(), GNUNET_CRYPTO_eddsa_verify, GNUNET_CRYPTO_hash_from_string, GNUNET_CRYPTO_PKEY_ASCII_LENGTH, GNUNET_FS_URI_LOC, GNUNET_FS_URI_LOC_PREFIX, GNUNET_htonll(), GNUNET_memcpy, GNUNET_new, GNUNET_OK, GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT, GNUNET_strdup, GNUNET_STRINGS_string_to_data(), GNUNET_TIME_absolute_hton(), ContentHashKey::key, GNUNET_FS_Uri::loc, Location::peer, LocUriAssembly::peer, GNUNET_PeerIdentity::public_key, GNUNET_CRYPTO_EccSignaturePurpose::purpose, LocUriAssembly::purpose, ContentHashKey::query, SIGNATURE_ASCII_LENGTH, GNUNET_CRYPTO_EccSignaturePurpose::size, GNUNET_FS_Uri::type, and uri.

Referenced by GNUNET_FS_uri_parse().

504 {
505  struct GNUNET_FS_Uri *uri;
506  char h1[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)];
507  char h2[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)];
508  unsigned int pos;
509  unsigned int npos;
510  unsigned long long exptime;
511  unsigned long long flen;
512  struct GNUNET_TIME_Absolute et;
513  struct GNUNET_CRYPTO_EddsaSignature sig;
514  struct LocUriAssembly ass;
515  size_t slen;
516 
517  slen = strlen (s);
518  pos = strlen (GNUNET_FS_URI_LOC_PREFIX);
519  if ((slen < pos + 2 * sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) + 1) ||
520  (0 != strncmp (s, GNUNET_FS_URI_LOC_PREFIX, pos)))
521  return NULL; /* not a LOC URI */
522  if ((s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] != '.') ||
523  (s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) * 2 - 1] != '.'))
524  {
525  *emsg = GNUNET_strdup (_ ("LOC URI malformed (wrong syntax)"));
526  return NULL;
527  }
528  GNUNET_memcpy (h1, &s[pos], sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded));
529  h1[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0';
530  GNUNET_memcpy (h2,
531  &s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)],
532  sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded));
533  h2[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0';
534 
535  if ((GNUNET_OK != GNUNET_CRYPTO_hash_from_string (h1, &ass.fi.chk.key)) ||
536  (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (h2, &ass.fi.chk.query)) ||
537  (1 !=
538  sscanf (&s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) * 2],
539  "%llu",
540  &flen)))
541  {
542  *emsg = GNUNET_strdup (_ ("LOC URI malformed (no CHK)"));
543  return NULL;
544  }
545  ass.fi.file_length = GNUNET_htonll (flen);
546 
547  npos = pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) * 2;
548  while ((s[npos] != '\0') && (s[npos] != '.'))
549  npos++;
550  if (s[npos] == '\0')
551  {
552  *emsg = GNUNET_strdup (_ ("LOC URI malformed (missing LOC)"));
553  goto ERR;
554  }
555  npos++;
556  if ((strlen (&s[npos]) <= GNUNET_CRYPTO_PKEY_ASCII_LENGTH + 1) ||
557  ('.' != s[npos + GNUNET_CRYPTO_PKEY_ASCII_LENGTH]))
558  {
559  *emsg =
560  GNUNET_strdup (_ ("LOC URI malformed (wrong syntax for public key)"));
561  }
562  if (
563  GNUNET_OK !=
566  &ass.peer.public_key))
567  {
568  *emsg =
569  GNUNET_strdup (_ ("LOC URI malformed (could not decode public key)"));
570  goto ERR;
571  }
573  if (s[npos++] != '.')
574  {
575  *emsg = GNUNET_strdup (_ ("LOC URI malformed (could not find signature)"));
576  goto ERR;
577  }
578  if ((strlen (&s[npos]) <= SIGNATURE_ASCII_LENGTH + 1) ||
579  ('.' != s[npos + SIGNATURE_ASCII_LENGTH]))
580  {
581  *emsg =
582  GNUNET_strdup (_ ("LOC URI malformed (wrong syntax for signature)"));
583  goto ERR;
584  }
585  if (GNUNET_OK !=
588  &sig,
589  sizeof(
591  {
592  *emsg =
593  GNUNET_strdup (_ ("LOC URI malformed (could not decode signature)"));
594  goto ERR;
595  }
596  npos += SIGNATURE_ASCII_LENGTH;
597  if (s[npos++] != '.')
598  {
599  *emsg = GNUNET_strdup (
600  _ ("LOC URI malformed (wrong syntax for expiration time)"));
601  goto ERR;
602  }
603  if (1 != sscanf (&s[npos], "%llu", &exptime))
604  {
605  *emsg =
606  GNUNET_strdup (_ ("LOC URI malformed (could not parse expiration time)"));
607  goto ERR;
608  }
609  ass.purpose.size = htonl (sizeof(struct LocUriAssembly));
610  ass.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT);
611  et.abs_value_us = exptime * 1000LL * 1000LL;
612  ass.exptime = GNUNET_TIME_absolute_hton (et);
613  if (GNUNET_OK !=
615  &ass,
616  &sig,
617  &ass.peer.public_key))
618  {
619  *emsg =
620  GNUNET_strdup (_ ("LOC URI malformed (signature failed validation)"));
621  goto ERR;
622  }
623  uri = GNUNET_new (struct GNUNET_FS_Uri);
624  uri->type = GNUNET_FS_URI_LOC;
625  uri->data.loc.fi = ass.fi;
626  uri->data.loc.peer = ass.peer;
627  uri->data.loc.expirationTime = et;
628  uri->data.loc.contentSignature = sig;
629 
630  return uri;
631 ERR:
632  return NULL;
633 }
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_PeerIdentity peer
Identity of the peer sharing the file.
Definition: fs_api.h:121
#define GNUNET_CRYPTO_eddsa_verify(purp, ps, sig, pub)
Verify EdDSA signature.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define _(String)
GNU gettext support macro.
Definition: platform.h:184
#define GNUNET_CRYPTO_PKEY_ASCII_LENGTH
How many characters (without 0-terminator) are our ASCII-encoded public keys (ECDSA/EDDSA/ECDHE).
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
#define GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT
Signature by which a peer affirms that it is providing a certain bit of content (used in LOCation URI...
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:36
struct GNUNET_TIME_Absolute expirationTime
Time when this location URI expires.
Definition: fs_api.h:126
enum GNUNET_FS_UriType type
Type of the URI.
Definition: fs_api.h:170
an ECC signature using EdDSA.
union GNUNET_FS_Uri::@13 data
0-terminated ASCII encoding of a struct GNUNET_HashCode.
int GNUNET_CRYPTO_eddsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a string representing a public key to a public key.
Definition: crypto_ecc.c:399
A Universal Resource Identifier (URI), opaque.
Definition: fs_api.h:165
struct GNUNET_CRYPTO_EddsaSignature contentSignature
Signature over the GNUNET_EC_FileIdentifier, peer identity and expiration time.
Definition: fs_api.h:132
struct FileIdentifier fi
Information about the shared file.
Definition: fs_api.h:116
Location (chk with identity of hosting peer).
Definition: fs_api.h:158
struct Location loc
Information needed to retrieve a file including signed location (identity of a peer) of the content...
Definition: fs_api.h:217
Time for absolute times used by GNUnet, in microseconds.
#define SIGNATURE_ASCII_LENGTH
Definition: fs_uri.c:492
#define GNUNET_FS_URI_LOC_PREFIX
Definition: fs_uri.c:490
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:657
#define GNUNET_CRYPTO_hash_from_string(enc, result)
Convert ASCII encoding back to struct GNUNET_HashCode
int GNUNET_STRINGS_string_to_data(const char *enc, size_t enclen, void *out, size_t out_size)
Convert CrockfordBase32 encoding back to data.
Definition: strings.c:970
Structure that defines how the contents of a location URI must be assembled in memory to create or ve...
Definition: fs_uri.c:465
Here is the call graph for this function:
Here is the caller graph for this function:

◆ insert_non_mandatory_keyword()

static void insert_non_mandatory_keyword ( const char *  s,
char **  array,
int  index 
)
static

Add a keyword as non-mandatory (with ' '-prefix) to the given keyword list at offset 'index'.

The array is guaranteed to be long enough.

Parameters
skeyword to add
arrayarray to add the keyword to
indexoffset where to add the keyword

Definition at line 1410 of file fs_uri.c.

References GNUNET_asprintf().

Referenced by gather_uri_data(), get_keywords_from_parens(), and get_keywords_from_tokens().

1411 {
1412  char *nkword;
1413 
1414  GNUNET_asprintf (&nkword,
1415  " %s", /* space to mark as 'non mandatory' */
1416  s);
1417  array[index] = nkword;
1418 }
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_duplicate()

static int find_duplicate ( const char *  s,
const char **  array,
int  array_length 
)
static

Test if the given keyword s is already present in the given array, ignoring the '+'-mandatory prefix in the array.

Parameters
skeyword to test
arraykeywords to test against, with ' ' or '+' prefix to ignore
array_lengthlength of the array
Returns
GNUNET_YES if the keyword exists, GNUNET_NO if not

Definition at line 1431 of file fs_uri.c.

References GNUNET_NO, and GNUNET_YES.

Referenced by gather_uri_data(), get_keywords_from_parens(), and get_keywords_from_tokens().

1432 {
1433  int j;
1434 
1435  for (j = array_length - 1; j >= 0; j--)
1436  if (0 == strcmp (&array[j][1], s))
1437  return GNUNET_YES;
1438  return GNUNET_NO;
1439 }
Here is the caller graph for this function:

◆ normalize_metadata()

static char* normalize_metadata ( enum EXTRACTOR_MetaFormat  format,
const char *  data,
size_t  data_len 
)
static

FIXME: comment.

Definition at line 1446 of file fs_uri.c.

References data, EXTRACTOR_METAFORMAT_C_STRING, EXTRACTOR_METAFORMAT_UTF8, GNUNET_malloc, and GNUNET_memcpy.

Referenced by gather_uri_data(), get_keywords_from_parens(), and get_keywords_from_tokens().

1449 {
1450  uint8_t *free_str = NULL;
1451  uint8_t *str_to_normalize = (uint8_t *) data;
1452  uint8_t *normalized;
1453  size_t r_len;
1454 
1455  if (str_to_normalize == NULL)
1456  return NULL;
1457  /* Don't trust libextractor */
1458  if (format == EXTRACTOR_METAFORMAT_UTF8)
1459  {
1460  free_str = (uint8_t *) u8_check ((const uint8_t *) data, data_len);
1461  if (free_str == NULL)
1462  free_str = NULL;
1463  else
1465  }
1466  if (format == EXTRACTOR_METAFORMAT_C_STRING)
1467  {
1468  free_str = u8_strconv_from_encoding (data,
1469  locale_charset (),
1470  iconveh_escape_sequence);
1471  if (free_str == NULL)
1472  return NULL;
1473  }
1474 
1475  normalized = u8_tolower (str_to_normalize,
1476  strlen ((char *) str_to_normalize),
1477  NULL,
1478  UNINORM_NFD,
1479  NULL,
1480  &r_len);
1481  /* free_str is allocated by libunistring internally, use free() */
1482  if (free_str != NULL)
1483  free (free_str);
1484  if (normalized != NULL)
1485  {
1486  /* u8_tolower allocates a non-NULL-terminated string! */
1487  free_str = GNUNET_malloc (r_len + 1);
1488  GNUNET_memcpy (free_str, normalized, r_len);
1489  free_str[r_len] = '\0';
1490  free (normalized);
1491  normalized = free_str;
1492  }
1493  return (char *) normalized;
1494 }
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
0-terminated, UTF-8 encoded string.
uint32_t data
The data value.
#define GNUNET_malloc(size)
Wrapper around malloc.
Here is the caller graph for this function:

◆ u8_strcount()

static size_t u8_strcount ( const uint8_t *  s)
static

Counts the number of UTF-8 characters (not bytes) in the string, returns that count.

Definition at line 1502 of file fs_uri.c.

References GNUNET_assert.

Referenced by gather_uri_data(), get_keywords_from_parens(), and get_keywords_from_tokens().

1503 {
1504  size_t count;
1505  ucs4_t c;
1506 
1507  GNUNET_assert (s != NULL);
1508  if (s[0] == 0)
1509  return 0;
1510  for (count = 0; s != NULL; count++)
1511  s = u8_next (&c, s);
1512  return count - 1;
1513 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Here is the caller graph for this function:

◆ get_keywords_from_parens()

static int get_keywords_from_parens ( const char *  s,
char **  array,
int  index 
)
static

Break the filename up by matching [], () and {} pairs to make keywords.

In case of nesting parentheses only the inner pair counts. You can't escape parentheses to scan something like "[blah\{foo]" to make a "blah{foo" keyword, this function is only a heuristic!

Parameters
sstring to break down.
arrayarray to fill with enclosed tokens. If NULL, then tokens are only counted.
indexindex at which to start filling the array (entries prior to it are used to check for duplicates). ignored if array == NULL.
Returns
number of tokens counted (including duplicates), or number of tokens extracted (excluding duplicates). 0 if there are no matching parens in the string (when counting), or when all tokens were duplicates (when extracting).

Definition at line 1533 of file fs_uri.c.

References EXTRACTOR_METAFORMAT_UTF8, find_duplicate(), GNUNET_free, GNUNET_NO, GNUNET_strdup, insert_non_mandatory_keyword(), normalize_metadata(), and u8_strcount().

Referenced by GNUNET_FS_uri_ksk_create_from_meta_data().

1534 {
1535  int count = 0;
1536  char *open_paren;
1537  char *close_paren;
1538  char *ss;
1539  char tmp;
1540 
1541  if (NULL == s)
1542  return 0;
1543  ss = GNUNET_strdup (s);
1544  open_paren = ss - 1;
1545  while (NULL != (open_paren = strpbrk (open_paren + 1, "[{(")))
1546  {
1547  int match = 0;
1548 
1549  close_paren = strpbrk (open_paren + 1, "]})");
1550  if (NULL == close_paren)
1551  continue;
1552  switch (open_paren[0])
1553  {
1554  case '[':
1555  if (']' == close_paren[0])
1556  match = 1;
1557  break;
1558 
1559  case '{':
1560  if ('}' == close_paren[0])
1561  match = 1;
1562  break;
1563 
1564  case '(':
1565  if (')' == close_paren[0])
1566  match = 1;
1567  break;
1568 
1569  default:
1570  break;
1571  }
1572  if (match && (close_paren - open_paren > 1))
1573  {
1574  tmp = close_paren[0];
1575  close_paren[0] = '\0';
1576  /* Keywords must be at least 3 characters long */
1577  if (u8_strcount ((const uint8_t *) &open_paren[1]) <= 2)
1578  {
1579  close_paren[0] = tmp;
1580  continue;
1581  }
1582  if (NULL != array)
1583  {
1584  char *normalized;
1585  if (GNUNET_NO == find_duplicate ((const char *) &open_paren[1],
1586  (const char **) array,
1587  index + count))
1588  {
1589  insert_non_mandatory_keyword ((const char *) &open_paren[1],
1590  array,
1591  index + count);
1592  count++;
1593  }
1595  &open_paren[1],
1596  close_paren - &open_paren[1]);
1597  if (normalized != NULL)
1598  {
1599  if (GNUNET_NO == find_duplicate ((const char *) normalized,
1600  (const char **) array,
1601  index + count))
1602  {
1603  insert_non_mandatory_keyword ((const char *) normalized,
1604  array,
1605  index + count);
1606  count++;
1607  }
1608  GNUNET_free (normalized);
1609  }
1610  }
1611  else
1612  count++;
1613  close_paren[0] = tmp;
1614  }
1615  }
1616  GNUNET_free (ss);
1617  return count;
1618 }
static size_t u8_strcount(const uint8_t *s)
Counts the number of UTF-8 characters (not bytes) in the string, returns that count.
Definition: fs_uri.c:1502
static void insert_non_mandatory_keyword(const char *s, char **array, int index)
Add a keyword as non-mandatory (with &#39; &#39;-prefix) to the given keyword list at offset &#39;index&#39;...
Definition: fs_uri.c:1410
0-terminated, UTF-8 encoded string.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
static int find_duplicate(const char *s, const char **array, int array_length)
Test if the given keyword s is already present in the given array, ignoring the &#39;+&#39;-mandatory prefix ...
Definition: fs_uri.c:1431
static char * normalize_metadata(enum EXTRACTOR_MetaFormat format, const char *data, size_t data_len)
FIXME: comment.
Definition: fs_uri.c:1446
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_keywords_from_tokens()

static int get_keywords_from_tokens ( const char *  s,
char **  array,
int  index 
)
static

Break the filename up by TOKENS to make keywords.

Parameters
sstring to break down.
arrayarray to fill with tokens. If NULL, then tokens are only counted.
indexindex at which to start filling the array (entries prior to it are used to check for duplicates). ignored if array == NULL.
Returns
number of tokens (>1) counted (including duplicates), or number of tokens extracted (excluding duplicates). 0 if there are no separators in the string (when counting), or when all tokens were duplicates (when extracting).

Definition at line 1641 of file fs_uri.c.

References EXTRACTOR_METAFORMAT_UTF8, find_duplicate(), GNUNET_free, GNUNET_NO, GNUNET_strdup, insert_non_mandatory_keyword(), normalize_metadata(), p, TOKENS, and u8_strcount().

Referenced by GNUNET_FS_uri_ksk_create_from_meta_data().

1642 {
1643  char *p;
1644  char *ss;
1645  int seps = 0;
1646 
1647  ss = GNUNET_strdup (s);
1648  for (p = strtok (ss, TOKENS); p != NULL; p = strtok (NULL, TOKENS))
1649  {
1650  /* Keywords must be at least 3 characters long */
1651  if (u8_strcount ((const uint8_t *) p) <= 2)
1652  continue;
1653  if (NULL != array)
1654  {
1655  char *normalized;
1656  if (GNUNET_NO == find_duplicate (p, (const char **) array, index + seps))
1657  {
1658  insert_non_mandatory_keyword (p, array, index + seps);
1659  seps++;
1660  }
1661  normalized =
1663  if (normalized != NULL)
1664  {
1665  if (GNUNET_NO == find_duplicate ((const char *) normalized,
1666  (const char **) array,
1667  index + seps))
1668  {
1669  insert_non_mandatory_keyword ((const char *) normalized,
1670  array,
1671  index + seps);
1672  seps++;
1673  }
1674  GNUNET_free (normalized);
1675  }
1676  }
1677  else
1678  seps++;
1679  }
1680  GNUNET_free (ss);
1681  return seps;
1682 }
static size_t u8_strcount(const uint8_t *s)
Counts the number of UTF-8 characters (not bytes) in the string, returns that count.
Definition: fs_uri.c:1502
static void insert_non_mandatory_keyword(const char *s, char **array, int index)
Add a keyword as non-mandatory (with &#39; &#39;-prefix) to the given keyword list at offset &#39;index&#39;...
Definition: fs_uri.c:1410
0-terminated, UTF-8 encoded string.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
static int find_duplicate(const char *s, const char **array, int array_length)
Test if the given keyword s is already present in the given array, ignoring the &#39;+&#39;-mandatory prefix ...
Definition: fs_uri.c:1431
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
#define TOKENS
Where to break up keywords.
Definition: fs_uri.c:1624
static char * normalize_metadata(enum EXTRACTOR_MetaFormat format, const char *data, size_t data_len)
FIXME: comment.
Definition: fs_uri.c:1446
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ gather_uri_data()

static int gather_uri_data ( void *  cls,
const char *  plugin_name,
enum EXTRACTOR_MetaType  type,
enum EXTRACTOR_MetaFormat  format,
const char *  data_mime_type,
const char *  data,
size_t  data_len 
)
static

Function called on each value in the meta data.

Adds it to the URI.

Parameters
clsURI to update
plugin_namename of the plugin that produced this value; special values can be used (i.e. '<zlib>' for zlib being used in the main libextractor library and yielding meta data).
typelibextractor-type describing the meta data
formatbasic format information about data
data_mime_typemime-type of data (not of the original file); can be NULL (if mime-type is not known)
dataactual meta-data found
data_lennumber of bytes in data
Returns
0 (always)

Definition at line 1706 of file fs_uri.c.

References GNUNET_FS_Uri::data, EXTRACTOR_METAFORMAT_C_STRING, EXTRACTOR_METAFORMAT_UTF8, EXTRACTOR_METATYPE_MIMETYPE, find_duplicate(), GNUNET_asprintf(), GNUNET_free, insert_non_mandatory_keyword(), GNUNET_FS_Uri::ksk, normalize_metadata(), u8_strcount(), and uri.

Referenced by GNUNET_FS_uri_ksk_create_from_meta_data().

1713 {
1714  struct GNUNET_FS_Uri *uri = cls;
1715  char *normalized_data;
1716  const char *sep;
1717 
1718  if ((format != EXTRACTOR_METAFORMAT_UTF8) &&
1719  (format != EXTRACTOR_METAFORMAT_C_STRING))
1720  return 0;
1721  /* Keywords must be at least 3 characters long
1722  * If given non-utf8 string it will, most likely, find it to be invalid,
1723  * and will return the length of its valid part, skipping the keyword.
1724  * If it does - fix the extractor, not this check!
1725  */if (u8_strcount ((const uint8_t *) data) <= 2)
1726  return 0;
1727  if ((EXTRACTOR_METATYPE_MIMETYPE == type) &&
1728  (NULL != (sep = memchr (data, '/', data_len))) && (sep != data))
1729  {
1730  char *xtra;
1731 
1732  GNUNET_asprintf (&xtra, "mimetype:%.*s", (int) (sep - data), data);
1733  if (! find_duplicate (xtra,
1734  (const char **) uri->data.ksk.keywords,
1735  uri->data.ksk.keywordCount))
1736  {
1738  uri->data.ksk.keywords,
1739  uri->data.ksk.keywordCount);
1740  uri->data.ksk.keywordCount++;
1741  }
1742  GNUNET_free (xtra);
1743  }
1744 
1745  normalized_data = normalize_metadata (format, data, data_len);
1746  if (! find_duplicate (data,
1747  (const char **) uri->data.ksk.keywords,
1748  uri->data.ksk.keywordCount))
1749  {
1751  uri->data.ksk.keywords,
1752  uri->data.ksk.keywordCount);
1753  uri->data.ksk.keywordCount++;
1754  }
1755  if (NULL != normalized_data)
1756  {
1757  if (! find_duplicate (normalized_data,
1758  (const char **) uri->data.ksk.keywords,
1759  uri->data.ksk.keywordCount))
1760  {
1761  insert_non_mandatory_keyword (normalized_data,
1762  uri->data.ksk.keywords,
1763  uri->data.ksk.keywordCount);
1764  uri->data.ksk.keywordCount++;
1765  }
1766  GNUNET_free (normalized_data);
1767  }
1768  return 0;
1769 }
static size_t u8_strcount(const uint8_t *s)
Counts the number of UTF-8 characters (not bytes) in the string, returns that count.
Definition: fs_uri.c:1502
static void insert_non_mandatory_keyword(const char *s, char **array, int index)
Add a keyword as non-mandatory (with &#39; &#39;-prefix) to the given keyword list at offset &#39;index&#39;...
Definition: fs_uri.c:1410
0-terminated, UTF-8 encoded string.
static int find_duplicate(const char *s, const char **array, int array_length)
Test if the given keyword s is already present in the given array, ignoring the &#39;+&#39;-mandatory prefix ...
Definition: fs_uri.c:1431
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
union GNUNET_FS_Uri::@13 data
A Universal Resource Identifier (URI), opaque.
Definition: fs_api.h:165
struct GNUNET_FS_Uri::@13::@14 ksk
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
static char * normalize_metadata(enum EXTRACTOR_MetaFormat format, const char *data, size_t data_len)
FIXME: comment.
Definition: fs_uri.c:1446
uint32_t data
The data value.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ needs_percent()

static int needs_percent ( char  c)
static

In URI-encoding, does the given character need to be encoded using %-encoding?

Definition at line 1838 of file fs_uri.c.

Referenced by uri_ksk_to_string().

1839 {
1840  return(! ((isalnum ((unsigned char) c)) || (c == '-') || (c == '_') ||
1841  (c == '.') || (c == '~')));
1842 }
Here is the caller graph for this function:

◆ uri_ksk_to_string()

static char* uri_ksk_to_string ( const struct GNUNET_FS_Uri uri)
static

Convert a KSK URI to a string.

Parameters
urithe URI to convert
Returns
NULL on error (i.e. keywordCount == 0)

Definition at line 1852 of file fs_uri.c.

References GNUNET_FS_Uri::data, GNUNET_FS_URI_KSK, GNUNET_FS_URI_KSK_INFIX, GNUNET_FS_URI_PREFIX, GNUNET_malloc, GNUNET_FS_Uri::keywordCount, GNUNET_FS_Uri::keywords, GNUNET_FS_Uri::ksk, needs_percent(), ret, and GNUNET_FS_Uri::type.

Referenced by GNUNET_FS_uri_to_string().

1853 {
1854  char **keywords;
1855  unsigned int keywordCount;
1856  size_t n;
1857  char *ret;
1858  unsigned int i;
1859  unsigned int j;
1860  unsigned int wpos;
1861  size_t slen;
1862  const char *keyword;
1863 
1864  if (uri->type != GNUNET_FS_URI_KSK)
1865  return NULL;
1866  keywords = uri->data.ksk.keywords;
1867  keywordCount = uri->data.ksk.keywordCount;
1868  n = keywordCount + strlen (GNUNET_FS_URI_PREFIX)
1869  + strlen (GNUNET_FS_URI_KSK_INFIX) + 1;
1870  for (i = 0; i < keywordCount; i++)
1871  {
1872  keyword = keywords[i];
1873  slen = strlen (keyword);
1874  n += slen;
1875  for (j = 0; j < slen; j++)
1876  {
1877  if ((j == 0) && (keyword[j] == ' '))
1878  {
1879  n--;
1880  continue; /* skip leading space */
1881  }
1882  if (needs_percent (keyword[j]))
1883  n += 2; /* will use %-encoding */
1884  }
1885  }
1886  ret = GNUNET_malloc (n);
1887  strcpy (ret, GNUNET_FS_URI_PREFIX);
1888  strcat (ret, GNUNET_FS_URI_KSK_INFIX);
1889  wpos = strlen (ret);
1890  for (i = 0; i < keywordCount; i++)
1891  {
1892  keyword = keywords[i];
1893  slen = strlen (keyword);
1894  for (j = 0; j < slen; j++)
1895  {
1896  if ((j == 0) && (keyword[j] == ' '))
1897  continue; /* skip leading space */
1898  if (needs_percent (keyword[j]))
1899  {
1900  sprintf (&ret[wpos], "%%%02X", (unsigned char) keyword[j]);
1901  wpos += 3;
1902  }
1903  else
1904  {
1905  ret[wpos++] = keyword[j];
1906  }
1907  }
1908  if (i != keywordCount - 1)
1909  ret[wpos++] = '+';
1910  }
1911  return ret;
1912 }
Keyword search key (query with keywords).
Definition: fs_api.h:153
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
char ** keywords
Keywords start with a &#39;+&#39; if they are mandatory (in which case the &#39;+&#39; is NOT part of the keyword) an...
Definition: fs_api.h:185
unsigned int keywordCount
Size of the keywords array.
Definition: fs_api.h:190
enum GNUNET_FS_UriType type
Type of the URI.
Definition: fs_api.h:170
#define GNUNET_FS_URI_KSK_INFIX
union GNUNET_FS_Uri::@13 data
#define GNUNET_FS_URI_PREFIX
struct GNUNET_FS_Uri::@13::@14 ksk
static int needs_percent(char c)
In URI-encoding, does the given character need to be encoded using %-encoding?
Definition: fs_uri.c:1838
#define GNUNET_malloc(size)
Wrapper around malloc.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uri_sks_to_string()

static char* uri_sks_to_string ( const struct GNUNET_FS_Uri uri)
static

Convert SKS URI to a string.

Parameters
urisks uri to convert
Returns
NULL on error

Definition at line 1922 of file fs_uri.c.

References buf, GNUNET_FS_Uri::data, GNUNET_asprintf(), GNUNET_assert, GNUNET_FS_URI_PREFIX, GNUNET_FS_URI_SKS, GNUNET_FS_URI_SKS_INFIX, GNUNET_STRINGS_data_to_string(), ret, GNUNET_FS_Uri::sks, and GNUNET_FS_Uri::type.

Referenced by GNUNET_FS_uri_to_string().

1923 {
1924  char *ret;
1925  char buf[1024];
1926 
1927  if (GNUNET_FS_URI_SKS != uri->type)
1928  return NULL;
1929  ret =
1931  sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
1932  buf,
1933  sizeof(buf));
1934  GNUNET_assert (NULL != ret);
1935  ret[0] = '\0';
1936  GNUNET_asprintf (&ret,
1937  "%s%s%s/%s",
1940  buf,
1941  uri->data.sks.identifier);
1942  return ret;
1943 }
#define GNUNET_FS_URI_SKS_INFIX
struct GNUNET_FS_Uri::@13::@15 sks
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
static char buf[2048]
enum GNUNET_FS_UriType type
Type of the URI.
Definition: fs_api.h:170
union GNUNET_FS_Uri::@13 data
Signed key space (file in namespace).
Definition: fs_api.h:148
#define GNUNET_FS_URI_PREFIX
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
char * GNUNET_STRINGS_data_to_string(const void *data, size_t size, char *out, size_t out_size)
Convert binary data to ASCII encoding using CrockfordBase32.
Definition: strings.c:870
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uri_chk_to_string()

static char* uri_chk_to_string ( const struct GNUNET_FS_Uri uri)
static

Convert a CHK URI to a string.

Parameters
urichk uri to convert
Returns
NULL on error

Definition at line 1953 of file fs_uri.c.

References GNUNET_FS_Uri::chk, FileIdentifier::chk, GNUNET_FS_Uri::data, LocUriAssembly::fi, FileIdentifier::file_length, GNUNET_asprintf(), GNUNET_CRYPTO_hash_to_enc(), GNUNET_FS_URI_CHK, GNUNET_FS_URI_CHK_INFIX, GNUNET_FS_URI_PREFIX, GNUNET_ntohll(), ContentHashKey::key, ContentHashKey::query, ret, and GNUNET_FS_Uri::type.

Referenced by GNUNET_FS_uri_to_string().

1954 {
1955  const struct FileIdentifier *fi;
1956  char *ret;
1957  struct GNUNET_CRYPTO_HashAsciiEncoded keyhash;
1958  struct GNUNET_CRYPTO_HashAsciiEncoded queryhash;
1959 
1960  if (uri->type != GNUNET_FS_URI_CHK)
1961  return NULL;
1962  fi = &uri->data.chk;
1963  GNUNET_CRYPTO_hash_to_enc (&fi->chk.key, &keyhash);
1964  GNUNET_CRYPTO_hash_to_enc (&fi->chk.query, &queryhash);
1965 
1966  GNUNET_asprintf (&ret,
1967  "%s%s%s.%s.%llu",
1970  (const char *) &keyhash,
1971  (const char *) &queryhash,
1972  GNUNET_ntohll (fi->file_length));
1973  return ret;
1974 }
struct ContentHashKey chk
Query and key of the top GNUNET_EC_IBlock.
Definition: fs_api.h:103
struct FileIdentifier chk
Information needed to retrieve a file (content-hash-key plus file size).
Definition: fs_api.h:211
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
struct GNUNET_HashCode query
Hash of the encrypted content, used for querying.
Definition: fs.h:63
#define GNUNET_FS_URI_CHK_INFIX
complete information needed to download a file.
Definition: fs_api.h:93
Content-hash-key (simple file).
Definition: fs_api.h:143
void GNUNET_CRYPTO_hash_to_enc(const struct GNUNET_HashCode *block, struct GNUNET_CRYPTO_HashAsciiEncoded *result)
Convert hash to ASCII encoding.
Definition: crypto_hash.c:73
enum GNUNET_FS_UriType type
Type of the URI.
Definition: fs_api.h:170
union GNUNET_FS_Uri::@13 data
0-terminated ASCII encoding of a struct GNUNET_HashCode.
struct GNUNET_HashCode key
Hash of the original content, used for encryption.
Definition: fs.h:58
#define GNUNET_FS_URI_PREFIX
uint64_t file_length
Total size of the file in bytes.
Definition: fs_api.h:98
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:53
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uri_loc_to_string()

static char* uri_loc_to_string ( const struct GNUNET_FS_Uri uri)
static

Convert a LOC URI to a string.

Parameters
uriloc uri to convert
Returns
NULL on error

Definition at line 1984 of file fs_uri.c.

References GNUNET_TIME_Absolute::abs_value_us, FileIdentifier::chk, Location::contentSignature, GNUNET_FS_Uri::data, Location::expirationTime, Location::fi, FileIdentifier::file_length, GNUNET_asprintf(), GNUNET_assert, GNUNET_CRYPTO_eddsa_public_key_to_string(), GNUNET_CRYPTO_hash_to_enc(), GNUNET_free, GNUNET_FS_URI_LOC_INFIX, GNUNET_FS_URI_PREFIX, GNUNET_ntohll(), GNUNET_STRINGS_data_to_string(), ContentHashKey::key, GNUNET_FS_Uri::loc, Location::peer, peer_id, GNUNET_PeerIdentity::public_key, ContentHashKey::query, ret, and SIGNATURE_ASCII_LENGTH.

Referenced by GNUNET_FS_uri_to_string().

1985 {
1986  char *ret;
1987  struct GNUNET_CRYPTO_HashAsciiEncoded keyhash;
1988  struct GNUNET_CRYPTO_HashAsciiEncoded queryhash;
1989  char *peer_id;
1990  char peer_sig[SIGNATURE_ASCII_LENGTH + 1];
1991 
1992  GNUNET_CRYPTO_hash_to_enc (&uri->data.loc.fi.chk.key, &keyhash);
1993  GNUNET_CRYPTO_hash_to_enc (&uri->data.loc.fi.chk.query, &queryhash);
1994  peer_id =
1996  GNUNET_assert (
1997  NULL !=
1999  sizeof(struct GNUNET_CRYPTO_EddsaSignature),
2000  peer_sig,
2001  sizeof(peer_sig)));
2002  GNUNET_asprintf (&ret,
2003  "%s%s%s.%s.%llu.%s.%s.%llu",
2006  (const char *) &keyhash,
2007  (const char *) &queryhash,
2008  (unsigned long long) GNUNET_ntohll (
2009  uri->data.loc.fi.file_length),
2010  peer_id,
2011  peer_sig,
2012  (unsigned long long)
2014  / 1000000LL);
2015  GNUNET_free (peer_id);
2016  return ret;
2017 }
struct ContentHashKey chk
Query and key of the top GNUNET_EC_IBlock.
Definition: fs_api.h:103
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static char * peer_id
Option –peer.
Definition: gnunet-cadet.c:42
struct GNUNET_PeerIdentity peer
Identity of the peer sharing the file.
Definition: fs_api.h:121
uint64_t abs_value_us
The actual value.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
char * GNUNET_CRYPTO_eddsa_public_key_to_string(const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a public key to a string.
Definition: crypto_ecc.c:265
struct GNUNET_HashCode query
Hash of the encrypted content, used for querying.
Definition: fs.h:63
void GNUNET_CRYPTO_hash_to_enc(const struct GNUNET_HashCode *block, struct GNUNET_CRYPTO_HashAsciiEncoded *result)
Convert hash to ASCII encoding.
Definition: crypto_hash.c:73
struct GNUNET_TIME_Absolute expirationTime
Time when this location URI expires.
Definition: fs_api.h:126
an ECC signature using EdDSA.
union GNUNET_FS_Uri::@13 data
0-terminated ASCII encoding of a struct GNUNET_HashCode.
struct GNUNET_HashCode key
Hash of the original content, used for encryption.
Definition: fs.h:58
#define GNUNET_FS_URI_PREFIX
uint64_t file_length
Total size of the file in bytes.
Definition: fs_api.h:98
struct GNUNET_CRYPTO_EddsaSignature contentSignature
Signature over the GNUNET_EC_FileIdentifier, peer identity and expiration time.
Definition: fs_api.h:132
struct FileIdentifier fi
Information about the shared file.
Definition: fs_api.h:116
struct Location loc
Information needed to retrieve a file including signed location (identity of a peer) of the content...
Definition: fs_api.h:217
#define SIGNATURE_ASCII_LENGTH
Definition: fs_uri.c:492
#define GNUNET_FS_URI_LOC_INFIX
char * GNUNET_STRINGS_data_to_string(const void *data, size_t size, char *out, size_t out_size)
Convert binary data to ASCII encoding using CrockfordBase32.
Definition: strings.c:870
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:53
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Here is the call graph for this function:
Here is the caller graph for this function: