GNUnet  0.10.x
fs_file_information.c
Go to the documentation of this file.
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 
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 
44 const char *
46 {
47  if (NULL != s->dir)
48  return NULL;
49  return s->serialization;
50 }
51 
58 const char *
60 {
61  return s->filename;
62 }
63 
64 
73 void
75  const char *filename)
76 {
78  if (filename)
79  s->filename = GNUNET_strdup (filename);
80  else
81  s->filename = NULL;
82 }
83 
84 
101  void *client_info,
102  const char *filename,
103  const struct GNUNET_FS_Uri
104  *keywords,
105  const struct
107  int do_index,
108  const struct GNUNET_FS_BlockOptions
109  *bo)
110 {
111  struct FileInfo *fi;
112  uint64_t fsize;
114  const char *fn;
115  const char *ss;
116 
117 #if WINDOWS
118  char fn_conv[MAX_PATH];
119 #endif
120 
121  /* FIXME: should include_symbolic_links be GNUNET_NO or GNUNET_YES here? */
122  if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fsize, GNUNET_NO, GNUNET_YES))
123  {
125  return NULL;
126  }
127  fi = GNUNET_FS_make_file_reader_context_ (filename);
128  if (NULL == fi)
129  {
130  GNUNET_break (0);
131  return NULL;
132  }
133  ret =
135  fsize,
137  fi, keywords, meta,
138  do_index, bo);
139  if (ret == NULL)
140  return NULL;
141  ret->h = h;
142  ret->filename = GNUNET_strdup (filename);
143 #if !WINDOWS
144  fn = filename;
145 #else
146  plibc_conv_to_win_path (filename, fn_conv);
147  fn = fn_conv;
148 #endif
149  while (NULL != (ss = strstr (fn, DIR_SEPARATOR_STR)))
150  fn = ss + 1;
151 /* FIXME: If we assume that on other platforms CRT is UTF-8-aware, then
152  * this should be changed to EXTRACTOR_METAFORMAT_UTF8
153  */
154 #if !WINDOWS
155  GNUNET_CONTAINER_meta_data_insert (ret->meta, "<gnunet>",
158  "text/plain", fn, strlen (fn) + 1);
159 #else
160  GNUNET_CONTAINER_meta_data_insert (ret->meta, "<gnunet>",
163  "text/plain", fn, strlen (fn) + 1);
164 #endif
165  return ret;
166 }
167 
168 
187  void *client_info, uint64_t length,
188  void *data,
189  const struct GNUNET_FS_Uri
190  *keywords,
191  const struct
193  int do_index,
194  const struct GNUNET_FS_BlockOptions
195  *bo)
196 {
197  if (GNUNET_YES == do_index)
198  {
199  GNUNET_break (0);
200  return NULL;
201  }
202  return GNUNET_FS_file_information_create_from_reader (h, client_info, length,
204  data, keywords, meta,
205  do_index, bo);
206 }
207 
208 
227  void *client_info,
228  uint64_t length,
230  void *reader_cls,
231  const struct GNUNET_FS_Uri
232  *keywords,
233  const struct
235  int do_index,
236  const struct
238 {
240 
241  if ((GNUNET_YES == do_index) && (reader != &GNUNET_FS_data_reader_file_))
242  {
243  GNUNET_break (0);
244  return NULL;
245  }
246  ret = GNUNET_new (struct GNUNET_FS_FileInformation);
247  ret->h = h;
248  ret->client_info = client_info;
250  if (ret->meta == NULL)
252  ret->keywords = (keywords == NULL) ? NULL : GNUNET_FS_uri_dup (keywords);
253  ret->data.file.reader = reader;
254  ret->data.file.reader_cls = reader_cls;
255  ret->data.file.do_index = do_index;
256  ret->data.file.file_size = length;
257  ret->bo = *bo;
258  return ret;
259 }
260 
261 
268 int
270  *ent)
271 {
272  return ent->is_directory;
273 }
274 
275 
290  void *client_info,
291  const struct GNUNET_FS_Uri
292  *keywords,
293  const struct
295  *meta,
296  const struct
298  const char *filename)
299 {
301 
302  ret = GNUNET_new (struct GNUNET_FS_FileInformation);
303  ret->h = h;
304  ret->client_info = client_info;
306  ret->keywords = GNUNET_FS_uri_dup (keywords);
307  ret->bo = *bo;
308  ret->is_directory = GNUNET_YES;
309  if (filename != NULL)
310  ret->filename = GNUNET_strdup (filename);
311  return ret;
312 }
313 
314 
326 int
328  struct GNUNET_FS_FileInformation *ent)
329 {
330  if ((ent->dir != NULL) || (ent->next != NULL) || (dir->is_directory != GNUNET_YES))
331  {
332  GNUNET_break (0);
333  return GNUNET_SYSERR;
334  }
335  ent->dir = dir;
336  ent->next = dir->data.dir.entries;
337  dir->data.dir.entries = ent;
338  dir->data.dir.dir_size = 0;
339  return GNUNET_OK;
340 }
341 
342 
357 void
360  void *proc_cls)
361 {
362  struct GNUNET_FS_FileInformation *pos;
363  int no;
364 
365  no = GNUNET_NO;
366  if (GNUNET_OK !=
367  proc (proc_cls, dir,
368  (dir->is_directory == GNUNET_YES) ? dir->data.dir.dir_size : dir->data.
369  file.file_size,
370  dir->meta, &dir->keywords, &dir->bo,
371  (dir->is_directory == GNUNET_YES) ? &no : &dir->data.file.do_index,
372  &dir->client_info))
373  return;
374  if (dir->is_directory != GNUNET_YES)
375  return;
376  pos = dir->data.dir.entries;
377  while (pos != NULL)
378  {
379  no = GNUNET_NO;
380  if (GNUNET_OK !=
381  proc (proc_cls, pos,
382  (pos->is_directory == GNUNET_YES) ? pos->data.dir.dir_size : pos->data.
383  file.file_size, pos->meta, &pos->keywords, &pos->bo,
384  (pos->is_directory == GNUNET_YES) ? &no : &pos->data.file.do_index,
385  &pos->client_info))
386  break;
387  pos = pos->next;
388  }
389 }
390 
391 
402 void
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, fi, fi->data.dir.dir_size, fi->meta, &fi->keywords,
422  &fi->bo, &no, &fi->client_info);
424  }
425  else
426  {
427  /* call clean-up function of the reader */
428  if (NULL != fi->data.file.reader)
429  {
430  (void) fi->data.file.reader (fi->data.file.reader_cls, 0, 0, NULL, NULL);
431  fi->data.file.reader = NULL;
432  }
433  /* clean up client-info */
434  if (NULL != cleaner)
435  cleaner (cleaner_cls, fi, fi->data.file.file_size, fi->meta,
436  &fi->keywords, &fi->bo, &fi->data.file.do_index,
437  &fi->client_info);
438  }
441  if (NULL != fi->sks_uri)
443  if (NULL != fi->chk_uri)
445  /* clean up serialization */
446  if ((NULL != fi->serialization) && (0 != UNLINK (fi->serialization)))
448  fi->serialization);
449  if (NULL != fi->keywords)
451  if (NULL != fi->meta)
454  if (NULL != fi->te)
455  {
456  GNUNET_FS_tree_encoder_finish (fi->te, NULL);
457  fi->te = NULL;
458  }
459  GNUNET_free (fi);
460 }
461 
462 
463 /* end of fs_file_information.c */
struct GNUNET_FS_FileInformation * entries
Linked list of entries in the directory.
Definition: fs_api.h:371
void * reader_cls
Closure for reader.
Definition: fs_api.h:329
static char * dir
Set to the directory where runtime files are stored.
Definition: gnunet-arm.c:84
struct GNUNET_FS_FileInformation * dir
If this is a file in a directory, "dir" refers to the directory; otherwise NULL.
Definition: fs_api.h:243
struct GNUNET_FS_FileInformation * GNUNET_FS_file_information_create_empty_directory(struct GNUNET_FS_Handle *h, void *client_info, const struct GNUNET_FS_Uri *keywords, const struct GNUNET_CONTAINER_MetaData *meta, const struct GNUNET_FS_BlockOptions *bo, const char *filename)
Create an entry for an empty directory in a publish-structure.
int(* GNUNET_FS_FileInformationProcessor)(void *cls, struct GNUNET_FS_FileInformation *fi, uint64_t length, struct GNUNET_CONTAINER_MetaData *meta, struct GNUNET_FS_Uri **uri, struct GNUNET_FS_BlockOptions *bo, int *do_index, void **client_info)
Function called on entries in a struct GNUNET_FS_FileInformation iteration.
struct GNUNET_CONTAINER_MetaData * meta
Metadata to use for the file.
Definition: fs_api.h:258
struct GNUNET_FS_FileInformation::@19::@20 file
Data for a file.
void * client_info
Pointer kept for the client.
Definition: fs_api.h:253
char * emsg
Error message (non-NULL if this operation failed).
Definition: fs_api.h:302
char * serialization
Under what filename is this struct serialized (for operational persistence).
Definition: fs_api.h:292
Master context for most FS operations.
Definition: fs_api.h:1087
GNUNET_FS_DataReader reader
Function that can be used to read the data for the file.
Definition: fs_api.h:324
int GNUNET_FS_file_information_add(struct GNUNET_FS_FileInformation *dir, struct GNUNET_FS_FileInformation *ent)
Add an entry to a directory in a publish-structure.
size_t GNUNET_FS_data_reader_copy_(void *cls, uint64_t offset, size_t max, void *buf, char **emsg)
Function that provides data by copying from a buffer.
Definition: fs_api.c:569
struct GNUNET_FS_FileInformation * GNUNET_FS_file_information_create_from_data(struct GNUNET_FS_Handle *h, void *client_info, uint64_t length, void *data, const struct GNUNET_FS_Uri *keywords, const struct GNUNET_CONTAINER_MetaData *meta, int do_index, const struct GNUNET_FS_BlockOptions *bo)
Create an entry for a file in a publish-structure.
char * filename
Name of the file or directory (must be an absolute path).
Definition: fs_api.h:307
struct GNUNET_FS_FileInformation * GNUNET_FS_file_information_create_from_file(struct GNUNET_FS_Handle *h, void *client_info, const char *filename, const struct GNUNET_FS_Uri *keywords, const struct GNUNET_CONTAINER_MetaData *meta, int do_index, const struct GNUNET_FS_BlockOptions *bo)
Create an entry for a file in a publish-structure.
0-terminated, UTF-8 encoded string.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
size_t GNUNET_FS_data_reader_file_(void *cls, uint64_t offset, size_t max, void *buf, char **emsg)
Function that provides data by reading from a file.
Definition: fs_api.c:464
Information for a file or directory that is about to be published.
Definition: fs_api.h:231
struct GNUNET_FS_Handle * h
Handle to the master context.
Definition: fs_api.h:248
static int ret
Final status code.
Definition: gnunet-arm.c:89
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
void * dir_data
Pointer to the data for the directory (or NULL if not available).
Definition: fs_api.h:383
struct GNUNET_FS_Uri * GNUNET_FS_uri_dup(const struct GNUNET_FS_Uri *uri)
Duplicate URI.
Definition: fs_uri.c:988
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:94
#define UNLINK(f)
Definition: plibc.h:666
void GNUNET_FS_file_information_set_filename(struct GNUNET_FS_FileInformation *s, const char *filename)
Set the filename in the file information structure.
Meta data to associate with a file, directory or namespace.
struct GNUNET_FS_TreeEncoder * te
Encoder being used to publish this file.
Definition: fs_api.h:297
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
static char * fn
Filename of the unique file.
struct GNUNET_CONTAINER_MetaData * GNUNET_CONTAINER_meta_data_create(void)
Create a fresh meta data container.
int is_directory
Is this struct for a file or directory?
Definition: fs_api.h:402
static char * filename
void GNUNET_CONTAINER_meta_data_destroy(struct GNUNET_CONTAINER_MetaData *md)
Free meta data.
struct GNUNET_FS_Uri * chk_uri
CHK for this file or directory.
Definition: fs_api.h:269
void GNUNET_FS_uri_destroy(struct GNUNET_FS_Uri *uri)
Free URI.
Definition: fs_uri.c:670
const char * GNUNET_FS_file_information_get_filename(struct GNUNET_FS_FileInformation *s)
Obtain the filename from the file information structure.
int GNUNET_CONTAINER_meta_data_insert(struct GNUNET_CONTAINER_MetaData *md, const char *plugin_name, enum EXTRACTOR_MetaType type, enum EXTRACTOR_MetaFormat format, const char *data_mime_type, const char *data, size_t data_size)
Extend metadata.
int plibc_conv_to_win_path(const char *pszUnix, char *pszWindows)
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
void * GNUNET_FS_make_file_reader_context_(const char *filename)
Create the closure for the GNUNET_FS_data_reader_file_() callback.
Definition: fs_api.c:533
Settings for publishing a block (which may of course also apply to an entire directory or file)...
struct GNUNET_FS_FileInformation * next
Files in a directory are kept as a linked list.
Definition: fs_api.h:237
int GNUNET_DISK_file_size(const char *filename, uint64_t *size, int include_symbolic_links, int single_file_mode)
Get the size of the file (or directory) of the given file (in bytes).
Definition: disk.c:289
int GNUNET_FS_file_information_is_directory(const struct GNUNET_FS_FileInformation *ent)
Test if a given entry represents a directory.
struct GNUNET_FS_BlockOptions bo
Block options for the file.
Definition: fs_api.h:280
int do_index
Should the file be indexed or inserted?
Definition: fs_api.h:346
size_t(* GNUNET_FS_DataReader)(void *cls, uint64_t offset, size_t max, void *buf, char **emsg)
Function that provides data.
union GNUNET_FS_FileInformation::@19 data
Data describing either the file or the directory.
shared definitions for the FS library
void GNUNET_FS_file_information_inspect(struct GNUNET_FS_FileInformation *dir, GNUNET_FS_FileInformationProcessor proc, void *proc_cls)
Inspect a file or directory in a publish-structure.
A Universal Resource Identifier (URI), opaque.
Definition: fs_api.h:168
static struct GNUNET_CONTAINER_MetaData * meta
Meta-data provided via command-line option.
struct GNUNET_FS_Uri * keywords
Keywords to use for KBlocks.
Definition: fs_api.h:263
void GNUNET_FS_file_information_destroy(struct GNUNET_FS_FileInformation *fi, GNUNET_FS_FileInformationProcessor cleaner, void *cleaner_cls)
Destroy publish-structure.
struct GNUNET_FS_FileInformation * GNUNET_FS_file_information_create_from_reader(struct GNUNET_FS_Handle *h, void *client_info, uint64_t length, GNUNET_FS_DataReader reader, void *reader_cls, const struct GNUNET_FS_Uri *keywords, const struct GNUNET_CONTAINER_MetaData *meta, int do_index, const struct GNUNET_FS_BlockOptions *bo)
Create an entry for a file in a publish-structure.
void GNUNET_FS_tree_encoder_finish(struct GNUNET_FS_TreeEncoder *te, char **emsg)
Clean up a tree encoder and return information about possible errors.
Definition: fs_tree.c:444
#define GNUNET_YES
Definition: gnunet_common.h:80
#define DIR_SEPARATOR_STR
Definition: plibc.h:632
uint32_t data
The data value.
size_t dir_size
Size of the directory itself (in bytes); 0 if the size has not yet been calculated.
Definition: fs_api.h:377
struct GNUNET_FS_Uri * sks_uri
SKS URI for this file or directory.
Definition: fs_api.h:275
Closure for GNUNET_FS_data_reader_file_().
Definition: fs_api.c:429
const char * GNUNET_FS_file_information_get_id(struct GNUNET_FS_FileInformation *s)
Obtain the name under which this file information structure is stored on disk.
static struct GNUNET_FS_BlockOptions bo
Options we set for published blocks.
#define GNUNET_free(ptr)
Wrapper around free.
Merkle-tree-ish-CHK file encoding for GNUnet.
struct GNUNET_CONTAINER_MetaData * GNUNET_CONTAINER_meta_data_duplicate(const struct GNUNET_CONTAINER_MetaData *md)
Duplicate a MetaData token.