📄 fslib.c
字号:
/** * Search for blocks matching the given key and type. * * @param timeout how long to search * @param anonymity_level what are the anonymity * requirements for this request? 0 for no * anonymity (DHT/direct transfer ok) * @param callback method to call for each result * @param priority priority to use for the search */intGNUNET_FS_start_search (struct GNUNET_FS_SearchContext *ctx, const GNUNET_PeerIdentity * target, unsigned int type, unsigned int keyCount, const GNUNET_HashCode * keys, unsigned int anonymityLevel, GNUNET_DatastoreValueIterator callback, void *closure){ struct GNUNET_FS_SearchHandle *ret; CS_fs_request_search_MESSAGE *req;#if DEBUG_FSLIB GNUNET_EncName enc;#endif ret = GNUNET_malloc (sizeof (struct GNUNET_FS_SearchHandle) + sizeof (CS_fs_request_search_MESSAGE) + (keyCount - 1) * sizeof (GNUNET_HashCode)); req = (CS_fs_request_search_MESSAGE *) & ret[1];#if DEBUG_FSLIB GNUNET_hash_to_enc (keys, &enc); fprintf (stderr, "FSLIB: start search for `%s' (%p)\n", (char *) &enc, ret);#endif req->header.size = htons (sizeof (CS_fs_request_search_MESSAGE) + (keyCount - 1) * sizeof (GNUNET_HashCode)); req->header.type = htons (GNUNET_CS_PROTO_GAP_QUERY_START); req->anonymity_level = htonl (anonymityLevel); req->type = htonl (type); if (target != NULL) req->target = *target; else memset (&req->target, 0, sizeof (GNUNET_PeerIdentity)); memcpy (&req->query[0], keys, keyCount * sizeof (GNUNET_HashCode)); ret->callback = callback; ret->closure = closure; GNUNET_mutex_lock (ctx->lock); ret->next = ctx->handles; ctx->handles = ret;#if DEBUG_FSLIB fprintf (stderr, "FSLIB passes request %u to daemon (%d)\n", ctx->total_requested++, type);#endif if (GNUNET_OK != GNUNET_client_connection_write (ctx->sock, &req->header)) GNUNET_client_connection_close_temporarily (ctx->sock); GNUNET_mutex_unlock (ctx->lock); return GNUNET_OK;}/** * Stop searching for blocks matching the given key and type. * * @param callback method to call for each result * @return GNUNET_OK (or GNUNET_SYSERR if this search * was never started for this context) */intGNUNET_FS_stop_search (struct GNUNET_FS_SearchContext *ctx, GNUNET_DatastoreValueIterator callback, void *closure){ struct GNUNET_FS_SearchHandle *pos; struct GNUNET_FS_SearchHandle *prev; CS_fs_request_search_MESSAGE *req; prev = NULL; GNUNET_mutex_lock (ctx->lock); pos = ctx->handles; while ((pos != NULL) && ((pos->callback != callback) || (pos->closure != closure))) { prev = pos; pos = pos->next; } if (pos != NULL) { if (prev == NULL) ctx->handles = pos->next; else prev->next = pos->next; /* TODO: consider sending "stop" message to gnunetd? */ req = (CS_fs_request_search_MESSAGE *) & pos[1]; req->header.type = htons (GNUNET_CS_PROTO_GAP_QUERY_STOP); if (GNUNET_OK != GNUNET_client_connection_write (ctx->sock, &req->header)) GNUNET_client_connection_close_temporarily (ctx->sock); GNUNET_free (pos); } GNUNET_mutex_unlock (ctx->lock); return GNUNET_SYSERR;}/** * Insert a block. * * @param block the block (properly encoded and all) * @return GNUNET_OK on success, GNUNET_SYSERR on error, GNUNET_NO on transient error */intGNUNET_FS_insert (struct GNUNET_ClientServerConnection *sock, const GNUNET_DatastoreValue * block){ int ret; CS_fs_request_insert_MESSAGE *ri; unsigned int size; int retry; if (ntohl (block->size) <= sizeof (GNUNET_DatastoreValue)) { GNUNET_GE_BREAK (NULL, 0); return GNUNET_SYSERR; } size = ntohl (block->size) - sizeof (GNUNET_DatastoreValue); ri = GNUNET_malloc (sizeof (CS_fs_request_insert_MESSAGE) + size); ri->header.size = htons (sizeof (CS_fs_request_insert_MESSAGE) + size); ri->header.type = htons (GNUNET_CS_PROTO_GAP_INSERT); ri->priority = block->priority; ri->expiration = block->expiration_time; ri->anonymity_level = block->anonymity_level; memcpy (&ri[1], &block[1], size); retry = AUTO_RETRY; do { if (GNUNET_OK != GNUNET_client_connection_write (sock, &ri->header)) { GNUNET_free (ri); return GNUNET_SYSERR; } if (GNUNET_OK != GNUNET_client_connection_read_result (sock, &ret)) { GNUNET_GE_BREAK (NULL, GNUNET_shutdown_test ()); GNUNET_free (ri); return GNUNET_SYSERR; } } while ((ret == GNUNET_NO) && (retry-- > 0)); GNUNET_free (ri); return ret;}/** * Initialize to index a file */intGNUNET_FS_prepare_to_index (struct GNUNET_ClientServerConnection *sock, const GNUNET_HashCode * fileHc, const char *fn){ int ret; CS_fs_request_init_index_MESSAGE *ri; unsigned int size; size_t fnSize; fnSize = strlen (fn); fnSize = (fnSize + 7) & (~7); /* align */ size = sizeof (CS_fs_request_init_index_MESSAGE) + fnSize; GNUNET_GE_ASSERT (NULL, size < 65536); ri = GNUNET_malloc (size); memset (ri, 0, size); ri->header.size = htons (size); ri->header.type = htons (GNUNET_CS_PROTO_GAP_INIT_INDEX); ri->reserved = htonl (0); ri->fileId = *fileHc; memcpy (&ri[1], fn, strlen (fn));#if DEBUG_FSLIB fprintf (stderr, "Sending index initialization request to gnunetd\n");#endif if (GNUNET_OK != GNUNET_client_connection_write (sock, &ri->header)) { GNUNET_free (ri); return GNUNET_SYSERR; } GNUNET_free (ri);#if DEBUG_FSLIB fprintf (stderr, "Waiting for confirmation of index initialization request by gnunetd\n");#endif if (GNUNET_OK != GNUNET_client_connection_read_result (sock, &ret)) return GNUNET_SYSERR; return ret;}/** * Index a block. * * @param fileHc the GNUNET_hash of the entire file * @param block the data from the file (in plaintext) * @param offset the offset of the block into the file * @return GNUNET_OK on success, GNUNET_SYSERR on error */intGNUNET_FS_index (struct GNUNET_ClientServerConnection *sock, const GNUNET_HashCode * fileHc, const GNUNET_DatastoreValue * block, unsigned long long offset){ int ret; CS_fs_request_index_MESSAGE *ri; unsigned int size; int retry;#if DEBUG_FSLIB GNUNET_HashCode hc; GNUNET_EncName enc;#endif size = ntohl (block->size) - sizeof (GNUNET_DatastoreValue); ri = GNUNET_malloc (sizeof (CS_fs_request_index_MESSAGE) + size); ri->header.size = htons (sizeof (CS_fs_request_index_MESSAGE) + size); ri->header.type = htons (GNUNET_CS_PROTO_GAP_INDEX); ri->priority = block->priority; ri->expiration = block->expiration_time; ri->anonymity_level = block->anonymity_level; ri->fileId = *fileHc; ri->fileOffset = GNUNET_htonll (offset); memcpy (&ri[1], &block[1], size);#if DEBUG_FSLIB GNUNET_EC_file_block_get_query ((const GNUNET_EC_DBlock *) &block[1], size, &hc); GNUNET_hash_to_enc (&hc, &enc); fprintf (stderr, "Sending index request for `%s' to gnunetd)\n", (const char *) &enc);#endif retry = AUTO_RETRY; do { if (GNUNET_OK != GNUNET_client_connection_write (sock, &ri->header)) { GNUNET_free (ri); return GNUNET_SYSERR; }#if DEBUG_FSLIB fprintf (stderr, "Waiting for confirmation of index request by gnunetd\n");#endif if (GNUNET_OK != GNUNET_client_connection_read_result (sock, &ret)) { GNUNET_free (ri); return GNUNET_SYSERR; } } while ((ret == GNUNET_NO) && (retry-- > 0)); GNUNET_free (ri); return ret;}/** * Delete a block. The arguments are the same as the ones for * GNUNET_FS_insert. * * @param block the block (properly encoded and all) * @return number of items deleted on success, * GNUNET_SYSERR on error */intGNUNET_FS_delete (struct GNUNET_ClientServerConnection *sock, const GNUNET_DatastoreValue * block){ int ret; CS_fs_request_delete_MESSAGE *rd; unsigned int size; int retry; size = ntohl (block->size) - sizeof (GNUNET_DatastoreValue); rd = GNUNET_malloc (sizeof (CS_fs_request_delete_MESSAGE) + size); rd->header.size = htons (sizeof (CS_fs_request_delete_MESSAGE) + size); rd->header.type = htons (GNUNET_CS_PROTO_GAP_DELETE); memcpy (&rd[1], &block[1], size); retry = AUTO_RETRY; do { if (GNUNET_OK != GNUNET_client_connection_write (sock, &rd->header)) { GNUNET_free (rd); GNUNET_GE_BREAK (NULL, 0); return GNUNET_SYSERR; } if (GNUNET_OK != GNUNET_client_connection_read_result (sock, &ret)) { GNUNET_GE_BREAK (NULL, 0); GNUNET_free (rd); return GNUNET_SYSERR; } } while ((ret == GNUNET_NO) && (retry-- > 0)); GNUNET_free (rd); return ret;}/** * Unindex a file. * * @param hc the GNUNET_hash of the entire file * @return GNUNET_OK on success, GNUNET_SYSERR on error */intGNUNET_FS_unindex (struct GNUNET_ClientServerConnection *sock, unsigned int blocksize, const GNUNET_HashCode * hc){ int ret; CS_fs_request_unindex_MESSAGE ru; ru.header.size = htons (sizeof (CS_fs_request_unindex_MESSAGE)); ru.header.type = htons (GNUNET_CS_PROTO_GAP_UNINDEX); ru.blocksize = htonl (blocksize); ru.fileId = *hc; if (GNUNET_OK != GNUNET_client_connection_write (sock, &ru.header)) return GNUNET_SYSERR; if (GNUNET_OK != GNUNET_client_connection_read_result (sock, &ret)) return GNUNET_SYSERR; return ret;}/** * Test if a file of the given GNUNET_hash is indexed. * * @param hc the GNUNET_hash of the entire file * @return GNUNET_YES if so, GNUNET_NO if not, GNUNET_SYSERR on error */intGNUNET_FS_test_indexed (struct GNUNET_ClientServerConnection *sock, const GNUNET_HashCode * hc){ CS_fs_request_test_index_MESSAGE ri; int ret; ri.header.size = htons (sizeof (CS_fs_request_test_index_MESSAGE)); ri.header.type = htons (GNUNET_CS_PROTO_GAP_TESTINDEX); ri.reserved = htonl (0); ri.fileId = *hc; if (GNUNET_OK != GNUNET_client_connection_write (sock, &ri.header)) return GNUNET_SYSERR; if (GNUNET_OK != GNUNET_client_connection_read_result (sock, &ret)) return GNUNET_SYSERR; return ret;}/* end of fslib.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -