diff options
Diffstat (limited to 'src/fs/fs_file_information.c')
-rw-r--r-- | src/fs/fs_file_information.c | 475 |
1 files changed, 0 insertions, 475 deletions
diff --git a/src/fs/fs_file_information.c b/src/fs/fs_file_information.c deleted file mode 100644 index c5faa14d4..000000000 --- a/src/fs/fs_file_information.c +++ /dev/null | |||
@@ -1,475 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009, 2011 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your 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 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file fs/fs_file_information.c | ||
23 | * @brief Manage information for publishing directory hierarchies | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #if HAVE_EXTRACTOR_H | ||
28 | #include <extractor.h> | ||
29 | #endif | ||
30 | #include "gnunet_fs_service.h" | ||
31 | #include "fs_api.h" | ||
32 | #include "fs_tree.h" | ||
33 | |||
34 | |||
35 | /** | ||
36 | * Obtain the name under which this file information | ||
37 | * structure is stored on disk. Only works for top-level | ||
38 | * file information structures. | ||
39 | * | ||
40 | * @param s structure to get the filename for | ||
41 | * @return NULL on error, otherwise filename that | ||
42 | * can be used to read this fi-struct from disk. | ||
43 | */ | ||
44 | const char * | ||
45 | GNUNET_FS_file_information_get_id (struct GNUNET_FS_FileInformation *s) | ||
46 | { | ||
47 | if (NULL != s->dir) | ||
48 | return NULL; | ||
49 | return s->serialization; | ||
50 | } | ||
51 | |||
52 | |||
53 | /** | ||
54 | * Obtain the filename from the file information structure. | ||
55 | * | ||
56 | * @param s structure to get the filename for | ||
57 | * @return "filename" field of the structure (can be NULL) | ||
58 | */ | ||
59 | const char * | ||
60 | GNUNET_FS_file_information_get_filename (const struct GNUNET_FS_FileInformation *s) | ||
61 | { | ||
62 | return s->filename; | ||
63 | } | ||
64 | |||
65 | |||
66 | /** | ||
67 | * Set the filename in the file information structure. | ||
68 | * If filename was already set, frees it before setting the new one. | ||
69 | * Makes a copy of the argument. | ||
70 | * | ||
71 | * @param s structure to get the filename for | ||
72 | * @param filename filename to set | ||
73 | */ | ||
74 | void | ||
75 | GNUNET_FS_file_information_set_filename (struct GNUNET_FS_FileInformation *s, | ||
76 | const char *filename) | ||
77 | { | ||
78 | GNUNET_free (s->filename); | ||
79 | if (filename) | ||
80 | s->filename = GNUNET_strdup (filename); | ||
81 | else | ||
82 | s->filename = NULL; | ||
83 | } | ||
84 | |||
85 | |||
86 | /** | ||
87 | * Create an entry for a file in a publish-structure. | ||
88 | * | ||
89 | * @param h handle to the file sharing subsystem | ||
90 | * @param client_info initial value for the client-info value for this entry | ||
91 | * @param filename name of the file or directory to publish | ||
92 | * @param keywords under which keywords should this file be available | ||
93 | * directly; can be NULL | ||
94 | * @param meta metadata for the file | ||
95 | * @param do_index #GNUNET_YES for index, #GNUNET_NO for insertion, | ||
96 | * #GNUNET_SYSERR for simulation | ||
97 | * @param bo block options | ||
98 | * @return publish structure entry for the file | ||
99 | */ | ||
100 | struct GNUNET_FS_FileInformation * | ||
101 | GNUNET_FS_file_information_create_from_file ( | ||
102 | struct GNUNET_FS_Handle *h, | ||
103 | void *client_info, | ||
104 | const char *filename, | ||
105 | const struct GNUNET_FS_Uri *keywords, | ||
106 | const struct GNUNET_CONTAINER_MetaData *meta, | ||
107 | int do_index, | ||
108 | const struct GNUNET_FS_BlockOptions *bo) | ||
109 | { | ||
110 | struct FileInfo *fi; | ||
111 | uint64_t fsize; | ||
112 | struct GNUNET_FS_FileInformation *ret; | ||
113 | const char *fn; | ||
114 | const char *ss; | ||
115 | |||
116 | /* FIXME: should include_symbolic_links be GNUNET_NO or GNUNET_YES here? */ | ||
117 | if (GNUNET_OK != | ||
118 | GNUNET_DISK_file_size (filename, &fsize, GNUNET_NO, GNUNET_YES)) | ||
119 | { | ||
120 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "stat", filename); | ||
121 | return NULL; | ||
122 | } | ||
123 | fi = GNUNET_FS_make_file_reader_context_ (filename); | ||
124 | if (NULL == fi) | ||
125 | { | ||
126 | GNUNET_break (0); | ||
127 | return NULL; | ||
128 | } | ||
129 | ret = | ||
130 | GNUNET_FS_file_information_create_from_reader (h, | ||
131 | client_info, | ||
132 | fsize, | ||
133 | &GNUNET_FS_data_reader_file_, | ||
134 | fi, | ||
135 | keywords, | ||
136 | meta, | ||
137 | do_index, | ||
138 | bo); | ||
139 | if (ret == NULL) | ||
140 | return NULL; | ||
141 | ret->h = h; | ||
142 | ret->filename = GNUNET_strdup (filename); | ||
143 | fn = filename; | ||
144 | while (NULL != (ss = strstr (fn, DIR_SEPARATOR_STR))) | ||
145 | fn = ss + 1; | ||
146 | /* FIXME: If we assume that on other platforms CRT is UTF-8-aware, then | ||
147 | * this should be changed to EXTRACTOR_METAFORMAT_UTF8 | ||
148 | */ | ||
149 | GNUNET_CONTAINER_meta_data_insert (ret->meta, | ||
150 | "<gnunet>", | ||
151 | EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME, | ||
152 | EXTRACTOR_METAFORMAT_C_STRING, | ||
153 | "text/plain", | ||
154 | fn, | ||
155 | strlen (fn) + 1); | ||
156 | return ret; | ||
157 | } | ||
158 | |||
159 | |||
160 | /** | ||
161 | * Create an entry for a file in a publish-structure. | ||
162 | * | ||
163 | * @param h handle to the file sharing subsystem | ||
164 | * @param client_info initial value for the client-info value for this entry | ||
165 | * @param length length of the file | ||
166 | * @param data data for the file (should not be used afterwards by | ||
167 | * the caller; callee will "free") | ||
168 | * @param keywords under which keywords should this file be available | ||
169 | * directly; can be NULL | ||
170 | * @param meta metadata for the file | ||
171 | * @param do_index GNUNET_YES for index, GNUNET_NO for insertion, | ||
172 | * GNUNET_SYSERR for simulation | ||
173 | * @param bo block options | ||
174 | * @return publish structure entry for the file | ||
175 | */ | ||
176 | struct GNUNET_FS_FileInformation * | ||
177 | GNUNET_FS_file_information_create_from_data ( | ||
178 | struct GNUNET_FS_Handle *h, | ||
179 | void *client_info, | ||
180 | uint64_t length, | ||
181 | void *data, | ||
182 | const struct GNUNET_FS_Uri *keywords, | ||
183 | const struct GNUNET_CONTAINER_MetaData *meta, | ||
184 | int do_index, | ||
185 | const struct GNUNET_FS_BlockOptions *bo) | ||
186 | { | ||
187 | if (GNUNET_YES == do_index) | ||
188 | { | ||
189 | GNUNET_break (0); | ||
190 | return NULL; | ||
191 | } | ||
192 | return GNUNET_FS_file_information_create_from_reader (h, | ||
193 | client_info, | ||
194 | length, | ||
195 | & | ||
196 | GNUNET_FS_data_reader_copy_, | ||
197 | data, | ||
198 | keywords, | ||
199 | meta, | ||
200 | do_index, | ||
201 | bo); | ||
202 | } | ||
203 | |||
204 | |||
205 | /** | ||
206 | * Create an entry for a file in a publish-structure. | ||
207 | * | ||
208 | * @param h handle to the file sharing subsystem | ||
209 | * @param client_info initial value for the client-info value for this entry | ||
210 | * @param length length of the file | ||
211 | * @param reader function that can be used to obtain the data for the file | ||
212 | * @param reader_cls closure for "reader" | ||
213 | * @param keywords under which keywords should this file be available | ||
214 | * directly; can be NULL | ||
215 | * @param meta metadata for the file | ||
216 | * @param do_index #GNUNET_YES for index, #GNUNET_NO for insertion, | ||
217 | * #GNUNET_SYSERR for simulation | ||
218 | * @param bo block options | ||
219 | * @return publish structure entry for the file | ||
220 | */ | ||
221 | struct GNUNET_FS_FileInformation * | ||
222 | GNUNET_FS_file_information_create_from_reader ( | ||
223 | struct GNUNET_FS_Handle *h, | ||
224 | void *client_info, | ||
225 | uint64_t length, | ||
226 | GNUNET_FS_DataReader reader, | ||
227 | void *reader_cls, | ||
228 | const struct GNUNET_FS_Uri *keywords, | ||
229 | const struct GNUNET_CONTAINER_MetaData *meta, | ||
230 | int do_index, | ||
231 | const struct GNUNET_FS_BlockOptions *bo) | ||
232 | { | ||
233 | struct GNUNET_FS_FileInformation *ret; | ||
234 | |||
235 | if ((GNUNET_YES == do_index) && (reader != &GNUNET_FS_data_reader_file_)) | ||
236 | { | ||
237 | GNUNET_break (0); | ||
238 | return NULL; | ||
239 | } | ||
240 | ret = GNUNET_new (struct GNUNET_FS_FileInformation); | ||
241 | ret->h = h; | ||
242 | ret->client_info = client_info; | ||
243 | ret->meta = GNUNET_CONTAINER_meta_data_duplicate (meta); | ||
244 | if (ret->meta == NULL) | ||
245 | ret->meta = GNUNET_CONTAINER_meta_data_create (); | ||
246 | ret->keywords = (keywords == NULL) ? NULL : GNUNET_FS_uri_dup (keywords); | ||
247 | ret->data.file.reader = reader; | ||
248 | ret->data.file.reader_cls = reader_cls; | ||
249 | ret->data.file.do_index = do_index; | ||
250 | ret->data.file.file_size = length; | ||
251 | ret->bo = *bo; | ||
252 | return ret; | ||
253 | } | ||
254 | |||
255 | |||
256 | /** | ||
257 | * Test if a given entry represents a directory. | ||
258 | * | ||
259 | * @param ent check if this FI represents a directory | ||
260 | * @return #GNUNET_YES if so, #GNUNET_NO if not | ||
261 | */ | ||
262 | int | ||
263 | GNUNET_FS_file_information_is_directory ( | ||
264 | const struct GNUNET_FS_FileInformation *ent) | ||
265 | { | ||
266 | return ent->is_directory; | ||
267 | } | ||
268 | |||
269 | |||
270 | /** | ||
271 | * Create an entry for an empty directory in a publish-structure. | ||
272 | * | ||
273 | * @param h handle to the file sharing subsystem | ||
274 | * @param client_info initial value for the client-info value for this entry | ||
275 | * @param meta metadata for the directory | ||
276 | * @param keywords under which keywords should this directory be available | ||
277 | * directly; can be NULL | ||
278 | * @param bo block options | ||
279 | * @param filename name of the directory; can be NULL | ||
280 | * @return publish structure entry for the directory , NULL on error | ||
281 | */ | ||
282 | struct GNUNET_FS_FileInformation * | ||
283 | GNUNET_FS_file_information_create_empty_directory ( | ||
284 | struct GNUNET_FS_Handle *h, | ||
285 | void *client_info, | ||
286 | const struct GNUNET_FS_Uri *keywords, | ||
287 | const struct GNUNET_CONTAINER_MetaData *meta, | ||
288 | const struct GNUNET_FS_BlockOptions *bo, | ||
289 | const char *filename) | ||
290 | { | ||
291 | struct GNUNET_FS_FileInformation *ret; | ||
292 | |||
293 | ret = GNUNET_new (struct GNUNET_FS_FileInformation); | ||
294 | ret->h = h; | ||
295 | ret->client_info = client_info; | ||
296 | ret->meta = GNUNET_CONTAINER_meta_data_duplicate (meta); | ||
297 | ret->keywords = GNUNET_FS_uri_dup (keywords); | ||
298 | ret->bo = *bo; | ||
299 | ret->is_directory = GNUNET_YES; | ||
300 | if (filename != NULL) | ||
301 | ret->filename = GNUNET_strdup (filename); | ||
302 | return ret; | ||
303 | } | ||
304 | |||
305 | |||
306 | /** | ||
307 | * Add an entry to a directory in a publish-structure. Clients | ||
308 | * should never modify publish structures that were passed to | ||
309 | * #GNUNET_FS_publish_start already. | ||
310 | * | ||
311 | * @param dir the directory | ||
312 | * @param ent the entry to add; the entry must not have been | ||
313 | * added to any other directory at this point and | ||
314 | * must not include @a dir in its structure | ||
315 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
316 | */ | ||
317 | int | ||
318 | GNUNET_FS_file_information_add (struct GNUNET_FS_FileInformation *dir, | ||
319 | struct GNUNET_FS_FileInformation *ent) | ||
320 | { | ||
321 | if ((ent->dir != NULL) || (ent->next != NULL) || | ||
322 | (dir->is_directory != GNUNET_YES)) | ||
323 | { | ||
324 | GNUNET_break (0); | ||
325 | return GNUNET_SYSERR; | ||
326 | } | ||
327 | ent->dir = dir; | ||
328 | ent->next = dir->data.dir.entries; | ||
329 | dir->data.dir.entries = ent; | ||
330 | dir->data.dir.dir_size = 0; | ||
331 | return GNUNET_OK; | ||
332 | } | ||
333 | |||
334 | |||
335 | /** | ||
336 | * Inspect a file or directory in a publish-structure. Clients | ||
337 | * should never modify publish structures that were passed to | ||
338 | * #GNUNET_FS_publish_start already. When called on a directory, | ||
339 | * this function will FIRST call @a proc with information about | ||
340 | * the directory itself and then for each of the files in the | ||
341 | * directory (but not for files in subdirectories). When called | ||
342 | * on a file, @a proc will be called exactly once (with information | ||
343 | * about the specific file). | ||
344 | * | ||
345 | * @param dir the directory | ||
346 | * @param proc function to call on each entry | ||
347 | * @param proc_cls closure for @a proc | ||
348 | */ | ||
349 | void | ||
350 | GNUNET_FS_file_information_inspect (struct GNUNET_FS_FileInformation *dir, | ||
351 | GNUNET_FS_FileInformationProcessor proc, | ||
352 | void *proc_cls) | ||
353 | { | ||
354 | struct GNUNET_FS_FileInformation *pos; | ||
355 | int no; | ||
356 | |||
357 | no = GNUNET_NO; | ||
358 | if (GNUNET_OK != | ||
359 | proc (proc_cls, | ||
360 | dir, | ||
361 | (dir->is_directory == GNUNET_YES) ? dir->data.dir.dir_size | ||
362 | : dir->data.file.file_size, | ||
363 | dir->meta, | ||
364 | &dir->keywords, | ||
365 | &dir->bo, | ||
366 | (dir->is_directory == GNUNET_YES) ? &no : &dir->data.file.do_index, | ||
367 | &dir->client_info)) | ||
368 | return; | ||
369 | if (dir->is_directory != GNUNET_YES) | ||
370 | return; | ||
371 | pos = dir->data.dir.entries; | ||
372 | while (pos != NULL) | ||
373 | { | ||
374 | no = GNUNET_NO; | ||
375 | if (GNUNET_OK != | ||
376 | proc (proc_cls, | ||
377 | pos, | ||
378 | (pos->is_directory == GNUNET_YES) ? pos->data.dir.dir_size | ||
379 | : pos->data.file.file_size, | ||
380 | pos->meta, | ||
381 | &pos->keywords, | ||
382 | &pos->bo, | ||
383 | (pos->is_directory == GNUNET_YES) ? &no | ||
384 | : &pos->data.file.do_index, | ||
385 | &pos->client_info)) | ||
386 | break; | ||
387 | pos = pos->next; | ||
388 | } | ||
389 | } | ||
390 | |||
391 | |||
392 | /** | ||
393 | * Destroy publish-structure. Clients should never destroy publish | ||
394 | * structures that were passed to #GNUNET_FS_publish_start already. | ||
395 | * | ||
396 | * @param fi structure to destroy | ||
397 | * @param cleaner function to call on each entry in the structure | ||
398 | * (useful to clean up client_info); can be NULL; return | ||
399 | * values are ignored | ||
400 | * @param cleaner_cls closure for @a cleaner | ||
401 | */ | ||
402 | void | ||
403 | GNUNET_FS_file_information_destroy (struct GNUNET_FS_FileInformation *fi, | ||
404 | GNUNET_FS_FileInformationProcessor cleaner, | ||
405 | void *cleaner_cls) | ||
406 | { | ||
407 | struct GNUNET_FS_FileInformation *pos; | ||
408 | int no; | ||
409 | |||
410 | no = GNUNET_NO; | ||
411 | if (GNUNET_YES == fi->is_directory) | ||
412 | { | ||
413 | /* clean up directory */ | ||
414 | while (NULL != (pos = fi->data.dir.entries)) | ||
415 | { | ||
416 | fi->data.dir.entries = pos->next; | ||
417 | GNUNET_FS_file_information_destroy (pos, cleaner, cleaner_cls); | ||
418 | } | ||
419 | /* clean up client-info */ | ||
420 | if (NULL != cleaner) | ||
421 | cleaner (cleaner_cls, | ||
422 | fi, | ||
423 | fi->data.dir.dir_size, | ||
424 | fi->meta, | ||
425 | &fi->keywords, | ||
426 | &fi->bo, | ||
427 | &no, | ||
428 | &fi->client_info); | ||
429 | GNUNET_free (fi->data.dir.dir_data); | ||
430 | } | ||
431 | else | ||
432 | { | ||
433 | /* call clean-up function of the reader */ | ||
434 | if (NULL != fi->data.file.reader) | ||
435 | { | ||
436 | (void) fi->data.file.reader (fi->data.file.reader_cls, 0, 0, NULL, NULL); | ||
437 | fi->data.file.reader = NULL; | ||
438 | } | ||
439 | /* clean up client-info */ | ||
440 | if (NULL != cleaner) | ||
441 | cleaner (cleaner_cls, | ||
442 | fi, | ||
443 | fi->data.file.file_size, | ||
444 | fi->meta, | ||
445 | &fi->keywords, | ||
446 | &fi->bo, | ||
447 | &fi->data.file.do_index, | ||
448 | &fi->client_info); | ||
449 | } | ||
450 | GNUNET_free (fi->filename); | ||
451 | GNUNET_free (fi->emsg); | ||
452 | if (NULL != fi->sks_uri) | ||
453 | GNUNET_FS_uri_destroy (fi->sks_uri); | ||
454 | if (NULL != fi->chk_uri) | ||
455 | GNUNET_FS_uri_destroy (fi->chk_uri); | ||
456 | /* clean up serialization */ | ||
457 | if ((NULL != fi->serialization) && (0 != unlink (fi->serialization))) | ||
458 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, | ||
459 | "unlink", | ||
460 | fi->serialization); | ||
461 | if (NULL != fi->keywords) | ||
462 | GNUNET_FS_uri_destroy (fi->keywords); | ||
463 | if (NULL != fi->meta) | ||
464 | GNUNET_CONTAINER_meta_data_destroy (fi->meta); | ||
465 | GNUNET_free (fi->serialization); | ||
466 | if (NULL != fi->te) | ||
467 | { | ||
468 | GNUNET_FS_tree_encoder_finish (fi->te, NULL); | ||
469 | fi->te = NULL; | ||
470 | } | ||
471 | GNUNET_free (fi); | ||
472 | } | ||
473 | |||
474 | |||
475 | /* end of fs_file_information.c */ | ||