include plugin in gnunet-transport output
[oweals/gnunet.git] / src / include / gnunet_disk_lib.h
1 /*
2      This file is part of GNUnet.
3      (C) 2001, 2002, 2003, 2004, 2005, 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 include/gnunet_disk_lib.h
23  * @brief disk IO apis
24  */
25 #ifndef GNUNET_DISK_LIB_H
26 #define GNUNET_DISK_LIB_H
27
28 /**
29  * Opaque handle used to access files.
30  */
31 struct GNUNET_DISK_FileHandle;
32
33 /**
34  * Handle used to manage a pipe.
35  */
36 struct GNUNET_DISK_PipeHandle;
37
38
39 enum GNUNET_FILE_Type
40 {
41   GNUNET_DISK_FILE, GNUNET_PIPE
42 };
43
44 /**
45  * Handle used to access files (and pipes).
46  */
47 struct GNUNET_DISK_FileHandle
48 {
49
50 #if WINDOWS
51   /**
52    * File handle under W32.
53    */
54   HANDLE h;
55
56   /**
57    * Type
58    */
59   enum GNUNET_FILE_Type type;
60
61   /**
62    * Structure for overlapped reading (for pipes)
63    */
64   OVERLAPPED *oOverlapRead;
65
66   /**
67    * Structure for overlapped writing (for pipes)
68    */
69   OVERLAPPED *oOverlapWrite;
70 #else
71
72   /**
73    * File handle on other OSes.
74    */
75   int fd;
76
77 #endif                          /*
78                                  */
79 };
80
81
82 /* we need size_t, and since it can be both unsigned int
83    or unsigned long long, this IS platform dependent;
84    but "stdlib.h" should be portable 'enough' to be
85    unconditionally available... */
86 #include <stdlib.h>
87 #include "gnunet_configuration_lib.h"
88 #include "gnunet_scheduler_lib.h"
89
90 #ifdef __cplusplus
91 extern "C"
92 {
93 #if 0                           /* keep Emacsens' auto-indent happy */
94 }
95 #endif
96 #endif
97
98
99 /**
100  * Specifies how a file should be opened.
101  */
102 enum GNUNET_DISK_OpenFlags
103 {
104
105     /**
106      * Open the file for reading
107      */
108   GNUNET_DISK_OPEN_READ = 1,
109
110     /**
111      * Open the file for writing
112      */
113   GNUNET_DISK_OPEN_WRITE = 2,
114
115     /**
116      * Open the file for both reading and writing
117      */
118   GNUNET_DISK_OPEN_READWRITE = 3,
119
120     /**
121      * Fail if file already exists
122      */
123   GNUNET_DISK_OPEN_FAILIFEXISTS = 4,
124
125     /**
126      * Truncate file if it exists
127      */
128   GNUNET_DISK_OPEN_TRUNCATE = 8,
129
130     /**
131      * Create file if it doesn't exist
132      */
133   GNUNET_DISK_OPEN_CREATE = 16,
134
135     /**
136      * Append to the file
137      */
138   GNUNET_DISK_OPEN_APPEND = 32
139 };
140
141 /**
142  * Specifies what type of memory map is desired.
143  */
144 enum GNUNET_DISK_MapType
145 {
146     /**
147      * Read-only memory map.
148      */
149   GNUNET_DISK_MAP_TYPE_READ = 1,
150
151     /**
152      * Write-able memory map.
153      */
154   GNUNET_DISK_MAP_TYPE_WRITE = 2,
155     /**
156      * Read-write memory map.
157      */
158   GNUNET_DISK_MAP_TYPE_READWRITE = 3
159 };
160
161
162 /**
163  * File access permissions, UNIX-style.
164  */
165 enum GNUNET_DISK_AccessPermissions
166 {
167     /**
168      * Nobody is allowed to do anything to the file.
169      */
170   GNUNET_DISK_PERM_NONE = 0,
171
172     /**
173      * Owner can read.
174      */
175   GNUNET_DISK_PERM_USER_READ = 1,
176
177     /**
178      * Owner can write.
179      */
180   GNUNET_DISK_PERM_USER_WRITE = 2,
181
182     /**
183      * Owner can execute.
184      */
185   GNUNET_DISK_PERM_USER_EXEC = 4,
186
187     /**
188      * Group can read.
189      */
190   GNUNET_DISK_PERM_GROUP_READ = 8,
191
192     /**
193      * Group can write.
194      */
195   GNUNET_DISK_PERM_GROUP_WRITE = 16,
196
197     /**
198      * Group can execute.
199      */
200   GNUNET_DISK_PERM_GROUP_EXEC = 32,
201
202     /**
203      * Everybody can read.
204      */
205   GNUNET_DISK_PERM_OTHER_READ = 64,
206
207     /**
208      * Everybody can write.
209      */
210   GNUNET_DISK_PERM_OTHER_WRITE = 128,
211
212     /**
213      * Everybody can execute.
214      */
215   GNUNET_DISK_PERM_OTHER_EXEC = 256
216 };
217
218
219 /**
220  * Constants for specifying how to seek.
221  */
222 enum GNUNET_DISK_Seek
223 {
224     /**
225      * Seek an absolute position (from the start of the file).
226      */
227   GNUNET_DISK_SEEK_SET,
228
229     /**
230      * Seek a relative position (from the current offset).
231      */
232   GNUNET_DISK_SEEK_CUR,
233
234     /**
235      * Seek an absolute position from the end of the file.
236      */
237   GNUNET_DISK_SEEK_END
238 };
239
240
241 /**
242  * Enumeration identifying the two ends of a pipe.
243  */
244 enum GNUNET_DISK_PipeEnd
245 {
246     /**
247      * The reading-end of a pipe.
248      */
249   GNUNET_DISK_PIPE_END_READ = 0,
250
251     /**
252      * The writing-end of a pipe.
253      */
254   GNUNET_DISK_PIPE_END_WRITE = 1
255 };
256
257
258 /**
259  * Get the number of blocks that are left on the partition that
260  * contains the given file (for normal users).
261  *
262  * @param part a file on the partition to check
263  * @return -1 on errors, otherwise the number of free blocks
264  */
265 long
266 GNUNET_DISK_get_blocks_available (const char *part);
267
268
269 /**
270  * Checks whether a handle is invalid
271  *
272  * @param h handle to check
273  * @return GNUNET_YES if invalid, GNUNET_NO if valid
274  */
275 int
276 GNUNET_DISK_handle_invalid (const struct GNUNET_DISK_FileHandle *h);
277
278
279 /**
280  * Check that fil corresponds to a filename
281  * (of a file that exists and that is not a directory).
282  *
283  * @param fil filename to check
284  * @return GNUNET_YES if yes, GNUNET_NO if not a file, GNUNET_SYSERR if something
285  * else (will print an error message in that case, too).
286  */
287 int
288 GNUNET_DISK_file_test (const char *fil);
289
290
291 /**
292  * Move the read/write pointer in a file
293  * @param h handle of an open file
294  * @param offset position to move to
295  * @param whence specification to which position the offset parameter relates to
296  * @return the new position on success, GNUNET_SYSERR otherwise
297  */
298 off_t
299 GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle *h, off_t offset,
300                        enum GNUNET_DISK_Seek whence);
301
302
303 /**
304  * Get the size of the file (or directory)
305  * of the given file (in bytes).
306  *
307  * @param filename name of the file or directory
308  * @param size set to the size of the file (or,
309  *             in the case of directories, the sum
310  *             of all sizes of files in the directory)
311  * @param includeSymLinks should symbolic links be
312  *        included?
313  * @return GNUNET_OK on success, GNUNET_SYSERR on error
314  */
315 int
316 GNUNET_DISK_file_size (const char *filename, uint64_t * size,
317                        int includeSymLinks);
318
319
320 /**
321  * Obtain some unique identifiers for the given file
322  * that can be used to identify it in the local system.
323  * This function is used between GNUnet processes to
324  * quickly check if two files with the same absolute path
325  * are actually identical.  The two processes represent
326  * the same peer but may communicate over the network
327  * (and the file may be on an NFS volume).  This function
328  * may not be supported on all operating systems.
329  *
330  * @param filename name of the file
331  * @param dev set to the device ID
332  * @param ino set to the inode ID
333  * @return GNUNET_OK on success
334  */
335 int
336 GNUNET_DISK_file_get_identifiers (const char *filename, uint64_t * dev,
337                                   uint64_t * ino);
338
339
340 /**
341  * Create an (empty) temporary file on disk.  If the given name is not
342  * an absolute path, the current 'TMPDIR' will be prepended.  In any case,
343  * 6 random characters will be appended to the name to create a unique
344  * filename.
345  *
346  * @param t component to use for the name;
347  *        does NOT contain "XXXXXX" or "/tmp/".
348  * @return NULL on error, otherwise name of fresh
349  *         file on disk in directory for temporary files
350  */
351 char *
352 GNUNET_DISK_mktemp (const char *t);
353
354
355 /**
356  * Open a file.  Note that the access permissions will only be
357  * used if a new file is created and if the underlying operating
358  * system supports the given permissions.
359  *
360  * @param fn file name to be opened
361  * @param flags opening flags, a combination of GNUNET_DISK_OPEN_xxx bit flags
362  * @param perm permissions for the newly created file, use
363  *             GNUNET_DISK_PERM_NONE if a file could not be created by this
364  *             call (because of flags)
365  * @return IO handle on success, NULL on error
366  */
367 struct GNUNET_DISK_FileHandle *
368 GNUNET_DISK_file_open (const char *fn, enum GNUNET_DISK_OpenFlags flags,
369                        enum GNUNET_DISK_AccessPermissions perm);
370
371
372 /**
373  * Get the size of an open file.
374  *
375  * @param fh open file handle
376  * @param size where to write size of the file
377  * @return GNUNET_OK on success, GNUNET_SYSERR on error
378  */
379 int
380 GNUNET_DISK_file_handle_size (struct GNUNET_DISK_FileHandle *fh,
381                               off_t *size);
382
383
384 /**
385  * Creates an interprocess channel
386  * @param blocking creates an asynchronous pipe if set to GNUNET_NO
387  * @param inherit_read 1 to make read handle inheritable, 0 otherwise (NT only)
388  * @param inherit_write 1 to make write handle inheritable, 0 otherwise (NT only)
389  * @return handle to the new pipe, NULL on error
390  */
391 struct GNUNET_DISK_PipeHandle *
392 GNUNET_DISK_pipe (int blocking, int inherit_read, int inherit_write);
393
394
395 /**
396  * Closes an interprocess channel
397  * @param p pipe
398  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
399  */
400 int
401 GNUNET_DISK_pipe_close (struct GNUNET_DISK_PipeHandle *p);
402
403 /**
404  * Closes one half of an interprocess channel
405  *
406  * @param p pipe to close end of
407  * @param end which end of the pipe to close
408  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
409  */
410 int
411 GNUNET_DISK_pipe_close_end (struct GNUNET_DISK_PipeHandle *p,
412                             enum GNUNET_DISK_PipeEnd end);
413
414 /**
415  * Close an open file.
416  *
417  * @param h file handle
418  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
419  */
420 int
421 GNUNET_DISK_file_close (struct GNUNET_DISK_FileHandle *h);
422
423
424 /**
425  * Get the handle to a particular pipe end
426  *
427  * @param p pipe
428  * @param n end to access
429  * @return handle for the respective end
430  */
431 const struct GNUNET_DISK_FileHandle *
432 GNUNET_DISK_pipe_handle (const struct GNUNET_DISK_PipeHandle *p,
433                          enum GNUNET_DISK_PipeEnd n);
434
435 /**
436  * Read the contents of a binary file into a buffer.
437  * @param h handle to an open file
438  * @param result the buffer to write the result to
439  * @param len the maximum number of bytes to read
440  * @return the number of bytes read on success, GNUNET_SYSERR on failure
441  */
442 ssize_t
443 GNUNET_DISK_file_read (const struct GNUNET_DISK_FileHandle *h, void *result,
444                        size_t len);
445
446
447 /**
448  * Read the contents of a binary file into a buffer.
449  *
450  * @param fn file name
451  * @param result the buffer to write the result to
452  * @param len the maximum number of bytes to read
453  * @return number of bytes read, GNUNET_SYSERR on failure
454  */
455 ssize_t
456 GNUNET_DISK_fn_read (const char *fn, void *result, size_t len);
457
458
459 /**
460  * Write a buffer to a file.
461  *
462  * @param h handle to open file
463  * @param buffer the data to write
464  * @param n number of bytes to write
465  * @return number of bytes written on success, GNUNET_SYSERR on error
466  */
467 ssize_t
468 GNUNET_DISK_file_write (const struct GNUNET_DISK_FileHandle *h,
469                         const void *buffer, size_t n);
470
471
472 /**
473  * Write a buffer to a file.  If the file is longer than
474  * the given buffer size, it will be truncated.
475  *
476  * @param fn file name
477  * @param buffer the data to write
478  * @param n number of bytes to write
479  * @param mode file permissions
480  * @return number of bytes written on success, GNUNET_SYSERR on error
481  */
482 ssize_t
483 GNUNET_DISK_fn_write (const char *fn, const void *buffer, size_t n,
484                       enum GNUNET_DISK_AccessPermissions mode);
485
486
487 /**
488  * Copy a file.
489  *
490  * @param src file to copy
491  * @param dst destination file name
492  * @return GNUNET_OK on success, GNUNET_SYSERR on error
493  */
494 int
495 GNUNET_DISK_file_copy (const char *src, const char *dst);
496
497
498 /**
499  * Scan a directory for files.
500  *
501  * @param dirName the name of the directory
502  * @param callback the method to call for each file
503  * @param callback_cls closure for callback
504  * @return the number of files found, -1 on error
505  */
506 int
507 GNUNET_DISK_directory_scan (const char *dirName,
508                             GNUNET_FileNameCallback callback,
509                             void *callback_cls);
510
511
512 /**
513  * Opaque handle used for iterating over a directory.
514  */
515 struct GNUNET_DISK_DirectoryIterator;
516
517
518 /**
519  * Function called to iterate over a directory.
520  *
521  * @param cls closure
522  * @param di argument to pass to "GNUNET_DISK_directory_iterator_next" to
523  *           get called on the next entry (or finish cleanly);
524  *           NULL on error (will be the last call in that case)
525  * @param filename complete filename (absolute path)
526  * @param dirname directory name (absolute path)
527  */
528 typedef void (*GNUNET_DISK_DirectoryIteratorCallback) (void *cls,
529                                                        struct
530                                                        GNUNET_DISK_DirectoryIterator
531                                                        * di,
532                                                        const char *filename,
533                                                        const char *dirname);
534
535
536 /**
537  * This function must be called during the DiskIteratorCallback
538  * (exactly once) to schedule the task to process the next
539  * filename in the directory (if there is one).
540  *
541  * @param iter opaque handle for the iterator
542  * @param can set to GNUNET_YES to terminate the iteration early
543  * @return GNUNET_YES if iteration will continue,
544  *         GNUNET_NO if this was the last entry (and iteration is complete),
545  *         GNUNET_SYSERR if "can" was YES
546  */
547 int
548 GNUNET_DISK_directory_iterator_next (struct GNUNET_DISK_DirectoryIterator *iter,
549                                      int can);
550
551
552 /**
553  * Scan a directory for files using the scheduler to run a task for
554  * each entry.  The name of the directory must be expanded first (!).
555  * If a scheduler does not need to be used, GNUNET_DISK_directory_scan
556  * may provide a simpler API.
557  *
558  * @param prio priority to use
559  * @param dirName the name of the directory
560  * @param callback the method to call for each file
561  * @param callback_cls closure for callback
562  */
563 void
564 GNUNET_DISK_directory_iterator_start (enum GNUNET_SCHEDULER_Priority prio,
565                                       const char *dirName,
566                                       GNUNET_DISK_DirectoryIteratorCallback
567                                       callback, void *callback_cls);
568
569
570 /**
571  * Create the directory structure for storing
572  * a file.
573  *
574  * @param filename name of a file in the directory
575  * @returns GNUNET_OK on success, GNUNET_SYSERR on failure,
576  *          GNUNET_NO if directory exists but is not writeable
577  */
578 int
579 GNUNET_DISK_directory_create_for_file (const char *filename);
580
581
582 /**
583  * Test if "fil" is a directory that can be accessed.
584  * Will not print an error message if the directory
585  * does not exist.  Will log errors if GNUNET_SYSERR is
586  * returned.
587  *
588  * @param fil filename to test
589  * @return GNUNET_YES if yes, GNUNET_NO if does not exist, GNUNET_SYSERR
590  *   on any error and if exists but not directory
591  */
592 int
593 GNUNET_DISK_directory_test (const char *fil);
594
595
596 /**
597  * Remove all files in a directory (rm -rf). Call with
598  * caution.
599  *
600  * @param fileName the file to remove
601  * @return GNUNET_OK on success, GNUNET_SYSERR on error
602  */
603 int
604 GNUNET_DISK_directory_remove (const char *fileName);
605
606
607 /**
608  * Implementation of "mkdir -p"
609  *
610  * @param dir the directory to create
611  * @returns GNUNET_SYSERR on failure, GNUNET_OK otherwise
612  */
613 int
614 GNUNET_DISK_directory_create (const char *dir);
615
616
617 /**
618  * Lock a part of a file.
619  *
620  * @param fh file handle
621  * @param lockStart absolute position from where to lock
622  * @param lockEnd absolute position until where to lock
623  * @param excl GNUNET_YES for an exclusive lock
624  * @return GNUNET_OK on success, GNUNET_SYSERR on error
625  */
626 int
627 GNUNET_DISK_file_lock (struct GNUNET_DISK_FileHandle *fh, off_t lockStart,
628                        off_t lockEnd, int excl);
629
630
631 /**
632  * Unlock a part of a file
633  * @param fh file handle
634  * @param unlockStart absolute position from where to unlock
635  * @param unlockEnd absolute position until where to unlock
636  * @return GNUNET_OK on success, GNUNET_SYSERR on error
637  */
638 int
639 GNUNET_DISK_file_unlock (struct GNUNET_DISK_FileHandle *fh, off_t unlockStart,
640                          off_t unlockEnd);
641
642
643 /**
644  * @brief Removes special characters as ':' from a filename.
645  * @param fn the filename to canonicalize
646  */
647 void
648 GNUNET_DISK_filename_canonicalize (char *fn);
649
650
651 /**
652  * @brief Change owner of a file
653  * @param filename file to change
654  * @param user new owner of the file
655  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
656  */
657 int
658 GNUNET_DISK_file_change_owner (const char *filename, const char *user);
659
660
661 /**
662  * Construct full path to a file inside of the private
663  * directory used by GNUnet.  Also creates the corresponding
664  * directory.  If the resulting name is supposed to be
665  * a directory, end the last argument in '/' (or pass
666  * DIR_SEPARATOR_STR as the last argument before NULL).
667  *
668  * @param cfg configuration to use
669  * @param serviceName name of the service asking
670  * @param ... is NULL-terminated list of
671  *                path components to append to the
672  *                private directory name.
673  * @return the constructed filename
674  */
675 char *
676 GNUNET_DISK_get_home_filename (const struct GNUNET_CONFIGURATION_Handle *cfg,
677                                const char *serviceName, ...);
678
679
680 /**
681  * Opaque handle for a memory-mapping operation.
682  */
683 struct GNUNET_DISK_MapHandle;
684
685 /**
686  * Map a file into memory
687  * @param h open file handle
688  * @param m handle to the new mapping (will be set)
689  * @param access access specification, GNUNET_DISK_MAP_TYPE_xxx
690  * @param len size of the mapping
691  * @return pointer to the mapped memory region, NULL on failure
692  */
693 void *
694 GNUNET_DISK_file_map (const struct GNUNET_DISK_FileHandle *h,
695                       struct GNUNET_DISK_MapHandle **m,
696                       enum GNUNET_DISK_MapType access, size_t len);
697
698 /**
699  * Unmap a file
700  *
701  * @param h mapping handle
702  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
703  */
704 int
705 GNUNET_DISK_file_unmap (struct GNUNET_DISK_MapHandle *h);
706
707 /**
708  * Write file changes to disk
709  * @param h handle to an open file
710  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
711  */
712 int
713 GNUNET_DISK_file_sync (const struct GNUNET_DISK_FileHandle *h);
714
715 /**
716  * Creates a named pipe/FIFO and opens it
717  * @param fn pointer to the name of the named pipe or to NULL
718  * @param flags open flags
719  * @param perm access permissions
720  * @return pipe handle on success, NULL on error
721  */
722 struct GNUNET_DISK_FileHandle *
723 GNUNET_DISK_npipe_create (char **fn, enum GNUNET_DISK_OpenFlags flags,
724                           enum GNUNET_DISK_AccessPermissions perm);
725
726 /**
727  * Opens already existing named pipe/FIFO
728  *
729  * @param fn name of an existing named pipe
730  * @param flags open flags
731  * @param perm access permissions
732  * @return pipe handle on success, NULL on error
733  */
734 struct GNUNET_DISK_FileHandle *
735 GNUNET_DISK_npipe_open (const char *fn, enum GNUNET_DISK_OpenFlags flags,
736                         enum GNUNET_DISK_AccessPermissions perm);
737
738 /**
739  * Closes a named pipe/FIFO
740  * @param pipe named pipe
741  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
742  */
743 int
744 GNUNET_DISK_npipe_close (struct GNUNET_DISK_FileHandle *pipe);
745
746 #if 0                           /* keep Emacsens' auto-indent happy */
747 {
748 #endif
749 #ifdef __cplusplus
750 }
751 #endif
752
753
754 /* ifndef GNUNET_DISK_LIB_H */
755 #endif
756 /* end of gnunet_disk_lib.h */