From: Christian Grothoff Date: Sun, 30 Aug 2009 21:37:12 +0000 (+0000) Subject: adding listing of indexed files X-Git-Tag: initial-import-from-subversion-38251~23548 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=0634957156088bc3c53d787c13ba3006307d8ca5;p=oweals%2Fgnunet.git adding listing of indexed files --- diff --git a/TODO b/TODO index 073c5e137..ef2a459bf 100644 --- a/TODO +++ b/TODO @@ -41,7 +41,7 @@ PHASE #2: (Goal: recover basic file-sharing functionality) + search/download, response - implement basic FS library + sharing API - ~ unindex & list indexed!!! (need publish to be done) + ~ unindex (need publish to be done) ~ search (need publish to be done) ~ download (need publish/search to be done) - design network structs (CS/P2P) diff --git a/src/fs/fs.h b/src/fs/fs.h index e4eee7fd0..9fc15e62f 100644 --- a/src/fs/fs.h +++ b/src/fs/fs.h @@ -671,6 +671,29 @@ struct IndexStartMessage }; +/** + * Message send by FS service in response to a request + * asking for a list of all indexed files. + */ +struct IndexInfoMessage +{ + /** + * Message type will be + * GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_ENTRY. + */ + struct GNUNET_MessageHeader header; + + /** + * Hash of the indexed file. + */ + GNUNET_HashCode file_id; + + /* this is followed by a 0-terminated + filename of a file with the hash + "file_id" as seen by the client */ + +}; + #endif diff --git a/src/fs/fs_unindex.c b/src/fs/fs_unindex.c index 8fb13a644..c32a10cbf 100644 --- a/src/fs/fs_unindex.c +++ b/src/fs/fs_unindex.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2003, 2004, 2006 Christian Grothoff (and other contributing authors) + (C) 2003, 2004, 2006, 2009 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -29,21 +29,228 @@ */ #include "platform.h" +#include "gnunet_constants.h" #include "gnunet_fs_service.h" +#include "gnunet_protocols.h" #include "fs.h" + +/** + * Context for "GNUNET_FS_get_indexed_files". + */ +struct GetIndexedContext +{ + /** + * Handle to global FS context. + */ + struct GNUNET_FS_Handle *h; + + /** + * Connection to the FS service. + */ + struct GNUNET_CLIENT_Connection *client; + + /** + * Function to call for each indexed file. + */ + GNUNET_FS_IndexedFileProcessor iterator; + + /** + * Closure for iterator. + */ + void *iterator_cls; + + /** + * Continuation to trigger at the end. + */ + GNUNET_SCHEDULER_Task cont; + + /** + * Closure for cont. + */ + void *cont_cls; +}; + + +/** + * Function called on each response from the FS + * service with information about indexed files. + * + * @param cls closure (of type "struct GetIndexedContext*") + * @param msg message with indexing information + */ +static void +handle_index_info (void *cls, + const struct GNUNET_MessageHeader *msg) +{ + struct GetIndexedContext *gic = cls; + const struct IndexInfoMessage *iim; + uint16_t msize; + const char *filename; + + if (NULL == msg) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Failed to receive response for `%s' request from `%s' service.\n"), + "GET_INDEXED", + "fs"); + GNUNET_SCHEDULER_add_continuation (gic->h->sched, + GNUNET_NO, + gic->cont, + gic->cont_cls, + GNUNET_SCHEDULER_REASON_TIMEOUT); + GNUNET_CLIENT_disconnect (gic->client); + GNUNET_free (gic); + return; + } + if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_END) + { + /* normal end-of-list */ + GNUNET_SCHEDULER_add_continuation (gic->h->sched, + GNUNET_NO, + gic->cont, + gic->cont_cls, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); + GNUNET_CLIENT_disconnect (gic->client); + GNUNET_free (gic); + return; + } + msize = ntohs (msg->size); + iim = (const struct IndexInfoMessage*) msg; + filename = (const char*) &iim[1]; + if ( (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_ENTRY) || + (msize <= sizeof (struct IndexInfoMessage)) || + (filename[msize-sizeof (struct IndexInfoMessage) -1] != '\0') ) + { + /* bogus reply */ + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Failed to receive valid response for `%s' request from `%s' service.\n"), + "GET_INDEXED", + "fs"); + GNUNET_SCHEDULER_add_continuation (gic->h->sched, + GNUNET_NO, + gic->cont, + gic->cont_cls, + GNUNET_SCHEDULER_REASON_TIMEOUT); + GNUNET_CLIENT_disconnect (gic->client); + GNUNET_free (gic); + return; + } + if (GNUNET_OK != + gic->iterator (gic->iterator_cls, + filename, + &iim->file_id)) + { + GNUNET_SCHEDULER_add_continuation (gic->h->sched, + GNUNET_NO, + gic->cont, + gic->cont_cls, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); + GNUNET_CLIENT_disconnect (gic->client); + GNUNET_free (gic); + return; + } + /* get more */ + GNUNET_CLIENT_receive (gic->client, + &handle_index_info, + gic, + GNUNET_CONSTANTS_SERVICE_TIMEOUT); +} + + +/** + * Transmit the request to get a list of all + * indexed files to the "FS" service. + * + * @param cls closure (of type "struct GetIndexedContext*") + * @param size number of bytes availabe in buf + * @param buf where to write the message, NULL on error + * @return number of bytes written to buf + */ +static size_t +transmit_get_indexed (void *cls, + size_t size, + void *buf) +{ + struct GetIndexedContext *gic = cls; + struct GNUNET_MessageHeader *hdr; + + if (NULL == buf) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Failed to transmit `%s' request to `%s' service.\n"), + "GET_INDEXED", + "fs"); + GNUNET_SCHEDULER_add_continuation (gic->h->sched, + GNUNET_NO, + gic->cont, + gic->cont_cls, + GNUNET_SCHEDULER_REASON_TIMEOUT); + GNUNET_CLIENT_disconnect (gic->client); + GNUNET_free (gic); + return 0; + } + GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); + hdr = buf; + hdr->size = htons (sizeof (struct GNUNET_MessageHeader)); + hdr->type = htons (GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_GET); + GNUNET_CLIENT_receive (gic->client, + &handle_index_info, + gic, + GNUNET_CONSTANTS_SERVICE_TIMEOUT); + return sizeof (struct GNUNET_MessageHeader); +} + + /** * Iterate over all indexed files. * * @param h handle to the file sharing subsystem * @param iterator function to call on each indexed file * @param iterator_cls closure for iterator + * @param cont continuation to call when done; + * reason should be "TIMEOUT" (on + * error) or "PREREQ_DONE" (on success) + * @param cont_cls closure for cont */ void GNUNET_FS_get_indexed_files (struct GNUNET_FS_Handle *h, GNUNET_FS_IndexedFileProcessor iterator, - void *iterator_cls) + void *iterator_cls, + GNUNET_SCHEDULER_Task cont, + void *cont_cls) { + struct GNUNET_CLIENT_Connection *client; + struct GetIndexedContext *gic; + + client = GNUNET_CLIENT_connect (h->sched, + "fs", + h->cfg); + if (NULL == client) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Failed to not connect to `%s' service.\n"), + "fs"); + GNUNET_SCHEDULER_add_continuation (h->sched, + GNUNET_NO, + cont, + cont_cls, + GNUNET_SCHEDULER_REASON_TIMEOUT); + return; + } + + gic = GNUNET_malloc (sizeof (struct GetIndexedContext)); + gic->h = h; + gic->client = client; + gic->iterator = iterator; + gic->iterator_cls = iterator_cls; + gic->cont = cont; + gic->cont_cls = cont_cls; + GNUNET_CLIENT_notify_transmit_ready (client, + sizeof (struct GNUNET_MessageHeader), + GNUNET_CONSTANTS_SERVICE_TIMEOUT, + &transmit_get_indexed, + gic); } diff --git a/src/include/gnunet_fs_service.h b/src/include/gnunet_fs_service.h index d0032f72d..994c6eb15 100644 --- a/src/include/gnunet_fs_service.h +++ b/src/include/gnunet_fs_service.h @@ -1897,10 +1897,12 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, * * @param cls closure * @param filename the name of the file + * @param file_id hash of the contents of the indexed file * @return GNUNET_OK to continue iteration, GNUNET_SYSERR to abort */ typedef int (*GNUNET_FS_IndexedFileProcessor) (void *cls, - const char *filename); + const char *filename, + const GNUNET_HashCode *file_id); /** @@ -1909,11 +1911,17 @@ typedef int (*GNUNET_FS_IndexedFileProcessor) (void *cls, * @param h handle to the file sharing subsystem * @param iterator function to call on each indexed file * @param iterator_cls closure for iterator + * @param cont continuation to call when done; + * reason should be "TIMEOUT" (on + * error) or "PREREQ_DONE" (on success) + * @param cont_cls closure for cont */ void GNUNET_FS_get_indexed_files (struct GNUNET_FS_Handle *h, GNUNET_FS_IndexedFileProcessor iterator, - void *iterator_cls); + void *iterator_cls, + GNUNET_SCHEDULER_Task cont, + void *cont_cls); /** diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 686205c31..5a11f29e9 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h @@ -378,13 +378,28 @@ extern "C" */ #define GNUNET_MESSAGE_TYPE_FS_INDEX_START_OK 129 - /** * Response to a request for start indexing that * refuses. */ #define GNUNET_MESSAGE_TYPE_FS_INDEX_START_FAILED 130 +/** + * Request from client for list of indexed files. + */ +#define GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_GET 131 + +/** + * Reply to client with an indexed file name. + */ +#define GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_ENTRY 132 + +/** + * Reply to client indicating end of list. + */ +#define GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_END 133 + + /* TODO: - DV