diff options
author | Christian Grothoff <christian@grothoff.org> | 2009-08-31 21:14:22 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2009-08-31 21:14:22 +0000 |
commit | 5dc5c7268ba88e70e208dc5c0a43b19bf111aeb3 (patch) | |
tree | f91bd544f2e14d69b9eee907e172588651215a76 | |
parent | 32716cc62ae96040bde78dacabe18a556290f392 (diff) | |
download | gnunet-5dc5c7268ba88e70e208dc5c0a43b19bf111aeb3.tar.gz gnunet-5dc5c7268ba88e70e208dc5c0a43b19bf111aeb3.zip |
working on unindex
-rw-r--r-- | src/fs/Makefile.am | 1 | ||||
-rw-r--r-- | src/fs/fs.h | 137 | ||||
-rw-r--r-- | src/fs/fs_list_indexed.c | 252 | ||||
-rw-r--r-- | src/fs/fs_publish.c | 9 | ||||
-rw-r--r-- | src/fs/fs_unindex.c | 687 | ||||
-rw-r--r-- | src/include/gnunet_disk_lib.h | 12 | ||||
-rw-r--r-- | src/include/gnunet_protocols.h | 10 | ||||
-rw-r--r-- | src/util/disk.c | 5 |
8 files changed, 559 insertions, 554 deletions
diff --git a/src/fs/Makefile.am b/src/fs/Makefile.am index f1bc64784..ebe6790c9 100644 --- a/src/fs/Makefile.am +++ b/src/fs/Makefile.am | |||
@@ -19,6 +19,7 @@ libgnunetfs_la_SOURCES = \ | |||
19 | fs_download.c \ | 19 | fs_download.c \ |
20 | fs_file_information.c \ | 20 | fs_file_information.c \ |
21 | fs_getopt.c \ | 21 | fs_getopt.c \ |
22 | fs_list_indexed.c \ | ||
22 | fs_publish.c \ | 23 | fs_publish.c \ |
23 | fs_namespace.c \ | 24 | fs_namespace.c \ |
24 | fs_search.c \ | 25 | fs_search.c \ |
diff --git a/src/fs/fs.h b/src/fs/fs.h index 9fc15e62f..956048cc5 100644 --- a/src/fs/fs.h +++ b/src/fs/fs.h | |||
@@ -52,6 +52,15 @@ | |||
52 | #define MAX_INLINE_SIZE 65536 | 52 | #define MAX_INLINE_SIZE 65536 |
53 | 53 | ||
54 | 54 | ||
55 | /** | ||
56 | * Blocksize to use when hashing files | ||
57 | * for indexing (blocksize for IO, not for | ||
58 | * the DBlocks). Larger blocksizes can | ||
59 | * be more efficient but will be more disruptive | ||
60 | * as far as the scheduler is concerned. | ||
61 | */ | ||
62 | #define HASHING_BLOCKSIZE (1024 * 1024) | ||
63 | |||
55 | 64 | ||
56 | /** | 65 | /** |
57 | * @brief content hash key | 66 | * @brief content hash key |
@@ -491,10 +500,106 @@ struct GNUNET_FS_PublishContext | |||
491 | 500 | ||
492 | 501 | ||
493 | /** | 502 | /** |
503 | * Phases of unindex processing (state machine). | ||
504 | */ | ||
505 | enum UnindexState | ||
506 | { | ||
507 | /** | ||
508 | * We're currently hashing the file. | ||
509 | */ | ||
510 | UNINDEX_STATE_HASHING = 0, | ||
511 | |||
512 | /** | ||
513 | * We're notifying the FS service about | ||
514 | * the unindexing. | ||
515 | */ | ||
516 | UNINDEX_STATE_FS_NOTIFY = 1, | ||
517 | |||
518 | /** | ||
519 | * We're telling the datastore to delete | ||
520 | * the respective entries. | ||
521 | */ | ||
522 | UNINDEX_STATE_DS_REMOVE = 2, | ||
523 | |||
524 | /** | ||
525 | * We're done. | ||
526 | */ | ||
527 | UNINDEX_STATE_COMPLETE = 3, | ||
528 | |||
529 | /** | ||
530 | * We've encountered a fatal error. | ||
531 | */ | ||
532 | UNINDEX_STATE_ERROR = 4, | ||
533 | |||
534 | /** | ||
535 | * We've been aborted. The next callback should clean up the | ||
536 | * struct. | ||
537 | */ | ||
538 | UNINDEX_STATE_ABORTED = 5 | ||
539 | }; | ||
540 | |||
541 | |||
542 | /** | ||
494 | * Handle for controlling an unindexing operation. | 543 | * Handle for controlling an unindexing operation. |
495 | */ | 544 | */ |
496 | struct GNUNET_FS_UnindexContext | 545 | struct GNUNET_FS_UnindexContext |
497 | { | 546 | { |
547 | |||
548 | /** | ||
549 | * Global FS context. | ||
550 | */ | ||
551 | struct GNUNET_FS_Handle *h; | ||
552 | |||
553 | /** | ||
554 | * Name of the file that we are unindexing. | ||
555 | */ | ||
556 | char *filename; | ||
557 | |||
558 | /** | ||
559 | * Connection to the FS service, | ||
560 | * only valid during the UNINDEX_STATE_FS_NOTIFY | ||
561 | * phase. | ||
562 | */ | ||
563 | struct GNUNET_CLIENT_Connection *client; | ||
564 | |||
565 | /** | ||
566 | * Connection to the datastore service, | ||
567 | * only valid during the UNINDEX_STATE_DS_NOTIFY | ||
568 | * phase. | ||
569 | */ | ||
570 | struct GNUNET_DATASTORE_Handle *dsh; | ||
571 | |||
572 | /** | ||
573 | * Pointer kept for the client. | ||
574 | */ | ||
575 | void *client_info; | ||
576 | |||
577 | /** | ||
578 | * Overall size of the file. | ||
579 | */ | ||
580 | uint64_t file_size; | ||
581 | |||
582 | /** | ||
583 | * How far have we gotten? | ||
584 | */ | ||
585 | uint64_t unindex_offset; | ||
586 | |||
587 | /** | ||
588 | * When did we start? | ||
589 | */ | ||
590 | struct GNUNET_TIME_Absolute start_time; | ||
591 | |||
592 | /** | ||
593 | * Hash of the file's contents (once | ||
594 | * computed). | ||
595 | */ | ||
596 | GNUNET_HashCode file_id; | ||
597 | |||
598 | /** | ||
599 | * Current operatinonal phase. | ||
600 | */ | ||
601 | enum UnindexState state; | ||
602 | |||
498 | }; | 603 | }; |
499 | 604 | ||
500 | 605 | ||
@@ -695,6 +800,38 @@ struct IndexInfoMessage | |||
695 | }; | 800 | }; |
696 | 801 | ||
697 | 802 | ||
803 | /** | ||
804 | * Message sent from a GNUnet (fs) unindexing | ||
805 | * activity to the gnunet-fs-service to | ||
806 | * indicate that a file will be unindexed. The service | ||
807 | * is supposed to remove the file from the | ||
808 | * list of indexed files and response with | ||
809 | * a confirmation message (even if the file | ||
810 | * was already not on the list). | ||
811 | */ | ||
812 | struct UnindexMessage | ||
813 | { | ||
814 | |||
815 | /** | ||
816 | * Message type will be | ||
817 | * GNUNET_MESSAGE_TYPE_FS_UNINDEX. | ||
818 | */ | ||
819 | struct GNUNET_MessageHeader header; | ||
820 | |||
821 | /** | ||
822 | * Always zero. | ||
823 | */ | ||
824 | uint32_t reserved; | ||
825 | |||
826 | /** | ||
827 | * Hash of the file that we will unindex. | ||
828 | */ | ||
829 | GNUNET_HashCode file_id; | ||
830 | |||
831 | }; | ||
832 | |||
833 | |||
834 | |||
698 | #endif | 835 | #endif |
699 | 836 | ||
700 | /* end of fs.h */ | 837 | /* end of fs.h */ |
diff --git a/src/fs/fs_list_indexed.c b/src/fs/fs_list_indexed.c new file mode 100644 index 000000000..1a404a078 --- /dev/null +++ b/src/fs/fs_list_indexed.c | |||
@@ -0,0 +1,252 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2003, 2004, 2006, 2009 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 2, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file fs/fs_list_indexed.c | ||
23 | * @author Christian Grothoff | ||
24 | * @brief provide a list of all indexed files | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_constants.h" | ||
29 | #include "gnunet_fs_service.h" | ||
30 | #include "gnunet_protocols.h" | ||
31 | #include "fs.h" | ||
32 | |||
33 | |||
34 | /** | ||
35 | * Context for "GNUNET_FS_get_indexed_files". | ||
36 | */ | ||
37 | struct GetIndexedContext | ||
38 | { | ||
39 | /** | ||
40 | * Handle to global FS context. | ||
41 | */ | ||
42 | struct GNUNET_FS_Handle *h; | ||
43 | |||
44 | /** | ||
45 | * Connection to the FS service. | ||
46 | */ | ||
47 | struct GNUNET_CLIENT_Connection *client; | ||
48 | |||
49 | /** | ||
50 | * Function to call for each indexed file. | ||
51 | */ | ||
52 | GNUNET_FS_IndexedFileProcessor iterator; | ||
53 | |||
54 | /** | ||
55 | * Closure for iterator. | ||
56 | */ | ||
57 | void *iterator_cls; | ||
58 | |||
59 | /** | ||
60 | * Continuation to trigger at the end. | ||
61 | */ | ||
62 | GNUNET_SCHEDULER_Task cont; | ||
63 | |||
64 | /** | ||
65 | * Closure for cont. | ||
66 | */ | ||
67 | void *cont_cls; | ||
68 | }; | ||
69 | |||
70 | |||
71 | /** | ||
72 | * Function called on each response from the FS | ||
73 | * service with information about indexed files. | ||
74 | * | ||
75 | * @param cls closure (of type "struct GetIndexedContext*") | ||
76 | * @param msg message with indexing information | ||
77 | */ | ||
78 | static void | ||
79 | handle_index_info (void *cls, | ||
80 | const struct GNUNET_MessageHeader *msg) | ||
81 | { | ||
82 | struct GetIndexedContext *gic = cls; | ||
83 | const struct IndexInfoMessage *iim; | ||
84 | uint16_t msize; | ||
85 | const char *filename; | ||
86 | |||
87 | if (NULL == msg) | ||
88 | { | ||
89 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
90 | _("Failed to receive response for `%s' request from `%s' service.\n"), | ||
91 | "GET_INDEXED", | ||
92 | "fs"); | ||
93 | GNUNET_SCHEDULER_add_continuation (gic->h->sched, | ||
94 | GNUNET_NO, | ||
95 | gic->cont, | ||
96 | gic->cont_cls, | ||
97 | GNUNET_SCHEDULER_REASON_TIMEOUT); | ||
98 | GNUNET_CLIENT_disconnect (gic->client); | ||
99 | GNUNET_free (gic); | ||
100 | return; | ||
101 | } | ||
102 | if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_END) | ||
103 | { | ||
104 | /* normal end-of-list */ | ||
105 | GNUNET_SCHEDULER_add_continuation (gic->h->sched, | ||
106 | GNUNET_NO, | ||
107 | gic->cont, | ||
108 | gic->cont_cls, | ||
109 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | ||
110 | GNUNET_CLIENT_disconnect (gic->client); | ||
111 | GNUNET_free (gic); | ||
112 | return; | ||
113 | } | ||
114 | msize = ntohs (msg->size); | ||
115 | iim = (const struct IndexInfoMessage*) msg; | ||
116 | filename = (const char*) &iim[1]; | ||
117 | if ( (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_ENTRY) || | ||
118 | (msize <= sizeof (struct IndexInfoMessage)) || | ||
119 | (filename[msize-sizeof (struct IndexInfoMessage) -1] != '\0') ) | ||
120 | { | ||
121 | /* bogus reply */ | ||
122 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
123 | _("Failed to receive valid response for `%s' request from `%s' service.\n"), | ||
124 | "GET_INDEXED", | ||
125 | "fs"); | ||
126 | GNUNET_SCHEDULER_add_continuation (gic->h->sched, | ||
127 | GNUNET_NO, | ||
128 | gic->cont, | ||
129 | gic->cont_cls, | ||
130 | GNUNET_SCHEDULER_REASON_TIMEOUT); | ||
131 | GNUNET_CLIENT_disconnect (gic->client); | ||
132 | GNUNET_free (gic); | ||
133 | return; | ||
134 | } | ||
135 | if (GNUNET_OK != | ||
136 | gic->iterator (gic->iterator_cls, | ||
137 | filename, | ||
138 | &iim->file_id)) | ||
139 | { | ||
140 | GNUNET_SCHEDULER_add_continuation (gic->h->sched, | ||
141 | GNUNET_NO, | ||
142 | gic->cont, | ||
143 | gic->cont_cls, | ||
144 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | ||
145 | GNUNET_CLIENT_disconnect (gic->client); | ||
146 | GNUNET_free (gic); | ||
147 | return; | ||
148 | } | ||
149 | /* get more */ | ||
150 | GNUNET_CLIENT_receive (gic->client, | ||
151 | &handle_index_info, | ||
152 | gic, | ||
153 | GNUNET_CONSTANTS_SERVICE_TIMEOUT); | ||
154 | } | ||
155 | |||
156 | |||
157 | /** | ||
158 | * Transmit the request to get a list of all | ||
159 | * indexed files to the "FS" service. | ||
160 | * | ||
161 | * @param cls closure (of type "struct GetIndexedContext*") | ||
162 | * @param size number of bytes availabe in buf | ||
163 | * @param buf where to write the message, NULL on error | ||
164 | * @return number of bytes written to buf | ||
165 | */ | ||
166 | static size_t | ||
167 | transmit_get_indexed (void *cls, | ||
168 | size_t size, | ||
169 | void *buf) | ||
170 | { | ||
171 | struct GetIndexedContext *gic = cls; | ||
172 | struct GNUNET_MessageHeader *hdr; | ||
173 | |||
174 | if (NULL == buf) | ||
175 | { | ||
176 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
177 | _("Failed to transmit `%s' request to `%s' service.\n"), | ||
178 | "GET_INDEXED", | ||
179 | "fs"); | ||
180 | GNUNET_SCHEDULER_add_continuation (gic->h->sched, | ||
181 | GNUNET_NO, | ||
182 | gic->cont, | ||
183 | gic->cont_cls, | ||
184 | GNUNET_SCHEDULER_REASON_TIMEOUT); | ||
185 | GNUNET_CLIENT_disconnect (gic->client); | ||
186 | GNUNET_free (gic); | ||
187 | return 0; | ||
188 | } | ||
189 | GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); | ||
190 | hdr = buf; | ||
191 | hdr->size = htons (sizeof (struct GNUNET_MessageHeader)); | ||
192 | hdr->type = htons (GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_GET); | ||
193 | GNUNET_CLIENT_receive (gic->client, | ||
194 | &handle_index_info, | ||
195 | gic, | ||
196 | GNUNET_CONSTANTS_SERVICE_TIMEOUT); | ||
197 | return sizeof (struct GNUNET_MessageHeader); | ||
198 | } | ||
199 | |||
200 | |||
201 | /** | ||
202 | * Iterate over all indexed files. | ||
203 | * | ||
204 | * @param h handle to the file sharing subsystem | ||
205 | * @param iterator function to call on each indexed file | ||
206 | * @param iterator_cls closure for iterator | ||
207 | * @param cont continuation to call when done; | ||
208 | * reason should be "TIMEOUT" (on | ||
209 | * error) or "PREREQ_DONE" (on success) | ||
210 | * @param cont_cls closure for cont | ||
211 | */ | ||
212 | void | ||
213 | GNUNET_FS_get_indexed_files (struct GNUNET_FS_Handle *h, | ||
214 | GNUNET_FS_IndexedFileProcessor iterator, | ||
215 | void *iterator_cls, | ||
216 | GNUNET_SCHEDULER_Task cont, | ||
217 | void *cont_cls) | ||
218 | { | ||
219 | struct GNUNET_CLIENT_Connection *client; | ||
220 | struct GetIndexedContext *gic; | ||
221 | |||
222 | client = GNUNET_CLIENT_connect (h->sched, | ||
223 | "fs", | ||
224 | h->cfg); | ||
225 | if (NULL == client) | ||
226 | { | ||
227 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
228 | _("Failed to not connect to `%s' service.\n"), | ||
229 | "fs"); | ||
230 | GNUNET_SCHEDULER_add_continuation (h->sched, | ||
231 | GNUNET_NO, | ||
232 | cont, | ||
233 | cont_cls, | ||
234 | GNUNET_SCHEDULER_REASON_TIMEOUT); | ||
235 | return; | ||
236 | } | ||
237 | |||
238 | gic = GNUNET_malloc (sizeof (struct GetIndexedContext)); | ||
239 | gic->h = h; | ||
240 | gic->client = client; | ||
241 | gic->iterator = iterator; | ||
242 | gic->iterator_cls = iterator_cls; | ||
243 | gic->cont = cont; | ||
244 | gic->cont_cls = cont_cls; | ||
245 | GNUNET_CLIENT_notify_transmit_ready (client, | ||
246 | sizeof (struct GNUNET_MessageHeader), | ||
247 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, | ||
248 | &transmit_get_indexed, | ||
249 | gic); | ||
250 | } | ||
251 | |||
252 | /* end of fs_list_indexed.c */ | ||
diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c index 13ce4d5aa..0c950f38a 100644 --- a/src/fs/fs_publish.c +++ b/src/fs/fs_publish.c | |||
@@ -53,15 +53,6 @@ | |||
53 | #define MAX_SBLOCK_SIZE 60000 | 53 | #define MAX_SBLOCK_SIZE 60000 |
54 | 54 | ||
55 | /** | 55 | /** |
56 | * Blocksize to use when hashing files | ||
57 | * for indexing (blocksize for IO, not for | ||
58 | * the DBlocks). Larger blocksizes can | ||
59 | * be more efficient but will be more disruptive | ||
60 | * as far as the scheduler is concerned. | ||
61 | */ | ||
62 | #define HASHING_BLOCKSIZE (1024 * 1024) | ||
63 | |||
64 | /** | ||
65 | * Main function that performs the upload. | 56 | * Main function that performs the upload. |
66 | * @param cls "struct GNUNET_FS_PublishContext" identifies the upload | 57 | * @param cls "struct GNUNET_FS_PublishContext" identifies the upload |
67 | * @param tc task context | 58 | * @param tc task context |
diff --git a/src/fs/fs_unindex.c b/src/fs/fs_unindex.c index 8f09c44f6..9f1caac3a 100644 --- a/src/fs/fs_unindex.c +++ b/src/fs/fs_unindex.c | |||
@@ -27,7 +27,6 @@ | |||
27 | * TODO: | 27 | * TODO: |
28 | * - code cleanup (share more with upload.c) | 28 | * - code cleanup (share more with upload.c) |
29 | */ | 29 | */ |
30 | |||
31 | #include "platform.h" | 30 | #include "platform.h" |
32 | #include "gnunet_constants.h" | 31 | #include "gnunet_constants.h" |
33 | #include "gnunet_fs_service.h" | 32 | #include "gnunet_fs_service.h" |
@@ -35,222 +34,144 @@ | |||
35 | #include "fs.h" | 34 | #include "fs.h" |
36 | 35 | ||
37 | 36 | ||
37 | |||
38 | |||
38 | /** | 39 | /** |
39 | * Context for "GNUNET_FS_get_indexed_files". | 40 | * Fill in all of the generic fields for |
41 | * an unindex event. | ||
42 | * | ||
43 | * @param pc structure to fill in | ||
44 | * @param sc overall unindex context | ||
40 | */ | 45 | */ |
41 | struct GetIndexedContext | 46 | static void |
47 | make_unindex_status (struct GNUNET_FS_ProgressInfo *pi, | ||
48 | struct GNUNET_FS_UnindexContext *uc) | ||
42 | { | 49 | { |
43 | /** | 50 | pi->value.unindex.uc = uc; |
44 | * Handle to global FS context. | 51 | pi->value.unindex.cctx = uc->client_info; |
45 | */ | 52 | pi->value.unindex.filename = uc->filename; |
46 | struct GNUNET_FS_Handle *h; | 53 | pi->value.unindex.size = uc->file_size; |
47 | 54 | pi->value.unindex.eta | |
48 | /** | 55 | = GNUNET_TIME_calculate_eta (uc->start_time, |
49 | * Connection to the FS service. | 56 | uc->unindex_offset, |
50 | */ | 57 | uc->file_size); |
51 | struct GNUNET_CLIENT_Connection *client; | 58 | pi->value.publish.duration = GNUNET_TIME_absolute_get_duration (uc->start_time); |
52 | 59 | pi->value.publish.completed = uc->unindex_offset; | |
53 | /** | 60 | } |
54 | * Function to call for each indexed file. | ||
55 | */ | ||
56 | GNUNET_FS_IndexedFileProcessor iterator; | ||
57 | |||
58 | /** | ||
59 | * Closure for iterator. | ||
60 | */ | ||
61 | void *iterator_cls; | ||
62 | 61 | ||
63 | /** | ||
64 | * Continuation to trigger at the end. | ||
65 | */ | ||
66 | GNUNET_SCHEDULER_Task cont; | ||
67 | 62 | ||
68 | /** | 63 | /** |
69 | * Closure for cont. | 64 | * We've encountered an error during |
70 | */ | 65 | * unindexing. Signal the client. |
71 | void *cont_cls; | 66 | * |
72 | }; | 67 | * @param uc context for the failed unindexing operation |
68 | * @param emsg the error message | ||
69 | */ | ||
70 | static void | ||
71 | signal_unindex_error (struct GNUNET_FS_UnindexContext *uc, | ||
72 | const char *emsg) | ||
73 | { | ||
74 | struct GNUNET_FS_ProgressInfo pi; | ||
75 | |||
76 | pi.status = GNUNET_FS_STATUS_UNINDEX_ERROR; | ||
77 | make_unindex_status (&pi, uc); | ||
78 | pi.value.unindex.eta = GNUNET_TIME_UNIT_FOREVER_REL; | ||
79 | pi.value.unindex.specifics.error.message = emsg; | ||
80 | uc->client_info | ||
81 | = uc->h->upcb (uc->h->upcb_cls, | ||
82 | &pi); | ||
83 | } | ||
73 | 84 | ||
74 | 85 | ||
75 | /** | 86 | /** |
76 | * Function called on each response from the FS | 87 | * Function called with the response from the |
77 | * service with information about indexed files. | 88 | * FS service to our unindexing request. |
78 | * | 89 | * |
79 | * @param cls closure (of type "struct GetIndexedContext*") | 90 | * @param cls closure, unindex context |
80 | * @param msg message with indexing information | 91 | * @param msg NULL on timeout, otherwise the response |
81 | */ | 92 | */ |
82 | static void | 93 | static void |
83 | handle_index_info (void *cls, | 94 | process_fs_response (void *cls, |
84 | const struct GNUNET_MessageHeader *msg) | 95 | const struct GNUNET_MessageHeader *msg) |
85 | { | 96 | { |
86 | struct GetIndexedContext *gic = cls; | 97 | struct GNUNET_FS_UnindexContext *uc = cls; |
87 | const struct IndexInfoMessage *iim; | ||
88 | uint16_t msize; | ||
89 | const char *filename; | ||
90 | 98 | ||
91 | if (NULL == msg) | 99 | GNUNET_CLIENT_disconnect (uc->client); |
100 | uc->client = NULL; | ||
101 | if (uc->state != UNINDEX_STATE_FS_NOTIFY) | ||
92 | { | 102 | { |
93 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 103 | GNUNET_FS_unindex_stop (uc); |
94 | _("Failed to receive response for `%s' request from `%s' service.\n"), | ||
95 | "GET_INDEXED", | ||
96 | "fs"); | ||
97 | GNUNET_SCHEDULER_add_continuation (gic->h->sched, | ||
98 | GNUNET_NO, | ||
99 | gic->cont, | ||
100 | gic->cont_cls, | ||
101 | GNUNET_SCHEDULER_REASON_TIMEOUT); | ||
102 | GNUNET_CLIENT_disconnect (gic->client); | ||
103 | GNUNET_free (gic); | ||
104 | return; | 104 | return; |
105 | } | 105 | } |
106 | if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_END) | 106 | if (NULL == msg) |
107 | { | 107 | { |
108 | /* normal end-of-list */ | 108 | uc->state = UNINDEX_STATE_ERROR; |
109 | GNUNET_SCHEDULER_add_continuation (gic->h->sched, | 109 | signal_unindex_error (uc, |
110 | GNUNET_NO, | 110 | _("Timeout waiting for `fs' service.")); |
111 | gic->cont, | ||
112 | gic->cont_cls, | ||
113 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | ||
114 | GNUNET_CLIENT_disconnect (gic->client); | ||
115 | GNUNET_free (gic); | ||
116 | return; | 111 | return; |
117 | } | 112 | } |
118 | msize = ntohs (msg->size); | 113 | if (ntohs(msg->type) != GNUNET_MESSAGE_TYPE_FS_UNINDEX_OK) |
119 | iim = (const struct IndexInfoMessage*) msg; | ||
120 | filename = (const char*) &iim[1]; | ||
121 | if ( (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_ENTRY) || | ||
122 | (msize <= sizeof (struct IndexInfoMessage)) || | ||
123 | (filename[msize-sizeof (struct IndexInfoMessage) -1] != '\0') ) | ||
124 | { | 114 | { |
125 | /* bogus reply */ | 115 | uc->state = UNINDEX_STATE_ERROR; |
126 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 116 | signal_unindex_error (uc, |
127 | _("Failed to receive valid response for `%s' request from `%s' service.\n"), | 117 | _("Invalid response from `fs' service.")); |
128 | "GET_INDEXED", | 118 | return; |
129 | "fs"); | ||
130 | GNUNET_SCHEDULER_add_continuation (gic->h->sched, | ||
131 | GNUNET_NO, | ||
132 | gic->cont, | ||
133 | gic->cont_cls, | ||
134 | GNUNET_SCHEDULER_REASON_TIMEOUT); | ||
135 | GNUNET_CLIENT_disconnect (gic->client); | ||
136 | GNUNET_free (gic); | ||
137 | return; | ||
138 | } | 119 | } |
139 | if (GNUNET_OK != | 120 | uc->state = UNINDEX_STATE_DS_REMOVE; |
140 | gic->iterator (gic->iterator_cls, | 121 | uc->dsh = GNUNET_DATASTORE_connect (uc->h->cfg, |
141 | filename, | 122 | uc->h->sched); |
142 | &iim->file_id)) | 123 | if (NULL == uc->dsh) |
143 | { | 124 | { |
144 | GNUNET_SCHEDULER_add_continuation (gic->h->sched, | 125 | uc->state = UNINDEX_STATE_ERROR; |
145 | GNUNET_NO, | 126 | signal_unindex_error (uc, |
146 | gic->cont, | 127 | _("Failed to connect to `datastore' service.")); |
147 | gic->cont_cls, | ||
148 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | ||
149 | GNUNET_CLIENT_disconnect (gic->client); | ||
150 | GNUNET_free (gic); | ||
151 | return; | 128 | return; |
152 | } | 129 | } |
153 | /* get more */ | 130 | |
154 | GNUNET_CLIENT_receive (gic->client, | 131 | // FIXME: call shared code with publishing... |
155 | &handle_index_info, | ||
156 | gic, | ||
157 | GNUNET_CONSTANTS_SERVICE_TIMEOUT); | ||
158 | } | 132 | } |
159 | 133 | ||
160 | 134 | ||
161 | /** | 135 | /** |
162 | * Transmit the request to get a list of all | 136 | * Function called once the hash of the file |
163 | * indexed files to the "FS" service. | 137 | * that is being unindexed has been computed. |
164 | * | 138 | * |
165 | * @param cls closure (of type "struct GetIndexedContext*") | 139 | * @param cls closure, unindex context |
166 | * @param size number of bytes availabe in buf | 140 | * @param file_id computed hash, NULL on error |
167 | * @param buf where to write the message, NULL on error | ||
168 | * @return number of bytes written to buf | ||
169 | */ | 141 | */ |
170 | static size_t | 142 | static void |
171 | transmit_get_indexed (void *cls, | 143 | process_hash (void *cls, |
172 | size_t size, | 144 | const GNUNET_HashCode *file_id) |
173 | void *buf) | ||
174 | { | 145 | { |
175 | struct GetIndexedContext *gic = cls; | 146 | struct GNUNET_FS_UnindexContext *uc = cls; |
176 | struct GNUNET_MessageHeader *hdr; | 147 | struct UnindexMessage req; |
177 | 148 | ||
178 | if (NULL == buf) | 149 | if (uc->state != UNINDEX_STATE_HASHING) |
179 | { | 150 | { |
180 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 151 | GNUNET_FS_unindex_stop (uc); |
181 | _("Failed to transmit `%s' request to `%s' service.\n"), | 152 | return; |
182 | "GET_INDEXED", | ||
183 | "fs"); | ||
184 | GNUNET_SCHEDULER_add_continuation (gic->h->sched, | ||
185 | GNUNET_NO, | ||
186 | gic->cont, | ||
187 | gic->cont_cls, | ||
188 | GNUNET_SCHEDULER_REASON_TIMEOUT); | ||
189 | GNUNET_CLIENT_disconnect (gic->client); | ||
190 | GNUNET_free (gic); | ||
191 | return 0; | ||
192 | } | 153 | } |
193 | GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); | 154 | if (file_id == NULL) |
194 | hdr = buf; | ||
195 | hdr->size = htons (sizeof (struct GNUNET_MessageHeader)); | ||
196 | hdr->type = htons (GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_GET); | ||
197 | GNUNET_CLIENT_receive (gic->client, | ||
198 | &handle_index_info, | ||
199 | gic, | ||
200 | GNUNET_CONSTANTS_SERVICE_TIMEOUT); | ||
201 | return sizeof (struct GNUNET_MessageHeader); | ||
202 | } | ||
203 | |||
204 | |||
205 | /** | ||
206 | * Iterate over all indexed files. | ||
207 | * | ||
208 | * @param h handle to the file sharing subsystem | ||
209 | * @param iterator function to call on each indexed file | ||
210 | * @param iterator_cls closure for iterator | ||
211 | * @param cont continuation to call when done; | ||
212 | * reason should be "TIMEOUT" (on | ||
213 | * error) or "PREREQ_DONE" (on success) | ||
214 | * @param cont_cls closure for cont | ||
215 | */ | ||
216 | void | ||
217 | GNUNET_FS_get_indexed_files (struct GNUNET_FS_Handle *h, | ||
218 | GNUNET_FS_IndexedFileProcessor iterator, | ||
219 | void *iterator_cls, | ||
220 | GNUNET_SCHEDULER_Task cont, | ||
221 | void *cont_cls) | ||
222 | { | ||
223 | struct GNUNET_CLIENT_Connection *client; | ||
224 | struct GetIndexedContext *gic; | ||
225 | |||
226 | client = GNUNET_CLIENT_connect (h->sched, | ||
227 | "fs", | ||
228 | h->cfg); | ||
229 | if (NULL == client) | ||
230 | { | 155 | { |
231 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 156 | uc->state = UNINDEX_STATE_ERROR; |
232 | _("Failed to not connect to `%s' service.\n"), | 157 | signal_unindex_error (uc, |
233 | "fs"); | 158 | _("Failed to compute hash of file.")); |
234 | GNUNET_SCHEDULER_add_continuation (h->sched, | ||
235 | GNUNET_NO, | ||
236 | cont, | ||
237 | cont_cls, | ||
238 | GNUNET_SCHEDULER_REASON_TIMEOUT); | ||
239 | return; | 159 | return; |
240 | } | 160 | } |
241 | 161 | uc->file_id = *file_id; | |
242 | gic = GNUNET_malloc (sizeof (struct GetIndexedContext)); | 162 | uc->state = UNINDEX_STATE_FS_NOTIFY; |
243 | gic->h = h; | 163 | uc->client = GNUNET_CLIENT_connect (uc->h->sched, |
244 | gic->client = client; | 164 | "fs", |
245 | gic->iterator = iterator; | 165 | uc->h->cfg); |
246 | gic->iterator_cls = iterator_cls; | 166 | req.header.size = htons (sizeof (struct UnindexMessage)); |
247 | gic->cont = cont; | 167 | req.header.type = htons (GNUNET_MESSAGE_TYPE_FS_UNINDEX); |
248 | gic->cont_cls = cont_cls; | 168 | req.reserved = 0; |
249 | GNUNET_CLIENT_notify_transmit_ready (client, | 169 | req.file_id = *file_id; |
250 | sizeof (struct GNUNET_MessageHeader), | 170 | GNUNET_CLIENT_transmit_and_get_response (uc->client, |
251 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, | 171 | &req.header, |
252 | &transmit_get_indexed, | 172 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, |
253 | gic); | 173 | &process_fs_response, |
174 | uc); | ||
254 | } | 175 | } |
255 | 176 | ||
256 | 177 | ||
@@ -265,10 +186,36 @@ struct GNUNET_FS_UnindexContext * | |||
265 | GNUNET_FS_unindex (struct GNUNET_FS_Handle *h, | 186 | GNUNET_FS_unindex (struct GNUNET_FS_Handle *h, |
266 | const char *filename) | 187 | const char *filename) |
267 | { | 188 | { |
268 | // 1: compute file-id (hash over entire file) | 189 | struct GNUNET_FS_UnindexContext *ret; |
269 | // 2: notify FS service about file no longer being indexed | 190 | struct GNUNET_FS_ProgressInfo pi; |
270 | // 3: remove corresponding blocks from datastore! | 191 | uint64_t size; |
271 | return NULL; | 192 | |
193 | if (GNUNET_OK != | ||
194 | GNUNET_DISK_file_size (filename, | ||
195 | &size, | ||
196 | GNUNET_YES)) | ||
197 | return NULL; | ||
198 | ret = GNUNET_malloc (sizeof (struct GNUNET_FS_UnindexContext)); | ||
199 | ret->h = h; | ||
200 | ret->filename = GNUNET_strdup (filename); | ||
201 | ret->start_time = GNUNET_TIME_absolute_get (); | ||
202 | ret->file_size = size; | ||
203 | |||
204 | // FIXME: make persistent! | ||
205 | pi.status = GNUNET_FS_STATUS_UNINDEX_START; | ||
206 | make_unindex_status (&pi, ret); | ||
207 | pi.value.unindex.eta = GNUNET_TIME_UNIT_FOREVER_REL; | ||
208 | ret->client_info | ||
209 | = h->upcb (h->upcb_cls, | ||
210 | &pi); | ||
211 | GNUNET_CRYPTO_hash_file (h->sched, | ||
212 | GNUNET_SCHEDULER_PRIORITY_IDLE, | ||
213 | GNUNET_NO, | ||
214 | filename, | ||
215 | HASHING_BLOCKSIZE, | ||
216 | &process_hash, | ||
217 | ret); | ||
218 | return ret; | ||
272 | } | 219 | } |
273 | 220 | ||
274 | 221 | ||
@@ -279,365 +226,25 @@ GNUNET_FS_unindex (struct GNUNET_FS_Handle *h, | |||
279 | */ | 226 | */ |
280 | void | 227 | void |
281 | GNUNET_FS_unindex_stop (struct GNUNET_FS_UnindexContext *uc) | 228 | GNUNET_FS_unindex_stop (struct GNUNET_FS_UnindexContext *uc) |
282 | { | 229 | { |
283 | } | 230 | struct GNUNET_FS_ProgressInfo pi; |
284 | |||
285 | |||
286 | |||
287 | #if 0 | ||
288 | |||
289 | #define STRICT_CHECKS GNUNET_NO | ||
290 | |||
291 | /** | ||
292 | * Append the given key and query to the iblock[level]. | ||
293 | * If iblock[level] is already full, compute its chk | ||
294 | * and push it to level+1. iblocks is guaranteed to | ||
295 | * be big enough. | ||
296 | * | ||
297 | * This function matches exactly upload.c::pushBlock, | ||
298 | * except in the call to 'GNUNET_FS_delete'. TODO: refactor | ||
299 | * to avoid code duplication (move to block.c, pass | ||
300 | * GNUNET_FS_delete as argument!). | ||
301 | */ | ||
302 | static int | ||
303 | pushBlock (struct GNUNET_ClientServerConnection *sock, | ||
304 | const GNUNET_EC_ContentHashKey * chk, unsigned int level, | ||
305 | GNUNET_DatastoreValue ** iblocks) | ||
306 | { | ||
307 | unsigned int size; | ||
308 | unsigned int present; | ||
309 | GNUNET_DatastoreValue *value; | ||
310 | GNUNET_EC_DBlock *db; | ||
311 | GNUNET_EC_ContentHashKey ichk; | ||
312 | 231 | ||
313 | size = ntohl (iblocks[level]->size) - sizeof (GNUNET_DatastoreValue); | 232 | if ( (uc->state != UNINDEX_STATE_COMPLETE) && |
314 | present = | 233 | (uc->state != UNINDEX_STATE_ERROR) ) |
315 | (size - sizeof (GNUNET_EC_DBlock)) / sizeof (GNUNET_EC_ContentHashKey); | ||
316 | db = (GNUNET_EC_DBlock *) & iblocks[level][1]; | ||
317 | if (present == GNUNET_ECRS_CHK_PER_INODE) | ||
318 | { | 234 | { |
319 | GNUNET_EC_file_block_get_key (db, size, &ichk.key); | 235 | uc->state = UNINDEX_STATE_ABORTED; |
320 | GNUNET_EC_file_block_get_query (db, size, &ichk.query); | 236 | return; |
321 | if (GNUNET_OK != pushBlock (sock, &ichk, level + 1, iblocks)) | ||
322 | { | ||
323 | GNUNET_GE_BREAK (NULL, 0); | ||
324 | return GNUNET_SYSERR; | ||
325 | } | ||
326 | GNUNET_EC_file_block_encode (db, size, &ichk.query, &value); | ||
327 | #if STRICT_CHECKS | ||
328 | if (GNUNET_SYSERR == GNUNET_FS_delete (sock, value)) | ||
329 | { | ||
330 | GNUNET_free (value); | ||
331 | GNUNET_GE_BREAK (NULL, 0); | ||
332 | return GNUNET_SYSERR; | ||
333 | } | ||
334 | #else | ||
335 | GNUNET_FS_delete (sock, value); | ||
336 | #endif | ||
337 | GNUNET_free (value); | ||
338 | size = sizeof (GNUNET_EC_DBlock); | ||
339 | } | ||
340 | /* append GNUNET_EC_ContentHashKey */ | ||
341 | memcpy (&((char *) db)[size], chk, sizeof (GNUNET_EC_ContentHashKey)); | ||
342 | iblocks[level]->size = htonl (size + | ||
343 | sizeof (GNUNET_EC_ContentHashKey) + | ||
344 | sizeof (GNUNET_DatastoreValue)); | ||
345 | return GNUNET_OK; | ||
346 | } | ||
347 | |||
348 | |||
349 | |||
350 | /** | ||
351 | * Undo sym-linking operation: | ||
352 | * a) check if we have a symlink | ||
353 | * b) delete symbolic link | ||
354 | */ | ||
355 | static int | ||
356 | undoSymlinking (struct GNUNET_GE_Context *ectx, | ||
357 | const char *fn, | ||
358 | const GNUNET_HashCode * fileId, | ||
359 | struct GNUNET_ClientServerConnection *sock) | ||
360 | { | ||
361 | GNUNET_EncName enc; | ||
362 | char *serverDir; | ||
363 | char *serverFN; | ||
364 | struct stat buf; | ||
365 | |||
366 | #ifndef S_ISLNK | ||
367 | if (1) | ||
368 | return GNUNET_OK; /* symlinks do not exist? */ | ||
369 | #endif | ||
370 | if (0 != LSTAT (fn, &buf)) | ||
371 | { | ||
372 | GNUNET_GE_LOG_STRERROR_FILE (ectx, | ||
373 | GNUNET_GE_ERROR | GNUNET_GE_BULK | | ||
374 | GNUNET_GE_USER | GNUNET_GE_ADMIN, "stat", | ||
375 | fn); | ||
376 | return GNUNET_SYSERR; | ||
377 | } | ||
378 | #ifdef S_ISLNK | ||
379 | if (!S_ISLNK (buf.st_mode)) | ||
380 | return GNUNET_OK; | ||
381 | #endif | ||
382 | serverDir = | ||
383 | GNUNET_get_daemon_configuration_value (sock, "FS", "INDEX-DIRECTORY"); | ||
384 | if (serverDir == NULL) | ||
385 | return GNUNET_OK; | ||
386 | serverFN = GNUNET_malloc (strlen (serverDir) + 2 + sizeof (GNUNET_EncName)); | ||
387 | strcpy (serverFN, serverDir); | ||
388 | GNUNET_free (serverDir); | ||
389 | if (serverFN[strlen (serverFN) - 1] != DIR_SEPARATOR) | ||
390 | strcat (serverFN, DIR_SEPARATOR_STR); | ||
391 | GNUNET_hash_to_enc (fileId, &enc); | ||
392 | strcat (serverFN, (char *) &enc); | ||
393 | |||
394 | if (0 != UNLINK (serverFN)) | ||
395 | { | ||
396 | GNUNET_GE_LOG_STRERROR_FILE (ectx, | ||
397 | GNUNET_GE_ERROR | GNUNET_GE_BULK | | ||
398 | GNUNET_GE_USER | GNUNET_GE_ADMIN, "unlink", | ||
399 | serverFN); | ||
400 | GNUNET_free (serverFN); | ||
401 | return GNUNET_SYSERR; | ||
402 | } | ||
403 | GNUNET_free (serverFN); | ||
404 | return GNUNET_OK; | ||
405 | } | ||
406 | |||
407 | |||
408 | |||
409 | /** | ||
410 | * Unindex a file. | ||
411 | * | ||
412 | * @return GNUNET_SYSERR if the unindexing failed (i.e. not indexed) | ||
413 | */ | ||
414 | int | ||
415 | GNUNET_ECRS_file_unindex (struct GNUNET_GE_Context *ectx, | ||
416 | struct GNUNET_GC_Configuration *cfg, | ||
417 | const char *filename, | ||
418 | GNUNET_ECRS_UploadProgressCallback upcb, | ||
419 | void *upcbClosure, GNUNET_ECRS_TestTerminate tt, | ||
420 | void *ttClosure) | ||
421 | { | ||
422 | unsigned long long filesize; | ||
423 | unsigned long long pos; | ||
424 | unsigned int treedepth; | ||
425 | int fd; | ||
426 | int i; | ||
427 | unsigned int size; | ||
428 | GNUNET_DatastoreValue **iblocks; | ||
429 | GNUNET_DatastoreValue *dblock; | ||
430 | GNUNET_EC_DBlock *db; | ||
431 | GNUNET_DatastoreValue *value; | ||
432 | struct GNUNET_ClientServerConnection *sock; | ||
433 | GNUNET_HashCode fileId; | ||
434 | GNUNET_EC_ContentHashKey chk; | ||
435 | GNUNET_CronTime eta; | ||
436 | GNUNET_CronTime start; | ||
437 | GNUNET_CronTime now; | ||
438 | int wasIndexed; | ||
439 | |||
440 | start = GNUNET_get_time (); | ||
441 | if (GNUNET_YES != GNUNET_disk_file_test (ectx, filename)) | ||
442 | { | ||
443 | GNUNET_GE_BREAK (ectx, 0); | ||
444 | return GNUNET_SYSERR; | ||
445 | } | ||
446 | if (GNUNET_OK != | ||
447 | GNUNET_disk_file_size (ectx, filename, &filesize, GNUNET_YES)) | ||
448 | return GNUNET_SYSERR; | ||
449 | sock = GNUNET_client_connection_create (ectx, cfg); | ||
450 | if (sock == NULL) | ||
451 | return GNUNET_SYSERR; | ||
452 | eta = 0; | ||
453 | if (upcb != NULL) | ||
454 | upcb (filesize, 0, eta, upcbClosure); | ||
455 | if (GNUNET_SYSERR == GNUNET_hash_file (ectx, filename, &fileId)) | ||
456 | { | ||
457 | GNUNET_client_connection_destroy (sock); | ||
458 | GNUNET_GE_BREAK (ectx, 0); | ||
459 | return GNUNET_SYSERR; | ||
460 | } | ||
461 | now = GNUNET_get_time (); | ||
462 | eta = now + 2 * (now - start); | ||
463 | /* very rough estimate: GNUNET_hash reads once through the file, | ||
464 | we'll do that once more and write it. But of course | ||
465 | the second read may be cached, and we have the encryption, | ||
466 | so a factor of two is really, really just a rough estimate */ | ||
467 | start = now; | ||
468 | /* reset the counter since the formula later does not | ||
469 | take the time for GNUNET_hash_file into account */ | ||
470 | treedepth = GNUNET_ECRS_compute_depth (filesize); | ||
471 | |||
472 | /* Test if file is indexed! */ | ||
473 | wasIndexed = GNUNET_FS_test_indexed (sock, &fileId); | ||
474 | |||
475 | fd = GNUNET_disk_file_open (ectx, filename, O_RDONLY | O_LARGEFILE); | ||
476 | if (fd == -1) | ||
477 | { | ||
478 | GNUNET_client_connection_destroy (sock); | ||
479 | return GNUNET_SYSERR; | ||
480 | } | ||
481 | dblock = | ||
482 | GNUNET_malloc (sizeof (GNUNET_DatastoreValue) + GNUNET_ECRS_DBLOCK_SIZE + | ||
483 | sizeof (GNUNET_EC_DBlock)); | ||
484 | dblock->size = | ||
485 | htonl (sizeof (GNUNET_DatastoreValue) + GNUNET_ECRS_DBLOCK_SIZE + | ||
486 | sizeof (GNUNET_EC_DBlock)); | ||
487 | dblock->anonymity_level = htonl (0); | ||
488 | dblock->priority = htonl (0); | ||
489 | dblock->type = htonl (GNUNET_ECRS_BLOCKTYPE_DATA); | ||
490 | dblock->expiration_time = GNUNET_htonll (0); | ||
491 | db = (GNUNET_EC_DBlock *) & dblock[1]; | ||
492 | db->type = htonl (GNUNET_ECRS_BLOCKTYPE_DATA); | ||
493 | iblocks = | ||
494 | GNUNET_malloc (sizeof (GNUNET_DatastoreValue *) * (treedepth + 1)); | ||
495 | for (i = 0; i <= treedepth; i++) | ||
496 | { | ||
497 | iblocks[i] = | ||
498 | GNUNET_malloc (sizeof (GNUNET_DatastoreValue) + | ||
499 | GNUNET_ECRS_IBLOCK_SIZE + sizeof (GNUNET_EC_DBlock)); | ||
500 | iblocks[i]->size = | ||
501 | htonl (sizeof (GNUNET_DatastoreValue) + sizeof (GNUNET_EC_DBlock)); | ||
502 | iblocks[i]->anonymity_level = htonl (0); | ||
503 | iblocks[i]->priority = htonl (0); | ||
504 | iblocks[i]->type = htonl (GNUNET_ECRS_BLOCKTYPE_DATA); | ||
505 | iblocks[i]->expiration_time = GNUNET_htonll (0); | ||
506 | ((GNUNET_EC_DBlock *) & iblocks[i][1])->type = | ||
507 | htonl (GNUNET_ECRS_BLOCKTYPE_DATA); | ||
508 | } | ||
509 | |||
510 | pos = 0; | ||
511 | while (pos < filesize) | ||
512 | { | ||
513 | if (upcb != NULL) | ||
514 | upcb (filesize, pos, eta, upcbClosure); | ||
515 | if (tt != NULL) | ||
516 | if (GNUNET_OK != tt (ttClosure)) | ||
517 | goto FAILURE; | ||
518 | size = GNUNET_ECRS_DBLOCK_SIZE; | ||
519 | if (size > filesize - pos) | ||
520 | { | ||
521 | size = filesize - pos; | ||
522 | memset (&db[1], 0, GNUNET_ECRS_DBLOCK_SIZE); | ||
523 | } | ||
524 | dblock->size = | ||
525 | htonl (sizeof (GNUNET_DatastoreValue) + size + | ||
526 | sizeof (GNUNET_EC_DBlock)); | ||
527 | if (size != READ (fd, &db[1], size)) | ||
528 | { | ||
529 | GNUNET_GE_LOG_STRERROR_FILE (ectx, | ||
530 | GNUNET_GE_ERROR | GNUNET_GE_USER | | ||
531 | GNUNET_GE_ADMIN | GNUNET_GE_BULK, | ||
532 | "READ", filename); | ||
533 | goto FAILURE; | ||
534 | } | ||
535 | if (tt != NULL) | ||
536 | if (GNUNET_OK != tt (ttClosure)) | ||
537 | goto FAILURE; | ||
538 | GNUNET_EC_file_block_get_key (db, size + sizeof (GNUNET_EC_DBlock), | ||
539 | &chk.key); | ||
540 | GNUNET_EC_file_block_get_query (db, size + sizeof (GNUNET_EC_DBlock), | ||
541 | &chk.query); | ||
542 | if (GNUNET_OK != pushBlock (sock, &chk, 0, /* dblocks are on level 0 */ | ||
543 | iblocks)) | ||
544 | { | ||
545 | GNUNET_GE_BREAK (ectx, 0); | ||
546 | goto FAILURE; | ||
547 | } | ||
548 | if (!wasIndexed) | ||
549 | { | ||
550 | if (GNUNET_OK == | ||
551 | GNUNET_EC_file_block_encode (db, size, &chk.query, &value)) | ||
552 | { | ||
553 | *value = *dblock; /* copy options! */ | ||
554 | #if STRICT_CHECKS | ||
555 | if (GNUNET_OK != GNUNET_FS_delete (sock, value)) | ||
556 | { | ||
557 | GNUNET_free (value); | ||
558 | GNUNET_GE_BREAK (ectx, 0); | ||
559 | goto FAILURE; | ||
560 | } | ||
561 | #else | ||
562 | GNUNET_FS_delete (sock, value); | ||
563 | #endif | ||
564 | GNUNET_free (value); | ||
565 | } | ||
566 | else | ||
567 | { | ||
568 | goto FAILURE; | ||
569 | } | ||
570 | } | ||
571 | pos += size; | ||
572 | now = GNUNET_get_time (); | ||
573 | eta = (GNUNET_CronTime) (start + | ||
574 | (((double) (now - start) / (double) pos)) | ||
575 | * (double) filesize); | ||
576 | } | ||
577 | if (tt != NULL) | ||
578 | if (GNUNET_OK != tt (ttClosure)) | ||
579 | goto FAILURE; | ||
580 | for (i = 0; i < treedepth; i++) | ||
581 | { | ||
582 | size = ntohl (iblocks[i]->size) - sizeof (GNUNET_DatastoreValue); | ||
583 | db = (GNUNET_EC_DBlock *) & iblocks[i][1]; | ||
584 | GNUNET_EC_file_block_get_key (db, size, &chk.key); | ||
585 | GNUNET_EC_file_block_get_query (db, size, &chk.query); | ||
586 | if (GNUNET_OK != pushBlock (sock, &chk, i + 1, iblocks)) | ||
587 | { | ||
588 | GNUNET_GE_BREAK (ectx, 0); | ||
589 | goto FAILURE; | ||
590 | } | ||
591 | GNUNET_EC_file_block_encode (db, size, &chk.query, &value); | ||
592 | #if STRICT_CHECKS | ||
593 | if (GNUNET_OK != GNUNET_FS_delete (sock, value)) | ||
594 | { | ||
595 | GNUNET_free (value); | ||
596 | GNUNET_GE_BREAK (ectx, 0); | ||
597 | goto FAILURE; | ||
598 | } | ||
599 | #else | ||
600 | GNUNET_FS_delete (sock, value); | ||
601 | #endif | ||
602 | GNUNET_free (value); | ||
603 | GNUNET_free (iblocks[i]); | ||
604 | iblocks[i] = NULL; | ||
605 | } | ||
606 | |||
607 | if (wasIndexed) | ||
608 | { | ||
609 | if (GNUNET_OK == undoSymlinking (ectx, filename, &fileId, sock)) | ||
610 | { | ||
611 | if (GNUNET_OK != | ||
612 | GNUNET_FS_unindex (sock, GNUNET_ECRS_DBLOCK_SIZE, &fileId)) | ||
613 | { | ||
614 | GNUNET_GE_BREAK (ectx, 0); | ||
615 | goto FAILURE; | ||
616 | } | ||
617 | } | ||
618 | else | ||
619 | { | ||
620 | GNUNET_GE_BREAK (ectx, 0); | ||
621 | goto FAILURE; | ||
622 | } | ||
623 | } | 237 | } |
624 | GNUNET_free (iblocks[treedepth]); | 238 | // FIXME: make unpersistent! |
625 | /* free resources */ | 239 | pi.status = GNUNET_FS_STATUS_UNINDEX_STOPPED; |
626 | GNUNET_free (iblocks); | 240 | make_unindex_status (&pi, uc); |
627 | GNUNET_free (dblock); | 241 | pi.value.unindex.eta = GNUNET_TIME_UNIT_ZERO; |
628 | CLOSE (fd); | 242 | uc->client_info |
629 | GNUNET_client_connection_destroy (sock); | 243 | = uc->h->upcb (uc->h->upcb_cls, |
630 | return GNUNET_OK; | 244 | &pi); |
631 | FAILURE: | 245 | GNUNET_break (NULL == uc->client_info); |
632 | for (i = 0; i <= treedepth; i++) | 246 | GNUNET_free (uc->filename); |
633 | GNUNET_free_non_null (iblocks[i]); | 247 | GNUNET_free (uc); |
634 | GNUNET_free (iblocks); | ||
635 | GNUNET_free (dblock); | ||
636 | CLOSE (fd); | ||
637 | GNUNET_client_connection_destroy (sock); | ||
638 | return GNUNET_SYSERR; | ||
639 | } | 248 | } |
640 | 249 | ||
641 | #endif | ||
642 | |||
643 | /* end of fs_unindex.c */ | 250 | /* end of fs_unindex.c */ |
diff --git a/src/include/gnunet_disk_lib.h b/src/include/gnunet_disk_lib.h index a3ac30d7e..692507641 100644 --- a/src/include/gnunet_disk_lib.h +++ b/src/include/gnunet_disk_lib.h | |||
@@ -125,21 +125,27 @@ int GNUNET_DISK_file_test (const char *fil); | |||
125 | * @return the new position on success, GNUNET_SYSERR otherwise | 125 | * @return the new position on success, GNUNET_SYSERR otherwise |
126 | */ | 126 | */ |
127 | off_t | 127 | off_t |
128 | GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle *h, off_t offset, | 128 | GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle *h, |
129 | enum GNUNET_DISK_Seek whence); | 129 | off_t offset, |
130 | enum GNUNET_DISK_Seek whence); | ||
130 | 131 | ||
131 | 132 | ||
132 | /** | 133 | /** |
133 | * Get the size of the file (or directory) | 134 | * Get the size of the file (or directory) |
134 | * of the given file (in bytes). | 135 | * of the given file (in bytes). |
135 | * | 136 | * |
137 | * @param filename name of the file or directory | ||
138 | * @param size set to the size of the file (or, | ||
139 | * in the case of directories, the sum | ||
140 | * of all sizes of files in the directory) | ||
136 | * @param includeSymLinks should symbolic links be | 141 | * @param includeSymLinks should symbolic links be |
137 | * included? | 142 | * included? |
138 | * | 143 | * |
139 | * @return GNUNET_OK on success, GNUNET_SYSERR on error | 144 | * @return GNUNET_OK on success, GNUNET_SYSERR on error |
140 | */ | 145 | */ |
141 | int GNUNET_DISK_file_size (const char *filename, | 146 | int GNUNET_DISK_file_size (const char *filename, |
142 | unsigned long long *size, int includeSymLinks); | 147 | uint64_t *size, |
148 | int includeSymLinks); | ||
143 | 149 | ||
144 | 150 | ||
145 | /** | 151 | /** |
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 5a11f29e9..ad8e28bd1 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h | |||
@@ -399,6 +399,16 @@ extern "C" | |||
399 | */ | 399 | */ |
400 | #define GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_END 133 | 400 | #define GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_END 133 |
401 | 401 | ||
402 | /** | ||
403 | * Request from client to unindex a file. | ||
404 | */ | ||
405 | #define GNUNET_MESSAGE_TYPE_FS_UNINDEX 134 | ||
406 | |||
407 | /** | ||
408 | * Reply to client indicating unindex receipt. | ||
409 | */ | ||
410 | #define GNUNET_MESSAGE_TYPE_FS_UNINDEX_OK 135 | ||
411 | |||
402 | 412 | ||
403 | /* | 413 | /* |
404 | TODO: | 414 | TODO: |
diff --git a/src/util/disk.c b/src/util/disk.c index 412f8fb16..899299e07 100644 --- a/src/util/disk.c +++ b/src/util/disk.c | |||
@@ -71,7 +71,7 @@ | |||
71 | 71 | ||
72 | typedef struct | 72 | typedef struct |
73 | { | 73 | { |
74 | unsigned long long total; | 74 | uint64_t total; |
75 | int include_sym_links; | 75 | int include_sym_links; |
76 | } GetFileSizeData; | 76 | } GetFileSizeData; |
77 | 77 | ||
@@ -176,7 +176,8 @@ GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle *h, off_t offset, | |||
176 | */ | 176 | */ |
177 | int | 177 | int |
178 | GNUNET_DISK_file_size (const char *filename, | 178 | GNUNET_DISK_file_size (const char *filename, |
179 | unsigned long long *size, int includeSymLinks) | 179 | uint64_t *size, |
180 | int includeSymLinks) | ||
180 | { | 181 | { |
181 | GetFileSizeData gfsd; | 182 | GetFileSizeData gfsd; |
182 | int ret; | 183 | int ret; |