⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uri.c

📁 GNUnet是一个安全的点对点网络框架
💻 C
📖 第 1 页 / 共 2 页
字号:
      GNUNET_free (dup);      return GNUNET_SYSERR;    }  GNUNET_free (dup);  fi->file_length = GNUNET_htonll (fi->file_length);  return GNUNET_OK;}/** * Parses an URI that identifies a location (and file). * Also verifies validity of the location URI. * * @param uri an uri string * @param loc where to store the location * @return GNUNET_OK on success, GNUNET_SYSERR if this is not a file URI */static intparseLocationURI (struct GNUNET_GE_Context *ectx, const char *uri,                  Location * loc){  unsigned int pos;  unsigned int npos;  int ret;  size_t slen;  char *dup;  char *addr;  GNUNET_GE_ASSERT (ectx, uri != NULL);  addr = NULL;  slen = strlen (uri);  pos = strlen (GNUNET_ECRS_URI_PREFIX);  if (0 != strncmp (uri, GNUNET_ECRS_URI_PREFIX, pos))    return GNUNET_SYSERR;  if (0 != strncmp (&uri[pos],                    GNUNET_ECRS_LOCATION_INFIX,                    strlen (GNUNET_ECRS_LOCATION_INFIX)))    return GNUNET_SYSERR;  pos += strlen (GNUNET_ECRS_LOCATION_INFIX);  if ((slen < pos + 2 * sizeof (GNUNET_EncName) + 1) ||      (uri[pos + sizeof (GNUNET_EncName) - 1] != '.') ||      (uri[pos + sizeof (GNUNET_EncName) * 2 - 1] != '.'))    return GNUNET_SYSERR;  dup = GNUNET_strdup (uri);  dup[pos + sizeof (GNUNET_EncName) - 1] = '\0';  dup[pos + sizeof (GNUNET_EncName) * 2 - 1] = '\0';  npos = pos + sizeof (GNUNET_EncName) * 2;  while ((uri[npos] != '\0') && (uri[npos] != '.'))    npos++;  if (dup[npos] == '\0')    goto ERR;  dup[npos++] = '\0';  if ((GNUNET_OK != GNUNET_enc_to_hash (&dup[pos],                                        &loc->fi.chk.key)) ||      (GNUNET_OK != GNUNET_enc_to_hash (&dup[pos + sizeof (GNUNET_EncName)],                                        &loc->fi.chk.query)) ||      (1 != SSCANF (&dup[pos + sizeof (GNUNET_EncName) * 2],                    "%llu", &loc->fi.file_length)))    goto ERR;  loc->fi.file_length = GNUNET_htonll (loc->fi.file_length);  ret = enc2bin (&dup[npos], &loc->peer, sizeof (GNUNET_RSA_PublicKey));  if (ret == -1)    goto ERR;  npos += ret;  if (dup[npos++] != '.')    goto ERR;  ret =    enc2bin (&dup[npos], &loc->contentSignature,             sizeof (GNUNET_RSA_Signature));  if (ret == -1)    goto ERR;  npos += ret;  if (dup[npos++] != '.')    goto ERR;  if (1 != SSCANF (&dup[npos], "%u", &loc->expirationTime))    goto ERR;  /* Finally: verify sigs! */  if (GNUNET_OK != GNUNET_RSA_verify (&loc->fi,                                      sizeof (GNUNET_EC_FileIdentifier) +                                      sizeof (GNUNET_PeerIdentity) +                                      sizeof (GNUNET_Int32Time),                                      &loc->contentSignature, &loc->peer))    goto ERR;  GNUNET_free (dup);  return GNUNET_OK;ERR:  GNUNET_free (dup);  GNUNET_free_non_null (addr);  return GNUNET_SYSERR;}/** * Convert a UTF-8 String to a URI. */URI *GNUNET_ECRS_string_to_uri (struct GNUNET_GE_Context * ectx, const char *uri){  URI *ret;  int len;  ret = GNUNET_malloc (sizeof (URI));  if (GNUNET_OK == parseFileURI (ectx, uri, &ret->data.fi))    {      ret->type = chk;      return ret;    }  if (GNUNET_OK == parseSubspaceURI (ectx,                                     uri,                                     &ret->data.sks.namespace,                                     &ret->data.sks.identifier))    {      ret->type = sks;      return ret;    }  if (GNUNET_OK == parseLocationURI (ectx, uri, &ret->data.loc))    {      ret->type = loc;      return ret;    }  len = parseKeywordURI (ectx, uri, &ret->data.ksk.keywords);  if (len < 0)    {      GNUNET_free (ret);      return NULL;    }  ret->type = ksk;  ret->data.ksk.keywordCount = len;  return ret;}/** * Free URI. */voidGNUNET_ECRS_uri_destroy (struct GNUNET_ECRS_URI *uri){  int i;  GNUNET_GE_ASSERT (NULL, uri != NULL);  switch (uri->type)    {    case ksk:      for (i = 0; i < uri->data.ksk.keywordCount; i++)        GNUNET_free (uri->data.ksk.keywords[i]);      GNUNET_array_grow (uri->data.ksk.keywords, uri->data.ksk.keywordCount,                         0);      break;    case sks:      GNUNET_free (uri->data.sks.identifier);      break;    case loc:      break;    default:      /* do nothing */      break;    }  GNUNET_free (uri);}/** * Is this a namespace URI? */intGNUNET_ECRS_uri_test_sks (const struct GNUNET_ECRS_URI *uri){  return uri->type == sks;}/** * Get the (globally unique) ID of the namespace * from the given namespace URI. * * @return GNUNET_OK on success */intGNUNET_ECRS_uri_get_namespace_from_sks (const struct GNUNET_ECRS_URI *uri,                                        GNUNET_HashCode * id){  if (!GNUNET_ECRS_uri_test_sks (uri))    {      GNUNET_GE_BREAK (NULL, 0);      return GNUNET_SYSERR;    }  *id = uri->data.sks.namespace;  return GNUNET_OK;}/** * Get the content identifier of an SKS URI. * * @return NULL on error */char *GNUNET_ECRS_uri_get_content_id_from_sks (const struct GNUNET_ECRS_URI *uri){  if (!GNUNET_ECRS_uri_test_sks (uri))    {      GNUNET_GE_BREAK (NULL, 0);      return NULL;    }  return GNUNET_strdup (uri->data.sks.identifier);}/** * Is this a keyword URI? */intGNUNET_ECRS_uri_test_ksk (const struct GNUNET_ECRS_URI *uri){#if EXTRA_CHECKS  int i;  if (uri->type == ksk)    {      for (i = uri->data.ksk.keywordCount - 1; i >= 0; i--)        GNUNET_GE_ASSERT (NULL, uri->data.ksk.keywords[i] != NULL);    }#endif  return uri->type == ksk;}/** * How many keywords are ANDed in this keyword URI? * @return 0 if this is not a keyword URI */unsigned intGNUNET_ECRS_uri_get_keyword_count_from_ksk (const struct GNUNET_ECRS_URI *uri){  if (uri->type != ksk)    return 0;  return uri->data.ksk.keywordCount;}/** * Iterate over all keywords in this keyword URI? * @return -1 if this is not a keyword URI, otherwise number of *   keywords iterated over until iterator aborted */intGNUNET_ECRS_uri_get_keywords_from_ksk (const struct GNUNET_ECRS_URI *uri,                                       GNUNET_ECRS_KeywordIterator iterator,                                       void *cls){  unsigned int i;  char *keyword;  if (uri->type != ksk)    return -1;  if (iterator == NULL)    return uri->data.ksk.keywordCount;  for (i = 0; i < uri->data.ksk.keywordCount; i++)    {      keyword = uri->data.ksk.keywords[i];      /* first character of keyword indicates         if it is mandatory or not */      if (GNUNET_OK != iterator (&keyword[1], keyword[0] == '+', cls))        return i;    }  return i;}/** * Is this a file (or directory) URI? */intGNUNET_ECRS_uri_test_chk (const struct GNUNET_ECRS_URI *uri){  return uri->type == chk;}/** * Is this a location URI? (DHT specific!) */intGNUNET_ECRS_uri_test_loc (const struct GNUNET_ECRS_URI *uri){  return uri->type == loc;}/** * What is the size of the file that this URI * refers to? */unsigned long longGNUNET_ECRS_uri_get_file_size (const struct GNUNET_ECRS_URI *uri){  switch (uri->type)    {    case chk:      return GNUNET_ntohll (uri->data.fi.file_length);    case loc:      return GNUNET_ntohll (uri->data.loc.fi.file_length);    default:      GNUNET_GE_ASSERT (NULL, 0);    }  return 0;                     /* unreachable */}/** * Duplicate URI. */URI *GNUNET_ECRS_uri_duplicate (const URI * uri){  struct GNUNET_ECRS_URI *ret;  int i;  ret = GNUNET_malloc (sizeof (URI));  memcpy (ret, uri, sizeof (URI));  switch (ret->type)    {    case ksk:      if (ret->data.ksk.keywordCount > 0)        {          ret->data.ksk.keywords            = GNUNET_malloc (ret->data.ksk.keywordCount * sizeof (char *));          for (i = 0; i < ret->data.ksk.keywordCount; i++)            ret->data.ksk.keywords[i] =              GNUNET_strdup (uri->data.ksk.keywords[i]);        }      else        ret->data.ksk.keywords = NULL;  /* just to be sure */      break;    case sks:      ret->data.sks.identifier = GNUNET_strdup (uri->data.sks.identifier);      break;    case loc:      break;    default:      break;    }  return ret;}/** * Expand a keyword-URI by duplicating all keywords, * adding the current date (YYYY-MM-DD) after each * keyword. */URI *GNUNET_ECRS_uri_expand_keywords_with_date (const URI * uri){  URI *ret;  int i;  char *key;  char *kd;  struct tm t;  time_t now;  unsigned int keywordCount;  GNUNET_GE_ASSERT (NULL, uri->type == ksk);  time (&now);#ifdef HAVE_GMTIME_R  gmtime_r (&now, &t);#else  t = *gmtime (&now);#endif  ret = GNUNET_malloc (sizeof (URI));  ret->type = ksk;  keywordCount = uri->data.ksk.keywordCount;  ret->data.ksk.keywordCount = 2 * keywordCount;  if (keywordCount > 0)    {      ret->data.ksk.keywords =        GNUNET_malloc (sizeof (char *) * keywordCount * 2);      for (i = 0; i < keywordCount; i++)        {          key = uri->data.ksk.keywords[i];          GNUNET_GE_ASSERT (NULL, key != NULL);          ret->data.ksk.keywords[2 * i] = GNUNET_strdup (key);          kd = GNUNET_malloc (strlen (key) + 13);          memset (kd, 0, strlen (key) + 13);          strcpy (kd, key);          strftime (&kd[strlen (key)], 13, "-%Y-%m-%d", &t);          ret->data.ksk.keywords[2 * i + 1] = kd;        }    }  else    ret->data.ksk.keywords = NULL;  return ret;}static intgather_uri_data (EXTRACTOR_KeywordType type, const char *data, void *cls){  URI *uri = cls;  char *nkword;  int j;  for (j = uri->data.ksk.keywordCount - 1; j >= 0; j--)    if (0 == strcmp (&uri->data.ksk.keywords[j][1], data))      return GNUNET_OK;  nkword = GNUNET_malloc (strlen (data) + 2);  strcpy (nkword, " ");         /* not mandatory */  strcat (nkword, data);  uri->data.ksk.keywords[uri->data.ksk.keywordCount++] = nkword;  return GNUNET_OK;}/** * 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). */URI *GNUNET_meta_data_to_uri (const struct GNUNET_MetaData * md){  URI *ret;  if (md == NULL)    return NULL;  ret = GNUNET_malloc (sizeof (URI));  ret->type = ksk;  ret->data.ksk.keywordCount = 0;  ret->data.ksk.keywords = NULL;  ret->data.ksk.keywords    = GNUNET_malloc (sizeof (char *) *                     GNUNET_meta_data_get_contents (md, NULL, NULL));  GNUNET_meta_data_get_contents (md, &gather_uri_data, ret);  return ret;}/** * Are these two URIs equal? */intGNUNET_ECRS_uri_test_equal (const struct GNUNET_ECRS_URI *uri1,                            const struct GNUNET_ECRS_URI *uri2){  int ret;  int i;  int j;  GNUNET_GE_ASSERT (NULL, uri1 != NULL);  GNUNET_GE_ASSERT (NULL, uri2 != NULL);  if (uri1->type != uri2->type)    return GNUNET_NO;  switch (uri1->type)    {    case chk:      if (0 == memcmp (&uri1->data.fi,                       &uri2->data.fi, sizeof (GNUNET_EC_FileIdentifier)))        return GNUNET_YES;      return GNUNET_NO;    case sks:      if ((0 == memcmp (&uri1->data.sks.namespace,                        &uri2->data.sks.namespace,                        sizeof (GNUNET_HashCode))) &&          (0 == strcmp (uri1->data.sks.identifier,                        uri2->data.sks.identifier)))        return GNUNET_YES;      return GNUNET_NO;    case ksk:      if (uri1->data.ksk.keywordCount != uri2->data.ksk.keywordCount)        return GNUNET_NO;      for (i = 0; i < uri1->data.ksk.keywordCount; i++)        {          ret = GNUNET_NO;          for (j = 0; j < uri2->data.ksk.keywordCount; j++)            {              if (0 == strcmp (uri1->data.ksk.keywords[i],                               uri2->data.ksk.keywords[j]))                {                  ret = GNUNET_YES;                  break;                }            }          if (ret == GNUNET_NO)            return GNUNET_NO;        }      return GNUNET_YES;    case loc:      if (memcmp (&uri1->data.loc,                  &uri2->data.loc,                  sizeof (GNUNET_EC_FileIdentifier) +                  sizeof (GNUNET_RSA_PublicKey) +                  sizeof (GNUNET_Int32Time) +                  sizeof (unsigned short) + sizeof (unsigned short)) != 0)        return GNUNET_NO;      return GNUNET_YES;    default:      return GNUNET_NO;    }}/** * Obtain the identity of the peer offering the data * @return -1 if this is not a location URI, otherwise GNUNET_OK */intGNUNET_ECRS_uri_get_peer_identity_from_loc (const struct GNUNET_ECRS_URI *uri,                                            GNUNET_PeerIdentity * peer){  if (uri->type != loc)    return -1;  GNUNET_hash (&uri->data.loc.peer, sizeof (GNUNET_RSA_PublicKey),               &peer->hashPubKey);  return GNUNET_OK;}/** * Obtain the URI of the content itself. * * @return NULL if argument is not a location URI */struct GNUNET_ECRS_URI *GNUNET_ECRS_uri_get_content_uri_from_loc (const struct GNUNET_ECRS_URI *uri){  struct GNUNET_ECRS_URI *ret;  if (uri->type != loc)    return NULL;  ret = GNUNET_malloc (sizeof (struct GNUNET_ECRS_URI));  ret->type = chk;  ret->data.fi = uri->data.loc.fi;  return ret;}/** * Construct a location URI. * * @param baseURI content offered by the sender * @param sender identity of the peer with the content * @param expiration_time how long will the content be offered? * @param proto transport protocol to reach the peer * @param sas sender address size (for HELLO) * @param address sas bytes of address information * @param signer function to call for obtaining *        RSA signatures for "sender". * @return the location URI */struct GNUNET_ECRS_URI *GNUNET_ECRS_location_to_uri (const struct GNUNET_ECRS_URI *baseUri,                             const GNUNET_RSA_PublicKey * sender,                             GNUNET_Int32Time expirationTime,                             GNUNET_ECRS_SignFunction signer,                             void *signer_cls){  struct GNUNET_ECRS_URI *uri;  if (baseUri->type != chk)    return NULL;  uri = GNUNET_malloc (sizeof (struct GNUNET_ECRS_URI));  uri->type = loc;  uri->data.loc.fi = baseUri->data.fi;  uri->data.loc.peer = *sender;  uri->data.loc.expirationTime = expirationTime;  signer (signer_cls,          sizeof (GNUNET_EC_FileIdentifier) +          sizeof (GNUNET_PeerIdentity) +          sizeof (GNUNET_Int32Time),          &uri->data.loc.fi, &uri->data.loc.contentSignature);  return uri;}/* end of uri.c */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -